aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/phy/icplus.c79
1 files changed, 68 insertions, 11 deletions
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index d4cbc2922b23..6e344e59caf7 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -30,10 +30,17 @@
30#include <asm/irq.h> 30#include <asm/irq.h>
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
32 32
33MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers"); 33MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IC1001 PHY drivers");
34MODULE_AUTHOR("Michael Barkowski"); 34MODULE_AUTHOR("Michael Barkowski");
35MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
36 36
37/* IP101A/IP1001 */
38#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */
39#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */
40#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */
41#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */
42#define IP101A_APS_ON 2 /* IP101A APS Mode bit */
43
37static int ip175c_config_init(struct phy_device *phydev) 44static int ip175c_config_init(struct phy_device *phydev)
38{ 45{
39 int err, i; 46 int err, i;
@@ -89,27 +96,58 @@ static int ip175c_config_init(struct phy_device *phydev)
89 return 0; 96 return 0;
90} 97}
91 98
92static int ip1001_config_init(struct phy_device *phydev) 99static int ip1xx_reset(struct phy_device *phydev)
93{ 100{
94 int err, value; 101 int err, bmcr;
95 102
96 /* Software Reset PHY */ 103 /* Software Reset PHY */
97 value = phy_read(phydev, MII_BMCR); 104 bmcr = phy_read(phydev, MII_BMCR);
98 value |= BMCR_RESET; 105 bmcr |= BMCR_RESET;
99 err = phy_write(phydev, MII_BMCR, value); 106 err = phy_write(phydev, MII_BMCR, bmcr);
100 if (err < 0) 107 if (err < 0)
101 return err; 108 return err;
102 109
103 do { 110 do {
104 value = phy_read(phydev, MII_BMCR); 111 bmcr = phy_read(phydev, MII_BMCR);
105 } while (value & BMCR_RESET); 112 } while (bmcr & BMCR_RESET);
113
114 return err;
115}
116
117static int ip1001_config_init(struct phy_device *phydev)
118{
119 int c;
120
121 c = ip1xx_reset(phydev);
122 if (c < 0)
123 return c;
124
125 /* Enable Auto Power Saving mode */
126 c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2);
127 c |= IP1001_APS_ON;
128 if (c < 0)
129 return c;
106 130
107 /* Additional delay (2ns) used to adjust RX clock phase 131 /* Additional delay (2ns) used to adjust RX clock phase
108 * at GMII/ RGMII interface */ 132 * at GMII/ RGMII interface */
109 value = phy_read(phydev, 16); 133 c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
110 value |= 0x3; 134 c |= IP1001_PHASE_SEL_MASK;
135
136 return phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
137}
138
139static int ip101a_config_init(struct phy_device *phydev)
140{
141 int c;
111 142
112 return phy_write(phydev, 16, value); 143 c = ip1xx_reset(phydev);
144 if (c < 0)
145 return c;
146
147 /* Enable Auto Power Saving mode */
148 c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
149 c |= IP101A_APS_ON;
150 return c;
113} 151}
114 152
115static int ip175c_read_status(struct phy_device *phydev) 153static int ip175c_read_status(struct phy_device *phydev)
@@ -158,6 +196,20 @@ static struct phy_driver ip1001_driver = {
158 .driver = { .owner = THIS_MODULE,}, 196 .driver = { .owner = THIS_MODULE,},
159}; 197};
160 198
199static struct phy_driver ip101a_driver = {
200 .phy_id = 0x02430c54,
201 .name = "ICPlus IP101A",
202 .phy_id_mask = 0x0ffffff0,
203 .features = PHY_BASIC_FEATURES | SUPPORTED_Pause |
204 SUPPORTED_Asym_Pause,
205 .config_init = &ip101a_config_init,
206 .config_aneg = &genphy_config_aneg,
207 .read_status = &genphy_read_status,
208 .suspend = genphy_suspend,
209 .resume = genphy_resume,
210 .driver = { .owner = THIS_MODULE,},
211};
212
161static int __init icplus_init(void) 213static int __init icplus_init(void)
162{ 214{
163 int ret = 0; 215 int ret = 0;
@@ -166,12 +218,17 @@ static int __init icplus_init(void)
166 if (ret < 0) 218 if (ret < 0)
167 return -ENODEV; 219 return -ENODEV;
168 220
221 ret = phy_driver_register(&ip101a_driver);
222 if (ret < 0)
223 return -ENODEV;
224
169 return phy_driver_register(&ip175c_driver); 225 return phy_driver_register(&ip175c_driver);
170} 226}
171 227
172static void __exit icplus_exit(void) 228static void __exit icplus_exit(void)
173{ 229{
174 phy_driver_unregister(&ip1001_driver); 230 phy_driver_unregister(&ip1001_driver);
231 phy_driver_unregister(&ip101a_driver);
175 phy_driver_unregister(&ip175c_driver); 232 phy_driver_unregister(&ip175c_driver);
176} 233}
177 234