linux/drivers/spi/spi-sc18is602.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * NXP SC18IS602/603 SPI driver
   4 *
   5 * Copyright (C) Guenter Roeck <linux@roeck-us.net>
   6 */
   7
   8#include <linux/kernel.h>
   9#include <linux/err.h>
  10#include <linux/module.h>
  11#include <linux/spi/spi.h>
  12#include <linux/i2c.h>
  13#include <linux/delay.h>
  14#include <linux/pm_runtime.h>
  15#include <linux/of_device.h>
  16#include <linux/of.h>
  17#include <linux/platform_data/sc18is602.h>
  18#include <linux/gpio/consumer.h>
  19
  20enum chips { sc18is602, sc18is602b, sc18is603 };
  21
  22#define SC18IS602_BUFSIZ                200
  23#define SC18IS602_CLOCK                 7372000
  24
  25#define SC18IS602_MODE_CPHA             BIT(2)
  26#define SC18IS602_MODE_CPOL             BIT(3)
  27#define SC18IS602_MODE_LSB_FIRST        BIT(5)
  28#define SC18IS602_MODE_CLOCK_DIV_4      0x0
  29#define SC18IS602_MODE_CLOCK_DIV_16     0x1
  30#define SC18IS602_MODE_CLOCK_DIV_64     0x2
  31#define SC18IS602_MODE_CLOCK_DIV_128    0x3
  32
  33struct sc18is602 {
  34        struct spi_master       *master;
  35        struct device           *dev;
  36        u8                      ctrl;
  37        u32                     freq;
  38        u32                     speed;
  39
  40        /* I2C data */
  41        struct i2c_client       *client;
  42        enum chips              id;
  43        u8                      buffer[SC18IS602_BUFSIZ + 1];
  44        int                     tlen;   /* Data queued for tx in buffer */
  45        int                     rindex; /* Receive data index in buffer */
  46
  47        struct gpio_desc        *reset;
  48};
  49
  50static int sc18is602_wait_ready(struct sc18is602 *hw, int len)
  51{
  52        int i, err;
  53        int usecs = 1000000 * len / hw->speed + 1;
  54        u8 dummy[1];
  55
  56        for (i = 0; i < 10; i++) {
  57                err = i2c_master_recv(hw->client, dummy, 1);
  58                if (err >= 0)
  59                        return 0;
  60                usleep_range(usecs, usecs * 2);
  61        }
  62        return -ETIMEDOUT;
  63}
  64
  65static int sc18is602_txrx(struct sc18is602 *hw, struct spi_message *msg,
  66                          struct spi_transfer *t, bool do_transfer)
  67{
  68        unsigned int len = t->len;
  69        int ret;
  70
  71        if (hw->tlen == 0) {
  72                /* First byte (I2C command) is chip select */
  73                hw->buffer[0] = 1 << msg->spi->chip_select;
  74                hw->tlen = 1;
  75                hw->rindex = 0;
  76        }
  77        /*
  78         * We can not immediately send data to the chip, since each I2C message
  79         * resembles a full SPI message (from CS active to CS inactive).
  80         * Enqueue messages up to the first read or until do_transfer is true.
  81         */
  82        if (t->tx_buf) {
  83                memcpy(&hw->buffer[hw->tlen], t->tx_buf, len);
  84                hw->tlen += len;
  85                if (t->rx_buf)
  86                        do_transfer = true;
  87                else
  88                        hw->rindex = hw->tlen - 1;
  89        } else if (t->rx_buf) {
  90                /*
  91                 * For receive-only transfers we still need to perform a dummy
  92                 * write to receive data from the SPI chip.
  93                 * Read data starts at the end of transmit data (minus 1 to
  94                 * account for CS).
  95                 */
  96                hw->rindex = hw->tlen - 1;
  97                memset(&hw->buffer[hw->tlen], 0, len);
  98                hw->tlen += len;
  99                do_transfer = true;
 100        }
 101
 102        if (do_transfer && hw->tlen > 1) {
 103                ret = sc18is602_wait_ready(hw, SC18IS602_BUFSIZ);
 104                if (ret < 0)
 105                        return ret;
 106                ret = i2c_master_send(hw->client, hw->buffer, hw->tlen);
 107                if (ret < 0)
 108                        return ret;
 109                if (ret != hw->tlen)
 110                        return -EIO;
 111
 112                if (t->rx_buf) {
 113                        int rlen = hw->rindex + len;
 114
 115                        ret = sc18is602_wait_ready(hw, hw->tlen);
 116                        if (ret < 0)
 117                                return ret;
 118                        ret = i2c_master_recv(hw->client, hw->buffer, rlen);
 119                        if (ret < 0)
 120                                return ret;
 121                        if (ret != rlen)
 122                                return -EIO;
 123                        memcpy(t->rx_buf, &hw->buffer[hw->rindex], len);
 124                }
 125                hw->tlen = 0;
 126        }
 127        return len;
 128}
 129
 130static int sc18is602_setup_transfer(struct sc18is602 *hw, u32 hz, u8 mode)
 131{
 132        u8 ctrl = 0;
 133        int ret;
 134
 135        if (mode & SPI_CPHA)
 136                ctrl |= SC18IS602_MODE_CPHA;
 137        if (mode & SPI_CPOL)
 138                ctrl |= SC18IS602_MODE_CPOL;
 139        if (mode & SPI_LSB_FIRST)
 140                ctrl |= SC18IS602_MODE_LSB_FIRST;
 141
 142        /* Find the closest clock speed */
 143        if (hz >= hw->freq / 4) {
 144                ctrl |= SC18IS602_MODE_CLOCK_DIV_4;
 145                hw->speed = hw->freq / 4;
 146        } else if (hz >= hw->freq / 16) {
 147                ctrl |= SC18IS602_MODE_CLOCK_DIV_16;
 148                hw->speed = hw->freq / 16;
 149        } else if (hz >= hw->freq / 64) {
 150                ctrl |= SC18IS602_MODE_CLOCK_DIV_64;
 151                hw->speed = hw->freq / 64;
 152        } else {
 153                ctrl |= SC18IS602_MODE_CLOCK_DIV_128;
 154                hw->speed = hw->freq / 128;
 155        }
 156
 157        /*
 158         * Don't do anything if the control value did not change. The initial
 159         * value of 0xff for hw->ctrl ensures that the correct mode will be set
 160         * with the first call to this function.
 161         */
 162        if (ctrl == hw->ctrl)
 163                return 0;
 164
 165        ret = i2c_smbus_write_byte_data(hw->client, 0xf0, ctrl);
 166        if (ret < 0)
 167                return ret;
 168
 169        hw->ctrl = ctrl;
 170
 171        return 0;
 172}
 173
 174static int sc18is602_check_transfer(struct spi_device *spi,
 175                                    struct spi_transfer *t, int tlen)
 176{
 177        if (t && t->len + tlen > SC18IS602_BUFSIZ + 1)
 178                return -EINVAL;
 179
 180        return 0;
 181}
 182
 183static int sc18is602_transfer_one(struct spi_master *master,
 184                                  struct spi_message *m)
 185{
 186        struct sc18is602 *hw = spi_master_get_devdata(master);
 187        struct spi_device *spi = m->spi;
 188        struct spi_transfer *t;
 189        int status = 0;
 190
 191        hw->tlen = 0;
 192        list_for_each_entry(t, &m->transfers, transfer_list) {
 193                bool do_transfer;
 194
 195                status = sc18is602_check_transfer(spi, t, hw->tlen);
 196                if (status < 0)
 197                        break;
 198
 199                status = sc18is602_setup_transfer(hw, t->speed_hz, spi->mode);
 200                if (status < 0)
 201                        break;
 202
 203                do_transfer = t->cs_change || list_is_last(&t->transfer_list,
 204                                                           &m->transfers);
 205
 206                if (t->len) {
 207                        status = sc18is602_txrx(hw, m, t, do_transfer);
 208                        if (status < 0)
 209                                break;
 210                        m->actual_length += status;
 211                }
 212                status = 0;
 213
 214                spi_transfer_delay_exec(t);
 215        }
 216        m->status = status;
 217        spi_finalize_current_message(master);
 218
 219        return status;
 220}
 221
 222static size_t sc18is602_max_transfer_size(struct spi_device *spi)
 223{
 224        return SC18IS602_BUFSIZ;
 225}
 226
 227static int sc18is602_setup(struct spi_device *spi)
 228{
 229        struct sc18is602 *hw = spi_master_get_devdata(spi->master);
 230
 231        /* SC18IS602 does not support CS2 */
 232        if (hw->id == sc18is602 && spi->chip_select == 2)
 233                return -ENXIO;
 234
 235        return 0;
 236}
 237
 238static int sc18is602_probe(struct i2c_client *client,
 239                           const struct i2c_device_id *id)
 240{
 241        struct device *dev = &client->dev;
 242        struct device_node *np = dev->of_node;
 243        struct sc18is602_platform_data *pdata = dev_get_platdata(dev);
 244        struct sc18is602 *hw;
 245        struct spi_master *master;
 246
 247        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
 248                                     I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
 249                return -EINVAL;
 250
 251        master = devm_spi_alloc_master(dev, sizeof(struct sc18is602));
 252        if (!master)
 253                return -ENOMEM;
 254
 255        hw = spi_master_get_devdata(master);
 256        i2c_set_clientdata(client, hw);
 257
 258        /* assert reset and then release */
 259        hw->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 260        if (IS_ERR(hw->reset))
 261                return PTR_ERR(hw->reset);
 262        gpiod_set_value_cansleep(hw->reset, 0);
 263
 264        hw->master = master;
 265        hw->client = client;
 266        hw->dev = dev;
 267        hw->ctrl = 0xff;
 268
 269        if (client->dev.of_node)
 270                hw->id = (enum chips)of_device_get_match_data(&client->dev);
 271        else
 272                hw->id = id->driver_data;
 273
 274        switch (hw->id) {
 275        case sc18is602:
 276        case sc18is602b:
 277                master->num_chipselect = 4;
 278                hw->freq = SC18IS602_CLOCK;
 279                break;
 280        case sc18is603:
 281                master->num_chipselect = 2;
 282                if (pdata) {
 283                        hw->freq = pdata->clock_frequency;
 284                } else {
 285                        const __be32 *val;
 286                        int len;
 287
 288                        val = of_get_property(np, "clock-frequency", &len);
 289                        if (val && len >= sizeof(__be32))
 290                                hw->freq = be32_to_cpup(val);
 291                }
 292                if (!hw->freq)
 293                        hw->freq = SC18IS602_CLOCK;
 294                break;
 295        }
 296        master->bus_num = np ? -1 : client->adapter->nr;
 297        master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST;
 298        master->bits_per_word_mask = SPI_BPW_MASK(8);
 299        master->setup = sc18is602_setup;
 300        master->transfer_one_message = sc18is602_transfer_one;
 301        master->max_transfer_size = sc18is602_max_transfer_size;
 302        master->max_message_size = sc18is602_max_transfer_size;
 303        master->dev.of_node = np;
 304        master->min_speed_hz = hw->freq / 128;
 305        master->max_speed_hz = hw->freq / 4;
 306
 307        return devm_spi_register_master(dev, master);
 308}
 309
 310static const struct i2c_device_id sc18is602_id[] = {
 311        { "sc18is602", sc18is602 },
 312        { "sc18is602b", sc18is602b },
 313        { "sc18is603", sc18is603 },
 314        { }
 315};
 316MODULE_DEVICE_TABLE(i2c, sc18is602_id);
 317
 318static const struct of_device_id sc18is602_of_match[] = {
 319        {
 320                .compatible = "nxp,sc18is602",
 321                .data = (void *)sc18is602
 322        },
 323        {
 324                .compatible = "nxp,sc18is602b",
 325                .data = (void *)sc18is602b
 326        },
 327        {
 328                .compatible = "nxp,sc18is603",
 329                .data = (void *)sc18is603
 330        },
 331        { },
 332};
 333MODULE_DEVICE_TABLE(of, sc18is602_of_match);
 334
 335static struct i2c_driver sc18is602_driver = {
 336        .driver = {
 337                .name = "sc18is602",
 338                .of_match_table = of_match_ptr(sc18is602_of_match),
 339        },
 340        .probe = sc18is602_probe,
 341        .id_table = sc18is602_id,
 342};
 343
 344module_i2c_driver(sc18is602_driver);
 345
 346MODULE_DESCRIPTION("SC18IS602/603 SPI Master Driver");
 347MODULE_AUTHOR("Guenter Roeck");
 348MODULE_LICENSE("GPL");
 349