.. | .. |
---|
| 1 | +#include <linux/bitops.h> |
---|
| 2 | +#include <linux/phy.h> |
---|
| 3 | +#include <linux/module.h> |
---|
| 4 | +#include <linux/delay.h> |
---|
| 5 | +#include <linux/device.h> |
---|
| 6 | +#include <linux/mdio.h> |
---|
| 7 | +#include <linux/timer.h> |
---|
| 8 | +#include <linux/netdevice.h> |
---|
| 9 | + |
---|
| 10 | + |
---|
| 11 | + |
---|
| 12 | +#define MAXIO_PHY_VER "v1.8.1.4" |
---|
| 13 | +#define MAXIO_PAGE_SELECT 0x1f |
---|
| 14 | +#define MAXIO_MAE0621A_WORK_STATUS_REG 0x1d |
---|
| 15 | +#define MAXIO_MAE0621A_CLK_MODE_REG 0x02 |
---|
| 16 | + |
---|
| 17 | +#define MAXIO_PHYSR_P_A43 (0X1A) |
---|
| 18 | +#define MAXIO_PHY_LINK (1<<2) |
---|
| 19 | +#define MAXIO_PHY_DUPLEX (1<<3) |
---|
| 20 | +#define MAXIO_PHY_SPEED (3<<4) |
---|
| 21 | +#define MAXIO_PHY_1000M (0X20) |
---|
| 22 | +#define MAXIO_PHY_100M (0X10) |
---|
| 23 | +#define MAXIO_PHY_10M (0X00) |
---|
| 24 | + |
---|
| 25 | +#define AUTONEG_COMPLETED_INT_EN (0x8) |
---|
| 26 | +#define LINKOK (0x4) |
---|
| 27 | +#define AUTONEG_COMPLETED (0x8) |
---|
| 28 | + |
---|
| 29 | +#define PHY_READ(a,b) phy_read((a),(b)) |
---|
| 30 | +#define PHY_WRITE(a,b,c) phy_write((a),(b),(c)) |
---|
| 31 | + |
---|
| 32 | + |
---|
| 33 | +int maxio_read_paged(struct phy_device *phydev, int page, u32 regnum) |
---|
| 34 | +{ |
---|
| 35 | + int ret = 0, oldpage; |
---|
| 36 | + |
---|
| 37 | + oldpage = PHY_READ(phydev, MAXIO_PAGE_SELECT); |
---|
| 38 | + if (oldpage >= 0) { |
---|
| 39 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, page); |
---|
| 40 | + ret = PHY_READ(phydev, regnum); |
---|
| 41 | + } |
---|
| 42 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, oldpage); |
---|
| 43 | + |
---|
| 44 | + return ret; |
---|
| 45 | +} |
---|
| 46 | + |
---|
| 47 | + |
---|
| 48 | +int maxio_write_paged(struct phy_device *phydev, int page, u32 regnum, u16 val) |
---|
| 49 | +{ |
---|
| 50 | + int ret = 0, oldpage; |
---|
| 51 | + |
---|
| 52 | + oldpage = PHY_READ(phydev, MAXIO_PAGE_SELECT); |
---|
| 53 | + if (oldpage >= 0) { |
---|
| 54 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, page); |
---|
| 55 | + ret = PHY_WRITE(phydev, regnum, val); |
---|
| 56 | + } |
---|
| 57 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, oldpage); |
---|
| 58 | + |
---|
| 59 | + return ret; |
---|
| 60 | +} |
---|
| 61 | + |
---|
| 62 | + |
---|
| 63 | +int maxio_adcc_check(struct phy_device *phydev) |
---|
| 64 | +{ |
---|
| 65 | + int ret = 0; |
---|
| 66 | + int adcvalue; |
---|
| 67 | + u32 regval; |
---|
| 68 | + int i; |
---|
| 69 | + |
---|
| 70 | + maxio_write_paged(phydev, 0xd96, 0x2, 0x1fff ); |
---|
| 71 | + maxio_write_paged(phydev, 0xd96, 0x2, 0x1000 ); |
---|
| 72 | + |
---|
| 73 | + for(i = 0; i < 4;i++) |
---|
| 74 | + { |
---|
| 75 | + regval = 0xf908 + i * 0x100; |
---|
| 76 | + maxio_write_paged(phydev, 0xd8f, 0xb, regval ); |
---|
| 77 | + adcvalue = maxio_read_paged(phydev, 0xd92, 0xb); |
---|
| 78 | + if(adcvalue & 0x1ff) |
---|
| 79 | + { |
---|
| 80 | + continue; |
---|
| 81 | + } |
---|
| 82 | + else |
---|
| 83 | + { |
---|
| 84 | + ret = -1; |
---|
| 85 | + break; |
---|
| 86 | + } |
---|
| 87 | + } |
---|
| 88 | + |
---|
| 89 | + return ret; |
---|
| 90 | +} |
---|
| 91 | + |
---|
| 92 | + |
---|
| 93 | +int maxio_self_check(struct phy_device *phydev,int checknum) |
---|
| 94 | +{ |
---|
| 95 | + int ret = 0; |
---|
| 96 | + int i; |
---|
| 97 | + |
---|
| 98 | + for(i = 0;i < checknum; i++) |
---|
| 99 | + { |
---|
| 100 | + ret = maxio_adcc_check(phydev); |
---|
| 101 | + if(0 == ret) |
---|
| 102 | + { |
---|
| 103 | + printk("MAE0621A READY\n"); |
---|
| 104 | + break; |
---|
| 105 | + } |
---|
| 106 | + else |
---|
| 107 | + { |
---|
| 108 | + maxio_write_paged(phydev, 0x0, 0x0, 0x1940 ); |
---|
| 109 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, 0x0); |
---|
| 110 | + msleep(10); |
---|
| 111 | + maxio_write_paged(phydev, 0x0, 0x0, 0x1140 ); |
---|
| 112 | + maxio_write_paged(phydev, 0x0, 0x0, 0x9140 ); |
---|
| 113 | + } |
---|
| 114 | + } |
---|
| 115 | + |
---|
| 116 | + maxio_write_paged(phydev, 0xd96, 0x2, 0xfff ); |
---|
| 117 | + maxio_write_paged(phydev, 0x0, 0x0, 0x9140 ); |
---|
| 118 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, 0x0); |
---|
| 119 | + |
---|
| 120 | + return ret; |
---|
| 121 | +} |
---|
| 122 | + |
---|
| 123 | + |
---|
| 124 | + |
---|
| 125 | + |
---|
| 126 | +static int maxio_mae0621a_resume(struct phy_device *phydev) |
---|
| 127 | +{ |
---|
| 128 | + int ret; |
---|
| 129 | + |
---|
| 130 | + ret = genphy_resume(phydev); |
---|
| 131 | + |
---|
| 132 | + ret |= PHY_WRITE(phydev, MII_BMCR, BMCR_RESET | PHY_READ(phydev, MII_BMCR)); |
---|
| 133 | + msleep(20); |
---|
| 134 | + |
---|
| 135 | + return ret; |
---|
| 136 | +} |
---|
| 137 | + |
---|
| 138 | +static int maxio_mae0621a_suspend(struct phy_device *phydev) |
---|
| 139 | +{ |
---|
| 140 | + int ret = 0; |
---|
| 141 | + |
---|
| 142 | + ret = genphy_suspend(phydev); |
---|
| 143 | + ret |= PHY_WRITE(phydev, MAXIO_PAGE_SELECT ,0); |
---|
| 144 | + |
---|
| 145 | + return ret; |
---|
| 146 | +} |
---|
| 147 | + |
---|
| 148 | + |
---|
| 149 | + |
---|
| 150 | +int maxio_restart_aneg(struct phy_device *phydev) |
---|
| 151 | +{ |
---|
| 152 | + int ctl = PHY_READ(phydev, MII_BMCR); |
---|
| 153 | + |
---|
| 154 | + if (ctl < 0) |
---|
| 155 | + return ctl; |
---|
| 156 | + |
---|
| 157 | + ctl |= BMCR_ANENABLE | BMCR_ANRESTART; |
---|
| 158 | + |
---|
| 159 | + |
---|
| 160 | + ctl &= ~BMCR_ISOLATE; |
---|
| 161 | + |
---|
| 162 | + return PHY_WRITE(phydev, MII_BMCR, ctl); |
---|
| 163 | +} |
---|
| 164 | + |
---|
| 165 | +static void phy_resolve_aneg_linkmode_maxio(struct phy_device *phydev){ |
---|
| 166 | + |
---|
| 167 | + int physr_p_a43 = maxio_read_paged(phydev,0xa43,MAXIO_PHYSR_P_A43); |
---|
| 168 | + |
---|
| 169 | + if((physr_p_a43&MAXIO_PHY_SPEED)==MAXIO_PHY_1000M){ |
---|
| 170 | + phydev->speed=SPEED_1000; |
---|
| 171 | + }else if((physr_p_a43&MAXIO_PHY_SPEED)==MAXIO_PHY_100M){ |
---|
| 172 | + phydev->speed=SPEED_100; |
---|
| 173 | + }else if((physr_p_a43&MAXIO_PHY_SPEED)==MAXIO_PHY_10M){ |
---|
| 174 | + phydev->speed=SPEED_10; |
---|
| 175 | + } |
---|
| 176 | + |
---|
| 177 | + if(physr_p_a43 & MAXIO_PHY_DUPLEX){ |
---|
| 178 | + phydev->duplex=DUPLEX_FULL; |
---|
| 179 | + }else{ |
---|
| 180 | + phydev->duplex=DUPLEX_HALF; |
---|
| 181 | + } |
---|
| 182 | + |
---|
| 183 | + if(phydev->duplex==DUPLEX_FULL){ |
---|
| 184 | + int lpa=PHY_READ(phydev,MII_LPA); |
---|
| 185 | + phydev->pause=(lpa&LPA_PAUSE_CAP)?1:0; |
---|
| 186 | + phydev->asym_pause=(lpa&LPA_PAUSE_ASYM)?1:0; |
---|
| 187 | + } |
---|
| 188 | + |
---|
| 189 | + } |
---|
| 190 | + |
---|
| 191 | +void phy_resolve_link_compatibility_maxio(struct phy_device *phydev) |
---|
| 192 | +{ |
---|
| 193 | + int *paras = (int *)phydev->priv; |
---|
| 194 | + int maxio_an_times = paras[0]; |
---|
| 195 | + int link_stable = paras[1]; |
---|
| 196 | + int iner, physr, insr; |
---|
| 197 | + iner = maxio_read_paged(phydev, 0xa42, 0x12); |
---|
| 198 | + if(iner&AUTONEG_COMPLETED_INT_EN){ |
---|
| 199 | + |
---|
| 200 | + physr = maxio_read_paged(phydev, 0xa43, 0x1a); |
---|
| 201 | + if(physr & LINKOK) |
---|
| 202 | + { |
---|
| 203 | + insr = maxio_read_paged(phydev, 0xa43, 0x1d); |
---|
| 204 | + if((insr & AUTONEG_COMPLETED) == 0 && (link_stable == 0)){ |
---|
| 205 | + if(maxio_an_times < 4 ){ |
---|
| 206 | + maxio_restart_aneg(phydev); |
---|
| 207 | + phydev->link = 0; |
---|
| 208 | + maxio_an_times++; |
---|
| 209 | + } |
---|
| 210 | + else if(maxio_an_times == 4){ |
---|
| 211 | + link_stable = 1; |
---|
| 212 | + } |
---|
| 213 | + } |
---|
| 214 | + else if(insr & AUTONEG_COMPLETED){ |
---|
| 215 | + maxio_an_times = 0; |
---|
| 216 | + link_stable = 1; |
---|
| 217 | + } |
---|
| 218 | + if (link_stable == 1) |
---|
| 219 | + maxio_an_times = 0; |
---|
| 220 | + } |
---|
| 221 | + else |
---|
| 222 | + link_stable = 0; |
---|
| 223 | + } |
---|
| 224 | + paras[0] = maxio_an_times; |
---|
| 225 | + paras[1] = link_stable; |
---|
| 226 | +} |
---|
| 227 | + |
---|
| 228 | +static int maxio_mae0621a_status(struct phy_device *phydev) |
---|
| 229 | +{ |
---|
| 230 | + |
---|
| 231 | + int err, old_link = phydev->link; |
---|
| 232 | + |
---|
| 233 | + err = genphy_update_link(phydev); |
---|
| 234 | + if (err) |
---|
| 235 | + return err; |
---|
| 236 | + |
---|
| 237 | + |
---|
| 238 | + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) |
---|
| 239 | + return 0; |
---|
| 240 | + |
---|
| 241 | + phydev->speed = SPEED_UNKNOWN; |
---|
| 242 | + phydev->duplex = DUPLEX_UNKNOWN; |
---|
| 243 | + phydev->pause = 0; |
---|
| 244 | + phydev->asym_pause = 0; |
---|
| 245 | + |
---|
| 246 | + phy_resolve_aneg_linkmode_maxio(phydev); |
---|
| 247 | + |
---|
| 248 | + if(phydev->autoneg == AUTONEG_ENABLE) |
---|
| 249 | + phy_resolve_link_compatibility_maxio(phydev); |
---|
| 250 | + return 0; |
---|
| 251 | + |
---|
| 252 | +} |
---|
| 253 | + |
---|
| 254 | +static void maxio_mae0621a_remove(struct phy_device *phydev) |
---|
| 255 | +{ |
---|
| 256 | + printk("maxio driver remove\r\n"); |
---|
| 257 | + if(phydev->priv!=NULL){ |
---|
| 258 | + kfree(phydev->priv); |
---|
| 259 | + } |
---|
| 260 | + phydev->priv=NULL; |
---|
| 261 | +} |
---|
| 262 | + |
---|
| 263 | + |
---|
| 264 | + |
---|
| 265 | + |
---|
| 266 | +static int maxio_mae0621a_clk_init(struct phy_device *phydev) |
---|
| 267 | +{ |
---|
| 268 | + u32 workmode,clkmode,oldpage; |
---|
| 269 | + |
---|
| 270 | + oldpage = PHY_READ(phydev, MAXIO_PAGE_SELECT); |
---|
| 271 | + if (oldpage == 0xFFFF) { |
---|
| 272 | + oldpage = PHY_READ(phydev, MAXIO_PAGE_SELECT); |
---|
| 273 | + } |
---|
| 274 | + |
---|
| 275 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, 0x0); |
---|
| 276 | + PHY_WRITE(phydev, MII_BMCR, 0x9140); |
---|
| 277 | + |
---|
| 278 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, 0xa43); |
---|
| 279 | + workmode = PHY_READ(phydev, MAXIO_MAE0621A_WORK_STATUS_REG); |
---|
| 280 | + |
---|
| 281 | + PHY_WRITE( phydev, MAXIO_PAGE_SELECT, 0xd92 ); |
---|
| 282 | + clkmode = PHY_READ( phydev, MAXIO_MAE0621A_CLK_MODE_REG ); |
---|
| 283 | + |
---|
| 284 | + if (0 == (workmode&BIT(5))) { |
---|
| 285 | + if (0 == (clkmode&BIT(8))) { |
---|
| 286 | + PHY_WRITE(phydev, 0x02, clkmode | BIT(8)); |
---|
| 287 | + printk("****maxio_mae0621a_clk_init**clkmode**0x210a: 0x%x\n", phydev->phy_id); |
---|
| 288 | + } else { |
---|
| 289 | + printk("****maxio_mae0621a_clk_init**clkmode**0x200a: 0x%x\n", phydev->phy_id); |
---|
| 290 | + PHY_WRITE(phydev, 0x02, clkmode &(~ BIT(8))); |
---|
| 291 | + } |
---|
| 292 | + } |
---|
| 293 | + |
---|
| 294 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, 0x0); |
---|
| 295 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, oldpage); |
---|
| 296 | + msleep(1000); |
---|
| 297 | + |
---|
| 298 | + return 0; |
---|
| 299 | +} |
---|
| 300 | + |
---|
| 301 | +static int maxio_mae0621a_config_init(struct phy_device *phydev) |
---|
| 302 | +{ |
---|
| 303 | + int ret = 0; |
---|
| 304 | + |
---|
| 305 | + printk("MAXIO_PHY_VER: %s \n",MAXIO_PHY_VER); |
---|
| 306 | + |
---|
| 307 | + |
---|
| 308 | + maxio_mae0621a_clk_init(phydev); |
---|
| 309 | + |
---|
| 310 | + ret |= maxio_write_paged(phydev, 0xda0, 0x10, 0xc13); |
---|
| 311 | + ret |= maxio_write_paged(phydev, 0x0, 0xd, 0x7); |
---|
| 312 | + ret |= maxio_write_paged(phydev, 0x0, 0xe, 0x3c); |
---|
| 313 | + ret |= maxio_write_paged(phydev, 0x0, 0xd, 0x4007); |
---|
| 314 | + ret |= maxio_write_paged(phydev, 0x0, 0xe, 0x0); |
---|
| 315 | + ret |= maxio_write_paged(phydev, 0xd96, 0x13, 0x7bc); |
---|
| 316 | + ret |= maxio_write_paged(phydev, 0xd8f, 0x8, 0x2500); |
---|
| 317 | + ret |= maxio_write_paged(phydev, 0xd90, 0x2, 0x1555); |
---|
| 318 | + ret |= maxio_write_paged(phydev, 0xd90, 0x5, 0x2b15); |
---|
| 319 | + ret |= maxio_write_paged(phydev, 0xd92, 0x14, 0xa); |
---|
| 320 | + ret |= maxio_write_paged(phydev, 0xd91, 0x7, 0x5b00); |
---|
| 321 | + ret |= maxio_write_paged(phydev, 0xd8f, 0x0, 0x300); |
---|
| 322 | + ret |= maxio_write_paged(phydev, 0xd92, 0xa, 0x8506); |
---|
| 323 | + ret |= maxio_write_paged(phydev, 0xd91, 0x6, 0x6870); |
---|
| 324 | + ret |= maxio_write_paged(phydev, 0xd91, 0x1, 0x940); |
---|
| 325 | + ret |= maxio_write_paged(phydev, 0xda0, 0x13, 0x1303); |
---|
| 326 | + ret |= maxio_write_paged(phydev, 0xd97, 0xc, 0x177); |
---|
| 327 | + ret |= maxio_write_paged(phydev, 0xd97, 0xb, 0x9a9); |
---|
| 328 | + ret |= maxio_write_paged(phydev, 0xa42, 0x12, 0x28); |
---|
| 329 | + ret |= maxio_write_paged(phydev, 0x0, 0x4, 0xde1); |
---|
| 330 | + ret |= maxio_write_paged(phydev, 0x0, 0x0, 0x9140); |
---|
| 331 | + |
---|
| 332 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, 0x0); |
---|
| 333 | + |
---|
| 334 | + |
---|
| 335 | + ret |= maxio_self_check(phydev,50); |
---|
| 336 | + msleep(100); |
---|
| 337 | + return 0; |
---|
| 338 | +} |
---|
| 339 | + |
---|
| 340 | +static int maxio_mae0621a_probe(struct phy_device *phydev) |
---|
| 341 | +{ |
---|
| 342 | + int *paras; |
---|
| 343 | + paras = kzalloc( 2 * sizeof(int), GFP_KERNEL); |
---|
| 344 | + if(!paras) |
---|
| 345 | + return -ENOMEM; |
---|
| 346 | + phydev->priv = paras; |
---|
| 347 | + |
---|
| 348 | + |
---|
| 349 | + maxio_mae0621a_clk_init(phydev); |
---|
| 350 | + PHY_WRITE(phydev, MAXIO_PAGE_SELECT, 0x0); |
---|
| 351 | + mdelay(100); |
---|
| 352 | + return 0; |
---|
| 353 | +} |
---|
| 354 | + |
---|
| 355 | +static int maxio_mae0621aq3ci_probe(struct phy_device *phydev) |
---|
| 356 | +{ |
---|
| 357 | + int *paras; |
---|
| 358 | + paras = kzalloc( 2 * sizeof(int), GFP_KERNEL); |
---|
| 359 | + if(!paras) |
---|
| 360 | + return -ENOMEM; |
---|
| 361 | + phydev->priv = paras; |
---|
| 362 | + printk("maxio_mae0621aQ3C probe PHY_ID: 0x%x\n", phydev->phy_id); |
---|
| 363 | + return 0; |
---|
| 364 | +} |
---|
| 365 | + |
---|
| 366 | + |
---|
| 367 | +static int maxio_mae0621aq3ci_config_init(struct phy_device *phydev) |
---|
| 368 | +{ |
---|
| 369 | + int ret = 0; |
---|
| 370 | + printk("MAXIO_PHY_VER: %s \n",MAXIO_PHY_VER); |
---|
| 371 | + |
---|
| 372 | + ret |= maxio_write_paged(phydev, 0xa43, 0x19, 0x823); |
---|
| 373 | + |
---|
| 374 | + ret |= maxio_write_paged(phydev, 0xdab, 0x17, 0xC13); |
---|
| 375 | + ret |= maxio_write_paged(phydev, 0xd96, 0x15, 0xc08a); |
---|
| 376 | + ret |= maxio_write_paged(phydev, 0xda4, 0x12, 0x7bc); |
---|
| 377 | + ret |= maxio_write_paged(phydev, 0xd8f, 0x16, 0x2500); |
---|
| 378 | + ret |= maxio_write_paged(phydev, 0xd90, 0x16, 0x1555); |
---|
| 379 | + ret |= maxio_write_paged(phydev, 0xd92, 0x11, 0x2b15); |
---|
| 380 | + ret |= maxio_write_paged(phydev, 0xd96, 0x16, 0x4010); |
---|
| 381 | + ret |= maxio_write_paged(phydev, 0xda5, 0x11, 0x4a12); |
---|
| 382 | + ret |= maxio_write_paged(phydev, 0xda5, 0x12, 0x4a12); |
---|
| 383 | + ret |= maxio_write_paged(phydev, 0xd99, 0x16, 0xa); |
---|
| 384 | + ret |= maxio_write_paged(phydev, 0xd95, 0x13, 0x5b00); |
---|
| 385 | + ret |= maxio_write_paged(phydev, 0xd8f, 0x10, 0x300); |
---|
| 386 | + ret |= maxio_write_paged(phydev, 0xd98, 0x17, 0x8506); |
---|
| 387 | + ret |= maxio_write_paged(phydev, 0xd95, 0x12, 0x6870); |
---|
| 388 | + ret |= maxio_write_paged(phydev, 0xd93, 0x15, 0x940); |
---|
| 389 | + ret |= maxio_write_paged(phydev, 0xdad, 0x12, 0x1303); |
---|
| 390 | + ret |= maxio_write_paged(phydev, 0xda8, 0x11, 0x177); |
---|
| 391 | + ret |= maxio_write_paged(phydev, 0xda8, 0x10, 0x9a9); |
---|
| 392 | + ret |= maxio_write_paged(phydev, 0xa42, 0x12, 0x28); |
---|
| 393 | + ret |= maxio_write_paged(phydev, 0x0, 0x4, 0xde1); |
---|
| 394 | + ret |= maxio_write_paged(phydev, 0x0, 0x0, 0x9140); |
---|
| 395 | + |
---|
| 396 | + ret |= PHY_WRITE(phydev, MAXIO_PAGE_SELECT, 0); |
---|
| 397 | + |
---|
| 398 | + return 0; |
---|
| 399 | +} |
---|
| 400 | + |
---|
| 401 | + |
---|
| 402 | +static int maxio_mae0621aq3ci_resume(struct phy_device *phydev) |
---|
| 403 | +{ |
---|
| 404 | + int ret = 0; |
---|
| 405 | + ret = genphy_resume(phydev); |
---|
| 406 | + ret |= maxio_write_paged(phydev, 0xdaa, 0x17, 0x1001 ); |
---|
| 407 | + ret |= maxio_write_paged(phydev, 0xdab, 0x15, 0x0 ); |
---|
| 408 | + ret |= PHY_WRITE(phydev, MAXIO_PAGE_SELECT, 0); |
---|
| 409 | + |
---|
| 410 | + return ret; |
---|
| 411 | +} |
---|
| 412 | + |
---|
| 413 | +static int maxio_mae0621aq3ci_suspend(struct phy_device *phydev) |
---|
| 414 | +{ |
---|
| 415 | + int ret = 0; |
---|
| 416 | + |
---|
| 417 | + ret = maxio_write_paged(phydev, 0xdaa, 0x17, 0x1011 ); |
---|
| 418 | + ret |= maxio_write_paged(phydev, 0xdab, 0x15, 0x5550 ); |
---|
| 419 | + ret |= PHY_WRITE(phydev, MAXIO_PAGE_SELECT, 0); |
---|
| 420 | + |
---|
| 421 | + ret |= genphy_suspend(phydev); |
---|
| 422 | + |
---|
| 423 | + ret |= PHY_WRITE(phydev, MAXIO_PAGE_SELECT ,0); |
---|
| 424 | + |
---|
| 425 | + return ret; |
---|
| 426 | +} |
---|
| 427 | + |
---|
| 428 | + |
---|
| 429 | + |
---|
| 430 | +static struct phy_driver maxio_nc_drvs[] = { |
---|
| 431 | + { |
---|
| 432 | + .phy_id = 0x7b744411, |
---|
| 433 | + .phy_id_mask = 0x7fffffff, |
---|
| 434 | + .name = "MAE0621A-Q2C Gigabit Ethernet", |
---|
| 435 | + .features = PHY_GBIT_FEATURES , |
---|
| 436 | + .probe = maxio_mae0621a_probe, |
---|
| 437 | + .config_init = maxio_mae0621a_config_init, |
---|
| 438 | + .config_aneg = &genphy_config_aneg, |
---|
| 439 | + .read_status = maxio_mae0621a_status, |
---|
| 440 | + .suspend = maxio_mae0621a_suspend, |
---|
| 441 | + .resume = maxio_mae0621a_resume, |
---|
| 442 | + .remove = maxio_mae0621a_remove, |
---|
| 443 | + }, |
---|
| 444 | + { |
---|
| 445 | + .phy_id = 0x7b744412, |
---|
| 446 | + .phy_id_mask = 0x7fffffff, |
---|
| 447 | + .name = "MAE0621A/B-Q3C(I) Gigabit Ethernet", |
---|
| 448 | + .features = PHY_GBIT_FEATURES , |
---|
| 449 | + .probe = maxio_mae0621aq3ci_probe, |
---|
| 450 | + .config_aneg = &genphy_config_aneg, |
---|
| 451 | + .config_init = maxio_mae0621aq3ci_config_init, |
---|
| 452 | + .read_status = &maxio_mae0621a_status, |
---|
| 453 | + .suspend = maxio_mae0621aq3ci_suspend, |
---|
| 454 | + .resume = maxio_mae0621aq3ci_resume, |
---|
| 455 | + .remove = maxio_mae0621a_remove, |
---|
| 456 | + }, |
---|
| 457 | +}; |
---|
| 458 | + |
---|
| 459 | +module_phy_driver(maxio_nc_drvs); |
---|
| 460 | +static struct mdio_device_id __maybe_unused maxio_nc_tbl[] = { |
---|
| 461 | + { 0x7b744411, 0x7fffffff }, |
---|
| 462 | + { 0x7b744412, 0x7fffffff }, |
---|
| 463 | + { } |
---|
| 464 | +}; |
---|
| 465 | + |
---|
| 466 | +MODULE_DEVICE_TABLE(mdio, maxio_nc_tbl); |
---|
| 467 | + |
---|
| 468 | + |
---|
| 469 | +MODULE_DESCRIPTION("Maxio PHY driver"); |
---|
| 470 | +MODULE_AUTHOR("Zhao Yang"); |
---|
| 471 | +MODULE_LICENSE("GPL"); |
---|
| 472 | + |
---|
| 473 | + |
---|
| 474 | + |
---|
| 475 | + |
---|