|
28 | 28 | #define MMD_API_GET_DATA_0 (0x0 + 0x5) |
29 | 29 | #define MMD_API_RST_DATA (0x0 + 0x8) |
30 | 30 |
|
| 31 | +/* Clause 22 extended read/write access */ |
| 32 | +#define MXL862XX_MMD_DATA 0xE |
| 33 | +#define MXL862XX_MMD_CTRL 0xD |
| 34 | +#define MXL862XX_ACTYPE_ADDRESS (0 << 14) |
| 35 | +#define MXL862XX_ACTYPE_DATA (1 << 14) |
| 36 | + |
| 37 | +/** |
| 38 | + * write access to MMD register of PHYs via Clause 22 extended access |
| 39 | + */ |
| 40 | +static int __mxl862xx_c22_ext_mmd_write(const struct mxl862xx_priv *dev, struct mii_bus *bus, int sw_addr, int mmd, |
| 41 | + int reg, u16 data) |
| 42 | +{ |
| 43 | + int res; |
| 44 | + |
| 45 | + /* Set the DevID for Write Command */ |
| 46 | + res = __mdiobus_write(bus, sw_addr, MXL862XX_MMD_CTRL, mmd); |
| 47 | + if (res < 0) |
| 48 | + goto error; |
| 49 | + |
| 50 | + /* Issue the write command */ |
| 51 | + res = __mdiobus_write(bus, sw_addr, MXL862XX_MMD_DATA, reg); |
| 52 | + if (res < 0) |
| 53 | + goto error; |
| 54 | + |
| 55 | + /* Set the DevID for Write Command */ |
| 56 | + res = __mdiobus_write(bus, sw_addr, MXL862XX_MMD_CTRL, MXL862XX_ACTYPE_DATA | mmd); |
| 57 | + if (res < 0) |
| 58 | + goto error; |
| 59 | + |
| 60 | + /* Issue the write command */ |
| 61 | + if (mmd == 0x1e && reg == 0) /* ctrl register can't write twice */ |
| 62 | + res = __mdiobus_write(bus, sw_addr, MXL862XX_MMD_DATA, data); |
| 63 | + else |
| 64 | + res = __mdiobus_write(bus, sw_addr, MXL862XX_MMD_DATA, data); |
| 65 | + if (res < 0) |
| 66 | + goto error; |
| 67 | + |
| 68 | +error: |
| 69 | + return res; |
| 70 | +} |
| 71 | + |
| 72 | +/** |
| 73 | + * read access to MMD register of PHYs via Clause 22 extended access |
| 74 | + */ |
| 75 | +static int __mxl862xx_c22_ext_mmd_read(const struct mxl862xx_priv *dev, struct mii_bus *bus, int sw_addr, int mmd, int reg) |
| 76 | +{ |
| 77 | + int res; |
| 78 | + |
| 79 | + /* Set the DevID for Write Command */ |
| 80 | + res = __mdiobus_write(bus, sw_addr, MXL862XX_MMD_CTRL, mmd); |
| 81 | + if (res < 0) |
| 82 | + goto error; |
| 83 | + |
| 84 | + /* Issue the write command */ |
| 85 | + res = __mdiobus_write(bus, sw_addr, MXL862XX_MMD_DATA, reg); |
| 86 | + if (res < 0) |
| 87 | + goto error; |
| 88 | + |
| 89 | + /* Set the DevID for Write Command */ |
| 90 | + res = __mdiobus_write(bus, sw_addr, MXL862XX_MMD_CTRL, MXL862XX_ACTYPE_DATA | mmd); |
| 91 | + if (res < 0) |
| 92 | + goto error; |
| 93 | + |
| 94 | + /* Read the data */ |
| 95 | + res = __mdiobus_read(bus, sw_addr, MXL862XX_MMD_DATA); |
| 96 | + if (res < 0) |
| 97 | + goto error; |
| 98 | + |
| 99 | +error: |
| 100 | + return res; |
| 101 | +} |
| 102 | + |
31 | 103 | static int mxl862xx_read(struct mxl862xx_priv *dev, u32 addr) |
32 | 104 | { |
33 | | - return __mdiobus_c45_read(dev->bus, dev->sw_addr, MXL862XX_MMD_DEV, addr); |
| 105 | + if (dev->c22_extended) |
| 106 | + return __mxl862xx_c22_ext_mmd_read(dev, dev->bus, dev->sw_addr, MXL862XX_MMD_DEV, addr); |
| 107 | + else |
| 108 | + return __mdiobus_c45_read(dev->bus, dev->sw_addr, MXL862XX_MMD_DEV, addr); |
34 | 109 | } |
35 | 110 |
|
36 | 111 | int mxl862xx_write(struct mxl862xx_priv *dev, u32 addr, u16 data) |
37 | 112 | { |
38 | | - return __mdiobus_c45_write(dev->bus, dev->sw_addr, MXL862XX_MMD_DEV, addr, data); |
| 113 | + if (dev->c22_extended) |
| 114 | + return __mxl862xx_c22_ext_mmd_write(dev, dev->bus, dev->sw_addr, MXL862XX_MMD_DEV, addr, data); |
| 115 | + else |
| 116 | + return __mdiobus_c45_write(dev->bus, dev->sw_addr, MXL862XX_MMD_DEV, addr, data); |
39 | 117 | } |
40 | 118 |
|
41 | 119 | static int mxl862xx_busy_wait(struct mxl862xx_priv *dev) |
|
0 commit comments