0001
0002
0003
0004
0005
0006
0007 #include <linux/ethtool.h>
0008 #include <linux/etherdevice.h>
0009 #include <linux/kernel.h>
0010 #include <linux/mii.h>
0011 #include <linux/module.h>
0012 #include <linux/of.h>
0013 #include <linux/phy.h>
0014 #include <linux/netdevice.h>
0015
0016 #define DP83822_PHY_ID 0x2000a240
0017 #define DP83825S_PHY_ID 0x2000a140
0018 #define DP83825I_PHY_ID 0x2000a150
0019 #define DP83825CM_PHY_ID 0x2000a160
0020 #define DP83825CS_PHY_ID 0x2000a170
0021 #define DP83826C_PHY_ID 0x2000a130
0022 #define DP83826NC_PHY_ID 0x2000a110
0023
0024 #define DP83822_DEVADDR 0x1f
0025
0026 #define MII_DP83822_CTRL_2 0x0a
0027 #define MII_DP83822_PHYSTS 0x10
0028 #define MII_DP83822_PHYSCR 0x11
0029 #define MII_DP83822_MISR1 0x12
0030 #define MII_DP83822_MISR2 0x13
0031 #define MII_DP83822_FCSCR 0x14
0032 #define MII_DP83822_RCSR 0x17
0033 #define MII_DP83822_RESET_CTRL 0x1f
0034 #define MII_DP83822_GENCFG 0x465
0035 #define MII_DP83822_SOR1 0x467
0036
0037
0038 #define DP83822_SIG_DET_LOW BIT(0)
0039
0040
0041 #define DP83822_FX_ENABLE BIT(14)
0042
0043 #define DP83822_HW_RESET BIT(15)
0044 #define DP83822_SW_RESET BIT(14)
0045
0046
0047 #define DP83822_PHYSTS_DUPLEX BIT(2)
0048 #define DP83822_PHYSTS_10 BIT(1)
0049 #define DP83822_PHYSTS_LINK BIT(0)
0050
0051
0052 #define DP83822_PHYSCR_INT_OE BIT(0)
0053 #define DP83822_PHYSCR_INTEN BIT(1)
0054
0055
0056 #define DP83822_RX_ERR_HF_INT_EN BIT(0)
0057 #define DP83822_FALSE_CARRIER_HF_INT_EN BIT(1)
0058 #define DP83822_ANEG_COMPLETE_INT_EN BIT(2)
0059 #define DP83822_DUP_MODE_CHANGE_INT_EN BIT(3)
0060 #define DP83822_SPEED_CHANGED_INT_EN BIT(4)
0061 #define DP83822_LINK_STAT_INT_EN BIT(5)
0062 #define DP83822_ENERGY_DET_INT_EN BIT(6)
0063 #define DP83822_LINK_QUAL_INT_EN BIT(7)
0064
0065
0066 #define DP83822_JABBER_DET_INT_EN BIT(0)
0067 #define DP83822_WOL_PKT_INT_EN BIT(1)
0068 #define DP83822_SLEEP_MODE_INT_EN BIT(2)
0069 #define DP83822_MDI_XOVER_INT_EN BIT(3)
0070 #define DP83822_LB_FIFO_INT_EN BIT(4)
0071 #define DP83822_PAGE_RX_INT_EN BIT(5)
0072 #define DP83822_ANEG_ERR_INT_EN BIT(6)
0073 #define DP83822_EEE_ERROR_CHANGE_INT_EN BIT(7)
0074
0075
0076 #define DP83822_WOL_INT_EN BIT(4)
0077 #define DP83822_WOL_INT_STAT BIT(12)
0078
0079 #define MII_DP83822_RXSOP1 0x04a5
0080 #define MII_DP83822_RXSOP2 0x04a6
0081 #define MII_DP83822_RXSOP3 0x04a7
0082
0083
0084 #define MII_DP83822_WOL_CFG 0x04a0
0085 #define MII_DP83822_WOL_STAT 0x04a1
0086 #define MII_DP83822_WOL_DA1 0x04a2
0087 #define MII_DP83822_WOL_DA2 0x04a3
0088 #define MII_DP83822_WOL_DA3 0x04a4
0089
0090
0091 #define DP83822_WOL_MAGIC_EN BIT(0)
0092 #define DP83822_WOL_SECURE_ON BIT(5)
0093 #define DP83822_WOL_EN BIT(7)
0094 #define DP83822_WOL_INDICATION_SEL BIT(8)
0095 #define DP83822_WOL_CLR_INDICATION BIT(11)
0096
0097
0098 #define DP83822_RGMII_MODE_EN BIT(9)
0099 #define DP83822_RX_CLK_SHIFT BIT(12)
0100 #define DP83822_TX_CLK_SHIFT BIT(11)
0101
0102
0103 #define DP83822_STRAP_MODE1 0
0104 #define DP83822_STRAP_MODE2 BIT(0)
0105 #define DP83822_STRAP_MODE3 BIT(1)
0106 #define DP83822_STRAP_MODE4 GENMASK(1, 0)
0107
0108 #define DP83822_COL_STRAP_MASK GENMASK(11, 10)
0109 #define DP83822_COL_SHIFT 10
0110 #define DP83822_RX_ER_STR_MASK GENMASK(9, 8)
0111 #define DP83822_RX_ER_SHIFT 8
0112
0113 #define MII_DP83822_FIBER_ADVERTISE (ADVERTISED_TP | ADVERTISED_MII | \
0114 ADVERTISED_FIBRE | \
0115 ADVERTISED_Pause | ADVERTISED_Asym_Pause)
0116
0117 struct dp83822_private {
0118 bool fx_signal_det_low;
0119 int fx_enabled;
0120 u16 fx_sd_enable;
0121 };
0122
0123 static int dp83822_set_wol(struct phy_device *phydev,
0124 struct ethtool_wolinfo *wol)
0125 {
0126 struct net_device *ndev = phydev->attached_dev;
0127 u16 value;
0128 const u8 *mac;
0129
0130 if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
0131 mac = (const u8 *)ndev->dev_addr;
0132
0133 if (!is_valid_ether_addr(mac))
0134 return -EINVAL;
0135
0136
0137
0138
0139 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA1,
0140 (mac[1] << 8) | mac[0]);
0141 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA2,
0142 (mac[3] << 8) | mac[2]);
0143 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA3,
0144 (mac[5] << 8) | mac[4]);
0145
0146 value = phy_read_mmd(phydev, DP83822_DEVADDR,
0147 MII_DP83822_WOL_CFG);
0148 if (wol->wolopts & WAKE_MAGIC)
0149 value |= DP83822_WOL_MAGIC_EN;
0150 else
0151 value &= ~DP83822_WOL_MAGIC_EN;
0152
0153 if (wol->wolopts & WAKE_MAGICSECURE) {
0154 phy_write_mmd(phydev, DP83822_DEVADDR,
0155 MII_DP83822_RXSOP1,
0156 (wol->sopass[1] << 8) | wol->sopass[0]);
0157 phy_write_mmd(phydev, DP83822_DEVADDR,
0158 MII_DP83822_RXSOP2,
0159 (wol->sopass[3] << 8) | wol->sopass[2]);
0160 phy_write_mmd(phydev, DP83822_DEVADDR,
0161 MII_DP83822_RXSOP3,
0162 (wol->sopass[5] << 8) | wol->sopass[4]);
0163 value |= DP83822_WOL_SECURE_ON;
0164 } else {
0165 value &= ~DP83822_WOL_SECURE_ON;
0166 }
0167
0168
0169 phy_read(phydev, MII_DP83822_MISR2);
0170
0171 value |= DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL |
0172 DP83822_WOL_CLR_INDICATION;
0173
0174 return phy_write_mmd(phydev, DP83822_DEVADDR,
0175 MII_DP83822_WOL_CFG, value);
0176 } else {
0177 return phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
0178 MII_DP83822_WOL_CFG, DP83822_WOL_EN);
0179 }
0180 }
0181
0182 static void dp83822_get_wol(struct phy_device *phydev,
0183 struct ethtool_wolinfo *wol)
0184 {
0185 int value;
0186 u16 sopass_val;
0187
0188 wol->supported = (WAKE_MAGIC | WAKE_MAGICSECURE);
0189 wol->wolopts = 0;
0190
0191 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
0192
0193 if (value & DP83822_WOL_MAGIC_EN)
0194 wol->wolopts |= WAKE_MAGIC;
0195
0196 if (value & DP83822_WOL_SECURE_ON) {
0197 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
0198 MII_DP83822_RXSOP1);
0199 wol->sopass[0] = (sopass_val & 0xff);
0200 wol->sopass[1] = (sopass_val >> 8);
0201
0202 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
0203 MII_DP83822_RXSOP2);
0204 wol->sopass[2] = (sopass_val & 0xff);
0205 wol->sopass[3] = (sopass_val >> 8);
0206
0207 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
0208 MII_DP83822_RXSOP3);
0209 wol->sopass[4] = (sopass_val & 0xff);
0210 wol->sopass[5] = (sopass_val >> 8);
0211
0212 wol->wolopts |= WAKE_MAGICSECURE;
0213 }
0214
0215
0216 if (!(value & DP83822_WOL_EN))
0217 wol->wolopts = 0;
0218 }
0219
0220 static int dp83822_config_intr(struct phy_device *phydev)
0221 {
0222 struct dp83822_private *dp83822 = phydev->priv;
0223 int misr_status;
0224 int physcr_status;
0225 int err;
0226
0227 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
0228 misr_status = phy_read(phydev, MII_DP83822_MISR1);
0229 if (misr_status < 0)
0230 return misr_status;
0231
0232 misr_status |= (DP83822_LINK_STAT_INT_EN |
0233 DP83822_ENERGY_DET_INT_EN |
0234 DP83822_LINK_QUAL_INT_EN);
0235
0236 if (!dp83822->fx_enabled)
0237 misr_status |= DP83822_ANEG_COMPLETE_INT_EN |
0238 DP83822_DUP_MODE_CHANGE_INT_EN |
0239 DP83822_SPEED_CHANGED_INT_EN;
0240
0241
0242 err = phy_write(phydev, MII_DP83822_MISR1, misr_status);
0243 if (err < 0)
0244 return err;
0245
0246 misr_status = phy_read(phydev, MII_DP83822_MISR2);
0247 if (misr_status < 0)
0248 return misr_status;
0249
0250 misr_status |= (DP83822_JABBER_DET_INT_EN |
0251 DP83822_SLEEP_MODE_INT_EN |
0252 DP83822_LB_FIFO_INT_EN |
0253 DP83822_PAGE_RX_INT_EN |
0254 DP83822_EEE_ERROR_CHANGE_INT_EN);
0255
0256 if (!dp83822->fx_enabled)
0257 misr_status |= DP83822_MDI_XOVER_INT_EN |
0258 DP83822_ANEG_ERR_INT_EN |
0259 DP83822_WOL_PKT_INT_EN;
0260
0261 err = phy_write(phydev, MII_DP83822_MISR2, misr_status);
0262 if (err < 0)
0263 return err;
0264
0265 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
0266 if (physcr_status < 0)
0267 return physcr_status;
0268
0269 physcr_status |= DP83822_PHYSCR_INT_OE | DP83822_PHYSCR_INTEN;
0270
0271 } else {
0272 err = phy_write(phydev, MII_DP83822_MISR1, 0);
0273 if (err < 0)
0274 return err;
0275
0276 err = phy_write(phydev, MII_DP83822_MISR2, 0);
0277 if (err < 0)
0278 return err;
0279
0280 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
0281 if (physcr_status < 0)
0282 return physcr_status;
0283
0284 physcr_status &= ~DP83822_PHYSCR_INTEN;
0285 }
0286
0287 return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status);
0288 }
0289
0290 static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev)
0291 {
0292 bool trigger_machine = false;
0293 int irq_status;
0294
0295
0296
0297
0298
0299
0300
0301
0302 irq_status = phy_read(phydev, MII_DP83822_MISR1);
0303 if (irq_status < 0) {
0304 phy_error(phydev);
0305 return IRQ_NONE;
0306 }
0307 if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
0308 trigger_machine = true;
0309
0310 irq_status = phy_read(phydev, MII_DP83822_MISR2);
0311 if (irq_status < 0) {
0312 phy_error(phydev);
0313 return IRQ_NONE;
0314 }
0315 if (irq_status & ((irq_status & GENMASK(7, 0)) << 8))
0316 trigger_machine = true;
0317
0318 if (!trigger_machine)
0319 return IRQ_NONE;
0320
0321 phy_trigger_machine(phydev);
0322
0323 return IRQ_HANDLED;
0324 }
0325
0326 static int dp8382x_disable_wol(struct phy_device *phydev)
0327 {
0328 return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG,
0329 DP83822_WOL_EN | DP83822_WOL_MAGIC_EN |
0330 DP83822_WOL_SECURE_ON);
0331 }
0332
0333 static int dp83822_read_status(struct phy_device *phydev)
0334 {
0335 struct dp83822_private *dp83822 = phydev->priv;
0336 int status = phy_read(phydev, MII_DP83822_PHYSTS);
0337 int ctrl2;
0338 int ret;
0339
0340 if (dp83822->fx_enabled) {
0341 if (status & DP83822_PHYSTS_LINK) {
0342 phydev->speed = SPEED_UNKNOWN;
0343 phydev->duplex = DUPLEX_UNKNOWN;
0344 } else {
0345 ctrl2 = phy_read(phydev, MII_DP83822_CTRL_2);
0346 if (ctrl2 < 0)
0347 return ctrl2;
0348
0349 if (!(ctrl2 & DP83822_FX_ENABLE)) {
0350 ret = phy_write(phydev, MII_DP83822_CTRL_2,
0351 DP83822_FX_ENABLE | ctrl2);
0352 if (ret < 0)
0353 return ret;
0354 }
0355 }
0356 }
0357
0358 ret = genphy_read_status(phydev);
0359 if (ret)
0360 return ret;
0361
0362 if (status < 0)
0363 return status;
0364
0365 if (status & DP83822_PHYSTS_DUPLEX)
0366 phydev->duplex = DUPLEX_FULL;
0367 else
0368 phydev->duplex = DUPLEX_HALF;
0369
0370 if (status & DP83822_PHYSTS_10)
0371 phydev->speed = SPEED_10;
0372 else
0373 phydev->speed = SPEED_100;
0374
0375 return 0;
0376 }
0377
0378 static int dp83822_config_init(struct phy_device *phydev)
0379 {
0380 struct dp83822_private *dp83822 = phydev->priv;
0381 struct device *dev = &phydev->mdio.dev;
0382 int rgmii_delay;
0383 s32 rx_int_delay;
0384 s32 tx_int_delay;
0385 int err = 0;
0386 int bmcr;
0387
0388 if (phy_interface_is_rgmii(phydev)) {
0389 rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
0390 true);
0391
0392 if (rx_int_delay <= 0)
0393 rgmii_delay = 0;
0394 else
0395 rgmii_delay = DP83822_RX_CLK_SHIFT;
0396
0397 tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
0398 false);
0399 if (tx_int_delay <= 0)
0400 rgmii_delay &= ~DP83822_TX_CLK_SHIFT;
0401 else
0402 rgmii_delay |= DP83822_TX_CLK_SHIFT;
0403
0404 if (rgmii_delay) {
0405 err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
0406 MII_DP83822_RCSR, rgmii_delay);
0407 if (err)
0408 return err;
0409 }
0410
0411 phy_set_bits_mmd(phydev, DP83822_DEVADDR,
0412 MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
0413 } else {
0414 phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
0415 MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
0416 }
0417
0418 if (dp83822->fx_enabled) {
0419 err = phy_modify(phydev, MII_DP83822_CTRL_2,
0420 DP83822_FX_ENABLE, 1);
0421 if (err < 0)
0422 return err;
0423
0424
0425 linkmode_and(phydev->advertising, phydev->advertising,
0426 phydev->supported);
0427
0428 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
0429 phydev->supported);
0430 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
0431 phydev->advertising);
0432 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
0433 phydev->supported);
0434 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
0435 phydev->supported);
0436 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
0437 phydev->advertising);
0438 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
0439 phydev->advertising);
0440
0441
0442 bmcr = phy_read(phydev, MII_BMCR);
0443 if (bmcr < 0)
0444 return bmcr;
0445
0446 if (bmcr & BMCR_ANENABLE) {
0447 err = phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0);
0448 if (err < 0)
0449 return err;
0450 }
0451 phydev->autoneg = AUTONEG_DISABLE;
0452 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0453 phydev->supported);
0454 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
0455 phydev->advertising);
0456
0457
0458 err = phy_modify_changed(phydev, MII_ADVERTISE,
0459 MII_DP83822_FIBER_ADVERTISE,
0460 MII_DP83822_FIBER_ADVERTISE);
0461
0462 if (err < 0)
0463 return err;
0464
0465 if (dp83822->fx_signal_det_low) {
0466 err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
0467 MII_DP83822_GENCFG,
0468 DP83822_SIG_DET_LOW);
0469 if (err)
0470 return err;
0471 }
0472 }
0473 return dp8382x_disable_wol(phydev);
0474 }
0475
0476 static int dp8382x_config_init(struct phy_device *phydev)
0477 {
0478 return dp8382x_disable_wol(phydev);
0479 }
0480
0481 static int dp83822_phy_reset(struct phy_device *phydev)
0482 {
0483 int err;
0484
0485 err = phy_write(phydev, MII_DP83822_RESET_CTRL, DP83822_SW_RESET);
0486 if (err < 0)
0487 return err;
0488
0489 return phydev->drv->config_init(phydev);
0490 }
0491
0492 #ifdef CONFIG_OF_MDIO
0493 static int dp83822_of_init(struct phy_device *phydev)
0494 {
0495 struct dp83822_private *dp83822 = phydev->priv;
0496 struct device *dev = &phydev->mdio.dev;
0497
0498
0499
0500
0501
0502 if (dp83822->fx_enabled && dp83822->fx_sd_enable)
0503 dp83822->fx_signal_det_low = device_property_present(dev,
0504 "ti,link-loss-low");
0505 if (!dp83822->fx_enabled)
0506 dp83822->fx_enabled = device_property_present(dev,
0507 "ti,fiber-mode");
0508
0509 return 0;
0510 }
0511 #else
0512 static int dp83822_of_init(struct phy_device *phydev)
0513 {
0514 return 0;
0515 }
0516 #endif
0517
0518 static int dp83822_read_straps(struct phy_device *phydev)
0519 {
0520 struct dp83822_private *dp83822 = phydev->priv;
0521 int fx_enabled, fx_sd_enable;
0522 int val;
0523
0524 val = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_SOR1);
0525 if (val < 0)
0526 return val;
0527
0528 fx_enabled = (val & DP83822_COL_STRAP_MASK) >> DP83822_COL_SHIFT;
0529 if (fx_enabled == DP83822_STRAP_MODE2 ||
0530 fx_enabled == DP83822_STRAP_MODE3)
0531 dp83822->fx_enabled = 1;
0532
0533 if (dp83822->fx_enabled) {
0534 fx_sd_enable = (val & DP83822_RX_ER_STR_MASK) >> DP83822_RX_ER_SHIFT;
0535 if (fx_sd_enable == DP83822_STRAP_MODE3 ||
0536 fx_sd_enable == DP83822_STRAP_MODE4)
0537 dp83822->fx_sd_enable = 1;
0538 }
0539
0540 return 0;
0541 }
0542
0543 static int dp83822_probe(struct phy_device *phydev)
0544 {
0545 struct dp83822_private *dp83822;
0546 int ret;
0547
0548 dp83822 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83822),
0549 GFP_KERNEL);
0550 if (!dp83822)
0551 return -ENOMEM;
0552
0553 phydev->priv = dp83822;
0554
0555 ret = dp83822_read_straps(phydev);
0556 if (ret)
0557 return ret;
0558
0559 dp83822_of_init(phydev);
0560
0561 if (dp83822->fx_enabled)
0562 phydev->port = PORT_FIBRE;
0563
0564 return 0;
0565 }
0566
0567 static int dp83822_suspend(struct phy_device *phydev)
0568 {
0569 int value;
0570
0571 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
0572
0573 if (!(value & DP83822_WOL_EN))
0574 genphy_suspend(phydev);
0575
0576 return 0;
0577 }
0578
0579 static int dp83822_resume(struct phy_device *phydev)
0580 {
0581 int value;
0582
0583 genphy_resume(phydev);
0584
0585 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
0586
0587 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, value |
0588 DP83822_WOL_CLR_INDICATION);
0589
0590 return 0;
0591 }
0592
0593 #define DP83822_PHY_DRIVER(_id, _name) \
0594 { \
0595 PHY_ID_MATCH_MODEL(_id), \
0596 .name = (_name), \
0597 \
0598 .probe = dp83822_probe, \
0599 .soft_reset = dp83822_phy_reset, \
0600 .config_init = dp83822_config_init, \
0601 .read_status = dp83822_read_status, \
0602 .get_wol = dp83822_get_wol, \
0603 .set_wol = dp83822_set_wol, \
0604 .config_intr = dp83822_config_intr, \
0605 .handle_interrupt = dp83822_handle_interrupt, \
0606 .suspend = dp83822_suspend, \
0607 .resume = dp83822_resume, \
0608 }
0609
0610 #define DP8382X_PHY_DRIVER(_id, _name) \
0611 { \
0612 PHY_ID_MATCH_MODEL(_id), \
0613 .name = (_name), \
0614 \
0615 .soft_reset = dp83822_phy_reset, \
0616 .config_init = dp8382x_config_init, \
0617 .get_wol = dp83822_get_wol, \
0618 .set_wol = dp83822_set_wol, \
0619 .config_intr = dp83822_config_intr, \
0620 .handle_interrupt = dp83822_handle_interrupt, \
0621 .suspend = dp83822_suspend, \
0622 .resume = dp83822_resume, \
0623 }
0624
0625 static struct phy_driver dp83822_driver[] = {
0626 DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"),
0627 DP8382X_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"),
0628 DP8382X_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"),
0629 DP8382X_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"),
0630 DP8382X_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"),
0631 DP8382X_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"),
0632 DP8382X_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"),
0633 };
0634 module_phy_driver(dp83822_driver);
0635
0636 static struct mdio_device_id __maybe_unused dp83822_tbl[] = {
0637 { DP83822_PHY_ID, 0xfffffff0 },
0638 { DP83825I_PHY_ID, 0xfffffff0 },
0639 { DP83826C_PHY_ID, 0xfffffff0 },
0640 { DP83826NC_PHY_ID, 0xfffffff0 },
0641 { DP83825S_PHY_ID, 0xfffffff0 },
0642 { DP83825CM_PHY_ID, 0xfffffff0 },
0643 { DP83825CS_PHY_ID, 0xfffffff0 },
0644 { },
0645 };
0646 MODULE_DEVICE_TABLE(mdio, dp83822_tbl);
0647
0648 MODULE_DESCRIPTION("Texas Instruments DP83822 PHY driver");
0649 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com");
0650 MODULE_LICENSE("GPL v2");