xref: /linux/drivers/misc/keba/lan9252.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
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