root/drivers/spi/spi-sc18is602.c

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

DEFINITIONS

This source file includes following definitions.
  1. sc18is602_wait_ready
  2. sc18is602_txrx
  3. sc18is602_setup_transfer
  4. sc18is602_check_transfer
  5. sc18is602_transfer_one
  6. sc18is602_setup
  7. sc18is602_probe

   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 
  20 enum 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 
  33 struct 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 
  50 static 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 
  65 static 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 
 130 static 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 
 174 static int sc18is602_check_transfer(struct spi_device *spi,
 175                                     struct spi_transfer *t, int tlen)
 176 {
 177         if (t && t->len + tlen > SC18IS602_BUFSIZ)
 178                 return -EINVAL;
 179 
 180         return 0;
 181 }
 182 
 183 static 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                 if (t->delay_usecs)
 215                         udelay(t->delay_usecs);
 216         }
 217         m->status = status;
 218         spi_finalize_current_message(master);
 219 
 220         return status;
 221 }
 222 
 223 static int sc18is602_setup(struct spi_device *spi)
 224 {
 225         struct sc18is602 *hw = spi_master_get_devdata(spi->master);
 226 
 227         /* SC18IS602 does not support CS2 */
 228         if (hw->id == sc18is602 && spi->chip_select == 2)
 229                 return -ENXIO;
 230 
 231         return 0;
 232 }
 233 
 234 static int sc18is602_probe(struct i2c_client *client,
 235                            const struct i2c_device_id *id)
 236 {
 237         struct device *dev = &client->dev;
 238         struct device_node *np = dev->of_node;
 239         struct sc18is602_platform_data *pdata = dev_get_platdata(dev);
 240         struct sc18is602 *hw;
 241         struct spi_master *master;
 242         int error;
 243 
 244         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
 245                                      I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
 246                 return -EINVAL;
 247 
 248         master = spi_alloc_master(dev, sizeof(struct sc18is602));
 249         if (!master)
 250                 return -ENOMEM;
 251 
 252         hw = spi_master_get_devdata(master);
 253         i2c_set_clientdata(client, hw);
 254 
 255         /* assert reset and then release */
 256         hw->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 257         if (IS_ERR(hw->reset))
 258                 return PTR_ERR(hw->reset);
 259         gpiod_set_value_cansleep(hw->reset, 0);
 260 
 261         hw->master = master;
 262         hw->client = client;
 263         hw->dev = dev;
 264         hw->ctrl = 0xff;
 265 
 266         if (client->dev.of_node)
 267                 hw->id = (enum chips)of_device_get_match_data(&client->dev);
 268         else
 269                 hw->id = id->driver_data;
 270 
 271         switch (hw->id) {
 272         case sc18is602:
 273         case sc18is602b:
 274                 master->num_chipselect = 4;
 275                 hw->freq = SC18IS602_CLOCK;
 276                 break;
 277         case sc18is603:
 278                 master->num_chipselect = 2;
 279                 if (pdata) {
 280                         hw->freq = pdata->clock_frequency;
 281                 } else {
 282                         const __be32 *val;
 283                         int len;
 284 
 285                         val = of_get_property(np, "clock-frequency", &len);
 286                         if (val && len >= sizeof(__be32))
 287                                 hw->freq = be32_to_cpup(val);
 288                 }
 289                 if (!hw->freq)
 290                         hw->freq = SC18IS602_CLOCK;
 291                 break;
 292         }
 293         master->bus_num = np ? -1 : client->adapter->nr;
 294         master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST;
 295         master->bits_per_word_mask = SPI_BPW_MASK(8);
 296         master->setup = sc18is602_setup;
 297         master->transfer_one_message = sc18is602_transfer_one;
 298         master->dev.of_node = np;
 299         master->min_speed_hz = hw->freq / 128;
 300         master->max_speed_hz = hw->freq / 4;
 301 
 302         error = devm_spi_register_master(dev, master);
 303         if (error)
 304                 goto error_reg;
 305 
 306         return 0;
 307 
 308 error_reg:
 309         spi_master_put(master);
 310         return error;
 311 }
 312 
 313 static const struct i2c_device_id sc18is602_id[] = {
 314         { "sc18is602", sc18is602 },
 315         { "sc18is602b", sc18is602b },
 316         { "sc18is603", sc18is603 },
 317         { }
 318 };
 319 MODULE_DEVICE_TABLE(i2c, sc18is602_id);
 320 
 321 static const struct of_device_id sc18is602_of_match[] = {
 322         {
 323                 .compatible = "nxp,sc18is602",
 324                 .data = (void *)sc18is602
 325         },
 326         {
 327                 .compatible = "nxp,sc18is602b",
 328                 .data = (void *)sc18is602b
 329         },
 330         {
 331                 .compatible = "nxp,sc18is603",
 332                 .data = (void *)sc18is603
 333         },
 334         { },
 335 };
 336 MODULE_DEVICE_TABLE(of, sc18is602_of_match);
 337 
 338 static struct i2c_driver sc18is602_driver = {
 339         .driver = {
 340                 .name = "sc18is602",
 341                 .of_match_table = of_match_ptr(sc18is602_of_match),
 342         },
 343         .probe = sc18is602_probe,
 344         .id_table = sc18is602_id,
 345 };
 346 
 347 module_i2c_driver(sc18is602_driver);
 348 
 349 MODULE_DESCRIPTION("SC18IC602/603 SPI Master Driver");
 350 MODULE_AUTHOR("Guenter Roeck");
 351 MODULE_LICENSE("GPL");

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