xref: /openbmc/linux/drivers/net/phy/dp83822.c (revision 2ace13e10dbd1c8c5c9f118e5d4d0e0a77b152c7)
15f857575SAndrew Lunn // SPDX-License-Identifier: GPL-2.0
2*2ace13e1SDan Murphy /* Driver for the Texas Instruments DP83822, DP83825 and DP83826 PHYs.
387461f7aSDan Murphy  *
487461f7aSDan Murphy  * Copyright (C) 2017 Texas Instruments Inc.
587461f7aSDan Murphy  */
687461f7aSDan Murphy 
787461f7aSDan Murphy #include <linux/ethtool.h>
887461f7aSDan Murphy #include <linux/etherdevice.h>
987461f7aSDan Murphy #include <linux/kernel.h>
1087461f7aSDan Murphy #include <linux/mii.h>
1187461f7aSDan Murphy #include <linux/module.h>
1287461f7aSDan Murphy #include <linux/of.h>
1387461f7aSDan Murphy #include <linux/phy.h>
1487461f7aSDan Murphy #include <linux/netdevice.h>
1587461f7aSDan Murphy 
1687461f7aSDan Murphy #define DP83822_PHY_ID	        0x2000a240
17*2ace13e1SDan Murphy #define DP83825S_PHY_ID		0x2000a140
1806acc17aSDan Murphy #define DP83825I_PHY_ID		0x2000a150
19*2ace13e1SDan Murphy #define DP83825CM_PHY_ID	0x2000a160
20*2ace13e1SDan Murphy #define DP83825CS_PHY_ID	0x2000a170
21783da36bSDan Murphy #define DP83826C_PHY_ID		0x2000a130
22783da36bSDan Murphy #define DP83826NC_PHY_ID	0x2000a110
2306acc17aSDan Murphy 
2487461f7aSDan Murphy #define DP83822_DEVADDR		0x1f
2587461f7aSDan Murphy 
2687461f7aSDan Murphy #define MII_DP83822_PHYSCR	0x11
2787461f7aSDan Murphy #define MII_DP83822_MISR1	0x12
2887461f7aSDan Murphy #define MII_DP83822_MISR2	0x13
2987461f7aSDan Murphy #define MII_DP83822_RESET_CTRL	0x1f
3087461f7aSDan Murphy 
3187461f7aSDan Murphy #define DP83822_HW_RESET	BIT(15)
3287461f7aSDan Murphy #define DP83822_SW_RESET	BIT(14)
3387461f7aSDan Murphy 
3487461f7aSDan Murphy /* PHYSCR Register Fields */
3587461f7aSDan Murphy #define DP83822_PHYSCR_INT_OE		BIT(0) /* Interrupt Output Enable */
3687461f7aSDan Murphy #define DP83822_PHYSCR_INTEN		BIT(1) /* Interrupt Enable */
3787461f7aSDan Murphy 
3887461f7aSDan Murphy /* MISR1 bits */
3987461f7aSDan Murphy #define DP83822_RX_ERR_HF_INT_EN	BIT(0)
4087461f7aSDan Murphy #define DP83822_FALSE_CARRIER_HF_INT_EN	BIT(1)
4187461f7aSDan Murphy #define DP83822_ANEG_COMPLETE_INT_EN	BIT(2)
4287461f7aSDan Murphy #define DP83822_DUP_MODE_CHANGE_INT_EN	BIT(3)
4387461f7aSDan Murphy #define DP83822_SPEED_CHANGED_INT_EN	BIT(4)
4487461f7aSDan Murphy #define DP83822_LINK_STAT_INT_EN	BIT(5)
4587461f7aSDan Murphy #define DP83822_ENERGY_DET_INT_EN	BIT(6)
4687461f7aSDan Murphy #define DP83822_LINK_QUAL_INT_EN	BIT(7)
4787461f7aSDan Murphy 
4887461f7aSDan Murphy /* MISR2 bits */
4987461f7aSDan Murphy #define DP83822_JABBER_DET_INT_EN	BIT(0)
5087461f7aSDan Murphy #define DP83822_WOL_PKT_INT_EN		BIT(1)
5187461f7aSDan Murphy #define DP83822_SLEEP_MODE_INT_EN	BIT(2)
5287461f7aSDan Murphy #define DP83822_MDI_XOVER_INT_EN	BIT(3)
5387461f7aSDan Murphy #define DP83822_LB_FIFO_INT_EN		BIT(4)
5487461f7aSDan Murphy #define DP83822_PAGE_RX_INT_EN		BIT(5)
5587461f7aSDan Murphy #define DP83822_ANEG_ERR_INT_EN		BIT(6)
5687461f7aSDan Murphy #define DP83822_EEE_ERROR_CHANGE_INT_EN	BIT(7)
5787461f7aSDan Murphy 
5887461f7aSDan Murphy /* INT_STAT1 bits */
5987461f7aSDan Murphy #define DP83822_WOL_INT_EN	BIT(4)
6087461f7aSDan Murphy #define DP83822_WOL_INT_STAT	BIT(12)
6187461f7aSDan Murphy 
6287461f7aSDan Murphy #define MII_DP83822_RXSOP1	0x04a5
6387461f7aSDan Murphy #define	MII_DP83822_RXSOP2	0x04a6
6487461f7aSDan Murphy #define	MII_DP83822_RXSOP3	0x04a7
6587461f7aSDan Murphy 
6687461f7aSDan Murphy /* WoL Registers */
6787461f7aSDan Murphy #define	MII_DP83822_WOL_CFG	0x04a0
6887461f7aSDan Murphy #define	MII_DP83822_WOL_STAT	0x04a1
6987461f7aSDan Murphy #define	MII_DP83822_WOL_DA1	0x04a2
7087461f7aSDan Murphy #define	MII_DP83822_WOL_DA2	0x04a3
7187461f7aSDan Murphy #define	MII_DP83822_WOL_DA3	0x04a4
7287461f7aSDan Murphy 
7387461f7aSDan Murphy /* WoL bits */
7487461f7aSDan Murphy #define DP83822_WOL_MAGIC_EN	BIT(0)
7587461f7aSDan Murphy #define DP83822_WOL_SECURE_ON	BIT(5)
7687461f7aSDan Murphy #define DP83822_WOL_EN		BIT(7)
7787461f7aSDan Murphy #define DP83822_WOL_INDICATION_SEL BIT(8)
7887461f7aSDan Murphy #define DP83822_WOL_CLR_INDICATION BIT(11)
7987461f7aSDan Murphy 
8087461f7aSDan Murphy static int dp83822_ack_interrupt(struct phy_device *phydev)
8187461f7aSDan Murphy {
8287461f7aSDan Murphy 	int err;
8387461f7aSDan Murphy 
8487461f7aSDan Murphy 	err = phy_read(phydev, MII_DP83822_MISR1);
8587461f7aSDan Murphy 	if (err < 0)
8687461f7aSDan Murphy 		return err;
8787461f7aSDan Murphy 
8887461f7aSDan Murphy 	err = phy_read(phydev, MII_DP83822_MISR2);
8987461f7aSDan Murphy 	if (err < 0)
9087461f7aSDan Murphy 		return err;
9187461f7aSDan Murphy 
9287461f7aSDan Murphy 	return 0;
9387461f7aSDan Murphy }
9487461f7aSDan Murphy 
9587461f7aSDan Murphy static int dp83822_set_wol(struct phy_device *phydev,
9687461f7aSDan Murphy 			   struct ethtool_wolinfo *wol)
9787461f7aSDan Murphy {
9887461f7aSDan Murphy 	struct net_device *ndev = phydev->attached_dev;
9987461f7aSDan Murphy 	u16 value;
10087461f7aSDan Murphy 	const u8 *mac;
10187461f7aSDan Murphy 
10287461f7aSDan Murphy 	if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
10387461f7aSDan Murphy 		mac = (const u8 *)ndev->dev_addr;
10487461f7aSDan Murphy 
10587461f7aSDan Murphy 		if (!is_valid_ether_addr(mac))
10687461f7aSDan Murphy 			return -EINVAL;
10787461f7aSDan Murphy 
10887461f7aSDan Murphy 		/* MAC addresses start with byte 5, but stored in mac[0].
10987461f7aSDan Murphy 		 * 822 PHYs store bytes 4|5, 2|3, 0|1
11087461f7aSDan Murphy 		 */
11187461f7aSDan Murphy 		phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA1,
11287461f7aSDan Murphy 			      (mac[1] << 8) | mac[0]);
11387461f7aSDan Murphy 		phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA2,
11487461f7aSDan Murphy 			      (mac[3] << 8) | mac[2]);
11587461f7aSDan Murphy 		phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA3,
11687461f7aSDan Murphy 			      (mac[5] << 8) | mac[4]);
11787461f7aSDan Murphy 
11887461f7aSDan Murphy 		value = phy_read_mmd(phydev, DP83822_DEVADDR,
11987461f7aSDan Murphy 				     MII_DP83822_WOL_CFG);
12087461f7aSDan Murphy 		if (wol->wolopts & WAKE_MAGIC)
12187461f7aSDan Murphy 			value |= DP83822_WOL_MAGIC_EN;
12287461f7aSDan Murphy 		else
12387461f7aSDan Murphy 			value &= ~DP83822_WOL_MAGIC_EN;
12487461f7aSDan Murphy 
12587461f7aSDan Murphy 		if (wol->wolopts & WAKE_MAGICSECURE) {
12687461f7aSDan Murphy 			phy_write_mmd(phydev, DP83822_DEVADDR,
12787461f7aSDan Murphy 				      MII_DP83822_RXSOP1,
12887461f7aSDan Murphy 				      (wol->sopass[1] << 8) | wol->sopass[0]);
12987461f7aSDan Murphy 			phy_write_mmd(phydev, DP83822_DEVADDR,
13087461f7aSDan Murphy 				      MII_DP83822_RXSOP2,
13187461f7aSDan Murphy 				      (wol->sopass[3] << 8) | wol->sopass[2]);
13287461f7aSDan Murphy 			phy_write_mmd(phydev, DP83822_DEVADDR,
13387461f7aSDan Murphy 				      MII_DP83822_RXSOP3,
13487461f7aSDan Murphy 				      (wol->sopass[5] << 8) | wol->sopass[4]);
13587461f7aSDan Murphy 			value |= DP83822_WOL_SECURE_ON;
13687461f7aSDan Murphy 		} else {
13787461f7aSDan Murphy 			value &= ~DP83822_WOL_SECURE_ON;
13887461f7aSDan Murphy 		}
13987461f7aSDan Murphy 
14087461f7aSDan Murphy 		value |= (DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL |
14187461f7aSDan Murphy 			  DP83822_WOL_CLR_INDICATION);
14287461f7aSDan Murphy 		phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG,
14387461f7aSDan Murphy 			      value);
14487461f7aSDan Murphy 	} else {
14587461f7aSDan Murphy 		value = phy_read_mmd(phydev, DP83822_DEVADDR,
14687461f7aSDan Murphy 				     MII_DP83822_WOL_CFG);
14787461f7aSDan Murphy 		value &= ~DP83822_WOL_EN;
14887461f7aSDan Murphy 		phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG,
14987461f7aSDan Murphy 			      value);
15087461f7aSDan Murphy 	}
15187461f7aSDan Murphy 
15287461f7aSDan Murphy 	return 0;
15387461f7aSDan Murphy }
15487461f7aSDan Murphy 
15587461f7aSDan Murphy static void dp83822_get_wol(struct phy_device *phydev,
15687461f7aSDan Murphy 			    struct ethtool_wolinfo *wol)
15787461f7aSDan Murphy {
15887461f7aSDan Murphy 	int value;
15987461f7aSDan Murphy 	u16 sopass_val;
16087461f7aSDan Murphy 
16187461f7aSDan Murphy 	wol->supported = (WAKE_MAGIC | WAKE_MAGICSECURE);
16287461f7aSDan Murphy 	wol->wolopts = 0;
16387461f7aSDan Murphy 
16487461f7aSDan Murphy 	value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
16587461f7aSDan Murphy 
16687461f7aSDan Murphy 	if (value & DP83822_WOL_MAGIC_EN)
16787461f7aSDan Murphy 		wol->wolopts |= WAKE_MAGIC;
16887461f7aSDan Murphy 
16987461f7aSDan Murphy 	if (value & DP83822_WOL_SECURE_ON) {
17087461f7aSDan Murphy 		sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
17187461f7aSDan Murphy 					  MII_DP83822_RXSOP1);
17287461f7aSDan Murphy 		wol->sopass[0] = (sopass_val & 0xff);
17387461f7aSDan Murphy 		wol->sopass[1] = (sopass_val >> 8);
17487461f7aSDan Murphy 
17587461f7aSDan Murphy 		sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
17687461f7aSDan Murphy 					  MII_DP83822_RXSOP2);
17787461f7aSDan Murphy 		wol->sopass[2] = (sopass_val & 0xff);
17887461f7aSDan Murphy 		wol->sopass[3] = (sopass_val >> 8);
17987461f7aSDan Murphy 
18087461f7aSDan Murphy 		sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
18187461f7aSDan Murphy 					  MII_DP83822_RXSOP3);
18287461f7aSDan Murphy 		wol->sopass[4] = (sopass_val & 0xff);
18387461f7aSDan Murphy 		wol->sopass[5] = (sopass_val >> 8);
18487461f7aSDan Murphy 
18587461f7aSDan Murphy 		wol->wolopts |= WAKE_MAGICSECURE;
18687461f7aSDan Murphy 	}
18787461f7aSDan Murphy 
18887461f7aSDan Murphy 	/* WoL is not enabled so set wolopts to 0 */
18987461f7aSDan Murphy 	if (!(value & DP83822_WOL_EN))
19087461f7aSDan Murphy 		wol->wolopts = 0;
19187461f7aSDan Murphy }
19287461f7aSDan Murphy 
19387461f7aSDan Murphy static int dp83822_config_intr(struct phy_device *phydev)
19487461f7aSDan Murphy {
19587461f7aSDan Murphy 	int misr_status;
19687461f7aSDan Murphy 	int physcr_status;
19787461f7aSDan Murphy 	int err;
19887461f7aSDan Murphy 
19987461f7aSDan Murphy 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
20087461f7aSDan Murphy 		misr_status = phy_read(phydev, MII_DP83822_MISR1);
20187461f7aSDan Murphy 		if (misr_status < 0)
20287461f7aSDan Murphy 			return misr_status;
20387461f7aSDan Murphy 
20487461f7aSDan Murphy 		misr_status |= (DP83822_RX_ERR_HF_INT_EN |
20587461f7aSDan Murphy 				DP83822_FALSE_CARRIER_HF_INT_EN |
20687461f7aSDan Murphy 				DP83822_ANEG_COMPLETE_INT_EN |
20787461f7aSDan Murphy 				DP83822_DUP_MODE_CHANGE_INT_EN |
20887461f7aSDan Murphy 				DP83822_SPEED_CHANGED_INT_EN |
20987461f7aSDan Murphy 				DP83822_LINK_STAT_INT_EN |
21087461f7aSDan Murphy 				DP83822_ENERGY_DET_INT_EN |
21187461f7aSDan Murphy 				DP83822_LINK_QUAL_INT_EN);
21287461f7aSDan Murphy 
21387461f7aSDan Murphy 		err = phy_write(phydev, MII_DP83822_MISR1, misr_status);
21487461f7aSDan Murphy 		if (err < 0)
21587461f7aSDan Murphy 			return err;
21687461f7aSDan Murphy 
21787461f7aSDan Murphy 		misr_status = phy_read(phydev, MII_DP83822_MISR2);
21887461f7aSDan Murphy 		if (misr_status < 0)
21987461f7aSDan Murphy 			return misr_status;
22087461f7aSDan Murphy 
22187461f7aSDan Murphy 		misr_status |= (DP83822_JABBER_DET_INT_EN |
22287461f7aSDan Murphy 				DP83822_WOL_PKT_INT_EN |
22387461f7aSDan Murphy 				DP83822_SLEEP_MODE_INT_EN |
22487461f7aSDan Murphy 				DP83822_MDI_XOVER_INT_EN |
22587461f7aSDan Murphy 				DP83822_LB_FIFO_INT_EN |
22687461f7aSDan Murphy 				DP83822_PAGE_RX_INT_EN |
22787461f7aSDan Murphy 				DP83822_ANEG_ERR_INT_EN |
22887461f7aSDan Murphy 				DP83822_EEE_ERROR_CHANGE_INT_EN);
22987461f7aSDan Murphy 
23087461f7aSDan Murphy 		err = phy_write(phydev, MII_DP83822_MISR2, misr_status);
23187461f7aSDan Murphy 		if (err < 0)
23287461f7aSDan Murphy 			return err;
23387461f7aSDan Murphy 
23487461f7aSDan Murphy 		physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
23587461f7aSDan Murphy 		if (physcr_status < 0)
23687461f7aSDan Murphy 			return physcr_status;
23787461f7aSDan Murphy 
23887461f7aSDan Murphy 		physcr_status |= DP83822_PHYSCR_INT_OE | DP83822_PHYSCR_INTEN;
23987461f7aSDan Murphy 
24087461f7aSDan Murphy 	} else {
24187461f7aSDan Murphy 		err = phy_write(phydev, MII_DP83822_MISR1, 0);
24287461f7aSDan Murphy 		if (err < 0)
24387461f7aSDan Murphy 			return err;
24487461f7aSDan Murphy 
24587461f7aSDan Murphy 		err = phy_write(phydev, MII_DP83822_MISR1, 0);
24687461f7aSDan Murphy 		if (err < 0)
24787461f7aSDan Murphy 			return err;
24887461f7aSDan Murphy 
24987461f7aSDan Murphy 		physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
25087461f7aSDan Murphy 		if (physcr_status < 0)
25187461f7aSDan Murphy 			return physcr_status;
25287461f7aSDan Murphy 
25387461f7aSDan Murphy 		physcr_status &= ~DP83822_PHYSCR_INTEN;
25487461f7aSDan Murphy 	}
25587461f7aSDan Murphy 
25687461f7aSDan Murphy 	return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status);
25787461f7aSDan Murphy }
25887461f7aSDan Murphy 
25987461f7aSDan Murphy static int dp83822_config_init(struct phy_device *phydev)
26087461f7aSDan Murphy {
26187461f7aSDan Murphy 	int value;
26287461f7aSDan Murphy 
26387461f7aSDan Murphy 	value = DP83822_WOL_MAGIC_EN | DP83822_WOL_SECURE_ON | DP83822_WOL_EN;
26487461f7aSDan Murphy 
26587461f7aSDan Murphy 	return phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG,
26687461f7aSDan Murphy 	      value);
26787461f7aSDan Murphy }
26887461f7aSDan Murphy 
26987461f7aSDan Murphy static int dp83822_phy_reset(struct phy_device *phydev)
27087461f7aSDan Murphy {
27187461f7aSDan Murphy 	int err;
27287461f7aSDan Murphy 
27387461f7aSDan Murphy 	err = phy_write(phydev, MII_DP83822_RESET_CTRL, DP83822_HW_RESET);
27487461f7aSDan Murphy 	if (err < 0)
27587461f7aSDan Murphy 		return err;
27687461f7aSDan Murphy 
27787461f7aSDan Murphy 	dp83822_config_init(phydev);
27887461f7aSDan Murphy 
27987461f7aSDan Murphy 	return 0;
28087461f7aSDan Murphy }
28187461f7aSDan Murphy 
28287461f7aSDan Murphy static int dp83822_suspend(struct phy_device *phydev)
28387461f7aSDan Murphy {
28487461f7aSDan Murphy 	int value;
28587461f7aSDan Murphy 
28687461f7aSDan Murphy 	value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
28787461f7aSDan Murphy 
28887461f7aSDan Murphy 	if (!(value & DP83822_WOL_EN))
28987461f7aSDan Murphy 		genphy_suspend(phydev);
29087461f7aSDan Murphy 
29187461f7aSDan Murphy 	return 0;
29287461f7aSDan Murphy }
29387461f7aSDan Murphy 
29487461f7aSDan Murphy static int dp83822_resume(struct phy_device *phydev)
29587461f7aSDan Murphy {
29687461f7aSDan Murphy 	int value;
29787461f7aSDan Murphy 
29887461f7aSDan Murphy 	genphy_resume(phydev);
29987461f7aSDan Murphy 
30087461f7aSDan Murphy 	value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
30187461f7aSDan Murphy 
30287461f7aSDan Murphy 	phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, value |
30387461f7aSDan Murphy 		      DP83822_WOL_CLR_INDICATION);
30487461f7aSDan Murphy 
30587461f7aSDan Murphy 	return 0;
30687461f7aSDan Murphy }
30787461f7aSDan Murphy 
30806acc17aSDan Murphy #define DP83822_PHY_DRIVER(_id, _name)				\
30906acc17aSDan Murphy 	{							\
31006acc17aSDan Murphy 		PHY_ID_MATCH_MODEL(_id),			\
31106acc17aSDan Murphy 		.name		= (_name),			\
312dcdecdcfSHeiner Kallweit 		/* PHY_BASIC_FEATURES */			\
31306acc17aSDan Murphy 		.soft_reset	= dp83822_phy_reset,		\
31406acc17aSDan Murphy 		.config_init	= dp83822_config_init,		\
31506acc17aSDan Murphy 		.get_wol = dp83822_get_wol,			\
31606acc17aSDan Murphy 		.set_wol = dp83822_set_wol,			\
31706acc17aSDan Murphy 		.ack_interrupt = dp83822_ack_interrupt,		\
31806acc17aSDan Murphy 		.config_intr = dp83822_config_intr,		\
31906acc17aSDan Murphy 		.suspend = dp83822_suspend,			\
32006acc17aSDan Murphy 		.resume = dp83822_resume,			\
32106acc17aSDan Murphy 	}
32206acc17aSDan Murphy 
32387461f7aSDan Murphy static struct phy_driver dp83822_driver[] = {
32406acc17aSDan Murphy 	DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"),
32506acc17aSDan Murphy 	DP83822_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"),
326783da36bSDan Murphy 	DP83822_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"),
327783da36bSDan Murphy 	DP83822_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"),
328*2ace13e1SDan Murphy 	DP83822_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"),
329*2ace13e1SDan Murphy 	DP83822_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"),
330*2ace13e1SDan Murphy 	DP83822_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"),
33187461f7aSDan Murphy };
33287461f7aSDan Murphy module_phy_driver(dp83822_driver);
33387461f7aSDan Murphy 
33487461f7aSDan Murphy static struct mdio_device_id __maybe_unused dp83822_tbl[] = {
33587461f7aSDan Murphy 	{ DP83822_PHY_ID, 0xfffffff0 },
33606acc17aSDan Murphy 	{ DP83825I_PHY_ID, 0xfffffff0 },
337783da36bSDan Murphy 	{ DP83826C_PHY_ID, 0xfffffff0 },
338783da36bSDan Murphy 	{ DP83826NC_PHY_ID, 0xfffffff0 },
339*2ace13e1SDan Murphy 	{ DP83825S_PHY_ID, 0xfffffff0 },
340*2ace13e1SDan Murphy 	{ DP83825CM_PHY_ID, 0xfffffff0 },
341*2ace13e1SDan Murphy 	{ DP83825CS_PHY_ID, 0xfffffff0 },
34287461f7aSDan Murphy 	{ },
34387461f7aSDan Murphy };
34487461f7aSDan Murphy MODULE_DEVICE_TABLE(mdio, dp83822_tbl);
34587461f7aSDan Murphy 
34687461f7aSDan Murphy MODULE_DESCRIPTION("Texas Instruments DP83822 PHY driver");
34787461f7aSDan Murphy MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com");
3485f857575SAndrew Lunn MODULE_LICENSE("GPL v2");
349