1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) KEBA Industrial Automation Gmbh 2024 4 * 5 * Driver for LAN9252 on KEBA CP500 devices 6 * 7 * This driver is used for updating the configuration of the LAN9252 controller 8 * on KEBA CP500 devices. The LAN9252 is connected over SPI, which is also named 9 * PDI. 10 */ 11 12 #include <linux/spi/spi.h> 13 #include <linux/mii.h> 14 15 /* SPI commands */ 16 #define LAN9252_SPI_READ 0x3 17 #define LAN9252_SPI_WRITE 0x2 18 19 struct lan9252_read_cmd { 20 u8 cmd; 21 u8 addr_0; 22 u8 addr_1; 23 } __packed; 24 25 struct lan9252_write_cmd { 26 u8 cmd; 27 u8 addr_0; 28 u8 addr_1; 29 u32 data; 30 } __packed; 31 32 /* byte test register */ 33 #define LAN9252_BYTE_TEST 0x64 34 #define LAN9252_BYTE_TEST_VALUE 0x87654321 35 36 /* hardware configuration register */ 37 #define LAN9252_HW_CFG 0x74 38 #define LAN9252_HW_CFG_READY 0x08000000 39 40 /* EtherCAT CSR interface data register */ 41 #define LAN9252_ECAT_CSR_DATA 0x300 42 43 /* EtherCAT CSR interface command register */ 44 #define LAN9252_ECAT_CSR_CMD 0x304 45 #define LAN9252_ECAT_CSR_BUSY 0x80000000 46 #define LAN9252_ECAT_CSR_READ 0x40000000 47 48 /* EtherCAT slave controller MII register */ 49 #define LAN9252_ESC_MII 0x510 50 #define LAN9252_ESC_MII_BUSY 0x8000 51 #define LAN9252_ESC_MII_CMD_ERR 0x4000 52 #define LAN9252_ESC_MII_READ_ERR 0x2000 53 #define LAN9252_ESC_MII_ERR_MASK (LAN9252_ESC_MII_CMD_ERR | \ 54 LAN9252_ESC_MII_READ_ERR) 55 #define LAN9252_ESC_MII_WRITE 0x0200 56 #define LAN9252_ESC_MII_READ 0x0100 57 58 /* EtherCAT slave controller PHY address register */ 59 #define LAN9252_ESC_PHY_ADDR 0x512 60 61 /* EtherCAT slave controller PHY register address register */ 62 #define LAN9252_ESC_PHY_REG_ADDR 0x513 63 64 /* EtherCAT slave controller PHY data register */ 65 #define LAN9252_ESC_PHY_DATA 0x514 66 67 /* EtherCAT slave controller PDI access state register */ 68 #define LAN9252_ESC_MII_PDI 0x517 69 #define LAN9252_ESC_MII_ACCESS_PDI 0x01 70 #define LAN9252_ESC_MII_ACCESS_ECAT 0x00 71 72 /* PHY address */ 73 #define PHY_ADDRESS 2 74 75 #define SPI_RETRY_COUNT 10 76 #define SPI_WAIT_US 100 77 #define SPI_CSR_WAIT_US 500 78 79 static int lan9252_spi_read(struct spi_device *spi, u16 addr, u32 *data) 80 { 81 struct lan9252_read_cmd cmd; 82 83 cmd.cmd = LAN9252_SPI_READ; 84 cmd.addr_0 = (addr >> 8) & 0xFF; 85 cmd.addr_1 = addr & 0xFF; 86 87 return spi_write_then_read(spi, (u8 *)&cmd, 88 sizeof(struct lan9252_read_cmd), 89 (u8 *)data, sizeof(u32)); 90 } 91 92 static int lan9252_spi_write(struct spi_device *spi, u16 addr, u32 data) 93 { 94 struct lan9252_write_cmd cmd; 95 96 cmd.cmd = LAN9252_SPI_WRITE; 97 cmd.addr_0 = (addr >> 8) & 0xFF; 98 cmd.addr_1 = addr & 0xFF; 99 cmd.data = data; 100 101 return spi_write(spi, (u8 *)&cmd, sizeof(struct lan9252_write_cmd)); 102 } 103 104 static bool lan9252_init(struct spi_device *spi) 105 { 106 u32 data; 107 int ret; 108 109 ret = lan9252_spi_read(spi, LAN9252_BYTE_TEST, &data); 110 if (ret || data != LAN9252_BYTE_TEST_VALUE) 111 return false; 112 113 ret = lan9252_spi_read(spi, LAN9252_HW_CFG, &data); 114 if (ret || !(data & LAN9252_HW_CFG_READY)) 115 return false; 116 117 return true; 118 } 119 120 static u8 lan9252_esc_get_size(u16 addr) 121 { 122 if (addr == LAN9252_ESC_MII || addr == LAN9252_ESC_PHY_DATA) 123 return 2; 124 125 return 1; 126 } 127 128 static int lan9252_esc_wait(struct spi_device *spi) 129 { 130 ktime_t timeout = ktime_add_us(ktime_get(), SPI_WAIT_US); 131 u32 data; 132 int ret; 133 134 /* wait while CSR command is busy */ 135 for (;;) { 136 ret = lan9252_spi_read(spi, LAN9252_ECAT_CSR_CMD, &data); 137 if (ret) 138 return ret; 139 if (!(data & LAN9252_ECAT_CSR_BUSY)) 140 return 0; 141 142 if (ktime_compare(ktime_get(), timeout) > 0) { 143 ret = lan9252_spi_read(spi, LAN9252_ECAT_CSR_CMD, &data); 144 if (ret) 145 return ret; 146 break; 147 } 148 } 149 150 return (!(data & LAN9252_ECAT_CSR_BUSY)) ? 0 : -ETIMEDOUT; 151 } 152 153 static int lan9252_esc_read(struct spi_device *spi, u16 addr, u32 *data) 154 { 155 u32 csr_cmd; 156 u8 size; 157 int ret; 158 159 size = lan9252_esc_get_size(addr); 160 csr_cmd = LAN9252_ECAT_CSR_BUSY | LAN9252_ECAT_CSR_READ; 161 csr_cmd |= (size << 16) | addr; 162 ret = lan9252_spi_write(spi, LAN9252_ECAT_CSR_CMD, csr_cmd); 163 if (ret) 164 return ret; 165 166 ret = lan9252_esc_wait(spi); 167 if (ret) 168 return ret; 169 170 ret = lan9252_spi_read(spi, LAN9252_ECAT_CSR_DATA, data); 171 if (ret) 172 return ret; 173 174 return 0; 175 } 176 177 static int lan9252_esc_write(struct spi_device *spi, u16 addr, u32 data) 178 { 179 u32 csr_cmd; 180 u8 size; 181 int ret; 182 183 ret = lan9252_spi_write(spi, LAN9252_ECAT_CSR_DATA, data); 184 if (ret) 185 return ret; 186 187 size = lan9252_esc_get_size(addr); 188 csr_cmd = LAN9252_ECAT_CSR_BUSY; 189 csr_cmd |= (size << 16) | addr; 190 ret = lan9252_spi_write(spi, LAN9252_ECAT_CSR_CMD, csr_cmd); 191 if (ret) 192 return ret; 193 194 ret = lan9252_esc_wait(spi); 195 if (ret) 196 return ret; 197 198 return 0; 199 } 200 201 static int lan9252_access_mii(struct spi_device *spi, bool access) 202 { 203 u32 data; 204 205 if (access) 206 data = LAN9252_ESC_MII_ACCESS_PDI; 207 else 208 data = LAN9252_ESC_MII_ACCESS_ECAT; 209 210 return lan9252_esc_write(spi, LAN9252_ESC_MII_PDI, data); 211 } 212 213 static int lan9252_mii_wait(struct spi_device *spi) 214 { 215 ktime_t timeout = ktime_add_us(ktime_get(), SPI_CSR_WAIT_US); 216 u32 data; 217 int ret; 218 219 /* wait while MII control state machine is busy */ 220 for (;;) { 221 ret = lan9252_esc_read(spi, LAN9252_ESC_MII, &data); 222 if (ret) 223 return ret; 224 if (data & LAN9252_ESC_MII_ERR_MASK) 225 return -EIO; 226 if (!(data & LAN9252_ESC_MII_BUSY)) 227 return 0; 228 229 if (ktime_compare(ktime_get(), timeout) > 0) { 230 ret = lan9252_esc_read(spi, LAN9252_ESC_MII, &data); 231 if (ret) 232 return ret; 233 if (data & LAN9252_ESC_MII_ERR_MASK) 234 return -EIO; 235 break; 236 } 237 } 238 239 return (!(data & LAN9252_ESC_MII_BUSY)) ? 0 : -ETIMEDOUT; 240 } 241 242 static int lan9252_mii_read(struct spi_device *spi, u8 phy_addr, u8 reg_addr, 243 u32 *data) 244 { 245 int ret; 246 247 ret = lan9252_esc_write(spi, LAN9252_ESC_PHY_ADDR, phy_addr); 248 if (ret) 249 return ret; 250 ret = lan9252_esc_write(spi, LAN9252_ESC_PHY_REG_ADDR, reg_addr); 251 if (ret) 252 return ret; 253 254 ret = lan9252_esc_write(spi, LAN9252_ESC_MII, LAN9252_ESC_MII_READ); 255 if (ret) 256 return ret; 257 258 ret = lan9252_mii_wait(spi); 259 if (ret) 260 return ret; 261 262 return lan9252_esc_read(spi, LAN9252_ESC_PHY_DATA, data); 263 } 264 265 static int lan9252_mii_write(struct spi_device *spi, u8 phy_addr, u8 reg_addr, 266 u32 data) 267 { 268 int ret; 269 270 ret = lan9252_esc_write(spi, LAN9252_ESC_PHY_ADDR, phy_addr); 271 if (ret) 272 return ret; 273 ret = lan9252_esc_write(spi, LAN9252_ESC_PHY_REG_ADDR, reg_addr); 274 if (ret) 275 return ret; 276 ret = lan9252_esc_write(spi, LAN9252_ESC_PHY_DATA, data); 277 if (ret) 278 return ret; 279 280 ret = lan9252_esc_write(spi, LAN9252_ESC_MII, LAN9252_ESC_MII_WRITE); 281 if (ret) 282 return ret; 283 284 return lan9252_mii_wait(spi); 285 } 286 287 static int lan9252_probe(struct spi_device *spi) 288 { 289 u32 data; 290 int retry = SPI_RETRY_COUNT; 291 int ret; 292 293 /* execute specified initialization sequence */ 294 while (retry && !lan9252_init(spi)) 295 retry--; 296 if (retry == 0) { 297 dev_err(&spi->dev, 298 "Can't initialize LAN9252 SPI communication!"); 299 return -EIO; 300 } 301 302 /* enable access to MII management for PDI */ 303 ret = lan9252_access_mii(spi, true); 304 if (ret) { 305 dev_err(&spi->dev, "Can't enable access to MII management!"); 306 return ret; 307 } 308 309 /* 310 * check PHY configuration and configure if necessary 311 * - full duplex 312 * - auto negotiation disabled 313 * - 100 Mbps 314 */ 315 ret = lan9252_mii_read(spi, PHY_ADDRESS, MII_BMCR, &data); 316 if (ret) { 317 dev_err(&spi->dev, "Can't read LAN9252 configuration!"); 318 goto out; 319 } 320 if (!(data & BMCR_FULLDPLX) || (data & BMCR_ANENABLE) || 321 !(data & BMCR_SPEED100)) { 322 /* 323 */ 324 data &= ~(BMCR_ANENABLE); 325 data |= (BMCR_FULLDPLX | BMCR_SPEED100); 326 ret = lan9252_mii_write(spi, PHY_ADDRESS, MII_BMCR, data); 327 if (ret) 328 dev_err(&spi->dev, 329 "Can't write LAN9252 configuration!"); 330 } 331 332 dev_info(&spi->dev, "LAN9252 PHY configuration"); 333 334 out: 335 /* disable access to MII management for PDI */ 336 lan9252_access_mii(spi, false); 337 338 return ret; 339 } 340 341 static const struct spi_device_id lan9252_id[] = { 342 {"lan9252"}, 343 {} 344 }; 345 MODULE_DEVICE_TABLE(spi, lan9252_id); 346 347 static struct spi_driver lan9252_driver = { 348 .driver = { 349 .name = "lan9252", 350 }, 351 .probe = lan9252_probe, 352 .id_table = lan9252_id, 353 }; 354 module_spi_driver(lan9252_driver); 355 356 MODULE_AUTHOR("Petar Bojanic <boja@keba.com>"); 357 MODULE_AUTHOR("Gerhard Engleder <eg@keba.com>"); 358 MODULE_DESCRIPTION("KEBA LAN9252 driver"); 359 MODULE_LICENSE("GPL"); 360