linux/drivers/staging/iio/adc/ad7780.c
<<
>>
Prefs
   1/*
   2 * AD7780/AD7781 SPI ADC driver
   3 *
   4 * Copyright 2011 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2.
   7 */
   8
   9#include <linux/interrupt.h>
  10#include <linux/device.h>
  11#include <linux/kernel.h>
  12#include <linux/slab.h>
  13#include <linux/sysfs.h>
  14#include <linux/spi/spi.h>
  15#include <linux/regulator/consumer.h>
  16#include <linux/err.h>
  17#include <linux/sched.h>
  18#include <linux/gpio.h>
  19#include <linux/module.h>
  20
  21#include <linux/iio/iio.h>
  22#include <linux/iio/sysfs.h>
  23
  24#include "ad7780.h"
  25
  26#define AD7780_RDY      (1 << 7)
  27#define AD7780_FILTER   (1 << 6)
  28#define AD7780_ERR      (1 << 5)
  29#define AD7780_ID1      (1 << 4)
  30#define AD7780_ID0      (1 << 3)
  31#define AD7780_GAIN     (1 << 2)
  32#define AD7780_PAT1     (1 << 1)
  33#define AD7780_PAT0     (1 << 0)
  34
  35struct ad7780_chip_info {
  36        struct iio_chan_spec            channel;
  37};
  38
  39struct ad7780_state {
  40        struct spi_device               *spi;
  41        const struct ad7780_chip_info   *chip_info;
  42        struct regulator                *reg;
  43        struct ad7780_platform_data     *pdata;
  44        wait_queue_head_t               wq_data_avail;
  45        bool                            done;
  46        u16                             int_vref_mv;
  47        struct spi_transfer             xfer;
  48        struct spi_message              msg;
  49        /*
  50         * DMA (thus cache coherency maintenance) requires the
  51         * transfer buffers to live in their own cache lines.
  52         */
  53        unsigned int                    data ____cacheline_aligned;
  54};
  55
  56enum ad7780_supported_device_ids {
  57        ID_AD7780,
  58        ID_AD7781,
  59};
  60
  61static int ad7780_read(struct ad7780_state *st, int *val)
  62{
  63        int ret;
  64
  65        spi_bus_lock(st->spi->master);
  66
  67        enable_irq(st->spi->irq);
  68        st->done = false;
  69        gpio_set_value(st->pdata->gpio_pdrst, 1);
  70
  71        ret = wait_event_interruptible(st->wq_data_avail, st->done);
  72        disable_irq_nosync(st->spi->irq);
  73        if (ret)
  74                goto out;
  75
  76        ret = spi_sync_locked(st->spi, &st->msg);
  77        *val = be32_to_cpu(st->data);
  78out:
  79        gpio_set_value(st->pdata->gpio_pdrst, 0);
  80        spi_bus_unlock(st->spi->master);
  81
  82        return ret;
  83}
  84
  85static int ad7780_read_raw(struct iio_dev *indio_dev,
  86                           struct iio_chan_spec const *chan,
  87                           int *val,
  88                           int *val2,
  89                           long m)
  90{
  91        struct ad7780_state *st = iio_priv(indio_dev);
  92        struct iio_chan_spec channel = st->chip_info->channel;
  93        int ret, smpl = 0;
  94        unsigned long scale_uv;
  95
  96        switch (m) {
  97        case IIO_CHAN_INFO_RAW:
  98                mutex_lock(&indio_dev->mlock);
  99                ret = ad7780_read(st, &smpl);
 100                mutex_unlock(&indio_dev->mlock);
 101
 102                if (ret < 0)
 103                        return ret;
 104
 105                if ((smpl & AD7780_ERR) ||
 106                        !((smpl & AD7780_PAT0) && !(smpl & AD7780_PAT1)))
 107                        return -EIO;
 108
 109                *val = (smpl >> channel.scan_type.shift) &
 110                        ((1 << (channel.scan_type.realbits)) - 1);
 111                *val -= (1 << (channel.scan_type.realbits - 1));
 112
 113                if (!(smpl & AD7780_GAIN))
 114                        *val *= 128;
 115
 116                return IIO_VAL_INT;
 117        case IIO_CHAN_INFO_SCALE:
 118                scale_uv = (st->int_vref_mv * 100000)
 119                        >> (channel.scan_type.realbits - 1);
 120                *val =  scale_uv / 100000;
 121                *val2 = (scale_uv % 100000) * 10;
 122                return IIO_VAL_INT_PLUS_MICRO;
 123        }
 124        return -EINVAL;
 125}
 126
 127static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
 128        [ID_AD7780] = {
 129                .channel = {
 130                        .type = IIO_VOLTAGE,
 131                        .indexed = 1,
 132                        .channel = 0,
 133                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
 134                        IIO_CHAN_INFO_SCALE_SHARED_BIT |
 135                        IIO_CHAN_INFO_OFFSET_SHARED_BIT,
 136                        .scan_type = {
 137                                .sign = 'u',
 138                                .realbits = 24,
 139                                .storagebits = 32,
 140                                .shift = 8,
 141                        },
 142                },
 143        },
 144        [ID_AD7781] = {
 145                .channel = {
 146                        .type = IIO_VOLTAGE,
 147                        .indexed = 1,
 148                        .channel = 0,
 149                        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
 150                        IIO_CHAN_INFO_SCALE_SHARED_BIT |
 151                        IIO_CHAN_INFO_OFFSET_SHARED_BIT,
 152                        .scan_type = {
 153                                .sign = 'u',
 154                                .realbits = 20,
 155                                .storagebits = 32,
 156                                .shift = 12,
 157                        },
 158                },
 159        },
 160};
 161
 162/**
 163 *  Interrupt handler
 164 */
 165static irqreturn_t ad7780_interrupt(int irq, void *dev_id)
 166{
 167        struct ad7780_state *st = dev_id;
 168
 169        st->done = true;
 170        wake_up_interruptible(&st->wq_data_avail);
 171
 172        return IRQ_HANDLED;
 173};
 174
 175static const struct iio_info ad7780_info = {
 176        .read_raw = &ad7780_read_raw,
 177        .driver_module = THIS_MODULE,
 178};
 179
 180static int __devinit ad7780_probe(struct spi_device *spi)
 181{
 182        struct ad7780_platform_data *pdata = spi->dev.platform_data;
 183        struct ad7780_state *st;
 184        struct iio_dev *indio_dev;
 185        int ret, voltage_uv = 0;
 186
 187        if (!pdata) {
 188                dev_dbg(&spi->dev, "no platform data?\n");
 189                return -ENODEV;
 190        }
 191
 192        indio_dev = iio_device_alloc(sizeof(*st));
 193        if (indio_dev == NULL)
 194                return -ENOMEM;
 195
 196        st = iio_priv(indio_dev);
 197
 198        st->reg = regulator_get(&spi->dev, "vcc");
 199        if (!IS_ERR(st->reg)) {
 200                ret = regulator_enable(st->reg);
 201                if (ret)
 202                        goto error_put_reg;
 203
 204                voltage_uv = regulator_get_voltage(st->reg);
 205        }
 206
 207        st->chip_info =
 208                &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data];
 209
 210        st->pdata = pdata;
 211
 212        if (pdata && pdata->vref_mv)
 213                st->int_vref_mv = pdata->vref_mv;
 214        else if (voltage_uv)
 215                st->int_vref_mv = voltage_uv / 1000;
 216        else
 217                dev_warn(&spi->dev, "reference voltage unspecified\n");
 218
 219        spi_set_drvdata(spi, indio_dev);
 220        st->spi = spi;
 221
 222        indio_dev->dev.parent = &spi->dev;
 223        indio_dev->name = spi_get_device_id(spi)->name;
 224        indio_dev->modes = INDIO_DIRECT_MODE;
 225        indio_dev->channels = &st->chip_info->channel;
 226        indio_dev->num_channels = 1;
 227        indio_dev->info = &ad7780_info;
 228
 229        init_waitqueue_head(&st->wq_data_avail);
 230
 231        /* Setup default message */
 232
 233        st->xfer.rx_buf = &st->data;
 234        st->xfer.len = st->chip_info->channel.scan_type.storagebits / 8;
 235
 236        spi_message_init(&st->msg);
 237        spi_message_add_tail(&st->xfer, &st->msg);
 238
 239        ret = gpio_request_one(st->pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
 240                               "AD7780 /PDRST");
 241        if (ret) {
 242                dev_err(&spi->dev, "failed to request GPIO PDRST\n");
 243                goto error_disable_reg;
 244        }
 245
 246        ret = request_irq(spi->irq, ad7780_interrupt,
 247                IRQF_TRIGGER_FALLING, spi_get_device_id(spi)->name, st);
 248        if (ret)
 249                goto error_free_gpio;
 250
 251        disable_irq(spi->irq);
 252
 253        ret = iio_device_register(indio_dev);
 254        if (ret)
 255                goto error_free_irq;
 256
 257        return 0;
 258
 259error_free_irq:
 260        free_irq(spi->irq, st);
 261error_free_gpio:
 262        gpio_free(st->pdata->gpio_pdrst);
 263error_disable_reg:
 264        if (!IS_ERR(st->reg))
 265                regulator_disable(st->reg);
 266error_put_reg:
 267        if (!IS_ERR(st->reg))
 268                regulator_put(st->reg);
 269
 270        iio_device_free(indio_dev);
 271
 272        return ret;
 273}
 274
 275static int ad7780_remove(struct spi_device *spi)
 276{
 277        struct iio_dev *indio_dev = spi_get_drvdata(spi);
 278        struct ad7780_state *st = iio_priv(indio_dev);
 279
 280        iio_device_unregister(indio_dev);
 281        free_irq(spi->irq, st);
 282        gpio_free(st->pdata->gpio_pdrst);
 283        if (!IS_ERR(st->reg)) {
 284                regulator_disable(st->reg);
 285                regulator_put(st->reg);
 286        }
 287        iio_device_free(indio_dev);
 288
 289        return 0;
 290}
 291
 292static const struct spi_device_id ad7780_id[] = {
 293        {"ad7780", ID_AD7780},
 294        {"ad7781", ID_AD7781},
 295        {}
 296};
 297MODULE_DEVICE_TABLE(spi, ad7780_id);
 298
 299static struct spi_driver ad7780_driver = {
 300        .driver = {
 301                .name   = "ad7780",
 302                .owner  = THIS_MODULE,
 303        },
 304        .probe          = ad7780_probe,
 305        .remove         = __devexit_p(ad7780_remove),
 306        .id_table       = ad7780_id,
 307};
 308module_spi_driver(ad7780_driver);
 309
 310MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 311MODULE_DESCRIPTION("Analog Devices AD7780/1 ADC");
 312MODULE_LICENSE("GPL v2");
 313