1 /*
2  * Ethernet driver for the WIZnet W5100/W5200 chip.
3  *
4  * Copyright (C) 2016 Akinobu Mita <akinobu.mita@gmail.com>
5  *
6  * Licensed under the GPL-2 or later.
7  *
8  * Datasheet:
9  * http://www.wiznet.co.kr/wp-content/uploads/wiznethome/Chip/W5100/Document/W5100_Datasheet_v1.2.6.pdf
10  * http://wiznethome.cafe24.com/wp-content/uploads/wiznethome/Chip/W5200/Documents/W5200_DS_V140E.pdf
11  */
12 
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/delay.h>
16 #include <linux/netdevice.h>
17 #include <linux/spi/spi.h>
18 
19 #include "w5100.h"
20 
21 #define W5100_SPI_WRITE_OPCODE 0xf0
22 #define W5100_SPI_READ_OPCODE 0x0f
23 
24 static int w5100_spi_read(struct net_device *ndev, u16 addr)
25 {
26 	struct spi_device *spi = to_spi_device(ndev->dev.parent);
27 	u8 cmd[3] = { W5100_SPI_READ_OPCODE, addr >> 8, addr & 0xff };
28 	u8 data;
29 	int ret;
30 
31 	ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, 1);
32 
33 	return ret ? ret : data;
34 }
35 
36 static int w5100_spi_write(struct net_device *ndev, u16 addr, u8 data)
37 {
38 	struct spi_device *spi = to_spi_device(ndev->dev.parent);
39 	u8 cmd[4] = { W5100_SPI_WRITE_OPCODE, addr >> 8, addr & 0xff, data};
40 
41 	return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
42 }
43 
44 static int w5100_spi_read16(struct net_device *ndev, u16 addr)
45 {
46 	u16 data;
47 	int ret;
48 
49 	ret = w5100_spi_read(ndev, addr);
50 	if (ret < 0)
51 		return ret;
52 	data = ret << 8;
53 	ret = w5100_spi_read(ndev, addr + 1);
54 
55 	return ret < 0 ? ret : data | ret;
56 }
57 
58 static int w5100_spi_write16(struct net_device *ndev, u16 addr, u16 data)
59 {
60 	int ret;
61 
62 	ret = w5100_spi_write(ndev, addr, data >> 8);
63 	if (ret)
64 		return ret;
65 
66 	return w5100_spi_write(ndev, addr + 1, data & 0xff);
67 }
68 
69 static int w5100_spi_readbulk(struct net_device *ndev, u16 addr, u8 *buf,
70 			      int len)
71 {
72 	int i;
73 
74 	for (i = 0; i < len; i++) {
75 		int ret = w5100_spi_read(ndev, addr + i);
76 
77 		if (ret < 0)
78 			return ret;
79 		buf[i] = ret;
80 	}
81 
82 	return 0;
83 }
84 
85 static int w5100_spi_writebulk(struct net_device *ndev, u16 addr, const u8 *buf,
86 			       int len)
87 {
88 	int i;
89 
90 	for (i = 0; i < len; i++) {
91 		int ret = w5100_spi_write(ndev, addr + i, buf[i]);
92 
93 		if (ret)
94 			return ret;
95 	}
96 
97 	return 0;
98 }
99 
100 static const struct w5100_ops w5100_spi_ops = {
101 	.may_sleep = true,
102 	.chip_id = W5100,
103 	.read = w5100_spi_read,
104 	.write = w5100_spi_write,
105 	.read16 = w5100_spi_read16,
106 	.write16 = w5100_spi_write16,
107 	.readbulk = w5100_spi_readbulk,
108 	.writebulk = w5100_spi_writebulk,
109 };
110 
111 #define W5200_SPI_WRITE_OPCODE 0x80
112 
113 struct w5200_spi_priv {
114 	/* Serialize access to cmd_buf */
115 	struct mutex cmd_lock;
116 
117 	/* DMA (thus cache coherency maintenance) requires the
118 	 * transfer buffers to live in their own cache lines.
119 	 */
120 	u8 cmd_buf[4] ____cacheline_aligned;
121 };
122 
123 static struct w5200_spi_priv *w5200_spi_priv(struct net_device *ndev)
124 {
125 	return w5100_ops_priv(ndev);
126 }
127 
128 static int w5200_spi_init(struct net_device *ndev)
129 {
130 	struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);
131 
132 	mutex_init(&spi_priv->cmd_lock);
133 
134 	return 0;
135 }
136 
137 static int w5200_spi_read(struct net_device *ndev, u16 addr)
138 {
139 	struct spi_device *spi = to_spi_device(ndev->dev.parent);
140 	u8 cmd[4] = { addr >> 8, addr & 0xff, 0, 1 };
141 	u8 data;
142 	int ret;
143 
144 	ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, 1);
145 
146 	return ret ? ret : data;
147 }
148 
149 static int w5200_spi_write(struct net_device *ndev, u16 addr, u8 data)
150 {
151 	struct spi_device *spi = to_spi_device(ndev->dev.parent);
152 	u8 cmd[5] = { addr >> 8, addr & 0xff, W5200_SPI_WRITE_OPCODE, 1, data };
153 
154 	return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
155 }
156 
157 static int w5200_spi_read16(struct net_device *ndev, u16 addr)
158 {
159 	struct spi_device *spi = to_spi_device(ndev->dev.parent);
160 	u8 cmd[4] = { addr >> 8, addr & 0xff, 0, 2 };
161 	__be16 data;
162 	int ret;
163 
164 	ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, sizeof(data));
165 
166 	return ret ? ret : be16_to_cpu(data);
167 }
168 
169 static int w5200_spi_write16(struct net_device *ndev, u16 addr, u16 data)
170 {
171 	struct spi_device *spi = to_spi_device(ndev->dev.parent);
172 	u8 cmd[6] = {
173 		addr >> 8, addr & 0xff,
174 		W5200_SPI_WRITE_OPCODE, 2,
175 		data >> 8, data & 0xff
176 	};
177 
178 	return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
179 }
180 
181 static int w5200_spi_readbulk(struct net_device *ndev, u16 addr, u8 *buf,
182 			      int len)
183 {
184 	struct spi_device *spi = to_spi_device(ndev->dev.parent);
185 	struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);
186 	struct spi_transfer xfer[] = {
187 		{
188 			.tx_buf = spi_priv->cmd_buf,
189 			.len = sizeof(spi_priv->cmd_buf),
190 		},
191 		{
192 			.rx_buf = buf,
193 			.len = len,
194 		},
195 	};
196 	int ret;
197 
198 	mutex_lock(&spi_priv->cmd_lock);
199 
200 	spi_priv->cmd_buf[0] = addr >> 8;
201 	spi_priv->cmd_buf[1] = addr;
202 	spi_priv->cmd_buf[2] = len >> 8;
203 	spi_priv->cmd_buf[3] = len;
204 	ret = spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
205 
206 	mutex_unlock(&spi_priv->cmd_lock);
207 
208 	return ret;
209 }
210 
211 static int w5200_spi_writebulk(struct net_device *ndev, u16 addr, const u8 *buf,
212 			       int len)
213 {
214 	struct spi_device *spi = to_spi_device(ndev->dev.parent);
215 	struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);
216 	struct spi_transfer xfer[] = {
217 		{
218 			.tx_buf = spi_priv->cmd_buf,
219 			.len = sizeof(spi_priv->cmd_buf),
220 		},
221 		{
222 			.tx_buf = buf,
223 			.len = len,
224 		},
225 	};
226 	int ret;
227 
228 	mutex_lock(&spi_priv->cmd_lock);
229 
230 	spi_priv->cmd_buf[0] = addr >> 8;
231 	spi_priv->cmd_buf[1] = addr;
232 	spi_priv->cmd_buf[2] = W5200_SPI_WRITE_OPCODE | (len >> 8);
233 	spi_priv->cmd_buf[3] = len;
234 	ret = spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
235 
236 	mutex_unlock(&spi_priv->cmd_lock);
237 
238 	return ret;
239 }
240 
241 static const struct w5100_ops w5200_ops = {
242 	.may_sleep = true,
243 	.chip_id = W5200,
244 	.read = w5200_spi_read,
245 	.write = w5200_spi_write,
246 	.read16 = w5200_spi_read16,
247 	.write16 = w5200_spi_write16,
248 	.readbulk = w5200_spi_readbulk,
249 	.writebulk = w5200_spi_writebulk,
250 	.init = w5200_spi_init,
251 };
252 
253 static int w5100_spi_probe(struct spi_device *spi)
254 {
255 	const struct spi_device_id *id = spi_get_device_id(spi);
256 	const struct w5100_ops *ops;
257 	int priv_size;
258 
259 	switch (id->driver_data) {
260 	case W5100:
261 		ops = &w5100_spi_ops;
262 		priv_size = 0;
263 		break;
264 	case W5200:
265 		ops = &w5200_ops;
266 		priv_size = sizeof(struct w5200_spi_priv);
267 		break;
268 	default:
269 		return -EINVAL;
270 	}
271 
272 	return w5100_probe(&spi->dev, ops, priv_size, NULL, spi->irq, -EINVAL);
273 }
274 
275 static int w5100_spi_remove(struct spi_device *spi)
276 {
277 	return w5100_remove(&spi->dev);
278 }
279 
280 static const struct spi_device_id w5100_spi_ids[] = {
281 	{ "w5100", W5100 },
282 	{ "w5200", W5200 },
283 	{}
284 };
285 MODULE_DEVICE_TABLE(spi, w5100_spi_ids);
286 
287 static struct spi_driver w5100_spi_driver = {
288 	.driver		= {
289 		.name	= "w5100",
290 		.pm	= &w5100_pm_ops,
291 	},
292 	.probe		= w5100_spi_probe,
293 	.remove		= w5100_spi_remove,
294 	.id_table	= w5100_spi_ids,
295 };
296 module_spi_driver(w5100_spi_driver);
297 
298 MODULE_DESCRIPTION("WIZnet W5100/W5200 Ethernet driver for SPI mode");
299 MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
300 MODULE_LICENSE("GPL");
301