13ce8859eSGuenter Roeck /* 23ce8859eSGuenter Roeck * NXP SC18IS602/603 SPI driver 33ce8859eSGuenter Roeck * 43ce8859eSGuenter Roeck * Copyright (C) Guenter Roeck <linux@roeck-us.net> 53ce8859eSGuenter Roeck * 63ce8859eSGuenter Roeck * This program is free software; you can redistribute it and/or modify 73ce8859eSGuenter Roeck * it under the terms of the GNU General Public License as published by 83ce8859eSGuenter Roeck * the Free Software Foundation; either version 2 of the License, or 93ce8859eSGuenter Roeck * (at your option) any later version. 103ce8859eSGuenter Roeck * 113ce8859eSGuenter Roeck * This program is distributed in the hope that it will be useful, 123ce8859eSGuenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 133ce8859eSGuenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 143ce8859eSGuenter Roeck * GNU General Public License for more details. 153ce8859eSGuenter Roeck */ 163ce8859eSGuenter Roeck 173ce8859eSGuenter Roeck #include <linux/kernel.h> 183ce8859eSGuenter Roeck #include <linux/err.h> 193ce8859eSGuenter Roeck #include <linux/module.h> 203ce8859eSGuenter Roeck #include <linux/spi/spi.h> 213ce8859eSGuenter Roeck #include <linux/i2c.h> 223ce8859eSGuenter Roeck #include <linux/delay.h> 233ce8859eSGuenter Roeck #include <linux/pm_runtime.h> 2468c97b92SJavier Martinez Canillas #include <linux/of_device.h> 253ce8859eSGuenter Roeck #include <linux/of.h> 263ce8859eSGuenter Roeck #include <linux/platform_data/sc18is602.h> 27f9900801SPhil Reid #include <linux/gpio/consumer.h> 283ce8859eSGuenter Roeck 293ce8859eSGuenter Roeck enum chips { sc18is602, sc18is602b, sc18is603 }; 303ce8859eSGuenter Roeck 313ce8859eSGuenter Roeck #define SC18IS602_BUFSIZ 200 323ce8859eSGuenter Roeck #define SC18IS602_CLOCK 7372000 333ce8859eSGuenter Roeck 343ce8859eSGuenter Roeck #define SC18IS602_MODE_CPHA BIT(2) 353ce8859eSGuenter Roeck #define SC18IS602_MODE_CPOL BIT(3) 363ce8859eSGuenter Roeck #define SC18IS602_MODE_LSB_FIRST BIT(5) 373ce8859eSGuenter Roeck #define SC18IS602_MODE_CLOCK_DIV_4 0x0 383ce8859eSGuenter Roeck #define SC18IS602_MODE_CLOCK_DIV_16 0x1 393ce8859eSGuenter Roeck #define SC18IS602_MODE_CLOCK_DIV_64 0x2 403ce8859eSGuenter Roeck #define SC18IS602_MODE_CLOCK_DIV_128 0x3 413ce8859eSGuenter Roeck 423ce8859eSGuenter Roeck struct sc18is602 { 433ce8859eSGuenter Roeck struct spi_master *master; 443ce8859eSGuenter Roeck struct device *dev; 453ce8859eSGuenter Roeck u8 ctrl; 463ce8859eSGuenter Roeck u32 freq; 473ce8859eSGuenter Roeck u32 speed; 483ce8859eSGuenter Roeck 493ce8859eSGuenter Roeck /* I2C data */ 503ce8859eSGuenter Roeck struct i2c_client *client; 513ce8859eSGuenter Roeck enum chips id; 523ce8859eSGuenter Roeck u8 buffer[SC18IS602_BUFSIZ + 1]; 533ce8859eSGuenter Roeck int tlen; /* Data queued for tx in buffer */ 543ce8859eSGuenter Roeck int rindex; /* Receive data index in buffer */ 55f9900801SPhil Reid 56f9900801SPhil Reid struct gpio_desc *reset; 573ce8859eSGuenter Roeck }; 583ce8859eSGuenter Roeck 593ce8859eSGuenter Roeck static int sc18is602_wait_ready(struct sc18is602 *hw, int len) 603ce8859eSGuenter Roeck { 613ce8859eSGuenter Roeck int i, err; 623ce8859eSGuenter Roeck int usecs = 1000000 * len / hw->speed + 1; 633ce8859eSGuenter Roeck u8 dummy[1]; 643ce8859eSGuenter Roeck 653ce8859eSGuenter Roeck for (i = 0; i < 10; i++) { 663ce8859eSGuenter Roeck err = i2c_master_recv(hw->client, dummy, 1); 673ce8859eSGuenter Roeck if (err >= 0) 683ce8859eSGuenter Roeck return 0; 693ce8859eSGuenter Roeck usleep_range(usecs, usecs * 2); 703ce8859eSGuenter Roeck } 713ce8859eSGuenter Roeck return -ETIMEDOUT; 723ce8859eSGuenter Roeck } 733ce8859eSGuenter Roeck 743ce8859eSGuenter Roeck static int sc18is602_txrx(struct sc18is602 *hw, struct spi_message *msg, 753ce8859eSGuenter Roeck struct spi_transfer *t, bool do_transfer) 763ce8859eSGuenter Roeck { 773ce8859eSGuenter Roeck unsigned int len = t->len; 783ce8859eSGuenter Roeck int ret; 793ce8859eSGuenter Roeck 803ce8859eSGuenter Roeck if (hw->tlen == 0) { 813ce8859eSGuenter Roeck /* First byte (I2C command) is chip select */ 823ce8859eSGuenter Roeck hw->buffer[0] = 1 << msg->spi->chip_select; 833ce8859eSGuenter Roeck hw->tlen = 1; 843ce8859eSGuenter Roeck hw->rindex = 0; 853ce8859eSGuenter Roeck } 863ce8859eSGuenter Roeck /* 873ce8859eSGuenter Roeck * We can not immediately send data to the chip, since each I2C message 883ce8859eSGuenter Roeck * resembles a full SPI message (from CS active to CS inactive). 893ce8859eSGuenter Roeck * Enqueue messages up to the first read or until do_transfer is true. 903ce8859eSGuenter Roeck */ 913ce8859eSGuenter Roeck if (t->tx_buf) { 923ce8859eSGuenter Roeck memcpy(&hw->buffer[hw->tlen], t->tx_buf, len); 933ce8859eSGuenter Roeck hw->tlen += len; 943ce8859eSGuenter Roeck if (t->rx_buf) 953ce8859eSGuenter Roeck do_transfer = true; 963ce8859eSGuenter Roeck else 973ce8859eSGuenter Roeck hw->rindex = hw->tlen - 1; 983ce8859eSGuenter Roeck } else if (t->rx_buf) { 993ce8859eSGuenter Roeck /* 1003ce8859eSGuenter Roeck * For receive-only transfers we still need to perform a dummy 1013ce8859eSGuenter Roeck * write to receive data from the SPI chip. 1023ce8859eSGuenter Roeck * Read data starts at the end of transmit data (minus 1 to 1033ce8859eSGuenter Roeck * account for CS). 1043ce8859eSGuenter Roeck */ 1053ce8859eSGuenter Roeck hw->rindex = hw->tlen - 1; 1063ce8859eSGuenter Roeck memset(&hw->buffer[hw->tlen], 0, len); 1073ce8859eSGuenter Roeck hw->tlen += len; 1083ce8859eSGuenter Roeck do_transfer = true; 1093ce8859eSGuenter Roeck } 1103ce8859eSGuenter Roeck 1113ce8859eSGuenter Roeck if (do_transfer && hw->tlen > 1) { 1123ce8859eSGuenter Roeck ret = sc18is602_wait_ready(hw, SC18IS602_BUFSIZ); 1133ce8859eSGuenter Roeck if (ret < 0) 1143ce8859eSGuenter Roeck return ret; 1153ce8859eSGuenter Roeck ret = i2c_master_send(hw->client, hw->buffer, hw->tlen); 1163ce8859eSGuenter Roeck if (ret < 0) 1173ce8859eSGuenter Roeck return ret; 1183ce8859eSGuenter Roeck if (ret != hw->tlen) 1193ce8859eSGuenter Roeck return -EIO; 1203ce8859eSGuenter Roeck 1213ce8859eSGuenter Roeck if (t->rx_buf) { 1223ce8859eSGuenter Roeck int rlen = hw->rindex + len; 1233ce8859eSGuenter Roeck 1243ce8859eSGuenter Roeck ret = sc18is602_wait_ready(hw, hw->tlen); 1253ce8859eSGuenter Roeck if (ret < 0) 1263ce8859eSGuenter Roeck return ret; 1273ce8859eSGuenter Roeck ret = i2c_master_recv(hw->client, hw->buffer, rlen); 1283ce8859eSGuenter Roeck if (ret < 0) 1293ce8859eSGuenter Roeck return ret; 1303ce8859eSGuenter Roeck if (ret != rlen) 1313ce8859eSGuenter Roeck return -EIO; 1323ce8859eSGuenter Roeck memcpy(t->rx_buf, &hw->buffer[hw->rindex], len); 1333ce8859eSGuenter Roeck } 1343ce8859eSGuenter Roeck hw->tlen = 0; 1353ce8859eSGuenter Roeck } 1363ce8859eSGuenter Roeck return len; 1373ce8859eSGuenter Roeck } 1383ce8859eSGuenter Roeck 1393ce8859eSGuenter Roeck static int sc18is602_setup_transfer(struct sc18is602 *hw, u32 hz, u8 mode) 1403ce8859eSGuenter Roeck { 1413ce8859eSGuenter Roeck u8 ctrl = 0; 1423ce8859eSGuenter Roeck int ret; 1433ce8859eSGuenter Roeck 1443ce8859eSGuenter Roeck if (mode & SPI_CPHA) 1453ce8859eSGuenter Roeck ctrl |= SC18IS602_MODE_CPHA; 1463ce8859eSGuenter Roeck if (mode & SPI_CPOL) 1473ce8859eSGuenter Roeck ctrl |= SC18IS602_MODE_CPOL; 1483ce8859eSGuenter Roeck if (mode & SPI_LSB_FIRST) 1493ce8859eSGuenter Roeck ctrl |= SC18IS602_MODE_LSB_FIRST; 1503ce8859eSGuenter Roeck 1513ce8859eSGuenter Roeck /* Find the closest clock speed */ 1523ce8859eSGuenter Roeck if (hz >= hw->freq / 4) { 1533ce8859eSGuenter Roeck ctrl |= SC18IS602_MODE_CLOCK_DIV_4; 1543ce8859eSGuenter Roeck hw->speed = hw->freq / 4; 1553ce8859eSGuenter Roeck } else if (hz >= hw->freq / 16) { 1563ce8859eSGuenter Roeck ctrl |= SC18IS602_MODE_CLOCK_DIV_16; 1573ce8859eSGuenter Roeck hw->speed = hw->freq / 16; 1583ce8859eSGuenter Roeck } else if (hz >= hw->freq / 64) { 1593ce8859eSGuenter Roeck ctrl |= SC18IS602_MODE_CLOCK_DIV_64; 1603ce8859eSGuenter Roeck hw->speed = hw->freq / 64; 1613ce8859eSGuenter Roeck } else { 1623ce8859eSGuenter Roeck ctrl |= SC18IS602_MODE_CLOCK_DIV_128; 1633ce8859eSGuenter Roeck hw->speed = hw->freq / 128; 1643ce8859eSGuenter Roeck } 1653ce8859eSGuenter Roeck 1663ce8859eSGuenter Roeck /* 1673ce8859eSGuenter Roeck * Don't do anything if the control value did not change. The initial 1683ce8859eSGuenter Roeck * value of 0xff for hw->ctrl ensures that the correct mode will be set 1693ce8859eSGuenter Roeck * with the first call to this function. 1703ce8859eSGuenter Roeck */ 1713ce8859eSGuenter Roeck if (ctrl == hw->ctrl) 1723ce8859eSGuenter Roeck return 0; 1733ce8859eSGuenter Roeck 1743ce8859eSGuenter Roeck ret = i2c_smbus_write_byte_data(hw->client, 0xf0, ctrl); 1753ce8859eSGuenter Roeck if (ret < 0) 1763ce8859eSGuenter Roeck return ret; 1773ce8859eSGuenter Roeck 1783ce8859eSGuenter Roeck hw->ctrl = ctrl; 1793ce8859eSGuenter Roeck 1803ce8859eSGuenter Roeck return 0; 1813ce8859eSGuenter Roeck } 1823ce8859eSGuenter Roeck 1833ce8859eSGuenter Roeck static int sc18is602_check_transfer(struct spi_device *spi, 1843ce8859eSGuenter Roeck struct spi_transfer *t, int tlen) 1853ce8859eSGuenter Roeck { 1863ce8859eSGuenter Roeck if (t && t->len + tlen > SC18IS602_BUFSIZ) 1873ce8859eSGuenter Roeck return -EINVAL; 1883ce8859eSGuenter Roeck 1893ce8859eSGuenter Roeck return 0; 1903ce8859eSGuenter Roeck } 1913ce8859eSGuenter Roeck 1923ce8859eSGuenter Roeck static int sc18is602_transfer_one(struct spi_master *master, 1933ce8859eSGuenter Roeck struct spi_message *m) 1943ce8859eSGuenter Roeck { 1953ce8859eSGuenter Roeck struct sc18is602 *hw = spi_master_get_devdata(master); 1963ce8859eSGuenter Roeck struct spi_device *spi = m->spi; 1973ce8859eSGuenter Roeck struct spi_transfer *t; 1983ce8859eSGuenter Roeck int status = 0; 1993ce8859eSGuenter Roeck 2003ce8859eSGuenter Roeck hw->tlen = 0; 2013ce8859eSGuenter Roeck list_for_each_entry(t, &m->transfers, transfer_list) { 2023ce8859eSGuenter Roeck bool do_transfer; 2033ce8859eSGuenter Roeck 2043ce8859eSGuenter Roeck status = sc18is602_check_transfer(spi, t, hw->tlen); 2053ce8859eSGuenter Roeck if (status < 0) 2063ce8859eSGuenter Roeck break; 2073ce8859eSGuenter Roeck 20809e99bcaSAxel Lin status = sc18is602_setup_transfer(hw, t->speed_hz, spi->mode); 2093ce8859eSGuenter Roeck if (status < 0) 2103ce8859eSGuenter Roeck break; 2113ce8859eSGuenter Roeck 2123ce8859eSGuenter Roeck do_transfer = t->cs_change || list_is_last(&t->transfer_list, 2133ce8859eSGuenter Roeck &m->transfers); 2143ce8859eSGuenter Roeck 2153ce8859eSGuenter Roeck if (t->len) { 2163ce8859eSGuenter Roeck status = sc18is602_txrx(hw, m, t, do_transfer); 2173ce8859eSGuenter Roeck if (status < 0) 2183ce8859eSGuenter Roeck break; 2193ce8859eSGuenter Roeck m->actual_length += status; 2203ce8859eSGuenter Roeck } 2213ce8859eSGuenter Roeck status = 0; 2223ce8859eSGuenter Roeck 2233ce8859eSGuenter Roeck if (t->delay_usecs) 2243ce8859eSGuenter Roeck udelay(t->delay_usecs); 2253ce8859eSGuenter Roeck } 2263ce8859eSGuenter Roeck m->status = status; 2273ce8859eSGuenter Roeck spi_finalize_current_message(master); 2283ce8859eSGuenter Roeck 2293ce8859eSGuenter Roeck return status; 2303ce8859eSGuenter Roeck } 2313ce8859eSGuenter Roeck 232c5c67e31SAxel Lin static int sc18is602_setup(struct spi_device *spi) 233c5c67e31SAxel Lin { 234c5c67e31SAxel Lin struct sc18is602 *hw = spi_master_get_devdata(spi->master); 235c5c67e31SAxel Lin 236c5c67e31SAxel Lin /* SC18IS602 does not support CS2 */ 237c5c67e31SAxel Lin if (hw->id == sc18is602 && spi->chip_select == 2) 238c5c67e31SAxel Lin return -ENXIO; 239c5c67e31SAxel Lin 240c5c67e31SAxel Lin return 0; 241c5c67e31SAxel Lin } 242c5c67e31SAxel Lin 2433ce8859eSGuenter Roeck static int sc18is602_probe(struct i2c_client *client, 2443ce8859eSGuenter Roeck const struct i2c_device_id *id) 2453ce8859eSGuenter Roeck { 2463ce8859eSGuenter Roeck struct device *dev = &client->dev; 2473ce8859eSGuenter Roeck struct device_node *np = dev->of_node; 2483ce8859eSGuenter Roeck struct sc18is602_platform_data *pdata = dev_get_platdata(dev); 2493ce8859eSGuenter Roeck struct sc18is602 *hw; 2503ce8859eSGuenter Roeck struct spi_master *master; 2513ce8859eSGuenter Roeck int error; 2523ce8859eSGuenter Roeck 2533ce8859eSGuenter Roeck if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | 2543ce8859eSGuenter Roeck I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) 25558ed90deSGuenter Roeck return -EINVAL; 2563ce8859eSGuenter Roeck 2573ce8859eSGuenter Roeck master = spi_alloc_master(dev, sizeof(struct sc18is602)); 2583ce8859eSGuenter Roeck if (!master) 2593ce8859eSGuenter Roeck return -ENOMEM; 2603ce8859eSGuenter Roeck 2613ce8859eSGuenter Roeck hw = spi_master_get_devdata(master); 2623ce8859eSGuenter Roeck i2c_set_clientdata(client, hw); 2633ce8859eSGuenter Roeck 264f9900801SPhil Reid /* assert reset and then release */ 265f9900801SPhil Reid hw->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); 266f9900801SPhil Reid if (IS_ERR(hw->reset)) 267f9900801SPhil Reid return PTR_ERR(hw->reset); 26876cce7e3SPhil Reid gpiod_set_value_cansleep(hw->reset, 0); 269f9900801SPhil Reid 2703ce8859eSGuenter Roeck hw->master = master; 2713ce8859eSGuenter Roeck hw->client = client; 2723ce8859eSGuenter Roeck hw->dev = dev; 2733ce8859eSGuenter Roeck hw->ctrl = 0xff; 2743ce8859eSGuenter Roeck 27568c97b92SJavier Martinez Canillas if (client->dev.of_node) 27668c97b92SJavier Martinez Canillas hw->id = (enum chips)of_device_get_match_data(&client->dev); 27768c97b92SJavier Martinez Canillas else 2783ce8859eSGuenter Roeck hw->id = id->driver_data; 2793ce8859eSGuenter Roeck 2803ce8859eSGuenter Roeck switch (hw->id) { 2813ce8859eSGuenter Roeck case sc18is602: 2823ce8859eSGuenter Roeck case sc18is602b: 2833ce8859eSGuenter Roeck master->num_chipselect = 4; 2843ce8859eSGuenter Roeck hw->freq = SC18IS602_CLOCK; 2853ce8859eSGuenter Roeck break; 2863ce8859eSGuenter Roeck case sc18is603: 2873ce8859eSGuenter Roeck master->num_chipselect = 2; 2883ce8859eSGuenter Roeck if (pdata) { 2893ce8859eSGuenter Roeck hw->freq = pdata->clock_frequency; 2903ce8859eSGuenter Roeck } else { 2913ce8859eSGuenter Roeck const __be32 *val; 2923ce8859eSGuenter Roeck int len; 2933ce8859eSGuenter Roeck 2943ce8859eSGuenter Roeck val = of_get_property(np, "clock-frequency", &len); 2953ce8859eSGuenter Roeck if (val && len >= sizeof(__be32)) 2963ce8859eSGuenter Roeck hw->freq = be32_to_cpup(val); 2973ce8859eSGuenter Roeck } 2983ce8859eSGuenter Roeck if (!hw->freq) 2993ce8859eSGuenter Roeck hw->freq = SC18IS602_CLOCK; 3003ce8859eSGuenter Roeck break; 3013ce8859eSGuenter Roeck } 302b4e27545SGuenter Roeck master->bus_num = np ? -1 : client->adapter->nr; 3033ce8859eSGuenter Roeck master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST; 304463654ceSAxel Lin master->bits_per_word_mask = SPI_BPW_MASK(8); 305c5c67e31SAxel Lin master->setup = sc18is602_setup; 3063ce8859eSGuenter Roeck master->transfer_one_message = sc18is602_transfer_one; 3073ce8859eSGuenter Roeck master->dev.of_node = np; 30809e99bcaSAxel Lin master->min_speed_hz = hw->freq / 128; 30909e99bcaSAxel Lin master->max_speed_hz = hw->freq / 4; 3103ce8859eSGuenter Roeck 31115e0964dSJingoo Han error = devm_spi_register_master(dev, master); 3123ce8859eSGuenter Roeck if (error) 3133ce8859eSGuenter Roeck goto error_reg; 3143ce8859eSGuenter Roeck 3153ce8859eSGuenter Roeck return 0; 3163ce8859eSGuenter Roeck 3173ce8859eSGuenter Roeck error_reg: 3183ce8859eSGuenter Roeck spi_master_put(master); 3193ce8859eSGuenter Roeck return error; 3203ce8859eSGuenter Roeck } 3213ce8859eSGuenter Roeck 3223ce8859eSGuenter Roeck static const struct i2c_device_id sc18is602_id[] = { 3233ce8859eSGuenter Roeck { "sc18is602", sc18is602 }, 3243ce8859eSGuenter Roeck { "sc18is602b", sc18is602b }, 3253ce8859eSGuenter Roeck { "sc18is603", sc18is603 }, 3263ce8859eSGuenter Roeck { } 3273ce8859eSGuenter Roeck }; 3283ce8859eSGuenter Roeck MODULE_DEVICE_TABLE(i2c, sc18is602_id); 3293ce8859eSGuenter Roeck 33068c97b92SJavier Martinez Canillas static const struct of_device_id sc18is602_of_match[] = { 33168c97b92SJavier Martinez Canillas { 33268c97b92SJavier Martinez Canillas .compatible = "nxp,sc18is602", 33368c97b92SJavier Martinez Canillas .data = (void *)sc18is602 33468c97b92SJavier Martinez Canillas }, 33568c97b92SJavier Martinez Canillas { 33668c97b92SJavier Martinez Canillas .compatible = "nxp,sc18is602b", 33768c97b92SJavier Martinez Canillas .data = (void *)sc18is602b 33868c97b92SJavier Martinez Canillas }, 33968c97b92SJavier Martinez Canillas { 34068c97b92SJavier Martinez Canillas .compatible = "nxp,sc18is603", 34168c97b92SJavier Martinez Canillas .data = (void *)sc18is603 34268c97b92SJavier Martinez Canillas }, 34368c97b92SJavier Martinez Canillas { }, 34468c97b92SJavier Martinez Canillas }; 34568c97b92SJavier Martinez Canillas MODULE_DEVICE_TABLE(of, sc18is602_of_match); 34668c97b92SJavier Martinez Canillas 3473ce8859eSGuenter Roeck static struct i2c_driver sc18is602_driver = { 3483ce8859eSGuenter Roeck .driver = { 3493ce8859eSGuenter Roeck .name = "sc18is602", 35068c97b92SJavier Martinez Canillas .of_match_table = of_match_ptr(sc18is602_of_match), 3513ce8859eSGuenter Roeck }, 3523ce8859eSGuenter Roeck .probe = sc18is602_probe, 3533ce8859eSGuenter Roeck .id_table = sc18is602_id, 3543ce8859eSGuenter Roeck }; 3553ce8859eSGuenter Roeck 3563ce8859eSGuenter Roeck module_i2c_driver(sc18is602_driver); 3573ce8859eSGuenter Roeck 3583ce8859eSGuenter Roeck MODULE_DESCRIPTION("SC18IC602/603 SPI Master Driver"); 3593ce8859eSGuenter Roeck MODULE_AUTHOR("Guenter Roeck"); 3603ce8859eSGuenter Roeck MODULE_LICENSE("GPL"); 361