linux/drivers/input/misc/ad714x-spi.c
<<
>>
Prefs
   1/*
   2 * AD714X CapTouch Programmable Controller driver (SPI bus)
   3 *
   4 * Copyright 2009-2011 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <linux/input.h>        /* BUS_SPI */
  10#include <linux/module.h>
  11#include <linux/spi/spi.h>
  12#include <linux/pm.h>
  13#include <linux/types.h>
  14#include "ad714x.h"
  15
  16#define AD714x_SPI_CMD_PREFIX      0xE000   /* bits 15:11 */
  17#define AD714x_SPI_READ            BIT(10)
  18
  19static int __maybe_unused ad714x_spi_suspend(struct device *dev)
  20{
  21        return ad714x_disable(spi_get_drvdata(to_spi_device(dev)));
  22}
  23
  24static int __maybe_unused ad714x_spi_resume(struct device *dev)
  25{
  26        return ad714x_enable(spi_get_drvdata(to_spi_device(dev)));
  27}
  28
  29static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
  30
  31static int ad714x_spi_read(struct ad714x_chip *chip,
  32                           unsigned short reg, unsigned short *data, size_t len)
  33{
  34        struct spi_device *spi = to_spi_device(chip->dev);
  35        struct spi_message message;
  36        struct spi_transfer xfer[2];
  37        int i;
  38        int error;
  39
  40        spi_message_init(&message);
  41        memset(xfer, 0, sizeof(xfer));
  42
  43        chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
  44                                        AD714x_SPI_READ | reg);
  45        xfer[0].tx_buf = &chip->xfer_buf[0];
  46        xfer[0].len = sizeof(chip->xfer_buf[0]);
  47        spi_message_add_tail(&xfer[0], &message);
  48
  49        xfer[1].rx_buf = &chip->xfer_buf[1];
  50        xfer[1].len = sizeof(chip->xfer_buf[1]) * len;
  51        spi_message_add_tail(&xfer[1], &message);
  52
  53        error = spi_sync(spi, &message);
  54        if (unlikely(error)) {
  55                dev_err(chip->dev, "SPI read error: %d\n", error);
  56                return error;
  57        }
  58
  59        for (i = 0; i < len; i++)
  60                data[i] = be16_to_cpu(chip->xfer_buf[i + 1]);
  61
  62        return 0;
  63}
  64
  65static int ad714x_spi_write(struct ad714x_chip *chip,
  66                            unsigned short reg, unsigned short data)
  67{
  68        struct spi_device *spi = to_spi_device(chip->dev);
  69        int error;
  70
  71        chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg);
  72        chip->xfer_buf[1] = cpu_to_be16(data);
  73
  74        error = spi_write(spi, (u8 *)chip->xfer_buf,
  75                          2 * sizeof(*chip->xfer_buf));
  76        if (unlikely(error)) {
  77                dev_err(chip->dev, "SPI write error: %d\n", error);
  78                return error;
  79        }
  80
  81        return 0;
  82}
  83
  84static int ad714x_spi_probe(struct spi_device *spi)
  85{
  86        struct ad714x_chip *chip;
  87        int err;
  88
  89        spi->bits_per_word = 8;
  90        err = spi_setup(spi);
  91        if (err < 0)
  92                return err;
  93
  94        chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq,
  95                            ad714x_spi_read, ad714x_spi_write);
  96        if (IS_ERR(chip))
  97                return PTR_ERR(chip);
  98
  99        spi_set_drvdata(spi, chip);
 100
 101        return 0;
 102}
 103
 104static struct spi_driver ad714x_spi_driver = {
 105        .driver = {
 106                .name   = "ad714x_captouch",
 107                .pm     = &ad714x_spi_pm,
 108        },
 109        .probe          = ad714x_spi_probe,
 110};
 111
 112module_spi_driver(ad714x_spi_driver);
 113
 114MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor SPI Bus Driver");
 115MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 116MODULE_LICENSE("GPL");
 117