linux/drivers/iio/adc/ti-adc084s021.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2017 Axis Communications AB
   4 *
   5 * Driver for Texas Instruments' ADC084S021 ADC chip.
   6 * Datasheets can be found here:
   7 * https://www.ti.com/lit/ds/symlink/adc084s021.pdf
   8 */
   9
  10#include <linux/err.h>
  11#include <linux/spi/spi.h>
  12#include <linux/module.h>
  13#include <linux/mod_devicetable.h>
  14#include <linux/interrupt.h>
  15#include <linux/iio/iio.h>
  16#include <linux/iio/buffer.h>
  17#include <linux/iio/triggered_buffer.h>
  18#include <linux/iio/trigger_consumer.h>
  19#include <linux/regulator/consumer.h>
  20
  21#define ADC084S021_DRIVER_NAME "adc084s021"
  22
  23struct adc084s021 {
  24        struct spi_device *spi;
  25        struct spi_message message;
  26        struct spi_transfer spi_trans;
  27        struct regulator *reg;
  28        struct mutex lock;
  29        /* Buffer used to align data */
  30        struct {
  31                __be16 channels[4];
  32                s64 ts __aligned(8);
  33        } scan;
  34        /*
  35         * DMA (thus cache coherency maintenance) requires the
  36         * transfer buffers to live in their own cache line.
  37         */
  38        u16 tx_buf[4] ____cacheline_aligned;
  39        __be16 rx_buf[5]; /* First 16-bits are trash */
  40};
  41
  42#define ADC084S021_VOLTAGE_CHANNEL(num)                  \
  43        {                                                      \
  44                .type = IIO_VOLTAGE,                                 \
  45                .channel = (num),                                    \
  46                .indexed = 1,                                        \
  47                .scan_index = (num),                                 \
  48                .scan_type = {                                       \
  49                        .sign = 'u',                                       \
  50                        .realbits = 8,                                     \
  51                        .storagebits = 16,                                 \
  52                        .shift = 4,                                        \
  53                        .endianness = IIO_BE,                              \
  54                },                                                   \
  55                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),        \
  56                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
  57        }
  58
  59static const struct iio_chan_spec adc084s021_channels[] = {
  60        ADC084S021_VOLTAGE_CHANNEL(0),
  61        ADC084S021_VOLTAGE_CHANNEL(1),
  62        ADC084S021_VOLTAGE_CHANNEL(2),
  63        ADC084S021_VOLTAGE_CHANNEL(3),
  64        IIO_CHAN_SOFT_TIMESTAMP(4),
  65};
  66
  67/**
  68 * adc084s021_adc_conversion() - Read an ADC channel and return its value.
  69 *
  70 * @adc: The ADC SPI data.
  71 * @data: Buffer for converted data.
  72 */
  73static int adc084s021_adc_conversion(struct adc084s021 *adc, __be16 *data)
  74{
  75        int n_words = (adc->spi_trans.len >> 1) - 1; /* Discard first word */
  76        int ret, i = 0;
  77
  78        /* Do the transfer */
  79        ret = spi_sync(adc->spi, &adc->message);
  80        if (ret < 0)
  81                return ret;
  82
  83        for (; i < n_words; i++)
  84                *(data + i) = adc->rx_buf[i + 1];
  85
  86        return ret;
  87}
  88
  89static int adc084s021_read_raw(struct iio_dev *indio_dev,
  90                           struct iio_chan_spec const *channel, int *val,
  91                           int *val2, long mask)
  92{
  93        struct adc084s021 *adc = iio_priv(indio_dev);
  94        int ret;
  95        __be16 be_val;
  96
  97        switch (mask) {
  98        case IIO_CHAN_INFO_RAW:
  99                ret = iio_device_claim_direct_mode(indio_dev);
 100                if (ret < 0)
 101                        return ret;
 102
 103                ret = regulator_enable(adc->reg);
 104                if (ret) {
 105                        iio_device_release_direct_mode(indio_dev);
 106                        return ret;
 107                }
 108
 109                adc->tx_buf[0] = channel->channel << 3;
 110                ret = adc084s021_adc_conversion(adc, &be_val);
 111                iio_device_release_direct_mode(indio_dev);
 112                regulator_disable(adc->reg);
 113                if (ret < 0)
 114                        return ret;
 115
 116                *val = be16_to_cpu(be_val);
 117                *val = (*val >> channel->scan_type.shift) & 0xff;
 118
 119                return IIO_VAL_INT;
 120        case IIO_CHAN_INFO_SCALE:
 121                ret = regulator_enable(adc->reg);
 122                if (ret)
 123                        return ret;
 124
 125                ret = regulator_get_voltage(adc->reg);
 126                regulator_disable(adc->reg);
 127                if (ret < 0)
 128                        return ret;
 129
 130                *val = ret / 1000;
 131
 132                return IIO_VAL_INT;
 133        default:
 134                return -EINVAL;
 135        }
 136}
 137
 138/**
 139 * adc084s021_buffer_trigger_handler() - Read ADC channels and push to buffer.
 140 *
 141 * @irq: The interrupt number (not used).
 142 * @pollfunc: Pointer to the poll func.
 143 */
 144static irqreturn_t adc084s021_buffer_trigger_handler(int irq, void *pollfunc)
 145{
 146        struct iio_poll_func *pf = pollfunc;
 147        struct iio_dev *indio_dev = pf->indio_dev;
 148        struct adc084s021 *adc = iio_priv(indio_dev);
 149
 150        mutex_lock(&adc->lock);
 151
 152        if (adc084s021_adc_conversion(adc, adc->scan.channels) < 0)
 153                dev_err(&adc->spi->dev, "Failed to read data\n");
 154
 155        iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan,
 156                                           iio_get_time_ns(indio_dev));
 157        mutex_unlock(&adc->lock);
 158        iio_trigger_notify_done(indio_dev->trig);
 159
 160        return IRQ_HANDLED;
 161}
 162
 163static int adc084s021_buffer_preenable(struct iio_dev *indio_dev)
 164{
 165        struct adc084s021 *adc = iio_priv(indio_dev);
 166        int scan_index;
 167        int i = 0;
 168
 169        for_each_set_bit(scan_index, indio_dev->active_scan_mask,
 170                         indio_dev->masklength) {
 171                const struct iio_chan_spec *channel =
 172                        &indio_dev->channels[scan_index];
 173                adc->tx_buf[i++] = channel->channel << 3;
 174        }
 175        adc->spi_trans.len = 2 + (i * sizeof(__be16)); /* Trash + channels */
 176
 177        return regulator_enable(adc->reg);
 178}
 179
 180static int adc084s021_buffer_postdisable(struct iio_dev *indio_dev)
 181{
 182        struct adc084s021 *adc = iio_priv(indio_dev);
 183
 184        adc->spi_trans.len = 4; /* Trash + single channel */
 185
 186        return regulator_disable(adc->reg);
 187}
 188
 189static const struct iio_info adc084s021_info = {
 190        .read_raw = adc084s021_read_raw,
 191};
 192
 193static const struct iio_buffer_setup_ops adc084s021_buffer_setup_ops = {
 194        .preenable = adc084s021_buffer_preenable,
 195        .postdisable = adc084s021_buffer_postdisable,
 196};
 197
 198static int adc084s021_probe(struct spi_device *spi)
 199{
 200        struct iio_dev *indio_dev;
 201        struct adc084s021 *adc;
 202        int ret;
 203
 204        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
 205        if (!indio_dev) {
 206                dev_err(&spi->dev, "Failed to allocate IIO device\n");
 207                return -ENOMEM;
 208        }
 209
 210        adc = iio_priv(indio_dev);
 211        adc->spi = spi;
 212
 213        /* Initiate the Industrial I/O device */
 214        indio_dev->name = spi_get_device_id(spi)->name;
 215        indio_dev->modes = INDIO_DIRECT_MODE;
 216        indio_dev->info = &adc084s021_info;
 217        indio_dev->channels = adc084s021_channels;
 218        indio_dev->num_channels = ARRAY_SIZE(adc084s021_channels);
 219
 220        /* Create SPI transfer for channel reads */
 221        adc->spi_trans.tx_buf = adc->tx_buf;
 222        adc->spi_trans.rx_buf = adc->rx_buf;
 223        adc->spi_trans.len = 4; /* Trash + single channel */
 224        spi_message_init_with_transfers(&adc->message, &adc->spi_trans, 1);
 225
 226        adc->reg = devm_regulator_get(&spi->dev, "vref");
 227        if (IS_ERR(adc->reg))
 228                return PTR_ERR(adc->reg);
 229
 230        mutex_init(&adc->lock);
 231
 232        /* Setup triggered buffer with pollfunction */
 233        ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL,
 234                                            adc084s021_buffer_trigger_handler,
 235                                            &adc084s021_buffer_setup_ops);
 236        if (ret) {
 237                dev_err(&spi->dev, "Failed to setup triggered buffer\n");
 238                return ret;
 239        }
 240
 241        return devm_iio_device_register(&spi->dev, indio_dev);
 242}
 243
 244static const struct of_device_id adc084s021_of_match[] = {
 245        { .compatible = "ti,adc084s021", },
 246        {},
 247};
 248MODULE_DEVICE_TABLE(of, adc084s021_of_match);
 249
 250static const struct spi_device_id adc084s021_id[] = {
 251        { ADC084S021_DRIVER_NAME, 0},
 252        {}
 253};
 254MODULE_DEVICE_TABLE(spi, adc084s021_id);
 255
 256static struct spi_driver adc084s021_driver = {
 257        .driver = {
 258                .name = ADC084S021_DRIVER_NAME,
 259                .of_match_table = adc084s021_of_match,
 260        },
 261        .probe = adc084s021_probe,
 262        .id_table = adc084s021_id,
 263};
 264module_spi_driver(adc084s021_driver);
 265
 266MODULE_AUTHOR("MÃ¥rten Lindahl <martenli@axis.com>");
 267MODULE_DESCRIPTION("Texas Instruments ADC084S021");
 268MODULE_LICENSE("GPL v2");
 269MODULE_VERSION("1.0");
 270