Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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