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