linux/drivers/staging/iio/adc/ad7887_core.c
<<
>>
Prefs
   1/*
   2 * AD7887 SPI ADC driver
   3 *
   4 * Copyright 2010 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <linux/interrupt.h>
  10#include <linux/workqueue.h>
  11#include <linux/device.h>
  12#include <linux/kernel.h>
  13#include <linux/slab.h>
  14#include <linux/sysfs.h>
  15#include <linux/list.h>
  16#include <linux/spi/spi.h>
  17#include <linux/regulator/consumer.h>
  18#include <linux/err.h>
  19
  20#include "../iio.h"
  21#include "../sysfs.h"
  22#include "../ring_generic.h"
  23#include "adc.h"
  24
  25#include "ad7887.h"
  26
  27static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch)
  28{
  29        int ret = spi_sync(st->spi, &st->msg[ch]);
  30        if (ret)
  31                return ret;
  32
  33        return (st->data[(ch * 2)] << 8) | st->data[(ch * 2) + 1];
  34}
  35
  36static ssize_t ad7887_scan(struct device *dev,
  37                            struct device_attribute *attr,
  38                            char *buf)
  39{
  40        struct iio_dev *dev_info = dev_get_drvdata(dev);
  41        struct ad7887_state *st = dev_info->dev_data;
  42        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
  43        int ret;
  44
  45        mutex_lock(&dev_info->mlock);
  46        if (iio_ring_enabled(dev_info))
  47                ret = ad7887_scan_from_ring(st, 1 << this_attr->address);
  48        else
  49                ret = ad7887_scan_direct(st, this_attr->address);
  50        mutex_unlock(&dev_info->mlock);
  51
  52        if (ret < 0)
  53                return ret;
  54
  55        return sprintf(buf, "%d\n", (ret >> st->chip_info->left_shift) &
  56                       RES_MASK(st->chip_info->bits));
  57}
  58static IIO_DEV_ATTR_IN_RAW(0, ad7887_scan, 0);
  59static IIO_DEV_ATTR_IN_RAW(1, ad7887_scan, 1);
  60
  61static ssize_t ad7887_show_scale(struct device *dev,
  62                                struct device_attribute *attr,
  63                                char *buf)
  64{
  65        /* Driver currently only support internal vref */
  66        struct iio_dev *dev_info = dev_get_drvdata(dev);
  67        struct ad7887_state *st = iio_dev_get_devdata(dev_info);
  68        /* Corresponds to Vref / 2^(bits) */
  69        unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits;
  70
  71        return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
  72}
  73static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7887_show_scale, NULL, 0);
  74
  75static ssize_t ad7887_show_name(struct device *dev,
  76                                 struct device_attribute *attr,
  77                                 char *buf)
  78{
  79        struct iio_dev *dev_info = dev_get_drvdata(dev);
  80        struct ad7887_state *st = iio_dev_get_devdata(dev_info);
  81
  82        return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
  83}
  84static IIO_DEVICE_ATTR(name, S_IRUGO, ad7887_show_name, NULL, 0);
  85
  86static struct attribute *ad7887_attributes[] = {
  87        &iio_dev_attr_in0_raw.dev_attr.attr,
  88        &iio_dev_attr_in1_raw.dev_attr.attr,
  89        &iio_dev_attr_in_scale.dev_attr.attr,
  90        &iio_dev_attr_name.dev_attr.attr,
  91        NULL,
  92};
  93
  94static mode_t ad7887_attr_is_visible(struct kobject *kobj,
  95                                     struct attribute *attr, int n)
  96{
  97        struct device *dev = container_of(kobj, struct device, kobj);
  98        struct iio_dev *dev_info = dev_get_drvdata(dev);
  99        struct ad7887_state *st = iio_dev_get_devdata(dev_info);
 100
 101        mode_t mode = attr->mode;
 102
 103        if ((attr == &iio_dev_attr_in1_raw.dev_attr.attr) && !st->en_dual)
 104                        mode = 0;
 105
 106        return mode;
 107}
 108
 109static const struct attribute_group ad7887_attribute_group = {
 110        .attrs = ad7887_attributes,
 111        .is_visible = ad7887_attr_is_visible,
 112};
 113
 114static const struct ad7887_chip_info ad7887_chip_info_tbl[] = {
 115        /*
 116         * More devices added in future
 117         */
 118        [ID_AD7887] = {
 119                .bits = 12,
 120                .storagebits = 16,
 121                .left_shift = 0,
 122                .sign = IIO_SCAN_EL_TYPE_UNSIGNED,
 123                .int_vref_mv = 2500,
 124        },
 125};
 126
 127static int __devinit ad7887_probe(struct spi_device *spi)
 128{
 129        struct ad7887_platform_data *pdata = spi->dev.platform_data;
 130        struct ad7887_state *st;
 131        int ret, voltage_uv = 0;
 132
 133        st = kzalloc(sizeof(*st), GFP_KERNEL);
 134        if (st == NULL) {
 135                ret = -ENOMEM;
 136                goto error_ret;
 137        }
 138
 139        st->reg = regulator_get(&spi->dev, "vcc");
 140        if (!IS_ERR(st->reg)) {
 141                ret = regulator_enable(st->reg);
 142                if (ret)
 143                        goto error_put_reg;
 144
 145                voltage_uv = regulator_get_voltage(st->reg);
 146        }
 147
 148        st->chip_info =
 149                &ad7887_chip_info_tbl[spi_get_device_id(spi)->driver_data];
 150
 151        spi_set_drvdata(spi, st);
 152
 153        atomic_set(&st->protect_ring, 0);
 154        st->spi = spi;
 155
 156        st->indio_dev = iio_allocate_device();
 157        if (st->indio_dev == NULL) {
 158                ret = -ENOMEM;
 159                goto error_disable_reg;
 160        }
 161
 162        /* Estabilish that the iio_dev is a child of the spi device */
 163        st->indio_dev->dev.parent = &spi->dev;
 164        st->indio_dev->attrs = &ad7887_attribute_group;
 165        st->indio_dev->dev_data = (void *)(st);
 166        st->indio_dev->driver_module = THIS_MODULE;
 167        st->indio_dev->modes = INDIO_DIRECT_MODE;
 168
 169        /* Setup default message */
 170
 171        st->tx_cmd_buf[0] = AD7887_CH_AIN0 | AD7887_PM_MODE4 |
 172                            ((pdata && pdata->use_onchip_ref) ?
 173                            0 : AD7887_REF_DIS);
 174
 175        st->xfer[0].rx_buf = &st->data[0];
 176        st->xfer[0].tx_buf = &st->tx_cmd_buf[0];
 177        st->xfer[0].len = 2;
 178
 179        spi_message_init(&st->msg[AD7887_CH0]);
 180        spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]);
 181
 182        if (pdata && pdata->en_dual) {
 183                st->tx_cmd_buf[0] |= AD7887_DUAL | AD7887_REF_DIS;
 184
 185                st->tx_cmd_buf[2] = AD7887_CH_AIN1 | AD7887_DUAL |
 186                                    AD7887_REF_DIS | AD7887_PM_MODE4;
 187                st->tx_cmd_buf[4] = AD7887_CH_AIN0 | AD7887_DUAL |
 188                                    AD7887_REF_DIS | AD7887_PM_MODE4;
 189                st->tx_cmd_buf[6] = AD7887_CH_AIN1 | AD7887_DUAL |
 190                                    AD7887_REF_DIS | AD7887_PM_MODE4;
 191
 192                st->xfer[1].rx_buf = &st->data[0];
 193                st->xfer[1].tx_buf = &st->tx_cmd_buf[2];
 194                st->xfer[1].len = 2;
 195
 196                st->xfer[2].rx_buf = &st->data[2];
 197                st->xfer[2].tx_buf = &st->tx_cmd_buf[4];
 198                st->xfer[2].len = 2;
 199
 200                spi_message_init(&st->msg[AD7887_CH0_CH1]);
 201                spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]);
 202                spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]);
 203
 204                st->xfer[3].rx_buf = &st->data[0];
 205                st->xfer[3].tx_buf = &st->tx_cmd_buf[6];
 206                st->xfer[3].len = 2;
 207
 208                spi_message_init(&st->msg[AD7887_CH1]);
 209                spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]);
 210
 211                st->en_dual = true;
 212
 213                if (pdata && pdata->vref_mv)
 214                        st->int_vref_mv = pdata->vref_mv;
 215                else if (voltage_uv)
 216                        st->int_vref_mv = voltage_uv / 1000;
 217                else
 218                        dev_warn(&spi->dev, "reference voltage unspecified\n");
 219
 220        } else {
 221                if (pdata && pdata->vref_mv)
 222                        st->int_vref_mv = pdata->vref_mv;
 223                else if (pdata && pdata->use_onchip_ref)
 224                        st->int_vref_mv = st->chip_info->int_vref_mv;
 225                else
 226                        dev_warn(&spi->dev, "reference voltage unspecified\n");
 227        }
 228
 229
 230        ret = ad7887_register_ring_funcs_and_init(st->indio_dev);
 231        if (ret)
 232                goto error_free_device;
 233
 234        ret = iio_device_register(st->indio_dev);
 235        if (ret)
 236                goto error_free_device;
 237
 238        ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
 239        if (ret)
 240                goto error_cleanup_ring;
 241        return 0;
 242
 243error_cleanup_ring:
 244        ad7887_ring_cleanup(st->indio_dev);
 245        iio_device_unregister(st->indio_dev);
 246error_free_device:
 247        iio_free_device(st->indio_dev);
 248error_disable_reg:
 249        if (!IS_ERR(st->reg))
 250                regulator_disable(st->reg);
 251error_put_reg:
 252        if (!IS_ERR(st->reg))
 253                regulator_put(st->reg);
 254        kfree(st);
 255error_ret:
 256        return ret;
 257}
 258
 259static int ad7887_remove(struct spi_device *spi)
 260{
 261        struct ad7887_state *st = spi_get_drvdata(spi);
 262        struct iio_dev *indio_dev = st->indio_dev;
 263        iio_ring_buffer_unregister(indio_dev->ring);
 264        ad7887_ring_cleanup(indio_dev);
 265        iio_device_unregister(indio_dev);
 266        if (!IS_ERR(st->reg)) {
 267                regulator_disable(st->reg);
 268                regulator_put(st->reg);
 269        }
 270        kfree(st);
 271        return 0;
 272}
 273
 274static const struct spi_device_id ad7887_id[] = {
 275        {"ad7887", ID_AD7887},
 276        {}
 277};
 278
 279static struct spi_driver ad7887_driver = {
 280        .driver = {
 281                .name   = "ad7887",
 282                .bus    = &spi_bus_type,
 283                .owner  = THIS_MODULE,
 284        },
 285        .probe          = ad7887_probe,
 286        .remove         = __devexit_p(ad7887_remove),
 287        .id_table       = ad7887_id,
 288};
 289
 290static int __init ad7887_init(void)
 291{
 292        return spi_register_driver(&ad7887_driver);
 293}
 294module_init(ad7887_init);
 295
 296static void __exit ad7887_exit(void)
 297{
 298        spi_unregister_driver(&ad7887_driver);
 299}
 300module_exit(ad7887_exit);
 301
 302MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 303MODULE_DESCRIPTION("Analog Devices AD7887 ADC");
 304MODULE_LICENSE("GPL v2");
 305MODULE_ALIAS("spi:ad7887");
 306