Merge tag 'acpi-4.7-rc1-more' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[linux-2.6-block.git] / drivers / net / ethernet / wiznet / w5100-spi.c
CommitLineData
630cf097 1/*
35ef7d68 2 * Ethernet driver for the WIZnet W5100/W5200/W5500 chip.
630cf097
AM
3 *
4 * Copyright (C) 2016 Akinobu Mita <akinobu.mita@gmail.com>
5 *
6 * Licensed under the GPL-2 or later.
0c165ff2
AM
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
35ef7d68 11 * http://wizwiki.net/wiki/lib/exe/fetch.php?media=products:w5500:w5500_ds_v106e_141230.pdf
630cf097
AM
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/delay.h>
17#include <linux/netdevice.h>
c3875ca7 18#include <linux/of_net.h>
630cf097
AM
19#include <linux/spi/spi.h>
20
21#include "w5100.h"
22
23#define W5100_SPI_WRITE_OPCODE 0xf0
24#define W5100_SPI_READ_OPCODE 0x0f
25
35ef7d68 26static int w5100_spi_read(struct net_device *ndev, u32 addr)
630cf097
AM
27{
28 struct spi_device *spi = to_spi_device(ndev->dev.parent);
29 u8 cmd[3] = { W5100_SPI_READ_OPCODE, addr >> 8, addr & 0xff };
30 u8 data;
31 int ret;
32
33 ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, 1);
34
35 return ret ? ret : data;
36}
37
35ef7d68 38static int w5100_spi_write(struct net_device *ndev, u32 addr, u8 data)
630cf097
AM
39{
40 struct spi_device *spi = to_spi_device(ndev->dev.parent);
41 u8 cmd[4] = { W5100_SPI_WRITE_OPCODE, addr >> 8, addr & 0xff, data};
42
43 return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
44}
45
35ef7d68 46static int w5100_spi_read16(struct net_device *ndev, u32 addr)
630cf097
AM
47{
48 u16 data;
49 int ret;
50
51 ret = w5100_spi_read(ndev, addr);
52 if (ret < 0)
53 return ret;
54 data = ret << 8;
55 ret = w5100_spi_read(ndev, addr + 1);
56
57 return ret < 0 ? ret : data | ret;
58}
59
35ef7d68 60static int w5100_spi_write16(struct net_device *ndev, u32 addr, u16 data)
630cf097
AM
61{
62 int ret;
63
64 ret = w5100_spi_write(ndev, addr, data >> 8);
65 if (ret)
66 return ret;
67
68 return w5100_spi_write(ndev, addr + 1, data & 0xff);
69}
70
35ef7d68 71static int w5100_spi_readbulk(struct net_device *ndev, u32 addr, u8 *buf,
630cf097
AM
72 int len)
73{
74 int i;
75
76 for (i = 0; i < len; i++) {
77 int ret = w5100_spi_read(ndev, addr + i);
78
79 if (ret < 0)
80 return ret;
81 buf[i] = ret;
82 }
83
84 return 0;
85}
86
35ef7d68 87static int w5100_spi_writebulk(struct net_device *ndev, u32 addr, const u8 *buf,
630cf097
AM
88 int len)
89{
90 int i;
91
92 for (i = 0; i < len; i++) {
93 int ret = w5100_spi_write(ndev, addr + i, buf[i]);
94
95 if (ret)
96 return ret;
97 }
98
99 return 0;
100}
101
102static const struct w5100_ops w5100_spi_ops = {
103 .may_sleep = true,
0c165ff2 104 .chip_id = W5100,
630cf097
AM
105 .read = w5100_spi_read,
106 .write = w5100_spi_write,
107 .read16 = w5100_spi_read16,
108 .write16 = w5100_spi_write16,
109 .readbulk = w5100_spi_readbulk,
110 .writebulk = w5100_spi_writebulk,
111};
112
0c165ff2
AM
113#define W5200_SPI_WRITE_OPCODE 0x80
114
115struct w5200_spi_priv {
116 /* Serialize access to cmd_buf */
117 struct mutex cmd_lock;
118
119 /* DMA (thus cache coherency maintenance) requires the
120 * transfer buffers to live in their own cache lines.
121 */
122 u8 cmd_buf[4] ____cacheline_aligned;
123};
124
125static struct w5200_spi_priv *w5200_spi_priv(struct net_device *ndev)
126{
127 return w5100_ops_priv(ndev);
128}
129
130static int w5200_spi_init(struct net_device *ndev)
131{
132 struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);
133
134 mutex_init(&spi_priv->cmd_lock);
135
136 return 0;
137}
138
35ef7d68 139static int w5200_spi_read(struct net_device *ndev, u32 addr)
0c165ff2
AM
140{
141 struct spi_device *spi = to_spi_device(ndev->dev.parent);
142 u8 cmd[4] = { addr >> 8, addr & 0xff, 0, 1 };
143 u8 data;
144 int ret;
145
146 ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, 1);
147
148 return ret ? ret : data;
149}
150
35ef7d68 151static int w5200_spi_write(struct net_device *ndev, u32 addr, u8 data)
0c165ff2
AM
152{
153 struct spi_device *spi = to_spi_device(ndev->dev.parent);
154 u8 cmd[5] = { addr >> 8, addr & 0xff, W5200_SPI_WRITE_OPCODE, 1, data };
155
156 return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
157}
158
35ef7d68 159static int w5200_spi_read16(struct net_device *ndev, u32 addr)
0c165ff2
AM
160{
161 struct spi_device *spi = to_spi_device(ndev->dev.parent);
162 u8 cmd[4] = { addr >> 8, addr & 0xff, 0, 2 };
163 __be16 data;
164 int ret;
165
166 ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, sizeof(data));
167
168 return ret ? ret : be16_to_cpu(data);
169}
170
35ef7d68 171static int w5200_spi_write16(struct net_device *ndev, u32 addr, u16 data)
0c165ff2
AM
172{
173 struct spi_device *spi = to_spi_device(ndev->dev.parent);
174 u8 cmd[6] = {
175 addr >> 8, addr & 0xff,
176 W5200_SPI_WRITE_OPCODE, 2,
177 data >> 8, data & 0xff
178 };
179
180 return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
181}
182
35ef7d68 183static int w5200_spi_readbulk(struct net_device *ndev, u32 addr, u8 *buf,
0c165ff2
AM
184 int len)
185{
186 struct spi_device *spi = to_spi_device(ndev->dev.parent);
187 struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);
188 struct spi_transfer xfer[] = {
189 {
190 .tx_buf = spi_priv->cmd_buf,
191 .len = sizeof(spi_priv->cmd_buf),
192 },
193 {
194 .rx_buf = buf,
195 .len = len,
196 },
197 };
198 int ret;
199
200 mutex_lock(&spi_priv->cmd_lock);
201
202 spi_priv->cmd_buf[0] = addr >> 8;
203 spi_priv->cmd_buf[1] = addr;
204 spi_priv->cmd_buf[2] = len >> 8;
205 spi_priv->cmd_buf[3] = len;
206 ret = spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
207
208 mutex_unlock(&spi_priv->cmd_lock);
209
210 return ret;
211}
212
35ef7d68 213static int w5200_spi_writebulk(struct net_device *ndev, u32 addr, const u8 *buf,
0c165ff2
AM
214 int len)
215{
216 struct spi_device *spi = to_spi_device(ndev->dev.parent);
217 struct w5200_spi_priv *spi_priv = w5200_spi_priv(ndev);
218 struct spi_transfer xfer[] = {
219 {
220 .tx_buf = spi_priv->cmd_buf,
221 .len = sizeof(spi_priv->cmd_buf),
222 },
223 {
224 .tx_buf = buf,
225 .len = len,
226 },
227 };
228 int ret;
229
230 mutex_lock(&spi_priv->cmd_lock);
231
232 spi_priv->cmd_buf[0] = addr >> 8;
233 spi_priv->cmd_buf[1] = addr;
234 spi_priv->cmd_buf[2] = W5200_SPI_WRITE_OPCODE | (len >> 8);
235 spi_priv->cmd_buf[3] = len;
236 ret = spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
237
238 mutex_unlock(&spi_priv->cmd_lock);
239
240 return ret;
241}
242
243static const struct w5100_ops w5200_ops = {
244 .may_sleep = true,
245 .chip_id = W5200,
246 .read = w5200_spi_read,
247 .write = w5200_spi_write,
248 .read16 = w5200_spi_read16,
249 .write16 = w5200_spi_write16,
250 .readbulk = w5200_spi_readbulk,
251 .writebulk = w5200_spi_writebulk,
252 .init = w5200_spi_init,
253};
254
35ef7d68
AM
255#define W5500_SPI_BLOCK_SELECT(addr) (((addr) >> 16) & 0x1f)
256#define W5500_SPI_READ_CONTROL(addr) (W5500_SPI_BLOCK_SELECT(addr) << 3)
257#define W5500_SPI_WRITE_CONTROL(addr) \
258 ((W5500_SPI_BLOCK_SELECT(addr) << 3) | BIT(2))
259
260struct w5500_spi_priv {
261 /* Serialize access to cmd_buf */
262 struct mutex cmd_lock;
263
264 /* DMA (thus cache coherency maintenance) requires the
265 * transfer buffers to live in their own cache lines.
266 */
267 u8 cmd_buf[3] ____cacheline_aligned;
268};
269
270static struct w5500_spi_priv *w5500_spi_priv(struct net_device *ndev)
271{
272 return w5100_ops_priv(ndev);
273}
274
275static int w5500_spi_init(struct net_device *ndev)
276{
277 struct w5500_spi_priv *spi_priv = w5500_spi_priv(ndev);
278
279 mutex_init(&spi_priv->cmd_lock);
280
281 return 0;
282}
283
284static int w5500_spi_read(struct net_device *ndev, u32 addr)
285{
286 struct spi_device *spi = to_spi_device(ndev->dev.parent);
287 u8 cmd[3] = {
288 addr >> 8,
289 addr,
290 W5500_SPI_READ_CONTROL(addr)
291 };
292 u8 data;
293 int ret;
294
295 ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, 1);
296
297 return ret ? ret : data;
298}
299
300static int w5500_spi_write(struct net_device *ndev, u32 addr, u8 data)
301{
302 struct spi_device *spi = to_spi_device(ndev->dev.parent);
303 u8 cmd[4] = {
304 addr >> 8,
305 addr,
306 W5500_SPI_WRITE_CONTROL(addr),
307 data
308 };
309
310 return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
311}
312
313static int w5500_spi_read16(struct net_device *ndev, u32 addr)
314{
315 struct spi_device *spi = to_spi_device(ndev->dev.parent);
316 u8 cmd[3] = {
317 addr >> 8,
318 addr,
319 W5500_SPI_READ_CONTROL(addr)
320 };
321 __be16 data;
322 int ret;
323
324 ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, sizeof(data));
325
326 return ret ? ret : be16_to_cpu(data);
327}
328
329static int w5500_spi_write16(struct net_device *ndev, u32 addr, u16 data)
330{
331 struct spi_device *spi = to_spi_device(ndev->dev.parent);
332 u8 cmd[5] = {
333 addr >> 8,
334 addr,
335 W5500_SPI_WRITE_CONTROL(addr),
336 data >> 8,
337 data
338 };
339
340 return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
341}
342
343static int w5500_spi_readbulk(struct net_device *ndev, u32 addr, u8 *buf,
344 int len)
345{
346 struct spi_device *spi = to_spi_device(ndev->dev.parent);
347 struct w5500_spi_priv *spi_priv = w5500_spi_priv(ndev);
348 struct spi_transfer xfer[] = {
349 {
350 .tx_buf = spi_priv->cmd_buf,
351 .len = sizeof(spi_priv->cmd_buf),
352 },
353 {
354 .rx_buf = buf,
355 .len = len,
356 },
357 };
358 int ret;
359
360 mutex_lock(&spi_priv->cmd_lock);
361
362 spi_priv->cmd_buf[0] = addr >> 8;
363 spi_priv->cmd_buf[1] = addr;
364 spi_priv->cmd_buf[2] = W5500_SPI_READ_CONTROL(addr);
365 ret = spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
366
367 mutex_unlock(&spi_priv->cmd_lock);
368
369 return ret;
370}
371
372static int w5500_spi_writebulk(struct net_device *ndev, u32 addr, const u8 *buf,
373 int len)
374{
375 struct spi_device *spi = to_spi_device(ndev->dev.parent);
376 struct w5500_spi_priv *spi_priv = w5500_spi_priv(ndev);
377 struct spi_transfer xfer[] = {
378 {
379 .tx_buf = spi_priv->cmd_buf,
380 .len = sizeof(spi_priv->cmd_buf),
381 },
382 {
383 .tx_buf = buf,
384 .len = len,
385 },
386 };
387 int ret;
388
389 mutex_lock(&spi_priv->cmd_lock);
390
391 spi_priv->cmd_buf[0] = addr >> 8;
392 spi_priv->cmd_buf[1] = addr;
393 spi_priv->cmd_buf[2] = W5500_SPI_WRITE_CONTROL(addr);
394 ret = spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
395
396 mutex_unlock(&spi_priv->cmd_lock);
397
398 return ret;
399}
400
401static const struct w5100_ops w5500_ops = {
402 .may_sleep = true,
403 .chip_id = W5500,
404 .read = w5500_spi_read,
405 .write = w5500_spi_write,
406 .read16 = w5500_spi_read16,
407 .write16 = w5500_spi_write16,
408 .readbulk = w5500_spi_readbulk,
409 .writebulk = w5500_spi_writebulk,
410 .init = w5500_spi_init,
411};
412
630cf097
AM
413static int w5100_spi_probe(struct spi_device *spi)
414{
0c165ff2
AM
415 const struct spi_device_id *id = spi_get_device_id(spi);
416 const struct w5100_ops *ops;
417 int priv_size;
c3875ca7 418 const void *mac = of_get_mac_address(spi->dev.of_node);
0c165ff2
AM
419
420 switch (id->driver_data) {
421 case W5100:
422 ops = &w5100_spi_ops;
423 priv_size = 0;
424 break;
425 case W5200:
426 ops = &w5200_ops;
427 priv_size = sizeof(struct w5200_spi_priv);
428 break;
35ef7d68
AM
429 case W5500:
430 ops = &w5500_ops;
431 priv_size = sizeof(struct w5500_spi_priv);
432 break;
0c165ff2
AM
433 default:
434 return -EINVAL;
435 }
436
c3875ca7 437 return w5100_probe(&spi->dev, ops, priv_size, mac, spi->irq, -EINVAL);
630cf097
AM
438}
439
440static int w5100_spi_remove(struct spi_device *spi)
441{
442 return w5100_remove(&spi->dev);
443}
444
445static const struct spi_device_id w5100_spi_ids[] = {
0c165ff2
AM
446 { "w5100", W5100 },
447 { "w5200", W5200 },
35ef7d68 448 { "w5500", W5500 },
630cf097
AM
449 {}
450};
451MODULE_DEVICE_TABLE(spi, w5100_spi_ids);
452
453static struct spi_driver w5100_spi_driver = {
454 .driver = {
455 .name = "w5100",
456 .pm = &w5100_pm_ops,
457 },
458 .probe = w5100_spi_probe,
459 .remove = w5100_spi_remove,
460 .id_table = w5100_spi_ids,
461};
462module_spi_driver(w5100_spi_driver);
463
35ef7d68 464MODULE_DESCRIPTION("WIZnet W5100/W5200/W5500 Ethernet driver for SPI mode");
630cf097
AM
465MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
466MODULE_LICENSE("GPL");