cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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");