^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (C) 2018 Microchip Technology
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /* External Register Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define LAN87XX_EXT_REG_CTL (0x14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define LAN87XX_EXT_REG_CTL_RD_CTL (0x1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define LAN87XX_EXT_REG_CTL_WR_CTL (0x0800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /* External Register Read Data Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define LAN87XX_EXT_REG_RD_DATA (0x15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* External Register Write Data Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define LAN87XX_EXT_REG_WR_DATA (0x16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* Interrupt Source Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define LAN87XX_INTERRUPT_SOURCE (0x18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* Interrupt Mask Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define LAN87XX_INTERRUPT_MASK (0x19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define LAN87XX_MASK_LINK_UP (0x0004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define LAN87XX_MASK_LINK_DOWN (0x0002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* phyaccess nested types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PHYACC_ATTR_MODE_READ 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PHYACC_ATTR_MODE_WRITE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PHYACC_ATTR_MODE_MODIFY 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define PHYACC_ATTR_BANK_SMI 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PHYACC_ATTR_BANK_MISC 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PHYACC_ATTR_BANK_PCS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PHYACC_ATTR_BANK_AFE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define PHYACC_ATTR_BANK_MAX 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define DRIVER_AUTHOR "Nisar Sayed <nisar.sayed@microchip.com>"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define DRIVER_DESC "Microchip LAN87XX T1 PHY driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct access_ereg_val {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) u8 bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u8 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u16 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int access_ereg(struct phy_device *phydev, u8 mode, u8 bank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u8 offset, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u16 ereg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (mode > PHYACC_ATTR_MODE_WRITE || bank > PHYACC_ATTR_BANK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (bank == PHYACC_ATTR_BANK_SMI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (mode == PHYACC_ATTR_MODE_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) rc = phy_write(phydev, offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) rc = phy_read(phydev, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (mode == PHYACC_ATTR_MODE_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ereg = LAN87XX_EXT_REG_CTL_WR_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) rc = phy_write(phydev, LAN87XX_EXT_REG_WR_DATA, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ereg = LAN87XX_EXT_REG_CTL_RD_CTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ereg |= (bank << 8) | offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) rc = phy_write(phydev, LAN87XX_EXT_REG_CTL, ereg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (mode == PHYACC_ATTR_MODE_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) rc = phy_read(phydev, LAN87XX_EXT_REG_RD_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static int access_ereg_modify_changed(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) u8 bank, u8 offset, u16 val, u16 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int new = 0, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (bank > PHYACC_ATTR_BANK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, bank, offset, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) new = val | (rc & (mask ^ 0xFFFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, bank, offset, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int lan87xx_phy_init(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static const struct access_ereg_val init[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* TX Amplitude = 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_AFE, 0x0B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 0x000A, 0x001E},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* Clear SMI interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI, 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* Clear MISC interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_MISC, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* Turn on TC10 Ring Oscillator (ROSC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_MISC, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 0x0020, 0x0020},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* WUR Detect Length to 1.2uS, LPC Detect Length to 1.09uS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_PCS, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 0x283C, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* Wake_In Debounce Length to 39uS, Wake_Out Length to 79uS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 0x274F, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* Enable Auto Wake Forward to Wake_Out, ROSC on, Sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * and Wake_In to wake PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 0x80A7, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* Enable WUP Auto Fwd, Enable Wake on MDI, Wakeup Debouncer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * to 128 uS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 0xF110, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* Enable HW Init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_SMI, 0x1A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 0x0100, 0x0100},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int rc, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Start manual initialization procedures in Managed Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 0x1a, 0x0000, 0x0100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* Soft Reset the SMI block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 0x00, 0x8000, 0x8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* Check to see if the self-clearing bit is cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) PHYACC_ATTR_BANK_SMI, 0x00, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if ((rc & 0x8000) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* PHY Initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) for (i = 0; i < ARRAY_SIZE(init); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (init[i].mode == PHYACC_ATTR_MODE_MODIFY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) rc = access_ereg_modify_changed(phydev, init[i].bank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) init[i].offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) init[i].val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) init[i].mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rc = access_ereg(phydev, init[i].mode, init[i].bank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) init[i].offset, init[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static int lan87xx_phy_config_intr(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int rc, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* unmask all source and clear them before enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, 0x7FFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) rc = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) val = LAN87XX_MASK_LINK_UP | LAN87XX_MASK_LINK_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return rc < 0 ? rc : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int lan87xx_phy_ack_interrupt(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int rc = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return rc < 0 ? rc : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int lan87xx_config_init(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int rc = lan87xx_phy_init(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return rc < 0 ? rc : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static struct phy_driver microchip_t1_phy_driver[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .phy_id = 0x0007c150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .phy_id_mask = 0xfffffff0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .name = "Microchip LAN87xx T1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .features = PHY_BASIC_T1_FEATURES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .config_init = lan87xx_config_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .config_aneg = genphy_config_aneg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .ack_interrupt = lan87xx_phy_ack_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .config_intr = lan87xx_phy_config_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .suspend = genphy_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) .resume = genphy_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) module_phy_driver(microchip_t1_phy_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static struct mdio_device_id __maybe_unused microchip_t1_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) { 0x0007c150, 0xfffffff0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) MODULE_DEVICE_TABLE(mdio, microchip_t1_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) MODULE_LICENSE("GPL");