30
30
#define MII_DP83822_FCSCR 0x14
31
31
#define MII_DP83822_RCSR 0x17
32
32
#define MII_DP83822_RESET_CTRL 0x1f
33
+ #define MII_DP83822_MLEDCR 0x25
34
+ #define MII_DP83822_LEDCFG1 0x460
35
+ #define MII_DP83822_IOCTRL1 0x462
33
36
#define MII_DP83822_IOCTRL2 0x463
34
37
#define MII_DP83822_GENCFG 0x465
35
38
#define MII_DP83822_SOR1 0x467
105
108
#define DP83822_RX_CLK_SHIFT BIT(12)
106
109
#define DP83822_TX_CLK_SHIFT BIT(11)
107
110
111
+ /* MLEDCR bits */
112
+ #define DP83822_MLEDCR_CFG GENMASK(6, 3)
113
+ #define DP83822_MLEDCR_ROUTE GENMASK(1, 0)
114
+ #define DP83822_MLEDCR_ROUTE_LED_0 DP83822_MLEDCR_ROUTE
115
+
116
+ /* LEDCFG1 bits */
117
+ #define DP83822_LEDCFG1_LED1_CTRL GENMASK(11, 8)
118
+ #define DP83822_LEDCFG1_LED3_CTRL GENMASK(7, 4)
119
+
120
+ /* IOCTRL1 bits */
121
+ #define DP83822_IOCTRL1_GPIO3_CTRL GENMASK(10, 8)
122
+ #define DP83822_IOCTRL1_GPIO3_CTRL_LED3 BIT(0)
123
+ #define DP83822_IOCTRL1_GPIO1_CTRL GENMASK(2, 0)
124
+ #define DP83822_IOCTRL1_GPIO1_CTRL_LED_1 BIT(0)
125
+
108
126
/* IOCTRL2 bits */
109
127
#define DP83822_IOCTRL2_GPIO2_CLK_SRC GENMASK(6, 4)
110
128
#define DP83822_IOCTRL2_GPIO2_CTRL GENMASK(2, 0)
111
129
#define DP83822_IOCTRL2_GPIO2_CTRL_CLK_REF GENMASK(1, 0)
130
+ #define DP83822_IOCTRL2_GPIO2_CTRL_MLED BIT(0)
112
131
113
132
#define DP83822_CLK_SRC_MAC_IF 0x0
114
133
#define DP83822_CLK_SRC_XI 0x1
117
136
#define DP83822_CLK_SRC_FREE_RUNNING 0x6
118
137
#define DP83822_CLK_SRC_RECOVERED 0x7
119
138
139
+ #define DP83822_LED_FN_LINK 0x0 /* Link established */
140
+ #define DP83822_LED_FN_RX_TX 0x1 /* Receive or Transmit activity */
141
+ #define DP83822_LED_FN_TX 0x2 /* Transmit activity */
142
+ #define DP83822_LED_FN_RX 0x3 /* Receive activity */
143
+ #define DP83822_LED_FN_COLLISION 0x4 /* Collision detected */
144
+ #define DP83822_LED_FN_LINK_100_BTX 0x5 /* 100 BTX link established */
145
+ #define DP83822_LED_FN_LINK_10_BT 0x6 /* 10BT link established */
146
+ #define DP83822_LED_FN_FULL_DUPLEX 0x7 /* Full duplex */
147
+ #define DP83822_LED_FN_LINK_RX_TX 0x8 /* Link established, blink for rx or tx activity */
148
+ #define DP83822_LED_FN_ACTIVE_STRETCH 0x9 /* Active Stretch Signal */
149
+ #define DP83822_LED_FN_MII_LINK 0xa /* MII LINK (100BT+FD) */
150
+ #define DP83822_LED_FN_LPI_MODE 0xb /* LPI Mode (EEE) */
151
+ #define DP83822_LED_FN_RX_TX_ERR 0xc /* TX/RX MII Error */
152
+ #define DP83822_LED_FN_LINK_LOST 0xd /* Link Lost */
153
+ #define DP83822_LED_FN_PRBS_ERR 0xe /* Blink for PRBS error */
154
+
120
155
/* SOR1 mode */
121
156
#define DP83822_STRAP_MODE1 0
122
157
#define DP83822_STRAP_MODE2 BIT(0)
145
180
ADVERTISED_FIBRE | \
146
181
ADVERTISED_Pause | ADVERTISED_Asym_Pause)
147
182
183
+ #define DP83822_MAX_LED_PINS 4
184
+
185
+ #define DP83822_LED_INDEX_LED_0 0
186
+ #define DP83822_LED_INDEX_LED_1_GPIO1 1
187
+ #define DP83822_LED_INDEX_COL_GPIO2 2
188
+ #define DP83822_LED_INDEX_RX_D3_GPIO3 3
189
+
148
190
struct dp83822_private {
149
191
bool fx_signal_det_low ;
150
192
int fx_enabled ;
@@ -154,6 +196,7 @@ struct dp83822_private {
154
196
struct ethtool_wolinfo wol ;
155
197
bool set_gpio2_clk_out ;
156
198
u32 gpio2_clk_out ;
199
+ bool led_pin_enable [DP83822_MAX_LED_PINS ];
157
200
};
158
201
159
202
static int dp83822_config_wol (struct phy_device * phydev ,
@@ -418,6 +461,48 @@ static int dp83822_read_status(struct phy_device *phydev)
418
461
return 0 ;
419
462
}
420
463
464
+ static int dp83822_config_init_leds (struct phy_device * phydev )
465
+ {
466
+ struct dp83822_private * dp83822 = phydev -> priv ;
467
+ int ret ;
468
+
469
+ if (dp83822 -> led_pin_enable [DP83822_LED_INDEX_LED_0 ]) {
470
+ ret = phy_modify_mmd (phydev , MDIO_MMD_VEND2 , MII_DP83822_MLEDCR ,
471
+ DP83822_MLEDCR_ROUTE ,
472
+ FIELD_PREP (DP83822_MLEDCR_ROUTE ,
473
+ DP83822_MLEDCR_ROUTE_LED_0 ));
474
+ if (ret )
475
+ return ret ;
476
+ } else if (dp83822 -> led_pin_enable [DP83822_LED_INDEX_COL_GPIO2 ]) {
477
+ ret = phy_modify_mmd (phydev , MDIO_MMD_VEND2 , MII_DP83822_IOCTRL2 ,
478
+ DP83822_IOCTRL2_GPIO2_CTRL ,
479
+ FIELD_PREP (DP83822_IOCTRL2_GPIO2_CTRL ,
480
+ DP83822_IOCTRL2_GPIO2_CTRL_MLED ));
481
+ if (ret )
482
+ return ret ;
483
+ }
484
+
485
+ if (dp83822 -> led_pin_enable [DP83822_LED_INDEX_LED_1_GPIO1 ]) {
486
+ ret = phy_modify_mmd (phydev , MDIO_MMD_VEND2 , MII_DP83822_IOCTRL1 ,
487
+ DP83822_IOCTRL1_GPIO1_CTRL ,
488
+ FIELD_PREP (DP83822_IOCTRL1_GPIO1_CTRL ,
489
+ DP83822_IOCTRL1_GPIO1_CTRL_LED_1 ));
490
+ if (ret )
491
+ return ret ;
492
+ }
493
+
494
+ if (dp83822 -> led_pin_enable [DP83822_LED_INDEX_RX_D3_GPIO3 ]) {
495
+ ret = phy_modify_mmd (phydev , MDIO_MMD_VEND2 , MII_DP83822_IOCTRL1 ,
496
+ DP83822_IOCTRL1_GPIO3_CTRL ,
497
+ FIELD_PREP (DP83822_IOCTRL1_GPIO3_CTRL ,
498
+ DP83822_IOCTRL1_GPIO3_CTRL_LED3 ));
499
+ if (ret )
500
+ return ret ;
501
+ }
502
+
503
+ return 0 ;
504
+ }
505
+
421
506
static int dp83822_config_init (struct phy_device * phydev )
422
507
{
423
508
struct dp83822_private * dp83822 = phydev -> priv ;
@@ -437,6 +522,10 @@ static int dp83822_config_init(struct phy_device *phydev)
437
522
FIELD_PREP (DP83822_IOCTRL2_GPIO2_CLK_SRC ,
438
523
dp83822 -> gpio2_clk_out ));
439
524
525
+ err = dp83822_config_init_leds (phydev );
526
+ if (err )
527
+ return err ;
528
+
440
529
if (phy_interface_is_rgmii (phydev )) {
441
530
rx_int_delay = phy_get_internal_delay (phydev , dev , NULL , 0 ,
442
531
true);
@@ -631,6 +720,61 @@ static int dp83822_phy_reset(struct phy_device *phydev)
631
720
}
632
721
633
722
#ifdef CONFIG_OF_MDIO
723
+ static int dp83822_of_init_leds (struct phy_device * phydev )
724
+ {
725
+ struct device_node * node = phydev -> mdio .dev .of_node ;
726
+ struct dp83822_private * dp83822 = phydev -> priv ;
727
+ struct device_node * leds ;
728
+ u32 index ;
729
+ int err ;
730
+
731
+ if (!node )
732
+ return 0 ;
733
+
734
+ leds = of_get_child_by_name (node , "leds" );
735
+ if (!leds )
736
+ return 0 ;
737
+
738
+ for_each_available_child_of_node_scoped (leds , led ) {
739
+ err = of_property_read_u32 (led , "reg" , & index );
740
+ if (err ) {
741
+ of_node_put (leds );
742
+ return err ;
743
+ }
744
+
745
+ if (index <= DP83822_LED_INDEX_RX_D3_GPIO3 ) {
746
+ dp83822 -> led_pin_enable [index ] = true;
747
+ } else {
748
+ of_node_put (leds );
749
+ return - EINVAL ;
750
+ }
751
+ }
752
+
753
+ of_node_put (leds );
754
+ /* LED_0 and COL(GPIO2) use the MLED function. MLED can be routed to
755
+ * only one of these two pins at a time.
756
+ */
757
+ if (dp83822 -> led_pin_enable [DP83822_LED_INDEX_LED_0 ] &&
758
+ dp83822 -> led_pin_enable [DP83822_LED_INDEX_COL_GPIO2 ]) {
759
+ phydev_err (phydev , "LED_0 and COL(GPIO2) cannot be used as LED output at the same time\n" );
760
+ return - EINVAL ;
761
+ }
762
+
763
+ if (dp83822 -> led_pin_enable [DP83822_LED_INDEX_COL_GPIO2 ] &&
764
+ dp83822 -> set_gpio2_clk_out ) {
765
+ phydev_err (phydev , "COL(GPIO2) cannot be used as LED outout, already used as clock output\n" );
766
+ return - EINVAL ;
767
+ }
768
+
769
+ if (dp83822 -> led_pin_enable [DP83822_LED_INDEX_RX_D3_GPIO3 ] &&
770
+ phydev -> interface != PHY_INTERFACE_MODE_RMII ) {
771
+ phydev_err (phydev , "RX_D3 can only be used as LED output when in RMII mode\n" );
772
+ return - EINVAL ;
773
+ }
774
+
775
+ return 0 ;
776
+ }
777
+
634
778
static int dp83822_of_init (struct phy_device * phydev )
635
779
{
636
780
struct dp83822_private * dp83822 = phydev -> priv ;
@@ -671,7 +815,7 @@ static int dp83822_of_init(struct phy_device *phydev)
671
815
dp83822 -> set_gpio2_clk_out = true;
672
816
}
673
817
674
- return 0 ;
818
+ return dp83822_of_init_leds ( phydev ) ;
675
819
}
676
820
677
821
static int dp83826_to_dac_minus_one_regval (int percent )
@@ -769,7 +913,9 @@ static int dp83822_probe(struct phy_device *phydev)
769
913
if (ret )
770
914
return ret ;
771
915
772
- dp83822_of_init (phydev );
916
+ ret = dp83822_of_init (phydev );
917
+ if (ret )
918
+ return ret ;
773
919
774
920
if (dp83822 -> fx_enabled )
775
921
phydev -> port = PORT_FIBRE ;
@@ -816,6 +962,130 @@ static int dp83822_resume(struct phy_device *phydev)
816
962
return 0 ;
817
963
}
818
964
965
+ static int dp83822_led_mode (u8 index , unsigned long rules )
966
+ {
967
+ switch (rules ) {
968
+ case BIT (TRIGGER_NETDEV_LINK ):
969
+ return DP83822_LED_FN_LINK ;
970
+ case BIT (TRIGGER_NETDEV_LINK_10 ):
971
+ return DP83822_LED_FN_LINK_10_BT ;
972
+ case BIT (TRIGGER_NETDEV_LINK_100 ):
973
+ return DP83822_LED_FN_LINK_100_BTX ;
974
+ case BIT (TRIGGER_NETDEV_FULL_DUPLEX ):
975
+ return DP83822_LED_FN_FULL_DUPLEX ;
976
+ case BIT (TRIGGER_NETDEV_TX ):
977
+ return DP83822_LED_FN_TX ;
978
+ case BIT (TRIGGER_NETDEV_RX ):
979
+ return DP83822_LED_FN_RX ;
980
+ case BIT (TRIGGER_NETDEV_TX ) | BIT (TRIGGER_NETDEV_RX ):
981
+ return DP83822_LED_FN_RX_TX ;
982
+ case BIT (TRIGGER_NETDEV_TX_ERR ) | BIT (TRIGGER_NETDEV_RX_ERR ):
983
+ return DP83822_LED_FN_RX_TX_ERR ;
984
+ case BIT (TRIGGER_NETDEV_LINK ) | BIT (TRIGGER_NETDEV_TX ) | BIT (TRIGGER_NETDEV_RX ):
985
+ return DP83822_LED_FN_LINK_RX_TX ;
986
+ default :
987
+ return - EOPNOTSUPP ;
988
+ }
989
+ }
990
+
991
+ static int dp83822_led_hw_is_supported (struct phy_device * phydev , u8 index ,
992
+ unsigned long rules )
993
+ {
994
+ int mode ;
995
+
996
+ mode = dp83822_led_mode (index , rules );
997
+ if (mode < 0 )
998
+ return mode ;
999
+
1000
+ return 0 ;
1001
+ }
1002
+
1003
+ static int dp83822_led_hw_control_set (struct phy_device * phydev , u8 index ,
1004
+ unsigned long rules )
1005
+ {
1006
+ int mode ;
1007
+
1008
+ mode = dp83822_led_mode (index , rules );
1009
+ if (mode < 0 )
1010
+ return mode ;
1011
+
1012
+ if (index == DP83822_LED_INDEX_LED_0 || index == DP83822_LED_INDEX_COL_GPIO2 )
1013
+ return phy_modify_mmd (phydev , MDIO_MMD_VEND2 ,
1014
+ MII_DP83822_MLEDCR , DP83822_MLEDCR_CFG ,
1015
+ FIELD_PREP (DP83822_MLEDCR_CFG , mode ));
1016
+ else if (index == DP83822_LED_INDEX_LED_1_GPIO1 )
1017
+ return phy_modify_mmd (phydev , MDIO_MMD_VEND2 ,
1018
+ MII_DP83822_LEDCFG1 ,
1019
+ DP83822_LEDCFG1_LED1_CTRL ,
1020
+ FIELD_PREP (DP83822_LEDCFG1_LED1_CTRL ,
1021
+ mode ));
1022
+ else
1023
+ return phy_modify_mmd (phydev , MDIO_MMD_VEND2 ,
1024
+ MII_DP83822_LEDCFG1 ,
1025
+ DP83822_LEDCFG1_LED3_CTRL ,
1026
+ FIELD_PREP (DP83822_LEDCFG1_LED3_CTRL ,
1027
+ mode ));
1028
+ }
1029
+
1030
+ static int dp83822_led_hw_control_get (struct phy_device * phydev , u8 index ,
1031
+ unsigned long * rules )
1032
+ {
1033
+ int val ;
1034
+
1035
+ if (index == DP83822_LED_INDEX_LED_0 || index == DP83822_LED_INDEX_COL_GPIO2 ) {
1036
+ val = phy_read_mmd (phydev , MDIO_MMD_VEND2 , MII_DP83822_MLEDCR );
1037
+ if (val < 0 )
1038
+ return val ;
1039
+
1040
+ val = FIELD_GET (DP83822_MLEDCR_CFG , val );
1041
+ } else {
1042
+ val = phy_read_mmd (phydev , MDIO_MMD_VEND2 , MII_DP83822_LEDCFG1 );
1043
+ if (val < 0 )
1044
+ return val ;
1045
+
1046
+ if (index == DP83822_LED_INDEX_LED_1_GPIO1 )
1047
+ val = FIELD_GET (DP83822_LEDCFG1_LED1_CTRL , val );
1048
+ else
1049
+ val = FIELD_GET (DP83822_LEDCFG1_LED3_CTRL , val );
1050
+ }
1051
+
1052
+ switch (val ) {
1053
+ case DP83822_LED_FN_LINK :
1054
+ * rules = BIT (TRIGGER_NETDEV_LINK );
1055
+ break ;
1056
+ case DP83822_LED_FN_LINK_10_BT :
1057
+ * rules = BIT (TRIGGER_NETDEV_LINK_10 );
1058
+ break ;
1059
+ case DP83822_LED_FN_LINK_100_BTX :
1060
+ * rules = BIT (TRIGGER_NETDEV_LINK_100 );
1061
+ break ;
1062
+ case DP83822_LED_FN_FULL_DUPLEX :
1063
+ * rules = BIT (TRIGGER_NETDEV_FULL_DUPLEX );
1064
+ break ;
1065
+ case DP83822_LED_FN_TX :
1066
+ * rules = BIT (TRIGGER_NETDEV_TX );
1067
+ break ;
1068
+ case DP83822_LED_FN_RX :
1069
+ * rules = BIT (TRIGGER_NETDEV_RX );
1070
+ break ;
1071
+ case DP83822_LED_FN_RX_TX :
1072
+ * rules = BIT (TRIGGER_NETDEV_TX ) | BIT (TRIGGER_NETDEV_RX );
1073
+ break ;
1074
+ case DP83822_LED_FN_RX_TX_ERR :
1075
+ * rules = BIT (TRIGGER_NETDEV_TX_ERR ) | BIT (TRIGGER_NETDEV_RX_ERR );
1076
+ break ;
1077
+ case DP83822_LED_FN_LINK_RX_TX :
1078
+ * rules = BIT (TRIGGER_NETDEV_LINK ) | BIT (TRIGGER_NETDEV_TX ) |
1079
+ BIT (TRIGGER_NETDEV_RX );
1080
+ break ;
1081
+ default :
1082
+ * rules = 0 ;
1083
+ break ;
1084
+ }
1085
+
1086
+ return 0 ;
1087
+ }
1088
+
819
1089
#define DP83822_PHY_DRIVER (_id , _name ) \
820
1090
{ \
821
1091
PHY_ID_MATCH_MODEL(_id), \
@@ -831,6 +1101,9 @@ static int dp83822_resume(struct phy_device *phydev)
831
1101
.handle_interrupt = dp83822_handle_interrupt, \
832
1102
.suspend = dp83822_suspend, \
833
1103
.resume = dp83822_resume, \
1104
+ .led_hw_is_supported = dp83822_led_hw_is_supported, \
1105
+ .led_hw_control_set = dp83822_led_hw_control_set, \
1106
+ .led_hw_control_get = dp83822_led_hw_control_get, \
834
1107
}
835
1108
836
1109
#define DP83825_PHY_DRIVER (_id , _name ) \
0 commit comments