linux/drivers/mfd/cros_ec_spi.c
<<
>>
Prefs
   1/*
   2 * ChromeOS EC multi-function device (SPI)
   3 *
   4 * Copyright (C) 2012 Google, Inc
   5 *
   6 * This software is licensed under the terms of the GNU General Public
   7 * License version 2, as published by the Free Software Foundation, and
   8 * may be copied, distributed, and modified under those terms.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 */
  15
  16#include <linux/delay.h>
  17#include <linux/kernel.h>
  18#include <linux/module.h>
  19#include <linux/mfd/cros_ec.h>
  20#include <linux/mfd/cros_ec_commands.h>
  21#include <linux/platform_device.h>
  22#include <linux/slab.h>
  23#include <linux/spi/spi.h>
  24
  25
  26/* The header byte, which follows the preamble */
  27#define EC_MSG_HEADER                   0xec
  28
  29/*
  30 * Number of EC preamble bytes we read at a time. Since it takes
  31 * about 400-500us for the EC to respond there is not a lot of
  32 * point in tuning this. If the EC could respond faster then
  33 * we could increase this so that might expect the preamble and
  34 * message to occur in a single transaction. However, the maximum
  35 * SPI transfer size is 256 bytes, so at 5MHz we need a response
  36 * time of perhaps <320us (200 bytes / 1600 bits).
  37 */
  38#define EC_MSG_PREAMBLE_COUNT           32
  39
  40/*
  41  * We must get a response from the EC in 5ms. This is a very long
  42  * time, but the flash write command can take 2-3ms. The EC command
  43  * processing is currently not very fast (about 500us). We could
  44  * look at speeding this up and making the flash write command a
  45  * 'slow' command, requiring a GET_STATUS wait loop, like flash
  46  * erase.
  47  */
  48#define EC_MSG_DEADLINE_MS              5
  49
  50/*
  51  * Time between raising the SPI chip select (for the end of a
  52  * transaction) and dropping it again (for the next transaction).
  53  * If we go too fast, the EC will miss the transaction. It seems
  54  * that 50us is enough with the 16MHz STM32 EC.
  55  */
  56#define EC_SPI_RECOVERY_TIME_NS (50 * 1000)
  57
  58/**
  59 * struct cros_ec_spi - information about a SPI-connected EC
  60 *
  61 * @spi: SPI device we are connected to
  62 * @last_transfer_ns: time that we last finished a transfer, or 0 if there
  63 *      if no record
  64 */
  65struct cros_ec_spi {
  66        struct spi_device *spi;
  67        s64 last_transfer_ns;
  68};
  69
  70static void debug_packet(struct device *dev, const char *name, u8 *ptr,
  71                          int len)
  72{
  73#ifdef DEBUG
  74        int i;
  75
  76        dev_dbg(dev, "%s: ", name);
  77        for (i = 0; i < len; i++)
  78                dev_cont(dev, " %02x", ptr[i]);
  79#endif
  80}
  81
  82/**
  83 * cros_ec_spi_receive_response - Receive a response from the EC.
  84 *
  85 * This function has two phases: reading the preamble bytes (since if we read
  86 * data from the EC before it is ready to send, we just get preamble) and
  87 * reading the actual message.
  88 *
  89 * The received data is placed into ec_dev->din.
  90 *
  91 * @ec_dev: ChromeOS EC device
  92 * @need_len: Number of message bytes we need to read
  93 */
  94static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
  95                                        int need_len)
  96{
  97        struct cros_ec_spi *ec_spi = ec_dev->priv;
  98        struct spi_transfer trans;
  99        struct spi_message msg;
 100        u8 *ptr, *end;
 101        int ret;
 102        unsigned long deadline;
 103        int todo;
 104
 105        /* Receive data until we see the header byte */
 106        deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS);
 107        do {
 108                memset(&trans, '\0', sizeof(trans));
 109                trans.cs_change = 1;
 110                trans.rx_buf = ptr = ec_dev->din;
 111                trans.len = EC_MSG_PREAMBLE_COUNT;
 112
 113                spi_message_init(&msg);
 114                spi_message_add_tail(&trans, &msg);
 115                ret = spi_sync(ec_spi->spi, &msg);
 116                if (ret < 0) {
 117                        dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
 118                        return ret;
 119                }
 120
 121                for (end = ptr + EC_MSG_PREAMBLE_COUNT; ptr != end; ptr++) {
 122                        if (*ptr == EC_MSG_HEADER) {
 123                                dev_dbg(ec_dev->dev, "msg found at %zd\n",
 124                                        ptr - ec_dev->din);
 125                                break;
 126                        }
 127                }
 128
 129                if (time_after(jiffies, deadline)) {
 130                        dev_warn(ec_dev->dev, "EC failed to respond in time\n");
 131                        return -ETIMEDOUT;
 132                }
 133        } while (ptr == end);
 134
 135        /*
 136         * ptr now points to the header byte. Copy any valid data to the
 137         * start of our buffer
 138         */
 139        todo = end - ++ptr;
 140        BUG_ON(todo < 0 || todo > ec_dev->din_size);
 141        todo = min(todo, need_len);
 142        memmove(ec_dev->din, ptr, todo);
 143        ptr = ec_dev->din + todo;
 144        dev_dbg(ec_dev->dev, "need %d, got %d bytes from preamble\n",
 145                 need_len, todo);
 146        need_len -= todo;
 147
 148        /* Receive data until we have it all */
 149        while (need_len > 0) {
 150                /*
 151                 * We can't support transfers larger than the SPI FIFO size
 152                 * unless we have DMA. We don't have DMA on the ISP SPI ports
 153                 * for Exynos. We need a way of asking SPI driver for
 154                 * maximum-supported transfer size.
 155                 */
 156                todo = min(need_len, 256);
 157                dev_dbg(ec_dev->dev, "loop, todo=%d, need_len=%d, ptr=%zd\n",
 158                        todo, need_len, ptr - ec_dev->din);
 159
 160                memset(&trans, '\0', sizeof(trans));
 161                trans.cs_change = 1;
 162                trans.rx_buf = ptr;
 163                trans.len = todo;
 164                spi_message_init(&msg);
 165                spi_message_add_tail(&trans, &msg);
 166
 167                /* send command to EC and read answer */
 168                BUG_ON((u8 *)trans.rx_buf - ec_dev->din + todo >
 169                                ec_dev->din_size);
 170                ret = spi_sync(ec_spi->spi, &msg);
 171                if (ret < 0) {
 172                        dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
 173                        return ret;
 174                }
 175
 176                debug_packet(ec_dev->dev, "interim", ptr, todo);
 177                ptr += todo;
 178                need_len -= todo;
 179        }
 180
 181        dev_dbg(ec_dev->dev, "loop done, ptr=%zd\n", ptr - ec_dev->din);
 182
 183        return 0;
 184}
 185
 186/**
 187 * cros_ec_command_spi_xfer - Transfer a message over SPI and receive the reply
 188 *
 189 * @ec_dev: ChromeOS EC device
 190 * @ec_msg: Message to transfer
 191 */
 192static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev,
 193                                    struct cros_ec_msg *ec_msg)
 194{
 195        struct cros_ec_spi *ec_spi = ec_dev->priv;
 196        struct spi_transfer trans;
 197        struct spi_message msg;
 198        int i, len;
 199        u8 *ptr;
 200        int sum;
 201        int ret = 0, final_ret;
 202        struct timespec ts;
 203
 204        len = cros_ec_prepare_tx(ec_dev, ec_msg);
 205        dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);
 206
 207        /* If it's too soon to do another transaction, wait */
 208        if (ec_spi->last_transfer_ns) {
 209                struct timespec ts;
 210                unsigned long delay;    /* The delay completed so far */
 211
 212                ktime_get_ts(&ts);
 213                delay = timespec_to_ns(&ts) - ec_spi->last_transfer_ns;
 214                if (delay < EC_SPI_RECOVERY_TIME_NS)
 215                        ndelay(delay);
 216        }
 217
 218        /* Transmit phase - send our message */
 219        debug_packet(ec_dev->dev, "out", ec_dev->dout, len);
 220        memset(&trans, '\0', sizeof(trans));
 221        trans.tx_buf = ec_dev->dout;
 222        trans.len = len;
 223        trans.cs_change = 1;
 224        spi_message_init(&msg);
 225        spi_message_add_tail(&trans, &msg);
 226        ret = spi_sync(ec_spi->spi, &msg);
 227
 228        /* Get the response */
 229        if (!ret) {
 230                ret = cros_ec_spi_receive_response(ec_dev,
 231                                ec_msg->in_len + EC_MSG_TX_PROTO_BYTES);
 232        } else {
 233                dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
 234        }
 235
 236        /* turn off CS */
 237        spi_message_init(&msg);
 238        final_ret = spi_sync(ec_spi->spi, &msg);
 239        ktime_get_ts(&ts);
 240        ec_spi->last_transfer_ns = timespec_to_ns(&ts);
 241        if (!ret)
 242                ret = final_ret;
 243        if (ret < 0) {
 244                dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
 245                return ret;
 246        }
 247
 248        /* check response error code */
 249        ptr = ec_dev->din;
 250        if (ptr[0]) {
 251                dev_warn(ec_dev->dev, "command 0x%02x returned an error %d\n",
 252                         ec_msg->cmd, ptr[0]);
 253                debug_packet(ec_dev->dev, "in_err", ptr, len);
 254                return -EINVAL;
 255        }
 256        len = ptr[1];
 257        sum = ptr[0] + ptr[1];
 258        if (len > ec_msg->in_len) {
 259                dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)",
 260                        len, ec_msg->in_len);
 261                return -ENOSPC;
 262        }
 263
 264        /* copy response packet payload and compute checksum */
 265        for (i = 0; i < len; i++) {
 266                sum += ptr[i + 2];
 267                if (ec_msg->in_len)
 268                        ec_msg->in_buf[i] = ptr[i + 2];
 269        }
 270        sum &= 0xff;
 271
 272        debug_packet(ec_dev->dev, "in", ptr, len + 3);
 273
 274        if (sum != ptr[len + 2]) {
 275                dev_err(ec_dev->dev,
 276                        "bad packet checksum, expected %02x, got %02x\n",
 277                        sum, ptr[len + 2]);
 278                return -EBADMSG;
 279        }
 280
 281        return 0;
 282}
 283
 284static int cros_ec_probe_spi(struct spi_device *spi)
 285{
 286        struct device *dev = &spi->dev;
 287        struct cros_ec_device *ec_dev;
 288        struct cros_ec_spi *ec_spi;
 289        int err;
 290
 291        spi->bits_per_word = 8;
 292        spi->mode = SPI_MODE_0;
 293        err = spi_setup(spi);
 294        if (err < 0)
 295                return err;
 296
 297        ec_spi = devm_kzalloc(dev, sizeof(*ec_spi), GFP_KERNEL);
 298        if (ec_spi == NULL)
 299                return -ENOMEM;
 300        ec_spi->spi = spi;
 301        ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
 302        if (!ec_dev)
 303                return -ENOMEM;
 304
 305        spi_set_drvdata(spi, ec_dev);
 306        ec_dev->name = "SPI";
 307        ec_dev->dev = dev;
 308        ec_dev->priv = ec_spi;
 309        ec_dev->irq = spi->irq;
 310        ec_dev->command_xfer = cros_ec_command_spi_xfer;
 311        ec_dev->ec_name = ec_spi->spi->modalias;
 312        ec_dev->phys_name = dev_name(&ec_spi->spi->dev);
 313        ec_dev->parent = &ec_spi->spi->dev;
 314        ec_dev->din_size = EC_MSG_BYTES + EC_MSG_PREAMBLE_COUNT;
 315        ec_dev->dout_size = EC_MSG_BYTES;
 316
 317        err = cros_ec_register(ec_dev);
 318        if (err) {
 319                dev_err(dev, "cannot register EC\n");
 320                return err;
 321        }
 322
 323        return 0;
 324}
 325
 326static int cros_ec_remove_spi(struct spi_device *spi)
 327{
 328        struct cros_ec_device *ec_dev;
 329
 330        ec_dev = spi_get_drvdata(spi);
 331        cros_ec_remove(ec_dev);
 332
 333        return 0;
 334}
 335
 336#ifdef CONFIG_PM_SLEEP
 337static int cros_ec_spi_suspend(struct device *dev)
 338{
 339        struct cros_ec_device *ec_dev = dev_get_drvdata(dev);
 340
 341        return cros_ec_suspend(ec_dev);
 342}
 343
 344static int cros_ec_spi_resume(struct device *dev)
 345{
 346        struct cros_ec_device *ec_dev = dev_get_drvdata(dev);
 347
 348        return cros_ec_resume(ec_dev);
 349}
 350#endif
 351
 352static SIMPLE_DEV_PM_OPS(cros_ec_spi_pm_ops, cros_ec_spi_suspend,
 353                         cros_ec_spi_resume);
 354
 355static const struct spi_device_id cros_ec_spi_id[] = {
 356        { "cros-ec-spi", 0 },
 357        { }
 358};
 359MODULE_DEVICE_TABLE(spi, cros_ec_spi_id);
 360
 361static struct spi_driver cros_ec_driver_spi = {
 362        .driver = {
 363                .name   = "cros-ec-spi",
 364                .owner  = THIS_MODULE,
 365                .pm     = &cros_ec_spi_pm_ops,
 366        },
 367        .probe          = cros_ec_probe_spi,
 368        .remove         = cros_ec_remove_spi,
 369        .id_table       = cros_ec_spi_id,
 370};
 371
 372module_spi_driver(cros_ec_driver_spi);
 373
 374MODULE_LICENSE("GPL");
 375MODULE_DESCRIPTION("ChromeOS EC multi function device (SPI)");
 376
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.