summaryrefslogtreecommitdiff
path: root/drivers/input/misc/ad714x-spi.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2011-08-22 20:45:39 +0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-08-22 20:59:20 +0400
commitc0409feb86893f5ccf73964c7b2b47ca64bdb014 (patch)
treecb889f2e239a6261e8b657979b932b32bae579da /drivers/input/misc/ad714x-spi.c
parent6337de2204be3b7b40825a1d30de30e514e8947b (diff)
downloadlinux-c0409feb86893f5ccf73964c7b2b47ca64bdb014.tar.xz
Input: ad714x - use DMA-safe buffers for spi_write()
spi_write() requires use of DMA-safe (cacheline aligned) buffers. Also use the same buffers when reading data since to avoid extra locking and potential memory allocation in spi_write_then_read(). Acked-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/misc/ad714x-spi.c')
-rw-r--r--drivers/input/misc/ad714x-spi.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c
index 0c7f9488f5cb..306577dc0b98 100644
--- a/drivers/input/misc/ad714x-spi.c
+++ b/drivers/input/misc/ad714x-spi.c
@@ -30,31 +30,54 @@ static int ad714x_spi_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
-static int ad714x_spi_read(struct device *dev,
+static int ad714x_spi_read(struct ad714x_chip *chip,
unsigned short reg, unsigned short *data)
{
- struct spi_device *spi = to_spi_device(dev);
- unsigned short tx = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
+ struct spi_device *spi = to_spi_device(chip->dev);
+ struct spi_message message;
+ struct spi_transfer xfer[2];
+ int error;
+
+ spi_message_init(&message);
+ memset(xfer, 0, sizeof(xfer));
+
+ chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
AD714x_SPI_READ | reg);
- int ret;
+ xfer[0].tx_buf = &chip->xfer_buf[0];
+ xfer[0].len = sizeof(chip->xfer_buf[0]);
+ spi_message_add_tail(&xfer[0], &message);
- ret = spi_write_then_read(spi, &tx, 2, data, 2);
+ xfer[1].rx_buf = &chip->xfer_buf[1];
+ xfer[1].len = sizeof(chip->xfer_buf[1]);
+ spi_message_add_tail(&xfer[1], &message);
- *data = be16_to_cpup(data);
+ error = spi_sync(spi, &message);
+ if (unlikely(error)) {
+ dev_err(chip->dev, "SPI read error: %d\n", error);
+ return error;
+ }
- return ret;
+ *data = be16_to_cpu(chip->xfer_buf[1]);
+ return 0;
}
-static int ad714x_spi_write(struct device *dev,
+static int ad714x_spi_write(struct ad714x_chip *chip,
unsigned short reg, unsigned short data)
{
- struct spi_device *spi = to_spi_device(dev);
- unsigned short tx[2] = {
- cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg),
- cpu_to_be16(data)
- };
+ struct spi_device *spi = to_spi_device(chip->dev);
+ int error;
- return spi_write(spi, (u8 *)tx, 4);
+ chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg);
+ chip->xfer_buf[1] = cpu_to_be16(data);
+
+ error = spi_write(spi, (u8 *)chip->xfer_buf,
+ 2 * sizeof(*chip->xfer_buf));
+ if (unlikely(error)) {
+ dev_err(chip->dev, "SPI write error: %d\n", error);
+ return error;
+ }
+
+ return 0;
}
static int __devinit ad714x_spi_probe(struct spi_device *spi)