PageRenderTime 26ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/net/ethernet/wiznet/w5100-spi.c

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