1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) KEBA Industrial Automation Gmbh 2024
5 * Driver for LAN9252 on KEBA CP500 devices
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
12 #include <linux/spi/spi.h>
13 #include <linux/mii.h>
16 #define LAN9252_SPI_READ 0x3
17 #define LAN9252_SPI_WRITE 0x2
19 struct lan9252_read_cmd
{
25 struct lan9252_write_cmd
{
32 /* byte test register */
33 #define LAN9252_BYTE_TEST 0x64
34 #define LAN9252_BYTE_TEST_VALUE 0x87654321
36 /* hardware configuration register */
37 #define LAN9252_HW_CFG 0x74
38 #define LAN9252_HW_CFG_READY 0x08000000
40 /* EtherCAT CSR interface data register */
41 #define LAN9252_ECAT_CSR_DATA 0x300
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
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
58 /* EtherCAT slave controller PHY address register */
59 #define LAN9252_ESC_PHY_ADDR 0x512
61 /* EtherCAT slave controller PHY register address register */
62 #define LAN9252_ESC_PHY_REG_ADDR 0x513
64 /* EtherCAT slave controller PHY data register */
65 #define LAN9252_ESC_PHY_DATA 0x514
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
75 #define SPI_RETRY_COUNT 10
76 #define SPI_WAIT_US 100
77 #define SPI_CSR_WAIT_US 500
79 static int lan9252_spi_read(struct spi_device
*spi
, u16 addr
, u32
*data
)
81 struct lan9252_read_cmd cmd
;
83 cmd
.cmd
= LAN9252_SPI_READ
;
84 cmd
.addr_0
= (addr
>> 8) & 0xFF;
85 cmd
.addr_1
= addr
& 0xFF;
87 return spi_write_then_read(spi
, (u8
*)&cmd
,
88 sizeof(struct lan9252_read_cmd
),
89 (u8
*)data
, sizeof(u32
));
92 static int lan9252_spi_write(struct spi_device
*spi
, u16 addr
, u32 data
)
94 struct lan9252_write_cmd cmd
;
96 cmd
.cmd
= LAN9252_SPI_WRITE
;
97 cmd
.addr_0
= (addr
>> 8) & 0xFF;
98 cmd
.addr_1
= addr
& 0xFF;
101 return spi_write(spi
, (u8
*)&cmd
, sizeof(struct lan9252_write_cmd
));
104 static bool lan9252_init(struct spi_device
*spi
)
109 ret
= lan9252_spi_read(spi
, LAN9252_BYTE_TEST
, &data
);
110 if (ret
|| data
!= LAN9252_BYTE_TEST_VALUE
)
113 ret
= lan9252_spi_read(spi
, LAN9252_HW_CFG
, &data
);
114 if (ret
|| !(data
& LAN9252_HW_CFG_READY
))
120 static u8
lan9252_esc_get_size(u16 addr
)
122 if (addr
== LAN9252_ESC_MII
|| addr
== LAN9252_ESC_PHY_DATA
)
128 static int lan9252_esc_wait(struct spi_device
*spi
)
130 ktime_t timeout
= ktime_add_us(ktime_get(), SPI_WAIT_US
);
134 /* wait while CSR command is busy */
136 ret
= lan9252_spi_read(spi
, LAN9252_ECAT_CSR_CMD
, &data
);
139 if (!(data
& LAN9252_ECAT_CSR_BUSY
))
142 if (ktime_compare(ktime_get(), timeout
) > 0) {
143 ret
= lan9252_spi_read(spi
, LAN9252_ECAT_CSR_CMD
, &data
);
150 return (!(data
& LAN9252_ECAT_CSR_BUSY
)) ? 0 : -ETIMEDOUT
;
153 static int lan9252_esc_read(struct spi_device
*spi
, u16 addr
, u32
*data
)
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
);
166 ret
= lan9252_esc_wait(spi
);
170 ret
= lan9252_spi_read(spi
, LAN9252_ECAT_CSR_DATA
, data
);
177 static int lan9252_esc_write(struct spi_device
*spi
, u16 addr
, u32 data
)
183 ret
= lan9252_spi_write(spi
, LAN9252_ECAT_CSR_DATA
, data
);
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
);
194 ret
= lan9252_esc_wait(spi
);
201 static int lan9252_access_mii(struct spi_device
*spi
, bool access
)
206 data
= LAN9252_ESC_MII_ACCESS_PDI
;
208 data
= LAN9252_ESC_MII_ACCESS_ECAT
;
210 return lan9252_esc_write(spi
, LAN9252_ESC_MII_PDI
, data
);
213 static int lan9252_mii_wait(struct spi_device
*spi
)
215 ktime_t timeout
= ktime_add_us(ktime_get(), SPI_CSR_WAIT_US
);
219 /* wait while MII control state machine is busy */
221 ret
= lan9252_esc_read(spi
, LAN9252_ESC_MII
, &data
);
224 if (data
& LAN9252_ESC_MII_ERR_MASK
)
226 if (!(data
& LAN9252_ESC_MII_BUSY
))
229 if (ktime_compare(ktime_get(), timeout
) > 0) {
230 ret
= lan9252_esc_read(spi
, LAN9252_ESC_MII
, &data
);
233 if (data
& LAN9252_ESC_MII_ERR_MASK
)
239 return (!(data
& LAN9252_ESC_MII_BUSY
)) ? 0 : -ETIMEDOUT
;
242 static int lan9252_mii_read(struct spi_device
*spi
, u8 phy_addr
, u8 reg_addr
,
247 ret
= lan9252_esc_write(spi
, LAN9252_ESC_PHY_ADDR
, phy_addr
);
250 ret
= lan9252_esc_write(spi
, LAN9252_ESC_PHY_REG_ADDR
, reg_addr
);
254 ret
= lan9252_esc_write(spi
, LAN9252_ESC_MII
, LAN9252_ESC_MII_READ
);
258 ret
= lan9252_mii_wait(spi
);
262 return lan9252_esc_read(spi
, LAN9252_ESC_PHY_DATA
, data
);
265 static int lan9252_mii_write(struct spi_device
*spi
, u8 phy_addr
, u8 reg_addr
,
270 ret
= lan9252_esc_write(spi
, LAN9252_ESC_PHY_ADDR
, phy_addr
);
273 ret
= lan9252_esc_write(spi
, LAN9252_ESC_PHY_REG_ADDR
, reg_addr
);
276 ret
= lan9252_esc_write(spi
, LAN9252_ESC_PHY_DATA
, data
);
280 ret
= lan9252_esc_write(spi
, LAN9252_ESC_MII
, LAN9252_ESC_MII_WRITE
);
284 return lan9252_mii_wait(spi
);
287 static int lan9252_probe(struct spi_device
*spi
)
290 int retry
= SPI_RETRY_COUNT
;
293 /* execute specified initialization sequence */
294 while (retry
&& !lan9252_init(spi
))
298 "Can't initialize LAN9252 SPI communication!");
302 /* enable access to MII management for PDI */
303 ret
= lan9252_access_mii(spi
, true);
305 dev_err(&spi
->dev
, "Can't enable access to MII management!");
310 * check PHY configuration and configure if necessary
312 * - auto negotiation disabled
315 ret
= lan9252_mii_read(spi
, PHY_ADDRESS
, MII_BMCR
, &data
);
317 dev_err(&spi
->dev
, "Can't read LAN9252 configuration!");
320 if (!(data
& BMCR_FULLDPLX
) || (data
& BMCR_ANENABLE
) ||
321 !(data
& BMCR_SPEED100
)) {
324 data
&= ~(BMCR_ANENABLE
);
325 data
|= (BMCR_FULLDPLX
| BMCR_SPEED100
);
326 ret
= lan9252_mii_write(spi
, PHY_ADDRESS
, MII_BMCR
, data
);
329 "Can't write LAN9252 configuration!");
332 dev_info(&spi
->dev
, "LAN9252 PHY configuration");
335 /* disable access to MII management for PDI */
336 lan9252_access_mii(spi
, false);
341 static const struct spi_device_id lan9252_id
[] = {
345 MODULE_DEVICE_TABLE(spi
, lan9252_id
);
347 static struct spi_driver lan9252_driver
= {
351 .probe
= lan9252_probe
,
352 .id_table
= lan9252_id
,
354 module_spi_driver(lan9252_driver
);
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");