Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging:iio:adc: Add AD7791 driver

This patch adds support for the Analog Devices AD7787, AD7788, AD7789, AD7790
and AD7791 Sigma Delta Analog-to-Digital converters.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Lars-Peter Clausen and committed by
Jonathan Cameron
7b123c85 bf832380

+490
+12
drivers/iio/adc/Kconfig
··· 18 18 Say yes here to build support for Analog Devices AD7265 and AD7266 19 19 ADCs. 20 20 21 + config AD7791 22 + tristate "Analog Devices AD7791 ADC driver" 23 + depends on SPI 24 + select AD_SIGMA_DELTA 25 + help 26 + Say yes here to build support for Analog Devices AD7787, AD7788, AD7789, 27 + AD7790 and AD7791 SPI analog to digital converters (ADC). If unsure, say 28 + N (but it is safe to say "Y"). 29 + 30 + To compile this driver as a module, choose M here: the module will be 31 + called ad7791. 32 + 21 33 config AT91_ADC 22 34 tristate "Atmel AT91 ADC" 23 35 depends on ARCH_AT91
+1
drivers/iio/adc/Makefile
··· 4 4 5 5 obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o 6 6 obj-$(CONFIG_AD7266) += ad7266.o 7 + obj-$(CONFIG_AD7791) += ad7791.o 7 8 obj-$(CONFIG_AT91_ADC) += at91_adc.o
+460
drivers/iio/adc/ad7791.c
··· 1 + /* 2 + * AD7787/AD7788/AD7789/AD7790/AD7791 SPI ADC driver 3 + * 4 + * Copyright 2012 Analog Devices Inc. 5 + * Author: Lars-Peter Clausen <lars@metafoo.de> 6 + * 7 + * Licensed under the GPL-2. 8 + */ 9 + 10 + #include <linux/interrupt.h> 11 + #include <linux/device.h> 12 + #include <linux/kernel.h> 13 + #include <linux/slab.h> 14 + #include <linux/sysfs.h> 15 + #include <linux/spi/spi.h> 16 + #include <linux/regulator/consumer.h> 17 + #include <linux/err.h> 18 + #include <linux/sched.h> 19 + #include <linux/delay.h> 20 + #include <linux/module.h> 21 + 22 + #include <linux/iio/iio.h> 23 + #include <linux/iio/sysfs.h> 24 + #include <linux/iio/buffer.h> 25 + #include <linux/iio/trigger.h> 26 + #include <linux/iio/trigger_consumer.h> 27 + #include <linux/iio/triggered_buffer.h> 28 + #include <linux/iio/adc/ad_sigma_delta.h> 29 + 30 + #include <linux/platform_data/ad7791.h> 31 + 32 + #define AD7791_REG_COMM 0x0 /* For writes */ 33 + #define AD7791_REG_STATUS 0x0 /* For reads */ 34 + #define AD7791_REG_MODE 0x1 35 + #define AD7791_REG_FILTER 0x2 36 + #define AD7791_REG_DATA 0x3 37 + 38 + #define AD7791_MODE_CONTINUOUS 0x00 39 + #define AD7791_MODE_SINGLE 0x02 40 + #define AD7791_MODE_POWERDOWN 0x03 41 + 42 + #define AD7791_CH_AIN1P_AIN1N 0x00 43 + #define AD7791_CH_AIN2 0x01 44 + #define AD7791_CH_AIN1N_AIN1N 0x02 45 + #define AD7791_CH_AVDD_MONITOR 0x03 46 + 47 + #define AD7791_FILTER_CLK_DIV_1 (0x0 << 4) 48 + #define AD7791_FILTER_CLK_DIV_2 (0x1 << 4) 49 + #define AD7791_FILTER_CLK_DIV_4 (0x2 << 4) 50 + #define AD7791_FILTER_CLK_DIV_8 (0x3 << 4) 51 + #define AD7791_FILTER_CLK_MASK (0x3 << 4) 52 + #define AD7791_FILTER_RATE_120 0x0 53 + #define AD7791_FILTER_RATE_100 0x1 54 + #define AD7791_FILTER_RATE_33_3 0x2 55 + #define AD7791_FILTER_RATE_20 0x3 56 + #define AD7791_FILTER_RATE_16_6 0x4 57 + #define AD7791_FILTER_RATE_16_7 0x5 58 + #define AD7791_FILTER_RATE_13_3 0x6 59 + #define AD7791_FILTER_RATE_9_5 0x7 60 + #define AD7791_FILTER_RATE_MASK 0x7 61 + 62 + #define AD7791_MODE_BUFFER BIT(1) 63 + #define AD7791_MODE_UNIPOLAR BIT(2) 64 + #define AD7791_MODE_BURNOUT BIT(3) 65 + #define AD7791_MODE_SEL_MASK (0x3 << 6) 66 + #define AD7791_MODE_SEL(x) ((x) << 6) 67 + 68 + #define DECLARE_AD7787_CHANNELS(name, bits, storagebits) \ 69 + const struct iio_chan_spec name[] = { \ 70 + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \ 71 + (bits), (storagebits), 0), \ 72 + AD_SD_CHANNEL(1, 1, AD7791_CH_AIN2, (bits), (storagebits), 0), \ 73 + AD_SD_SHORTED_CHANNEL(2, 0, AD7791_CH_AIN1N_AIN1N, \ 74 + (bits), (storagebits), 0), \ 75 + AD_SD_SUPPLY_CHANNEL(3, 2, AD7791_CH_AVDD_MONITOR, \ 76 + (bits), (storagebits), 0), \ 77 + IIO_CHAN_SOFT_TIMESTAMP(4), \ 78 + } 79 + 80 + #define DECLARE_AD7791_CHANNELS(name, bits, storagebits) \ 81 + const struct iio_chan_spec name[] = { \ 82 + AD_SD_DIFF_CHANNEL(0, 0, 0, AD7791_CH_AIN1P_AIN1N, \ 83 + (bits), (storagebits), 0), \ 84 + AD_SD_SHORTED_CHANNEL(1, 0, AD7791_CH_AIN1N_AIN1N, \ 85 + (bits), (storagebits), 0), \ 86 + AD_SD_SUPPLY_CHANNEL(2, 1, AD7791_CH_AVDD_MONITOR, \ 87 + (bits), (storagebits), 0), \ 88 + IIO_CHAN_SOFT_TIMESTAMP(3), \ 89 + } 90 + 91 + static DECLARE_AD7787_CHANNELS(ad7787_channels, 24, 32); 92 + static DECLARE_AD7791_CHANNELS(ad7790_channels, 16, 16); 93 + static DECLARE_AD7791_CHANNELS(ad7791_channels, 24, 32); 94 + 95 + enum { 96 + AD7787, 97 + AD7788, 98 + AD7789, 99 + AD7790, 100 + AD7791, 101 + }; 102 + 103 + enum ad7791_chip_info_flags { 104 + AD7791_FLAG_HAS_FILTER = (1 << 0), 105 + AD7791_FLAG_HAS_BUFFER = (1 << 1), 106 + AD7791_FLAG_HAS_UNIPOLAR = (1 << 2), 107 + AD7791_FLAG_HAS_BURNOUT = (1 << 3), 108 + }; 109 + 110 + struct ad7791_chip_info { 111 + const struct iio_chan_spec *channels; 112 + unsigned int num_channels; 113 + enum ad7791_chip_info_flags flags; 114 + }; 115 + 116 + static const struct ad7791_chip_info ad7791_chip_infos[] = { 117 + [AD7787] = { 118 + .channels = ad7787_channels, 119 + .num_channels = ARRAY_SIZE(ad7787_channels), 120 + .flags = AD7791_FLAG_HAS_FILTER | AD7791_FLAG_HAS_BUFFER | 121 + AD7791_FLAG_HAS_UNIPOLAR | AD7791_FLAG_HAS_BURNOUT, 122 + }, 123 + [AD7788] = { 124 + .channels = ad7790_channels, 125 + .num_channels = ARRAY_SIZE(ad7790_channels), 126 + .flags = AD7791_FLAG_HAS_UNIPOLAR, 127 + }, 128 + [AD7789] = { 129 + .channels = ad7791_channels, 130 + .num_channels = ARRAY_SIZE(ad7791_channels), 131 + .flags = AD7791_FLAG_HAS_UNIPOLAR, 132 + }, 133 + [AD7790] = { 134 + .channels = ad7790_channels, 135 + .num_channels = ARRAY_SIZE(ad7790_channels), 136 + .flags = AD7791_FLAG_HAS_FILTER | AD7791_FLAG_HAS_BUFFER | 137 + AD7791_FLAG_HAS_BURNOUT, 138 + }, 139 + [AD7791] = { 140 + .channels = ad7791_channels, 141 + .num_channels = ARRAY_SIZE(ad7791_channels), 142 + .flags = AD7791_FLAG_HAS_FILTER | AD7791_FLAG_HAS_BUFFER | 143 + AD7791_FLAG_HAS_UNIPOLAR | AD7791_FLAG_HAS_BURNOUT, 144 + }, 145 + }; 146 + 147 + struct ad7791_state { 148 + struct ad_sigma_delta sd; 149 + uint8_t mode; 150 + uint8_t filter; 151 + 152 + struct regulator *reg; 153 + const struct ad7791_chip_info *info; 154 + }; 155 + 156 + static struct ad7791_state *ad_sigma_delta_to_ad7791(struct ad_sigma_delta *sd) 157 + { 158 + return container_of(sd, struct ad7791_state, sd); 159 + } 160 + 161 + static int ad7791_set_channel(struct ad_sigma_delta *sd, unsigned int channel) 162 + { 163 + ad_sd_set_comm(sd, channel); 164 + 165 + return 0; 166 + } 167 + 168 + static int ad7791_set_mode(struct ad_sigma_delta *sd, 169 + enum ad_sigma_delta_mode mode) 170 + { 171 + struct ad7791_state *st = ad_sigma_delta_to_ad7791(sd); 172 + 173 + switch (mode) { 174 + case AD_SD_MODE_CONTINUOUS: 175 + mode = AD7791_MODE_CONTINUOUS; 176 + break; 177 + case AD_SD_MODE_SINGLE: 178 + mode = AD7791_MODE_SINGLE; 179 + break; 180 + case AD_SD_MODE_IDLE: 181 + case AD_SD_MODE_POWERDOWN: 182 + mode = AD7791_MODE_POWERDOWN; 183 + break; 184 + } 185 + 186 + st->mode &= ~AD7791_MODE_SEL_MASK; 187 + st->mode |= AD7791_MODE_SEL(mode); 188 + 189 + return ad_sd_write_reg(sd, AD7791_REG_MODE, sizeof(st->mode), st->mode); 190 + } 191 + 192 + static const struct ad_sigma_delta_info ad7791_sigma_delta_info = { 193 + .set_channel = ad7791_set_channel, 194 + .set_mode = ad7791_set_mode, 195 + .has_registers = true, 196 + .addr_shift = 4, 197 + .read_mask = BIT(3), 198 + }; 199 + 200 + static int ad7791_read_raw(struct iio_dev *indio_dev, 201 + const struct iio_chan_spec *chan, int *val, int *val2, long info) 202 + { 203 + struct ad7791_state *st = iio_priv(indio_dev); 204 + bool unipolar = !!(st->mode & AD7791_MODE_UNIPOLAR); 205 + unsigned long long scale_pv; 206 + 207 + switch (info) { 208 + case IIO_CHAN_INFO_RAW: 209 + return ad_sigma_delta_single_conversion(indio_dev, chan, val); 210 + case IIO_CHAN_INFO_OFFSET: 211 + /** 212 + * Unipolar: 0 to VREF 213 + * Bipolar -VREF to VREF 214 + **/ 215 + if (unipolar) 216 + *val = 0; 217 + else 218 + *val = -(1 << (chan->scan_type.realbits - 1)); 219 + return IIO_VAL_INT; 220 + case IIO_CHAN_INFO_SCALE: 221 + /* The monitor channel uses an internal reference. */ 222 + if (chan->address == AD7791_CH_AVDD_MONITOR) { 223 + scale_pv = 5850000000000ULL; 224 + } else { 225 + int voltage_uv; 226 + 227 + voltage_uv = regulator_get_voltage(st->reg); 228 + if (voltage_uv < 0) 229 + return voltage_uv; 230 + scale_pv = (unsigned long long)voltage_uv * 1000000; 231 + } 232 + if (unipolar) 233 + scale_pv >>= chan->scan_type.realbits; 234 + else 235 + scale_pv >>= chan->scan_type.realbits - 1; 236 + *val2 = do_div(scale_pv, 1000000000); 237 + *val = scale_pv; 238 + 239 + return IIO_VAL_INT_PLUS_NANO; 240 + } 241 + 242 + return -EINVAL; 243 + } 244 + 245 + static const char * const ad7791_sample_freq_avail[] = { 246 + [AD7791_FILTER_RATE_120] = "120", 247 + [AD7791_FILTER_RATE_100] = "100", 248 + [AD7791_FILTER_RATE_33_3] = "33.3", 249 + [AD7791_FILTER_RATE_20] = "20", 250 + [AD7791_FILTER_RATE_16_6] = "16.6", 251 + [AD7791_FILTER_RATE_16_7] = "16.7", 252 + [AD7791_FILTER_RATE_13_3] = "13.3", 253 + [AD7791_FILTER_RATE_9_5] = "9.5", 254 + }; 255 + 256 + static ssize_t ad7791_read_frequency(struct device *dev, 257 + struct device_attribute *attr, char *buf) 258 + { 259 + struct iio_dev *indio_dev = dev_to_iio_dev(dev); 260 + struct ad7791_state *st = iio_priv(indio_dev); 261 + unsigned int rate = st->filter & AD7791_FILTER_RATE_MASK; 262 + 263 + return sprintf(buf, "%s\n", ad7791_sample_freq_avail[rate]); 264 + } 265 + 266 + static ssize_t ad7791_write_frequency(struct device *dev, 267 + struct device_attribute *attr, const char *buf, size_t len) 268 + { 269 + struct iio_dev *indio_dev = dev_to_iio_dev(dev); 270 + struct ad7791_state *st = iio_priv(indio_dev); 271 + int i, ret; 272 + 273 + mutex_lock(&indio_dev->mlock); 274 + if (iio_buffer_enabled(indio_dev)) { 275 + mutex_unlock(&indio_dev->mlock); 276 + return -EBUSY; 277 + } 278 + mutex_unlock(&indio_dev->mlock); 279 + 280 + ret = -EINVAL; 281 + 282 + for (i = 0; i < ARRAY_SIZE(ad7791_sample_freq_avail); i++) { 283 + if (sysfs_streq(ad7791_sample_freq_avail[i], buf)) { 284 + 285 + mutex_lock(&indio_dev->mlock); 286 + st->filter &= ~AD7791_FILTER_RATE_MASK; 287 + st->filter |= i; 288 + ad_sd_write_reg(&st->sd, AD7791_REG_FILTER, 289 + sizeof(st->filter), st->filter); 290 + mutex_unlock(&indio_dev->mlock); 291 + ret = 0; 292 + break; 293 + } 294 + } 295 + 296 + return ret ? ret : len; 297 + } 298 + 299 + static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, 300 + ad7791_read_frequency, 301 + ad7791_write_frequency); 302 + 303 + static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("120 100 33.3 20 16.7 16.6 13.3 9.5"); 304 + 305 + static struct attribute *ad7791_attributes[] = { 306 + &iio_dev_attr_sampling_frequency.dev_attr.attr, 307 + &iio_const_attr_sampling_frequency_available.dev_attr.attr, 308 + NULL 309 + }; 310 + 311 + static const struct attribute_group ad7791_attribute_group = { 312 + .attrs = ad7791_attributes, 313 + }; 314 + 315 + static const struct iio_info ad7791_info = { 316 + .read_raw = &ad7791_read_raw, 317 + .attrs = &ad7791_attribute_group, 318 + .validate_trigger = ad_sd_validate_trigger, 319 + .driver_module = THIS_MODULE, 320 + }; 321 + 322 + static const struct iio_info ad7791_no_filter_info = { 323 + .read_raw = &ad7791_read_raw, 324 + .validate_trigger = ad_sd_validate_trigger, 325 + .driver_module = THIS_MODULE, 326 + }; 327 + 328 + static int __devinit ad7791_setup(struct ad7791_state *st, 329 + struct ad7791_platform_data *pdata) 330 + { 331 + /* Set to poweron-reset default values */ 332 + st->mode = AD7791_MODE_BUFFER; 333 + st->filter = AD7791_FILTER_RATE_16_6; 334 + 335 + if (!pdata) 336 + return 0; 337 + 338 + if ((st->info->flags & AD7791_FLAG_HAS_BUFFER) && !pdata->buffered) 339 + st->mode &= ~AD7791_MODE_BUFFER; 340 + 341 + if ((st->info->flags & AD7791_FLAG_HAS_BURNOUT) && 342 + pdata->burnout_current) 343 + st->mode |= AD7791_MODE_BURNOUT; 344 + 345 + if ((st->info->flags & AD7791_FLAG_HAS_UNIPOLAR) && pdata->unipolar) 346 + st->mode |= AD7791_MODE_UNIPOLAR; 347 + 348 + return ad_sd_write_reg(&st->sd, AD7791_REG_MODE, sizeof(st->mode), 349 + st->mode); 350 + } 351 + 352 + static int __devinit ad7791_probe(struct spi_device *spi) 353 + { 354 + struct ad7791_platform_data *pdata = spi->dev.platform_data; 355 + struct iio_dev *indio_dev; 356 + struct ad7791_state *st; 357 + int ret; 358 + 359 + if (!spi->irq) { 360 + dev_err(&spi->dev, "Missing IRQ.\n"); 361 + return -ENXIO; 362 + } 363 + 364 + indio_dev = iio_device_alloc(sizeof(*st)); 365 + if (!indio_dev) 366 + return -ENOMEM; 367 + 368 + st = iio_priv(indio_dev); 369 + 370 + st->reg = regulator_get(&spi->dev, "refin"); 371 + if (IS_ERR(st->reg)) { 372 + ret = PTR_ERR(st->reg); 373 + goto err_iio_free; 374 + } 375 + 376 + ret = regulator_enable(st->reg); 377 + if (ret) 378 + goto error_put_reg; 379 + 380 + st->info = &ad7791_chip_infos[spi_get_device_id(spi)->driver_data]; 381 + ad_sd_init(&st->sd, indio_dev, spi, &ad7791_sigma_delta_info); 382 + 383 + spi_set_drvdata(spi, indio_dev); 384 + 385 + indio_dev->dev.parent = &spi->dev; 386 + indio_dev->name = spi_get_device_id(spi)->name; 387 + indio_dev->modes = INDIO_DIRECT_MODE; 388 + indio_dev->channels = st->info->channels; 389 + indio_dev->num_channels = st->info->num_channels; 390 + if (st->info->flags & AD7791_FLAG_HAS_FILTER) 391 + indio_dev->info = &ad7791_info; 392 + else 393 + indio_dev->info = &ad7791_no_filter_info; 394 + 395 + ret = ad_sd_setup_buffer_and_trigger(indio_dev); 396 + if (ret) 397 + goto error_disable_reg; 398 + 399 + ret = ad7791_setup(st, pdata); 400 + if (ret) 401 + goto error_remove_trigger; 402 + 403 + ret = iio_device_register(indio_dev); 404 + if (ret) 405 + goto error_remove_trigger; 406 + 407 + return 0; 408 + 409 + error_remove_trigger: 410 + ad_sd_cleanup_buffer_and_trigger(indio_dev); 411 + error_disable_reg: 412 + regulator_disable(st->reg); 413 + error_put_reg: 414 + regulator_put(st->reg); 415 + err_iio_free: 416 + iio_device_free(indio_dev); 417 + 418 + return ret; 419 + } 420 + 421 + static int __devexit ad7791_remove(struct spi_device *spi) 422 + { 423 + struct iio_dev *indio_dev = spi_get_drvdata(spi); 424 + struct ad7791_state *st = iio_priv(indio_dev); 425 + 426 + iio_device_unregister(indio_dev); 427 + ad_sd_cleanup_buffer_and_trigger(indio_dev); 428 + 429 + regulator_disable(st->reg); 430 + regulator_put(st->reg); 431 + 432 + iio_device_free(indio_dev); 433 + 434 + return 0; 435 + } 436 + 437 + static const struct spi_device_id ad7791_spi_ids[] = { 438 + { "ad7787", AD7787 }, 439 + { "ad7788", AD7788 }, 440 + { "ad7789", AD7789 }, 441 + { "ad7790", AD7790 }, 442 + { "ad7791", AD7791 }, 443 + {} 444 + }; 445 + MODULE_DEVICE_TABLE(spi, ad7791_spi_ids); 446 + 447 + static struct spi_driver ad7791_driver = { 448 + .driver = { 449 + .name = "ad7791", 450 + .owner = THIS_MODULE, 451 + }, 452 + .probe = ad7791_probe, 453 + .remove = __devexit_p(ad7791_remove), 454 + .id_table = ad7791_spi_ids, 455 + }; 456 + module_spi_driver(ad7791_driver); 457 + 458 + MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 459 + MODULE_DESCRIPTION("Analog Device AD7787/AD7788/AD7789/AD7790/AD7791 ADC driver"); 460 + MODULE_LICENSE("GPL v2");
+17
include/linux/platform_data/ad7791.h
··· 1 + #ifndef __LINUX_PLATFORM_DATA_AD7791__ 2 + #define __LINUX_PLATFORM_DATA_AD7791__ 3 + 4 + /** 5 + * struct ad7791_platform_data - AD7791 device platform data 6 + * @buffered: If set to true configure the device for buffered input mode. 7 + * @burnout_current: If set to true the 100mA burnout current is enabled. 8 + * @unipolar: If set to true sample in unipolar mode, if set to false sample in 9 + * bipolar mode. 10 + */ 11 + struct ad7791_platform_data { 12 + bool buffered; 13 + bool burnout_current; 14 + bool unipolar; 15 + }; 16 + 17 + #endif