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

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. w5100_spi_read
  2. w5100_spi_write
  3. w5100_spi_read16
  4. w5100_spi_write16
  5. w5100_spi_readbulk
  6. w5100_spi_writebulk
  7. w5200_spi_init
  8. w5200_spi_read
  9. w5200_spi_write
  10. w5200_spi_read16
  11. w5200_spi_write16
  12. w5200_spi_readbulk
  13. w5200_spi_writebulk
  14. w5500_spi_init
  15. w5500_spi_read
  16. w5500_spi_write
  17. w5500_spi_read16
  18. w5500_spi_write16
  19. w5500_spi_readbulk
  20. w5500_spi_writebulk
  21. w5100_spi_probe
  22. w5100_spi_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Ethernet driver for the WIZnet W5100/W5200/W5500 chip.
   4  *
   5  * Copyright (C) 2016 Akinobu Mita <akinobu.mita@gmail.com>
   6  *
   7  * Datasheet:
   8  * http://www.wiznet.co.kr/wp-content/uploads/wiznethome/Chip/W5100/Document/W5100_Datasheet_v1.2.6.pdf
   9  * http://wiznethome.cafe24.com/wp-content/uploads/wiznethome/Chip/W5200/Documents/W5200_DS_V140E.pdf
  10  * http://wizwiki.net/wiki/lib/exe/fetch.php?media=products:w5500:w5500_ds_v106e_141230.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/of_net.h>
  18 #include <linux/of_device.h>
  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 
  26 static int w5100_spi_read(struct net_device *ndev, u32 addr)
  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 
  38 static int w5100_spi_write(struct net_device *ndev, u32 addr, u8 data)
  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 
  46 static int w5100_spi_read16(struct net_device *ndev, u32 addr)
  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 
  60 static int w5100_spi_write16(struct net_device *ndev, u32 addr, u16 data)
  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 
  71 static int w5100_spi_readbulk(struct net_device *ndev, u32 addr, u8 *buf,
  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 
  87 static int w5100_spi_writebulk(struct net_device *ndev, u32 addr, const u8 *buf,
  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 
 102 static const struct w5100_ops w5100_spi_ops = {
 103         .may_sleep = true,
 104         .chip_id = W5100,
 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 
 113 #define W5200_SPI_WRITE_OPCODE 0x80
 114 
 115 struct 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 
 125 static struct w5200_spi_priv *w5200_spi_priv(struct net_device *ndev)
 126 {
 127         return w5100_ops_priv(ndev);
 128 }
 129 
 130 static 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 
 139 static int w5200_spi_read(struct net_device *ndev, u32 addr)
 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 
 151 static int w5200_spi_write(struct net_device *ndev, u32 addr, u8 data)
 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 
 159 static int w5200_spi_read16(struct net_device *ndev, u32 addr)
 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 
 171 static int w5200_spi_write16(struct net_device *ndev, u32 addr, u16 data)
 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 
 183 static int w5200_spi_readbulk(struct net_device *ndev, u32 addr, u8 *buf,
 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 
 213 static int w5200_spi_writebulk(struct net_device *ndev, u32 addr, const u8 *buf,
 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 
 243 static 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 
 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 
 260 struct 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 
 270 static struct w5500_spi_priv *w5500_spi_priv(struct net_device *ndev)
 271 {
 272         return w5100_ops_priv(ndev);
 273 }
 274 
 275 static 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 
 284 static 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 
 300 static 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 
 313 static 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 
 329 static 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 
 343 static 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 
 372 static 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 
 401 static 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 
 413 static const struct of_device_id w5100_of_match[] = {
 414         { .compatible = "wiznet,w5100", .data = (const void*)W5100, },
 415         { .compatible = "wiznet,w5200", .data = (const void*)W5200, },
 416         { .compatible = "wiznet,w5500", .data = (const void*)W5500, },
 417         { },
 418 };
 419 MODULE_DEVICE_TABLE(of, w5100_of_match);
 420 
 421 static int w5100_spi_probe(struct spi_device *spi)
 422 {
 423         const struct of_device_id *of_id;
 424         const struct w5100_ops *ops;
 425         kernel_ulong_t driver_data;
 426         int priv_size;
 427         const void *mac = of_get_mac_address(spi->dev.of_node);
 428 
 429         if (spi->dev.of_node) {
 430                 of_id = of_match_device(w5100_of_match, &spi->dev);
 431                 if (!of_id)
 432                         return -ENODEV;
 433                 driver_data = (kernel_ulong_t)of_id->data;
 434         } else {
 435                 driver_data = spi_get_device_id(spi)->driver_data;
 436         }
 437 
 438         switch (driver_data) {
 439         case W5100:
 440                 ops = &w5100_spi_ops;
 441                 priv_size = 0;
 442                 break;
 443         case W5200:
 444                 ops = &w5200_ops;
 445                 priv_size = sizeof(struct w5200_spi_priv);
 446                 break;
 447         case W5500:
 448                 ops = &w5500_ops;
 449                 priv_size = sizeof(struct w5500_spi_priv);
 450                 break;
 451         default:
 452                 return -EINVAL;
 453         }
 454 
 455         return w5100_probe(&spi->dev, ops, priv_size, mac, spi->irq, -EINVAL);
 456 }
 457 
 458 static int w5100_spi_remove(struct spi_device *spi)
 459 {
 460         return w5100_remove(&spi->dev);
 461 }
 462 
 463 static const struct spi_device_id w5100_spi_ids[] = {
 464         { "w5100", W5100 },
 465         { "w5200", W5200 },
 466         { "w5500", W5500 },
 467         {}
 468 };
 469 MODULE_DEVICE_TABLE(spi, w5100_spi_ids);
 470 
 471 static struct spi_driver w5100_spi_driver = {
 472         .driver         = {
 473                 .name   = "w5100",
 474                 .pm     = &w5100_pm_ops,
 475                 .of_match_table = w5100_of_match,
 476         },
 477         .probe          = w5100_spi_probe,
 478         .remove         = w5100_spi_remove,
 479         .id_table       = w5100_spi_ids,
 480 };
 481 module_spi_driver(w5100_spi_driver);
 482 
 483 MODULE_DESCRIPTION("WIZnet W5100/W5200/W5500 Ethernet driver for SPI mode");
 484 MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
 485 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */