Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * AD714X CapTouch Programmable Controller driver (SPI bus)
0004  *
0005  * Copyright 2009-2011 Analog Devices Inc.
0006  */
0007 
0008 #include <linux/input.h>    /* BUS_SPI */
0009 #include <linux/module.h>
0010 #include <linux/spi/spi.h>
0011 #include <linux/pm.h>
0012 #include <linux/types.h>
0013 #include "ad714x.h"
0014 
0015 #define AD714x_SPI_CMD_PREFIX      0xE000   /* bits 15:11 */
0016 #define AD714x_SPI_READ            BIT(10)
0017 
0018 static int __maybe_unused ad714x_spi_suspend(struct device *dev)
0019 {
0020     return ad714x_disable(spi_get_drvdata(to_spi_device(dev)));
0021 }
0022 
0023 static int __maybe_unused ad714x_spi_resume(struct device *dev)
0024 {
0025     return ad714x_enable(spi_get_drvdata(to_spi_device(dev)));
0026 }
0027 
0028 static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
0029 
0030 static int ad714x_spi_read(struct ad714x_chip *chip,
0031                unsigned short reg, unsigned short *data, size_t len)
0032 {
0033     struct spi_device *spi = to_spi_device(chip->dev);
0034     struct spi_message message;
0035     struct spi_transfer xfer[2];
0036     int i;
0037     int error;
0038 
0039     spi_message_init(&message);
0040     memset(xfer, 0, sizeof(xfer));
0041 
0042     chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
0043                     AD714x_SPI_READ | reg);
0044     xfer[0].tx_buf = &chip->xfer_buf[0];
0045     xfer[0].len = sizeof(chip->xfer_buf[0]);
0046     spi_message_add_tail(&xfer[0], &message);
0047 
0048     xfer[1].rx_buf = &chip->xfer_buf[1];
0049     xfer[1].len = sizeof(chip->xfer_buf[1]) * len;
0050     spi_message_add_tail(&xfer[1], &message);
0051 
0052     error = spi_sync(spi, &message);
0053     if (unlikely(error)) {
0054         dev_err(chip->dev, "SPI read error: %d\n", error);
0055         return error;
0056     }
0057 
0058     for (i = 0; i < len; i++)
0059         data[i] = be16_to_cpu(chip->xfer_buf[i + 1]);
0060 
0061     return 0;
0062 }
0063 
0064 static int ad714x_spi_write(struct ad714x_chip *chip,
0065                 unsigned short reg, unsigned short data)
0066 {
0067     struct spi_device *spi = to_spi_device(chip->dev);
0068     int error;
0069 
0070     chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg);
0071     chip->xfer_buf[1] = cpu_to_be16(data);
0072 
0073     error = spi_write(spi, (u8 *)chip->xfer_buf,
0074               2 * sizeof(*chip->xfer_buf));
0075     if (unlikely(error)) {
0076         dev_err(chip->dev, "SPI write error: %d\n", error);
0077         return error;
0078     }
0079 
0080     return 0;
0081 }
0082 
0083 static int ad714x_spi_probe(struct spi_device *spi)
0084 {
0085     struct ad714x_chip *chip;
0086     int err;
0087 
0088     spi->bits_per_word = 8;
0089     err = spi_setup(spi);
0090     if (err < 0)
0091         return err;
0092 
0093     chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq,
0094                 ad714x_spi_read, ad714x_spi_write);
0095     if (IS_ERR(chip))
0096         return PTR_ERR(chip);
0097 
0098     spi_set_drvdata(spi, chip);
0099 
0100     return 0;
0101 }
0102 
0103 static struct spi_driver ad714x_spi_driver = {
0104     .driver = {
0105         .name   = "ad714x_captouch",
0106         .pm = &ad714x_spi_pm,
0107     },
0108     .probe      = ad714x_spi_probe,
0109 };
0110 
0111 module_spi_driver(ad714x_spi_driver);
0112 
0113 MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor SPI Bus Driver");
0114 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
0115 MODULE_LICENSE("GPL");