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

ad7766.c (7680B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * AD7766/AD7767 SPI ADC driver
      4 *
      5 * Copyright 2016 Analog Devices Inc.
      6 */
      7
      8#include <linux/clk.h>
      9#include <linux/delay.h>
     10#include <linux/device.h>
     11#include <linux/err.h>
     12#include <linux/gpio/consumer.h>
     13#include <linux/module.h>
     14#include <linux/regulator/consumer.h>
     15#include <linux/slab.h>
     16#include <linux/spi/spi.h>
     17
     18#include <linux/iio/iio.h>
     19#include <linux/iio/buffer.h>
     20#include <linux/iio/trigger.h>
     21#include <linux/iio/trigger_consumer.h>
     22#include <linux/iio/triggered_buffer.h>
     23
     24struct ad7766_chip_info {
     25	unsigned int decimation_factor;
     26};
     27
     28enum {
     29	AD7766_SUPPLY_AVDD = 0,
     30	AD7766_SUPPLY_DVDD = 1,
     31	AD7766_SUPPLY_VREF = 2,
     32	AD7766_NUM_SUPPLIES = 3
     33};
     34
     35struct ad7766 {
     36	const struct ad7766_chip_info *chip_info;
     37	struct spi_device *spi;
     38	struct clk *mclk;
     39	struct gpio_desc *pd_gpio;
     40	struct regulator_bulk_data reg[AD7766_NUM_SUPPLIES];
     41
     42	struct iio_trigger *trig;
     43
     44	struct spi_transfer xfer;
     45	struct spi_message msg;
     46
     47	/*
     48	 * DMA (thus cache coherency maintenance) requires the
     49	 * transfer buffers to live in their own cache lines.
     50	 * Make the buffer large enough for one 24 bit sample and one 64 bit
     51	 * aligned 64 bit timestamp.
     52	 */
     53	unsigned char data[ALIGN(3, sizeof(s64)) + sizeof(s64)]
     54			____cacheline_aligned;
     55};
     56
     57/*
     58 * AD7766 and AD7767 variations are interface compatible, the main difference is
     59 * analog performance. Both parts will use the same ID.
     60 */
     61enum ad7766_device_ids {
     62	ID_AD7766,
     63	ID_AD7766_1,
     64	ID_AD7766_2,
     65};
     66
     67static irqreturn_t ad7766_trigger_handler(int irq, void *p)
     68{
     69	struct iio_poll_func *pf = p;
     70	struct iio_dev *indio_dev = pf->indio_dev;
     71	struct ad7766 *ad7766 = iio_priv(indio_dev);
     72	int ret;
     73
     74	ret = spi_sync(ad7766->spi, &ad7766->msg);
     75	if (ret < 0)
     76		goto done;
     77
     78	iio_push_to_buffers_with_timestamp(indio_dev, ad7766->data,
     79		pf->timestamp);
     80done:
     81	iio_trigger_notify_done(indio_dev->trig);
     82
     83	return IRQ_HANDLED;
     84}
     85
     86static int ad7766_preenable(struct iio_dev *indio_dev)
     87{
     88	struct ad7766 *ad7766 = iio_priv(indio_dev);
     89	int ret;
     90
     91	ret = regulator_bulk_enable(ARRAY_SIZE(ad7766->reg), ad7766->reg);
     92	if (ret < 0) {
     93		dev_err(&ad7766->spi->dev, "Failed to enable supplies: %d\n",
     94			ret);
     95		return ret;
     96	}
     97
     98	ret = clk_prepare_enable(ad7766->mclk);
     99	if (ret < 0) {
    100		dev_err(&ad7766->spi->dev, "Failed to enable MCLK: %d\n", ret);
    101		regulator_bulk_disable(ARRAY_SIZE(ad7766->reg), ad7766->reg);
    102		return ret;
    103	}
    104
    105	gpiod_set_value(ad7766->pd_gpio, 0);
    106
    107	return 0;
    108}
    109
    110static int ad7766_postdisable(struct iio_dev *indio_dev)
    111{
    112	struct ad7766 *ad7766 = iio_priv(indio_dev);
    113
    114	gpiod_set_value(ad7766->pd_gpio, 1);
    115
    116	/*
    117	 * The PD pin is synchronous to the clock, so give it some time to
    118	 * notice the change before we disable the clock.
    119	 */
    120	msleep(20);
    121
    122	clk_disable_unprepare(ad7766->mclk);
    123	regulator_bulk_disable(ARRAY_SIZE(ad7766->reg), ad7766->reg);
    124
    125	return 0;
    126}
    127
    128static int ad7766_read_raw(struct iio_dev *indio_dev,
    129	const struct iio_chan_spec *chan, int *val, int *val2, long info)
    130{
    131	struct ad7766 *ad7766 = iio_priv(indio_dev);
    132	struct regulator *vref = ad7766->reg[AD7766_SUPPLY_VREF].consumer;
    133	int scale_uv;
    134
    135	switch (info) {
    136	case IIO_CHAN_INFO_SCALE:
    137		scale_uv = regulator_get_voltage(vref);
    138		if (scale_uv < 0)
    139			return scale_uv;
    140		*val = scale_uv / 1000;
    141		*val2 = chan->scan_type.realbits;
    142		return IIO_VAL_FRACTIONAL_LOG2;
    143	case IIO_CHAN_INFO_SAMP_FREQ:
    144		*val = clk_get_rate(ad7766->mclk) /
    145			ad7766->chip_info->decimation_factor;
    146		return IIO_VAL_INT;
    147	}
    148	return -EINVAL;
    149}
    150
    151static const struct iio_chan_spec ad7766_channels[] = {
    152	{
    153		.type = IIO_VOLTAGE,
    154		.indexed = 1,
    155		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
    156		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
    157		.scan_type = {
    158			.sign = 's',
    159			.realbits = 24,
    160			.storagebits = 32,
    161			.endianness = IIO_BE,
    162		},
    163	},
    164	IIO_CHAN_SOFT_TIMESTAMP(1),
    165};
    166
    167static const struct ad7766_chip_info ad7766_chip_info[] = {
    168	[ID_AD7766] = {
    169		.decimation_factor = 8,
    170	},
    171	[ID_AD7766_1] = {
    172		.decimation_factor = 16,
    173	},
    174	[ID_AD7766_2] = {
    175		.decimation_factor = 32,
    176	},
    177};
    178
    179static const struct iio_buffer_setup_ops ad7766_buffer_setup_ops = {
    180	.preenable = &ad7766_preenable,
    181	.postdisable = &ad7766_postdisable,
    182};
    183
    184static const struct iio_info ad7766_info = {
    185	.read_raw = &ad7766_read_raw,
    186};
    187
    188static irqreturn_t ad7766_irq(int irq, void *private)
    189{
    190	iio_trigger_poll(private);
    191	return IRQ_HANDLED;
    192}
    193
    194static int ad7766_set_trigger_state(struct iio_trigger *trig, bool enable)
    195{
    196	struct ad7766 *ad7766 = iio_trigger_get_drvdata(trig);
    197
    198	if (enable)
    199		enable_irq(ad7766->spi->irq);
    200	else
    201		disable_irq(ad7766->spi->irq);
    202
    203	return 0;
    204}
    205
    206static const struct iio_trigger_ops ad7766_trigger_ops = {
    207	.set_trigger_state = ad7766_set_trigger_state,
    208	.validate_device = iio_trigger_validate_own_device,
    209};
    210
    211static int ad7766_probe(struct spi_device *spi)
    212{
    213	const struct spi_device_id *id = spi_get_device_id(spi);
    214	struct iio_dev *indio_dev;
    215	struct ad7766 *ad7766;
    216	int ret;
    217
    218	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*ad7766));
    219	if (!indio_dev)
    220		return -ENOMEM;
    221
    222	ad7766 = iio_priv(indio_dev);
    223	ad7766->chip_info = &ad7766_chip_info[id->driver_data];
    224
    225	ad7766->mclk = devm_clk_get(&spi->dev, "mclk");
    226	if (IS_ERR(ad7766->mclk))
    227		return PTR_ERR(ad7766->mclk);
    228
    229	ad7766->reg[AD7766_SUPPLY_AVDD].supply = "avdd";
    230	ad7766->reg[AD7766_SUPPLY_DVDD].supply = "dvdd";
    231	ad7766->reg[AD7766_SUPPLY_VREF].supply = "vref";
    232
    233	ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(ad7766->reg),
    234		ad7766->reg);
    235	if (ret)
    236		return ret;
    237
    238	ad7766->pd_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown",
    239		GPIOD_OUT_HIGH);
    240	if (IS_ERR(ad7766->pd_gpio))
    241		return PTR_ERR(ad7766->pd_gpio);
    242
    243	indio_dev->name = spi_get_device_id(spi)->name;
    244	indio_dev->modes = INDIO_DIRECT_MODE;
    245	indio_dev->channels = ad7766_channels;
    246	indio_dev->num_channels = ARRAY_SIZE(ad7766_channels);
    247	indio_dev->info = &ad7766_info;
    248
    249	if (spi->irq > 0) {
    250		ad7766->trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d",
    251						      indio_dev->name,
    252						      iio_device_id(indio_dev));
    253		if (!ad7766->trig)
    254			return -ENOMEM;
    255
    256		ad7766->trig->ops = &ad7766_trigger_ops;
    257		iio_trigger_set_drvdata(ad7766->trig, ad7766);
    258
    259		/*
    260		 * The device generates interrupts as long as it is powered up.
    261		 * Some platforms might not allow the option to power it down so
    262		 * don't enable the interrupt to avoid extra load on the system
    263		 */
    264		ret = devm_request_irq(&spi->dev, spi->irq, ad7766_irq,
    265				       IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN,
    266				       dev_name(&spi->dev),
    267				       ad7766->trig);
    268		if (ret < 0)
    269			return ret;
    270
    271		ret = devm_iio_trigger_register(&spi->dev, ad7766->trig);
    272		if (ret)
    273			return ret;
    274	}
    275
    276	ad7766->spi = spi;
    277
    278	/* First byte always 0 */
    279	ad7766->xfer.rx_buf = &ad7766->data[1];
    280	ad7766->xfer.len = 3;
    281
    282	spi_message_init(&ad7766->msg);
    283	spi_message_add_tail(&ad7766->xfer, &ad7766->msg);
    284
    285	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
    286		&iio_pollfunc_store_time, &ad7766_trigger_handler,
    287		&ad7766_buffer_setup_ops);
    288	if (ret)
    289		return ret;
    290
    291	return devm_iio_device_register(&spi->dev, indio_dev);
    292}
    293
    294static const struct spi_device_id ad7766_id[] = {
    295	{"ad7766", ID_AD7766},
    296	{"ad7766-1", ID_AD7766_1},
    297	{"ad7766-2", ID_AD7766_2},
    298	{"ad7767", ID_AD7766},
    299	{"ad7767-1", ID_AD7766_1},
    300	{"ad7767-2", ID_AD7766_2},
    301	{}
    302};
    303MODULE_DEVICE_TABLE(spi, ad7766_id);
    304
    305static struct spi_driver ad7766_driver = {
    306	.driver = {
    307		.name	= "ad7766",
    308	},
    309	.probe		= ad7766_probe,
    310	.id_table	= ad7766_id,
    311};
    312module_spi_driver(ad7766_driver);
    313
    314MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
    315MODULE_DESCRIPTION("Analog Devices AD7766 and AD7767 ADCs driver support");
    316MODULE_LICENSE("GPL v2");