1 // SPDX-License-Identifier: GPL-2.0 2 /* Driver for the Texas Instruments DP83822, DP83825 and DP83826 PHYs. 3 * 4 * Copyright (C) 2017 Texas Instruments Inc. 5 */ 6 7 #include <linux/ethtool.h> 8 #include <linux/etherdevice.h> 9 #include <linux/kernel.h> 10 #include <linux/mii.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/phy.h> 14 #include <linux/netdevice.h> 15 16 #define DP83822_PHY_ID 0x2000a240 17 #define DP83825S_PHY_ID 0x2000a140 18 #define DP83825I_PHY_ID 0x2000a150 19 #define DP83825CM_PHY_ID 0x2000a160 20 #define DP83825CS_PHY_ID 0x2000a170 21 #define DP83826C_PHY_ID 0x2000a130 22 #define DP83826NC_PHY_ID 0x2000a110 23 24 #define DP83822_DEVADDR 0x1f 25 26 #define MII_DP83822_CTRL_2 0x0a 27 #define MII_DP83822_PHYSTS 0x10 28 #define MII_DP83822_PHYSCR 0x11 29 #define MII_DP83822_MISR1 0x12 30 #define MII_DP83822_MISR2 0x13 31 #define MII_DP83822_FCSCR 0x14 32 #define MII_DP83822_RCSR 0x17 33 #define MII_DP83822_RESET_CTRL 0x1f 34 #define MII_DP83822_GENCFG 0x465 35 #define MII_DP83822_SOR1 0x467 36 37 /* GENCFG */ 38 #define DP83822_SIG_DET_LOW BIT(0) 39 40 /* Control Register 2 bits */ 41 #define DP83822_FX_ENABLE BIT(14) 42 43 #define DP83822_HW_RESET BIT(15) 44 #define DP83822_SW_RESET BIT(14) 45 46 /* PHY STS bits */ 47 #define DP83822_PHYSTS_DUPLEX BIT(2) 48 #define DP83822_PHYSTS_10 BIT(1) 49 #define DP83822_PHYSTS_LINK BIT(0) 50 51 /* PHYSCR Register Fields */ 52 #define DP83822_PHYSCR_INT_OE BIT(0) /* Interrupt Output Enable */ 53 #define DP83822_PHYSCR_INTEN BIT(1) /* Interrupt Enable */ 54 55 /* MISR1 bits */ 56 #define DP83822_RX_ERR_HF_INT_EN BIT(0) 57 #define DP83822_FALSE_CARRIER_HF_INT_EN BIT(1) 58 #define DP83822_ANEG_COMPLETE_INT_EN BIT(2) 59 #define DP83822_DUP_MODE_CHANGE_INT_EN BIT(3) 60 #define DP83822_SPEED_CHANGED_INT_EN BIT(4) 61 #define DP83822_LINK_STAT_INT_EN BIT(5) 62 #define DP83822_ENERGY_DET_INT_EN BIT(6) 63 #define DP83822_LINK_QUAL_INT_EN BIT(7) 64 65 /* MISR2 bits */ 66 #define DP83822_JABBER_DET_INT_EN BIT(0) 67 #define DP83822_WOL_PKT_INT_EN BIT(1) 68 #define DP83822_SLEEP_MODE_INT_EN BIT(2) 69 #define DP83822_MDI_XOVER_INT_EN BIT(3) 70 #define DP83822_LB_FIFO_INT_EN BIT(4) 71 #define DP83822_PAGE_RX_INT_EN BIT(5) 72 #define DP83822_ANEG_ERR_INT_EN BIT(6) 73 #define DP83822_EEE_ERROR_CHANGE_INT_EN BIT(7) 74 75 /* INT_STAT1 bits */ 76 #define DP83822_WOL_INT_EN BIT(4) 77 #define DP83822_WOL_INT_STAT BIT(12) 78 79 #define MII_DP83822_RXSOP1 0x04a5 80 #define MII_DP83822_RXSOP2 0x04a6 81 #define MII_DP83822_RXSOP3 0x04a7 82 83 /* WoL Registers */ 84 #define MII_DP83822_WOL_CFG 0x04a0 85 #define MII_DP83822_WOL_STAT 0x04a1 86 #define MII_DP83822_WOL_DA1 0x04a2 87 #define MII_DP83822_WOL_DA2 0x04a3 88 #define MII_DP83822_WOL_DA3 0x04a4 89 90 /* WoL bits */ 91 #define DP83822_WOL_MAGIC_EN BIT(0) 92 #define DP83822_WOL_SECURE_ON BIT(5) 93 #define DP83822_WOL_EN BIT(7) 94 #define DP83822_WOL_INDICATION_SEL BIT(8) 95 #define DP83822_WOL_CLR_INDICATION BIT(11) 96 97 /* RSCR bits */ 98 #define DP83822_RX_CLK_SHIFT BIT(12) 99 #define DP83822_TX_CLK_SHIFT BIT(11) 100 101 /* SOR1 mode */ 102 #define DP83822_STRAP_MODE1 0 103 #define DP83822_STRAP_MODE2 BIT(0) 104 #define DP83822_STRAP_MODE3 BIT(1) 105 #define DP83822_STRAP_MODE4 GENMASK(1, 0) 106 107 #define DP83822_COL_STRAP_MASK GENMASK(11, 10) 108 #define DP83822_COL_SHIFT 10 109 #define DP83822_RX_ER_STR_MASK GENMASK(9, 8) 110 #define DP83822_RX_ER_SHIFT 8 111 112 #define MII_DP83822_FIBER_ADVERTISE (ADVERTISED_TP | ADVERTISED_MII | \ 113 ADVERTISED_FIBRE | \ 114 ADVERTISED_Pause | ADVERTISED_Asym_Pause) 115 116 struct dp83822_private { 117 bool fx_signal_det_low; 118 int fx_enabled; 119 u16 fx_sd_enable; 120 }; 121 122 static int dp83822_set_wol(struct phy_device *phydev, 123 struct ethtool_wolinfo *wol) 124 { 125 struct net_device *ndev = phydev->attached_dev; 126 u16 value; 127 const u8 *mac; 128 129 if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) { 130 mac = (const u8 *)ndev->dev_addr; 131 132 if (!is_valid_ether_addr(mac)) 133 return -EINVAL; 134 135 /* MAC addresses start with byte 5, but stored in mac[0]. 136 * 822 PHYs store bytes 4|5, 2|3, 0|1 137 */ 138 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA1, 139 (mac[1] << 8) | mac[0]); 140 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA2, 141 (mac[3] << 8) | mac[2]); 142 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA3, 143 (mac[5] << 8) | mac[4]); 144 145 value = phy_read_mmd(phydev, DP83822_DEVADDR, 146 MII_DP83822_WOL_CFG); 147 if (wol->wolopts & WAKE_MAGIC) 148 value |= DP83822_WOL_MAGIC_EN; 149 else 150 value &= ~DP83822_WOL_MAGIC_EN; 151 152 if (wol->wolopts & WAKE_MAGICSECURE) { 153 phy_write_mmd(phydev, DP83822_DEVADDR, 154 MII_DP83822_RXSOP1, 155 (wol->sopass[1] << 8) | wol->sopass[0]); 156 phy_write_mmd(phydev, DP83822_DEVADDR, 157 MII_DP83822_RXSOP2, 158 (wol->sopass[3] << 8) | wol->sopass[2]); 159 phy_write_mmd(phydev, DP83822_DEVADDR, 160 MII_DP83822_RXSOP3, 161 (wol->sopass[5] << 8) | wol->sopass[4]); 162 value |= DP83822_WOL_SECURE_ON; 163 } else { 164 value &= ~DP83822_WOL_SECURE_ON; 165 } 166 167 /* Clear any pending WoL interrupt */ 168 phy_read(phydev, MII_DP83822_MISR2); 169 170 value |= DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL | 171 DP83822_WOL_CLR_INDICATION; 172 173 return phy_write_mmd(phydev, DP83822_DEVADDR, 174 MII_DP83822_WOL_CFG, value); 175 } else { 176 return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, 177 MII_DP83822_WOL_CFG, DP83822_WOL_EN); 178 } 179 } 180 181 static void dp83822_get_wol(struct phy_device *phydev, 182 struct ethtool_wolinfo *wol) 183 { 184 int value; 185 u16 sopass_val; 186 187 wol->supported = (WAKE_MAGIC | WAKE_MAGICSECURE); 188 wol->wolopts = 0; 189 190 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG); 191 192 if (value & DP83822_WOL_MAGIC_EN) 193 wol->wolopts |= WAKE_MAGIC; 194 195 if (value & DP83822_WOL_SECURE_ON) { 196 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR, 197 MII_DP83822_RXSOP1); 198 wol->sopass[0] = (sopass_val & 0xff); 199 wol->sopass[1] = (sopass_val >> 8); 200 201 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR, 202 MII_DP83822_RXSOP2); 203 wol->sopass[2] = (sopass_val & 0xff); 204 wol->sopass[3] = (sopass_val >> 8); 205 206 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR, 207 MII_DP83822_RXSOP3); 208 wol->sopass[4] = (sopass_val & 0xff); 209 wol->sopass[5] = (sopass_val >> 8); 210 211 wol->wolopts |= WAKE_MAGICSECURE; 212 } 213 214 /* WoL is not enabled so set wolopts to 0 */ 215 if (!(value & DP83822_WOL_EN)) 216 wol->wolopts = 0; 217 } 218 219 static int dp83822_config_intr(struct phy_device *phydev) 220 { 221 struct dp83822_private *dp83822 = phydev->priv; 222 int misr_status; 223 int physcr_status; 224 int err; 225 226 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { 227 misr_status = phy_read(phydev, MII_DP83822_MISR1); 228 if (misr_status < 0) 229 return misr_status; 230 231 misr_status |= (DP83822_RX_ERR_HF_INT_EN | 232 DP83822_FALSE_CARRIER_HF_INT_EN | 233 DP83822_LINK_STAT_INT_EN | 234 DP83822_ENERGY_DET_INT_EN | 235 DP83822_LINK_QUAL_INT_EN); 236 237 if (!dp83822->fx_enabled) 238 misr_status |= DP83822_ANEG_COMPLETE_INT_EN | 239 DP83822_DUP_MODE_CHANGE_INT_EN | 240 DP83822_SPEED_CHANGED_INT_EN; 241 242 243 err = phy_write(phydev, MII_DP83822_MISR1, misr_status); 244 if (err < 0) 245 return err; 246 247 misr_status = phy_read(phydev, MII_DP83822_MISR2); 248 if (misr_status < 0) 249 return misr_status; 250 251 misr_status |= (DP83822_JABBER_DET_INT_EN | 252 DP83822_SLEEP_MODE_INT_EN | 253 DP83822_LB_FIFO_INT_EN | 254 DP83822_PAGE_RX_INT_EN | 255 DP83822_EEE_ERROR_CHANGE_INT_EN); 256 257 if (!dp83822->fx_enabled) 258 misr_status |= DP83822_MDI_XOVER_INT_EN | 259 DP83822_ANEG_ERR_INT_EN | 260 DP83822_WOL_PKT_INT_EN; 261 262 err = phy_write(phydev, MII_DP83822_MISR2, misr_status); 263 if (err < 0) 264 return err; 265 266 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR); 267 if (physcr_status < 0) 268 return physcr_status; 269 270 physcr_status |= DP83822_PHYSCR_INT_OE | DP83822_PHYSCR_INTEN; 271 272 } else { 273 err = phy_write(phydev, MII_DP83822_MISR1, 0); 274 if (err < 0) 275 return err; 276 277 err = phy_write(phydev, MII_DP83822_MISR1, 0); 278 if (err < 0) 279 return err; 280 281 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR); 282 if (physcr_status < 0) 283 return physcr_status; 284 285 physcr_status &= ~DP83822_PHYSCR_INTEN; 286 } 287 288 return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status); 289 } 290 291 static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev) 292 { 293 bool trigger_machine = false; 294 int irq_status; 295 296 /* The MISR1 and MISR2 registers are holding the interrupt status in 297 * the upper half (15:8), while the lower half (7:0) is used for 298 * controlling the interrupt enable state of those individual interrupt 299 * sources. To determine the possible interrupt sources, just read the 300 * MISR* register and use it directly to know which interrupts have 301 * been enabled previously or not. 302 */ 303 irq_status = phy_read(phydev, MII_DP83822_MISR1); 304 if (irq_status < 0) { 305 phy_error(phydev); 306 return IRQ_NONE; 307 } 308 if (irq_status & ((irq_status & GENMASK(7, 0)) << 8)) 309 trigger_machine = true; 310 311 irq_status = phy_read(phydev, MII_DP83822_MISR2); 312 if (irq_status < 0) { 313 phy_error(phydev); 314 return IRQ_NONE; 315 } 316 if (irq_status & ((irq_status & GENMASK(7, 0)) << 8)) 317 trigger_machine = true; 318 319 if (!trigger_machine) 320 return IRQ_NONE; 321 322 phy_trigger_machine(phydev); 323 324 return IRQ_HANDLED; 325 } 326 327 static int dp8382x_disable_wol(struct phy_device *phydev) 328 { 329 int value = DP83822_WOL_EN | DP83822_WOL_MAGIC_EN | 330 DP83822_WOL_SECURE_ON; 331 332 return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, 333 MII_DP83822_WOL_CFG, value); 334 } 335 336 static int dp83822_read_status(struct phy_device *phydev) 337 { 338 struct dp83822_private *dp83822 = phydev->priv; 339 int status = phy_read(phydev, MII_DP83822_PHYSTS); 340 int ctrl2; 341 int ret; 342 343 if (dp83822->fx_enabled) { 344 if (status & DP83822_PHYSTS_LINK) { 345 phydev->speed = SPEED_UNKNOWN; 346 phydev->duplex = DUPLEX_UNKNOWN; 347 } else { 348 ctrl2 = phy_read(phydev, MII_DP83822_CTRL_2); 349 if (ctrl2 < 0) 350 return ctrl2; 351 352 if (!(ctrl2 & DP83822_FX_ENABLE)) { 353 ret = phy_write(phydev, MII_DP83822_CTRL_2, 354 DP83822_FX_ENABLE | ctrl2); 355 if (ret < 0) 356 return ret; 357 } 358 } 359 } 360 361 ret = genphy_read_status(phydev); 362 if (ret) 363 return ret; 364 365 if (status < 0) 366 return status; 367 368 if (status & DP83822_PHYSTS_DUPLEX) 369 phydev->duplex = DUPLEX_FULL; 370 else 371 phydev->duplex = DUPLEX_HALF; 372 373 if (status & DP83822_PHYSTS_10) 374 phydev->speed = SPEED_10; 375 else 376 phydev->speed = SPEED_100; 377 378 return 0; 379 } 380 381 static int dp83822_config_init(struct phy_device *phydev) 382 { 383 struct dp83822_private *dp83822 = phydev->priv; 384 struct device *dev = &phydev->mdio.dev; 385 int rgmii_delay; 386 s32 rx_int_delay; 387 s32 tx_int_delay; 388 int err = 0; 389 int bmcr; 390 391 if (phy_interface_is_rgmii(phydev)) { 392 rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0, 393 true); 394 395 if (rx_int_delay <= 0) 396 rgmii_delay = 0; 397 else 398 rgmii_delay = DP83822_RX_CLK_SHIFT; 399 400 tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0, 401 false); 402 if (tx_int_delay <= 0) 403 rgmii_delay &= ~DP83822_TX_CLK_SHIFT; 404 else 405 rgmii_delay |= DP83822_TX_CLK_SHIFT; 406 407 if (rgmii_delay) { 408 err = phy_set_bits_mmd(phydev, DP83822_DEVADDR, 409 MII_DP83822_RCSR, rgmii_delay); 410 if (err) 411 return err; 412 } 413 } 414 415 if (dp83822->fx_enabled) { 416 err = phy_modify(phydev, MII_DP83822_CTRL_2, 417 DP83822_FX_ENABLE, 1); 418 if (err < 0) 419 return err; 420 421 /* Only allow advertising what this PHY supports */ 422 linkmode_and(phydev->advertising, phydev->advertising, 423 phydev->supported); 424 425 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 426 phydev->supported); 427 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, 428 phydev->advertising); 429 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, 430 phydev->supported); 431 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT, 432 phydev->supported); 433 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, 434 phydev->advertising); 435 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT, 436 phydev->advertising); 437 438 /* Auto neg is not supported in fiber mode */ 439 bmcr = phy_read(phydev, MII_BMCR); 440 if (bmcr < 0) 441 return bmcr; 442 443 if (bmcr & BMCR_ANENABLE) { 444 err = phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0); 445 if (err < 0) 446 return err; 447 } 448 phydev->autoneg = AUTONEG_DISABLE; 449 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, 450 phydev->supported); 451 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, 452 phydev->advertising); 453 454 /* Setup fiber advertisement */ 455 err = phy_modify_changed(phydev, MII_ADVERTISE, 456 MII_DP83822_FIBER_ADVERTISE, 457 MII_DP83822_FIBER_ADVERTISE); 458 459 if (err < 0) 460 return err; 461 462 if (dp83822->fx_signal_det_low) { 463 err = phy_set_bits_mmd(phydev, DP83822_DEVADDR, 464 MII_DP83822_GENCFG, 465 DP83822_SIG_DET_LOW); 466 if (err) 467 return err; 468 } 469 } 470 return dp8382x_disable_wol(phydev); 471 } 472 473 static int dp8382x_config_init(struct phy_device *phydev) 474 { 475 return dp8382x_disable_wol(phydev); 476 } 477 478 static int dp83822_phy_reset(struct phy_device *phydev) 479 { 480 int err; 481 482 err = phy_write(phydev, MII_DP83822_RESET_CTRL, DP83822_SW_RESET); 483 if (err < 0) 484 return err; 485 486 return phydev->drv->config_init(phydev); 487 } 488 489 #ifdef CONFIG_OF_MDIO 490 static int dp83822_of_init(struct phy_device *phydev) 491 { 492 struct dp83822_private *dp83822 = phydev->priv; 493 struct device *dev = &phydev->mdio.dev; 494 495 /* Signal detection for the PHY is only enabled if the FX_EN and the 496 * SD_EN pins are strapped. Signal detection can only enabled if FX_EN 497 * is strapped otherwise signal detection is disabled for the PHY. 498 */ 499 if (dp83822->fx_enabled && dp83822->fx_sd_enable) 500 dp83822->fx_signal_det_low = device_property_present(dev, 501 "ti,link-loss-low"); 502 if (!dp83822->fx_enabled) 503 dp83822->fx_enabled = device_property_present(dev, 504 "ti,fiber-mode"); 505 506 return 0; 507 } 508 #else 509 static int dp83822_of_init(struct phy_device *phydev) 510 { 511 return 0; 512 } 513 #endif /* CONFIG_OF_MDIO */ 514 515 static int dp83822_read_straps(struct phy_device *phydev) 516 { 517 struct dp83822_private *dp83822 = phydev->priv; 518 int fx_enabled, fx_sd_enable; 519 int val; 520 521 val = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_SOR1); 522 if (val < 0) 523 return val; 524 525 fx_enabled = (val & DP83822_COL_STRAP_MASK) >> DP83822_COL_SHIFT; 526 if (fx_enabled == DP83822_STRAP_MODE2 || 527 fx_enabled == DP83822_STRAP_MODE3) 528 dp83822->fx_enabled = 1; 529 530 if (dp83822->fx_enabled) { 531 fx_sd_enable = (val & DP83822_RX_ER_STR_MASK) >> DP83822_RX_ER_SHIFT; 532 if (fx_sd_enable == DP83822_STRAP_MODE3 || 533 fx_sd_enable == DP83822_STRAP_MODE4) 534 dp83822->fx_sd_enable = 1; 535 } 536 537 return 0; 538 } 539 540 static int dp83822_probe(struct phy_device *phydev) 541 { 542 struct dp83822_private *dp83822; 543 int ret; 544 545 dp83822 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83822), 546 GFP_KERNEL); 547 if (!dp83822) 548 return -ENOMEM; 549 550 phydev->priv = dp83822; 551 552 ret = dp83822_read_straps(phydev); 553 if (ret) 554 return ret; 555 556 dp83822_of_init(phydev); 557 558 if (dp83822->fx_enabled) 559 phydev->port = PORT_FIBRE; 560 561 return 0; 562 } 563 564 static int dp83822_suspend(struct phy_device *phydev) 565 { 566 int value; 567 568 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG); 569 570 if (!(value & DP83822_WOL_EN)) 571 genphy_suspend(phydev); 572 573 return 0; 574 } 575 576 static int dp83822_resume(struct phy_device *phydev) 577 { 578 int value; 579 580 genphy_resume(phydev); 581 582 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG); 583 584 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, value | 585 DP83822_WOL_CLR_INDICATION); 586 587 return 0; 588 } 589 590 #define DP83822_PHY_DRIVER(_id, _name) \ 591 { \ 592 PHY_ID_MATCH_MODEL(_id), \ 593 .name = (_name), \ 594 /* PHY_BASIC_FEATURES */ \ 595 .probe = dp83822_probe, \ 596 .soft_reset = dp83822_phy_reset, \ 597 .config_init = dp83822_config_init, \ 598 .read_status = dp83822_read_status, \ 599 .get_wol = dp83822_get_wol, \ 600 .set_wol = dp83822_set_wol, \ 601 .config_intr = dp83822_config_intr, \ 602 .handle_interrupt = dp83822_handle_interrupt, \ 603 .suspend = dp83822_suspend, \ 604 .resume = dp83822_resume, \ 605 } 606 607 #define DP8382X_PHY_DRIVER(_id, _name) \ 608 { \ 609 PHY_ID_MATCH_MODEL(_id), \ 610 .name = (_name), \ 611 /* PHY_BASIC_FEATURES */ \ 612 .soft_reset = dp83822_phy_reset, \ 613 .config_init = dp8382x_config_init, \ 614 .get_wol = dp83822_get_wol, \ 615 .set_wol = dp83822_set_wol, \ 616 .config_intr = dp83822_config_intr, \ 617 .handle_interrupt = dp83822_handle_interrupt, \ 618 .suspend = dp83822_suspend, \ 619 .resume = dp83822_resume, \ 620 } 621 622 static struct phy_driver dp83822_driver[] = { 623 DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"), 624 DP8382X_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"), 625 DP8382X_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"), 626 DP8382X_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"), 627 DP8382X_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"), 628 DP8382X_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"), 629 DP8382X_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"), 630 }; 631 module_phy_driver(dp83822_driver); 632 633 static struct mdio_device_id __maybe_unused dp83822_tbl[] = { 634 { DP83822_PHY_ID, 0xfffffff0 }, 635 { DP83825I_PHY_ID, 0xfffffff0 }, 636 { DP83826C_PHY_ID, 0xfffffff0 }, 637 { DP83826NC_PHY_ID, 0xfffffff0 }, 638 { DP83825S_PHY_ID, 0xfffffff0 }, 639 { DP83825CM_PHY_ID, 0xfffffff0 }, 640 { DP83825CS_PHY_ID, 0xfffffff0 }, 641 { }, 642 }; 643 MODULE_DEVICE_TABLE(mdio, dp83822_tbl); 644 645 MODULE_DESCRIPTION("Texas Instruments DP83822 PHY driver"); 646 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com"); 647 MODULE_LICENSE("GPL v2"); 648