2 * Ethernet driver for the WIZnet W5100 chip.
4 * Copyright (C) 2016 Akinobu Mita <akinobu.mita@gmail.com>
6 * Licensed under the GPL-2 or later.
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/delay.h>
12 #include <linux/netdevice.h>
13 #include <linux/spi/spi.h>
17 #define W5100_SPI_WRITE_OPCODE 0xf0
18 #define W5100_SPI_READ_OPCODE 0x0f
20 static int w5100_spi_read(struct net_device *ndev, u16 addr)
22 struct spi_device *spi = to_spi_device(ndev->dev.parent);
23 u8 cmd[3] = { W5100_SPI_READ_OPCODE, addr >> 8, addr & 0xff };
27 ret = spi_write_then_read(spi, cmd, sizeof(cmd), &data, 1);
29 return ret ? ret : data;
32 static int w5100_spi_write(struct net_device *ndev, u16 addr, u8 data)
34 struct spi_device *spi = to_spi_device(ndev->dev.parent);
35 u8 cmd[4] = { W5100_SPI_WRITE_OPCODE, addr >> 8, addr & 0xff, data};
37 return spi_write_then_read(spi, cmd, sizeof(cmd), NULL, 0);
40 static int w5100_spi_read16(struct net_device *ndev, u16 addr)
45 ret = w5100_spi_read(ndev, addr);
49 ret = w5100_spi_read(ndev, addr + 1);
51 return ret < 0 ? ret : data | ret;
54 static int w5100_spi_write16(struct net_device *ndev, u16 addr, u16 data)
58 ret = w5100_spi_write(ndev, addr, data >> 8);
62 return w5100_spi_write(ndev, addr + 1, data & 0xff);
65 static int w5100_spi_readbulk(struct net_device *ndev, u16 addr, u8 *buf,
70 for (i = 0; i < len; i++) {
71 int ret = w5100_spi_read(ndev, addr + i);
81 static int w5100_spi_writebulk(struct net_device *ndev, u16 addr, const u8 *buf,
86 for (i = 0; i < len; i++) {
87 int ret = w5100_spi_write(ndev, addr + i, buf[i]);
96 static const struct w5100_ops w5100_spi_ops = {
98 .read = w5100_spi_read,
99 .write = w5100_spi_write,
100 .read16 = w5100_spi_read16,
101 .write16 = w5100_spi_write16,
102 .readbulk = w5100_spi_readbulk,
103 .writebulk = w5100_spi_writebulk,
106 static int w5100_spi_probe(struct spi_device *spi)
108 return w5100_probe(&spi->dev, &w5100_spi_ops, 0, NULL, spi->irq,
112 static int w5100_spi_remove(struct spi_device *spi)
114 return w5100_remove(&spi->dev);
117 static const struct spi_device_id w5100_spi_ids[] = {
121 MODULE_DEVICE_TABLE(spi, w5100_spi_ids);
123 static struct spi_driver w5100_spi_driver = {
128 .probe = w5100_spi_probe,
129 .remove = w5100_spi_remove,
130 .id_table = w5100_spi_ids,
132 module_spi_driver(w5100_spi_driver);
134 MODULE_DESCRIPTION("WIZnet W5100 Ethernet driver for SPI mode");
135 MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
136 MODULE_LICENSE("GPL");