12
12
#include <linux/of.h>
13
13
#include <linux/phy.h>
14
14
#include <linux/netdevice.h>
15
+ #include <linux/bitfield.h>
15
16
16
17
#define DP83822_PHY_ID 0x2000a240
17
18
#define DP83825S_PHY_ID 0x2000a140
34
35
#define MII_DP83822_GENCFG 0x465
35
36
#define MII_DP83822_SOR1 0x467
36
37
38
+ /* DP83826 specific registers */
39
+ #define MII_DP83826_VOD_CFG1 0x30b
40
+ #define MII_DP83826_VOD_CFG2 0x30c
41
+
37
42
/* GENCFG */
38
43
#define DP83822_SIG_DET_LOW BIT(0)
39
44
110
115
#define DP83822_RX_ER_STR_MASK GENMASK(9, 8)
111
116
#define DP83822_RX_ER_SHIFT 8
112
117
118
+ /* DP83826: VOD_CFG1 & VOD_CFG2 */
119
+ #define DP83826_VOD_CFG1_MINUS_MDIX_MASK GENMASK(13, 12)
120
+ #define DP83826_VOD_CFG1_MINUS_MDI_MASK GENMASK(11, 6)
121
+ #define DP83826_VOD_CFG2_MINUS_MDIX_MASK GENMASK(15, 12)
122
+ #define DP83826_VOD_CFG2_PLUS_MDIX_MASK GENMASK(11, 6)
123
+ #define DP83826_VOD_CFG2_PLUS_MDI_MASK GENMASK(5, 0)
124
+ #define DP83826_CFG_DAC_MINUS_MDIX_5_TO_4 GENMASK(5, 4)
125
+ #define DP83826_CFG_DAC_MINUS_MDIX_3_TO_0 GENMASK(3, 0)
126
+ #define DP83826_CFG_DAC_PERCENT_PER_STEP 625
127
+ #define DP83826_CFG_DAC_PERCENT_DEFAULT 10000
128
+ #define DP83826_CFG_DAC_MINUS_DEFAULT 0x30
129
+ #define DP83826_CFG_DAC_PLUS_DEFAULT 0x10
130
+
113
131
#define MII_DP83822_FIBER_ADVERTISE (ADVERTISED_TP | ADVERTISED_MII | \
114
132
ADVERTISED_FIBRE | \
115
133
ADVERTISED_Pause | ADVERTISED_Asym_Pause)
@@ -118,6 +136,8 @@ struct dp83822_private {
118
136
bool fx_signal_det_low ;
119
137
int fx_enabled ;
120
138
u16 fx_sd_enable ;
139
+ u8 cfg_dac_minus ;
140
+ u8 cfg_dac_plus ;
121
141
};
122
142
123
143
static int dp83822_set_wol (struct phy_device * phydev ,
@@ -233,7 +253,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
233
253
DP83822_ENERGY_DET_INT_EN |
234
254
DP83822_LINK_QUAL_INT_EN );
235
255
236
- /* Private data pointer is NULL on DP83825/26 */
256
+ /* Private data pointer is NULL on DP83825 */
237
257
if (!dp83822 || !dp83822 -> fx_enabled )
238
258
misr_status |= DP83822_ANEG_COMPLETE_INT_EN |
239
259
DP83822_DUP_MODE_CHANGE_INT_EN |
@@ -254,7 +274,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
254
274
DP83822_PAGE_RX_INT_EN |
255
275
DP83822_EEE_ERROR_CHANGE_INT_EN );
256
276
257
- /* Private data pointer is NULL on DP83825/26 */
277
+ /* Private data pointer is NULL on DP83825 */
258
278
if (!dp83822 || !dp83822 -> fx_enabled )
259
279
misr_status |= DP83822_ANEG_ERR_INT_EN |
260
280
DP83822_WOL_PKT_INT_EN ;
@@ -474,6 +494,43 @@ static int dp83822_config_init(struct phy_device *phydev)
474
494
return dp8382x_disable_wol (phydev );
475
495
}
476
496
497
+ static int dp83826_config_init (struct phy_device * phydev )
498
+ {
499
+ struct dp83822_private * dp83822 = phydev -> priv ;
500
+ u16 val , mask ;
501
+ int ret ;
502
+
503
+ if (dp83822 -> cfg_dac_minus != DP83826_CFG_DAC_MINUS_DEFAULT ) {
504
+ val = FIELD_PREP (DP83826_VOD_CFG1_MINUS_MDI_MASK , dp83822 -> cfg_dac_minus ) |
505
+ FIELD_PREP (DP83826_VOD_CFG1_MINUS_MDIX_MASK ,
506
+ FIELD_GET (DP83826_CFG_DAC_MINUS_MDIX_5_TO_4 ,
507
+ dp83822 -> cfg_dac_minus ));
508
+ mask = DP83826_VOD_CFG1_MINUS_MDIX_MASK | DP83826_VOD_CFG1_MINUS_MDI_MASK ;
509
+ ret = phy_modify_mmd (phydev , DP83822_DEVADDR , MII_DP83826_VOD_CFG1 , mask , val );
510
+ if (ret )
511
+ return ret ;
512
+
513
+ val = FIELD_PREP (DP83826_VOD_CFG2_MINUS_MDIX_MASK ,
514
+ FIELD_GET (DP83826_CFG_DAC_MINUS_MDIX_3_TO_0 ,
515
+ dp83822 -> cfg_dac_minus ));
516
+ mask = DP83826_VOD_CFG2_MINUS_MDIX_MASK ;
517
+ ret = phy_modify_mmd (phydev , DP83822_DEVADDR , MII_DP83826_VOD_CFG2 , mask , val );
518
+ if (ret )
519
+ return ret ;
520
+ }
521
+
522
+ if (dp83822 -> cfg_dac_plus != DP83826_CFG_DAC_PLUS_DEFAULT ) {
523
+ val = FIELD_PREP (DP83826_VOD_CFG2_PLUS_MDIX_MASK , dp83822 -> cfg_dac_plus ) |
524
+ FIELD_PREP (DP83826_VOD_CFG2_PLUS_MDI_MASK , dp83822 -> cfg_dac_plus );
525
+ mask = DP83826_VOD_CFG2_PLUS_MDIX_MASK | DP83826_VOD_CFG2_PLUS_MDI_MASK ;
526
+ ret = phy_modify_mmd (phydev , DP83822_DEVADDR , MII_DP83826_VOD_CFG2 , mask , val );
527
+ if (ret )
528
+ return ret ;
529
+ }
530
+
531
+ return 0 ;
532
+ }
533
+
477
534
static int dp8382x_config_init (struct phy_device * phydev )
478
535
{
479
536
return dp8382x_disable_wol (phydev );
@@ -509,11 +566,44 @@ static int dp83822_of_init(struct phy_device *phydev)
509
566
510
567
return 0 ;
511
568
}
569
+
570
+ static int dp83826_to_dac_minus_one_regval (int percent )
571
+ {
572
+ int tmp = DP83826_CFG_DAC_PERCENT_DEFAULT - percent ;
573
+
574
+ return tmp / DP83826_CFG_DAC_PERCENT_PER_STEP ;
575
+ }
576
+
577
+ static int dp83826_to_dac_plus_one_regval (int percent )
578
+ {
579
+ int tmp = percent - DP83826_CFG_DAC_PERCENT_DEFAULT ;
580
+
581
+ return tmp / DP83826_CFG_DAC_PERCENT_PER_STEP ;
582
+ }
583
+
584
+ static void dp83826_of_init (struct phy_device * phydev )
585
+ {
586
+ struct dp83822_private * dp83822 = phydev -> priv ;
587
+ struct device * dev = & phydev -> mdio .dev ;
588
+ u32 val ;
589
+
590
+ dp83822 -> cfg_dac_minus = DP83826_CFG_DAC_MINUS_DEFAULT ;
591
+ if (!device_property_read_u32 (dev , "ti,cfg-dac-minus-one-bp" , & val ))
592
+ dp83822 -> cfg_dac_minus += dp83826_to_dac_minus_one_regval (val );
593
+
594
+ dp83822 -> cfg_dac_plus = DP83826_CFG_DAC_PLUS_DEFAULT ;
595
+ if (!device_property_read_u32 (dev , "ti,cfg-dac-plus-one-bp" , & val ))
596
+ dp83822 -> cfg_dac_plus += dp83826_to_dac_plus_one_regval (val );
597
+ }
512
598
#else
513
599
static int dp83822_of_init (struct phy_device * phydev )
514
600
{
515
601
return 0 ;
516
602
}
603
+
604
+ static void dp83826_of_init (struct phy_device * phydev )
605
+ {
606
+ }
517
607
#endif /* CONFIG_OF_MDIO */
518
608
519
609
static int dp83822_read_straps (struct phy_device * phydev )
@@ -567,6 +657,22 @@ static int dp83822_probe(struct phy_device *phydev)
567
657
return 0 ;
568
658
}
569
659
660
+ static int dp83826_probe (struct phy_device * phydev )
661
+ {
662
+ struct dp83822_private * dp83822 ;
663
+
664
+ dp83822 = devm_kzalloc (& phydev -> mdio .dev , sizeof (* dp83822 ),
665
+ GFP_KERNEL );
666
+ if (!dp83822 )
667
+ return - ENOMEM ;
668
+
669
+ phydev -> priv = dp83822 ;
670
+
671
+ dp83826_of_init (phydev );
672
+
673
+ return 0 ;
674
+ }
675
+
570
676
static int dp83822_suspend (struct phy_device * phydev )
571
677
{
572
678
int value ;
@@ -610,6 +716,22 @@ static int dp83822_resume(struct phy_device *phydev)
610
716
.resume = dp83822_resume, \
611
717
}
612
718
719
+ #define DP83826_PHY_DRIVER (_id , _name ) \
720
+ { \
721
+ PHY_ID_MATCH_MODEL(_id), \
722
+ .name = (_name), \
723
+ /* PHY_BASIC_FEATURES */ \
724
+ .probe = dp83826_probe, \
725
+ .soft_reset = dp83822_phy_reset, \
726
+ .config_init = dp83826_config_init, \
727
+ .get_wol = dp83822_get_wol, \
728
+ .set_wol = dp83822_set_wol, \
729
+ .config_intr = dp83822_config_intr, \
730
+ .handle_interrupt = dp83822_handle_interrupt, \
731
+ .suspend = dp83822_suspend, \
732
+ .resume = dp83822_resume, \
733
+ }
734
+
613
735
#define DP8382X_PHY_DRIVER (_id , _name ) \
614
736
{ \
615
737
PHY_ID_MATCH_MODEL(_id), \
@@ -628,8 +750,8 @@ static int dp83822_resume(struct phy_device *phydev)
628
750
static struct phy_driver dp83822_driver [] = {
629
751
DP83822_PHY_DRIVER (DP83822_PHY_ID , "TI DP83822" ),
630
752
DP8382X_PHY_DRIVER (DP83825I_PHY_ID , "TI DP83825I" ),
631
- DP8382X_PHY_DRIVER (DP83826C_PHY_ID , "TI DP83826C" ),
632
- DP8382X_PHY_DRIVER (DP83826NC_PHY_ID , "TI DP83826NC" ),
753
+ DP83826_PHY_DRIVER (DP83826C_PHY_ID , "TI DP83826C" ),
754
+ DP83826_PHY_DRIVER (DP83826NC_PHY_ID , "TI DP83826NC" ),
633
755
DP8382X_PHY_DRIVER (DP83825S_PHY_ID , "TI DP83825S" ),
634
756
DP8382X_PHY_DRIVER (DP83825CM_PHY_ID , "TI DP83825M" ),
635
757
DP8382X_PHY_DRIVER (DP83825CS_PHY_ID , "TI DP83825CS" ),
0 commit comments