mei: me: add cannon point device ids
[linux/fpc-iii.git] / drivers / net / phy / realtek.c
blobeda0a6e869189a823e37a93ba50630c589bf6d8d
1 /*
2 * drivers/net/phy/realtek.c
4 * Driver for Realtek PHYs
6 * Author: Johnson Leung <r58129@freescale.com>
8 * Copyright (c) 2004 Freescale Semiconductor, Inc.
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
16 #include <linux/phy.h>
17 #include <linux/module.h>
19 #define RTL821x_PHYSR 0x11
20 #define RTL821x_PHYSR_DUPLEX 0x2000
21 #define RTL821x_PHYSR_SPEED 0xc000
22 #define RTL821x_INER 0x12
23 #define RTL821x_INER_INIT 0x6400
24 #define RTL821x_INSR 0x13
25 #define RTL821x_PAGE_SELECT 0x1f
26 #define RTL8211E_INER_LINK_STATUS 0x400
28 #define RTL8211F_INER_LINK_STATUS 0x0010
29 #define RTL8211F_INSR 0x1d
30 #define RTL8211F_TX_DELAY 0x100
32 #define RTL8201F_ISR 0x1e
33 #define RTL8201F_IER 0x13
35 MODULE_DESCRIPTION("Realtek PHY driver");
36 MODULE_AUTHOR("Johnson Leung");
37 MODULE_LICENSE("GPL");
39 static int rtl8201_ack_interrupt(struct phy_device *phydev)
41 int err;
43 err = phy_read(phydev, RTL8201F_ISR);
45 return (err < 0) ? err : 0;
48 static int rtl821x_ack_interrupt(struct phy_device *phydev)
50 int err;
52 err = phy_read(phydev, RTL821x_INSR);
54 return (err < 0) ? err : 0;
57 static int rtl8211f_ack_interrupt(struct phy_device *phydev)
59 int err;
61 phy_write(phydev, RTL821x_PAGE_SELECT, 0xa43);
62 err = phy_read(phydev, RTL8211F_INSR);
63 /* restore to default page 0 */
64 phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
66 return (err < 0) ? err : 0;
69 static int rtl8201_config_intr(struct phy_device *phydev)
71 int err;
73 /* switch to page 7 */
74 phy_write(phydev, RTL821x_PAGE_SELECT, 0x7);
76 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
77 err = phy_write(phydev, RTL8201F_IER,
78 BIT(13) | BIT(12) | BIT(11));
79 else
80 err = phy_write(phydev, RTL8201F_IER, 0);
82 /* restore to default page 0 */
83 phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
85 return err;
88 static int rtl8211b_config_intr(struct phy_device *phydev)
90 int err;
92 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
93 err = phy_write(phydev, RTL821x_INER,
94 RTL821x_INER_INIT);
95 else
96 err = phy_write(phydev, RTL821x_INER, 0);
98 return err;
101 static int rtl8211e_config_intr(struct phy_device *phydev)
103 int err;
105 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
106 err = phy_write(phydev, RTL821x_INER,
107 RTL8211E_INER_LINK_STATUS);
108 else
109 err = phy_write(phydev, RTL821x_INER, 0);
111 return err;
114 static int rtl8211f_config_intr(struct phy_device *phydev)
116 int err;
118 phy_write(phydev, RTL821x_PAGE_SELECT, 0xa42);
119 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
120 err = phy_write(phydev, RTL821x_INER,
121 RTL8211F_INER_LINK_STATUS);
122 else
123 err = phy_write(phydev, RTL821x_INER, 0);
124 phy_write(phydev, RTL821x_PAGE_SELECT, 0);
126 return err;
129 static int rtl8211f_config_init(struct phy_device *phydev)
131 int ret;
132 u16 reg;
134 ret = genphy_config_init(phydev);
135 if (ret < 0)
136 return ret;
138 phy_write(phydev, RTL821x_PAGE_SELECT, 0xd08);
139 reg = phy_read(phydev, 0x11);
141 /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
142 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
143 phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
144 reg |= RTL8211F_TX_DELAY;
145 else
146 reg &= ~RTL8211F_TX_DELAY;
148 phy_write(phydev, 0x11, reg);
149 /* restore to default page 0 */
150 phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
152 return 0;
155 static struct phy_driver realtek_drvs[] = {
157 .phy_id = 0x00008201,
158 .name = "RTL8201CP Ethernet",
159 .phy_id_mask = 0x0000ffff,
160 .features = PHY_BASIC_FEATURES,
161 .flags = PHY_HAS_INTERRUPT,
162 .config_aneg = &genphy_config_aneg,
163 .read_status = &genphy_read_status,
164 }, {
165 .phy_id = 0x001cc816,
166 .name = "RTL8201F 10/100Mbps Ethernet",
167 .phy_id_mask = 0x001fffff,
168 .features = PHY_BASIC_FEATURES,
169 .flags = PHY_HAS_INTERRUPT,
170 .config_aneg = &genphy_config_aneg,
171 .read_status = &genphy_read_status,
172 .ack_interrupt = &rtl8201_ack_interrupt,
173 .config_intr = &rtl8201_config_intr,
174 .suspend = genphy_suspend,
175 .resume = genphy_resume,
176 }, {
177 .phy_id = 0x001cc912,
178 .name = "RTL8211B Gigabit Ethernet",
179 .phy_id_mask = 0x001fffff,
180 .features = PHY_GBIT_FEATURES,
181 .flags = PHY_HAS_INTERRUPT,
182 .config_aneg = &genphy_config_aneg,
183 .read_status = &genphy_read_status,
184 .ack_interrupt = &rtl821x_ack_interrupt,
185 .config_intr = &rtl8211b_config_intr,
186 }, {
187 .phy_id = 0x001cc914,
188 .name = "RTL8211DN Gigabit Ethernet",
189 .phy_id_mask = 0x001fffff,
190 .features = PHY_GBIT_FEATURES,
191 .flags = PHY_HAS_INTERRUPT,
192 .config_aneg = genphy_config_aneg,
193 .read_status = genphy_read_status,
194 .ack_interrupt = rtl821x_ack_interrupt,
195 .config_intr = rtl8211e_config_intr,
196 .suspend = genphy_suspend,
197 .resume = genphy_resume,
198 }, {
199 .phy_id = 0x001cc915,
200 .name = "RTL8211E Gigabit Ethernet",
201 .phy_id_mask = 0x001fffff,
202 .features = PHY_GBIT_FEATURES,
203 .flags = PHY_HAS_INTERRUPT,
204 .config_aneg = &genphy_config_aneg,
205 .read_status = &genphy_read_status,
206 .ack_interrupt = &rtl821x_ack_interrupt,
207 .config_intr = &rtl8211e_config_intr,
208 .suspend = genphy_suspend,
209 .resume = genphy_resume,
210 }, {
211 .phy_id = 0x001cc916,
212 .name = "RTL8211F Gigabit Ethernet",
213 .phy_id_mask = 0x001fffff,
214 .features = PHY_GBIT_FEATURES,
215 .flags = PHY_HAS_INTERRUPT,
216 .config_aneg = &genphy_config_aneg,
217 .config_init = &rtl8211f_config_init,
218 .read_status = &genphy_read_status,
219 .ack_interrupt = &rtl8211f_ack_interrupt,
220 .config_intr = &rtl8211f_config_intr,
221 .suspend = genphy_suspend,
222 .resume = genphy_resume,
226 module_phy_driver(realtek_drvs);
228 static struct mdio_device_id __maybe_unused realtek_tbl[] = {
229 { 0x001cc816, 0x001fffff },
230 { 0x001cc912, 0x001fffff },
231 { 0x001cc914, 0x001fffff },
232 { 0x001cc915, 0x001fffff },
233 { 0x001cc916, 0x001fffff },
237 MODULE_DEVICE_TABLE(mdio, realtek_tbl);