| .. | .. |
|---|
| 12 | 12 | #include <linux/sysfs.h> |
|---|
| 13 | 13 | #include <linux/spi/spi.h> |
|---|
| 14 | 14 | #include <linux/regulator/consumer.h> |
|---|
| 15 | +#include <linux/gpio/consumer.h> |
|---|
| 15 | 16 | #include <linux/err.h> |
|---|
| 16 | 17 | #include <linux/module.h> |
|---|
| 17 | 18 | #include <linux/bitops.h> |
|---|
| 19 | +#include <linux/delay.h> |
|---|
| 18 | 20 | |
|---|
| 19 | 21 | #include <linux/iio/iio.h> |
|---|
| 20 | 22 | #include <linux/iio/sysfs.h> |
|---|
| .. | .. |
|---|
| 27 | 29 | struct ad7476_chip_info { |
|---|
| 28 | 30 | unsigned int int_vref_uv; |
|---|
| 29 | 31 | struct iio_chan_spec channel[2]; |
|---|
| 32 | + /* channels used when convst gpio is defined */ |
|---|
| 33 | + struct iio_chan_spec convst_channel[2]; |
|---|
| 30 | 34 | void (*reset)(struct ad7476_state *); |
|---|
| 31 | 35 | }; |
|---|
| 32 | 36 | |
|---|
| .. | .. |
|---|
| 34 | 38 | struct spi_device *spi; |
|---|
| 35 | 39 | const struct ad7476_chip_info *chip_info; |
|---|
| 36 | 40 | struct regulator *reg; |
|---|
| 41 | + struct gpio_desc *convst_gpio; |
|---|
| 37 | 42 | struct spi_transfer xfer; |
|---|
| 38 | 43 | struct spi_message msg; |
|---|
| 39 | 44 | /* |
|---|
| .. | .. |
|---|
| 59 | 64 | ID_ADC081S, |
|---|
| 60 | 65 | ID_ADC101S, |
|---|
| 61 | 66 | ID_ADC121S, |
|---|
| 67 | + ID_ADS7866, |
|---|
| 68 | + ID_ADS7867, |
|---|
| 69 | + ID_ADS7868, |
|---|
| 62 | 70 | }; |
|---|
| 71 | + |
|---|
| 72 | +static void ad7091_convst(struct ad7476_state *st) |
|---|
| 73 | +{ |
|---|
| 74 | + if (!st->convst_gpio) |
|---|
| 75 | + return; |
|---|
| 76 | + |
|---|
| 77 | + gpiod_set_value(st->convst_gpio, 0); |
|---|
| 78 | + udelay(1); /* CONVST pulse width: 10 ns min */ |
|---|
| 79 | + gpiod_set_value(st->convst_gpio, 1); |
|---|
| 80 | + udelay(1); /* Conversion time: 650 ns max */ |
|---|
| 81 | +} |
|---|
| 63 | 82 | |
|---|
| 64 | 83 | static irqreturn_t ad7476_trigger_handler(int irq, void *p) |
|---|
| 65 | 84 | { |
|---|
| .. | .. |
|---|
| 67 | 86 | struct iio_dev *indio_dev = pf->indio_dev; |
|---|
| 68 | 87 | struct ad7476_state *st = iio_priv(indio_dev); |
|---|
| 69 | 88 | int b_sent; |
|---|
| 89 | + |
|---|
| 90 | + ad7091_convst(st); |
|---|
| 70 | 91 | |
|---|
| 71 | 92 | b_sent = spi_sync(st->spi, &st->msg); |
|---|
| 72 | 93 | if (b_sent < 0) |
|---|
| .. | .. |
|---|
| 89 | 110 | static int ad7476_scan_direct(struct ad7476_state *st) |
|---|
| 90 | 111 | { |
|---|
| 91 | 112 | int ret; |
|---|
| 113 | + |
|---|
| 114 | + ad7091_convst(st); |
|---|
| 92 | 115 | |
|---|
| 93 | 116 | ret = spi_sync(st->spi, &st->msg); |
|---|
| 94 | 117 | if (ret) |
|---|
| .. | .. |
|---|
| 157 | 180 | #define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \ |
|---|
| 158 | 181 | BIT(IIO_CHAN_INFO_RAW)) |
|---|
| 159 | 182 | #define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0) |
|---|
| 183 | +#define AD7091R_CONVST_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), \ |
|---|
| 184 | + BIT(IIO_CHAN_INFO_RAW)) |
|---|
| 185 | +#define ADS786X_CHAN(bits) _AD7476_CHAN((bits), 12 - (bits), \ |
|---|
| 186 | + BIT(IIO_CHAN_INFO_RAW)) |
|---|
| 160 | 187 | |
|---|
| 161 | 188 | static const struct ad7476_chip_info ad7476_chip_info_tbl[] = { |
|---|
| 162 | 189 | [ID_AD7091R] = { |
|---|
| 163 | 190 | .channel[0] = AD7091R_CHAN(12), |
|---|
| 164 | 191 | .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), |
|---|
| 192 | + .convst_channel[0] = AD7091R_CONVST_CHAN(12), |
|---|
| 193 | + .convst_channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), |
|---|
| 165 | 194 | .reset = ad7091_reset, |
|---|
| 166 | 195 | }, |
|---|
| 167 | 196 | [ID_AD7276] = { |
|---|
| .. | .. |
|---|
| 209 | 238 | .channel[0] = ADC081S_CHAN(12), |
|---|
| 210 | 239 | .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), |
|---|
| 211 | 240 | }, |
|---|
| 241 | + [ID_ADS7866] = { |
|---|
| 242 | + .channel[0] = ADS786X_CHAN(12), |
|---|
| 243 | + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), |
|---|
| 244 | + }, |
|---|
| 245 | + [ID_ADS7867] = { |
|---|
| 246 | + .channel[0] = ADS786X_CHAN(10), |
|---|
| 247 | + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), |
|---|
| 248 | + }, |
|---|
| 249 | + [ID_ADS7868] = { |
|---|
| 250 | + .channel[0] = ADS786X_CHAN(8), |
|---|
| 251 | + .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1), |
|---|
| 252 | + }, |
|---|
| 212 | 253 | }; |
|---|
| 213 | 254 | |
|---|
| 214 | 255 | static const struct iio_info ad7476_info = { |
|---|
| 215 | 256 | .read_raw = &ad7476_read_raw, |
|---|
| 216 | 257 | }; |
|---|
| 258 | + |
|---|
| 259 | +static void ad7476_reg_disable(void *data) |
|---|
| 260 | +{ |
|---|
| 261 | + struct ad7476_state *st = data; |
|---|
| 262 | + |
|---|
| 263 | + regulator_disable(st->reg); |
|---|
| 264 | +} |
|---|
| 217 | 265 | |
|---|
| 218 | 266 | static int ad7476_probe(struct spi_device *spi) |
|---|
| 219 | 267 | { |
|---|
| .. | .. |
|---|
| 237 | 285 | if (ret) |
|---|
| 238 | 286 | return ret; |
|---|
| 239 | 287 | |
|---|
| 288 | + ret = devm_add_action_or_reset(&spi->dev, ad7476_reg_disable, |
|---|
| 289 | + st); |
|---|
| 290 | + if (ret) |
|---|
| 291 | + return ret; |
|---|
| 292 | + |
|---|
| 293 | + st->convst_gpio = devm_gpiod_get_optional(&spi->dev, |
|---|
| 294 | + "adi,conversion-start", |
|---|
| 295 | + GPIOD_OUT_LOW); |
|---|
| 296 | + if (IS_ERR(st->convst_gpio)) |
|---|
| 297 | + return PTR_ERR(st->convst_gpio); |
|---|
| 298 | + |
|---|
| 240 | 299 | spi_set_drvdata(spi, indio_dev); |
|---|
| 241 | 300 | |
|---|
| 242 | 301 | st->spi = spi; |
|---|
| 243 | 302 | |
|---|
| 244 | | - /* Establish that the iio_dev is a child of the spi device */ |
|---|
| 245 | | - indio_dev->dev.parent = &spi->dev; |
|---|
| 246 | | - indio_dev->dev.of_node = spi->dev.of_node; |
|---|
| 247 | 303 | indio_dev->name = spi_get_device_id(spi)->name; |
|---|
| 248 | 304 | indio_dev->modes = INDIO_DIRECT_MODE; |
|---|
| 249 | 305 | indio_dev->channels = st->chip_info->channel; |
|---|
| 250 | 306 | indio_dev->num_channels = 2; |
|---|
| 251 | 307 | indio_dev->info = &ad7476_info; |
|---|
| 308 | + |
|---|
| 309 | + if (st->convst_gpio) |
|---|
| 310 | + indio_dev->channels = st->chip_info->convst_channel; |
|---|
| 252 | 311 | /* Setup default message */ |
|---|
| 253 | 312 | |
|---|
| 254 | 313 | st->xfer.rx_buf = &st->data; |
|---|
| .. | .. |
|---|
| 257 | 316 | spi_message_init(&st->msg); |
|---|
| 258 | 317 | spi_message_add_tail(&st->xfer, &st->msg); |
|---|
| 259 | 318 | |
|---|
| 260 | | - ret = iio_triggered_buffer_setup(indio_dev, NULL, |
|---|
| 261 | | - &ad7476_trigger_handler, NULL); |
|---|
| 319 | + ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL, |
|---|
| 320 | + &ad7476_trigger_handler, NULL); |
|---|
| 262 | 321 | if (ret) |
|---|
| 263 | | - goto error_disable_reg; |
|---|
| 322 | + return ret; |
|---|
| 264 | 323 | |
|---|
| 265 | 324 | if (st->chip_info->reset) |
|---|
| 266 | 325 | st->chip_info->reset(st); |
|---|
| 267 | 326 | |
|---|
| 268 | | - ret = iio_device_register(indio_dev); |
|---|
| 269 | | - if (ret) |
|---|
| 270 | | - goto error_ring_unregister; |
|---|
| 271 | | - return 0; |
|---|
| 272 | | - |
|---|
| 273 | | -error_ring_unregister: |
|---|
| 274 | | - iio_triggered_buffer_cleanup(indio_dev); |
|---|
| 275 | | -error_disable_reg: |
|---|
| 276 | | - regulator_disable(st->reg); |
|---|
| 277 | | - |
|---|
| 278 | | - return ret; |
|---|
| 279 | | -} |
|---|
| 280 | | - |
|---|
| 281 | | -static int ad7476_remove(struct spi_device *spi) |
|---|
| 282 | | -{ |
|---|
| 283 | | - struct iio_dev *indio_dev = spi_get_drvdata(spi); |
|---|
| 284 | | - struct ad7476_state *st = iio_priv(indio_dev); |
|---|
| 285 | | - |
|---|
| 286 | | - iio_device_unregister(indio_dev); |
|---|
| 287 | | - iio_triggered_buffer_cleanup(indio_dev); |
|---|
| 288 | | - regulator_disable(st->reg); |
|---|
| 289 | | - |
|---|
| 290 | | - return 0; |
|---|
| 327 | + return devm_iio_device_register(&spi->dev, indio_dev); |
|---|
| 291 | 328 | } |
|---|
| 292 | 329 | |
|---|
| 293 | 330 | static const struct spi_device_id ad7476_id[] = { |
|---|
| 331 | + {"ad7091", ID_AD7091R}, |
|---|
| 294 | 332 | {"ad7091r", ID_AD7091R}, |
|---|
| 295 | 333 | {"ad7273", ID_AD7277}, |
|---|
| 296 | 334 | {"ad7274", ID_AD7276}, |
|---|
| .. | .. |
|---|
| 314 | 352 | {"adc081s", ID_ADC081S}, |
|---|
| 315 | 353 | {"adc101s", ID_ADC101S}, |
|---|
| 316 | 354 | {"adc121s", ID_ADC121S}, |
|---|
| 355 | + {"ads7866", ID_ADS7866}, |
|---|
| 356 | + {"ads7867", ID_ADS7867}, |
|---|
| 357 | + {"ads7868", ID_ADS7868}, |
|---|
| 317 | 358 | {} |
|---|
| 318 | 359 | }; |
|---|
| 319 | 360 | MODULE_DEVICE_TABLE(spi, ad7476_id); |
|---|
| .. | .. |
|---|
| 323 | 364 | .name = "ad7476", |
|---|
| 324 | 365 | }, |
|---|
| 325 | 366 | .probe = ad7476_probe, |
|---|
| 326 | | - .remove = ad7476_remove, |
|---|
| 327 | 367 | .id_table = ad7476_id, |
|---|
| 328 | 368 | }; |
|---|
| 329 | 369 | module_spi_driver(ad7476_driver); |
|---|
| 330 | 370 | |
|---|
| 331 | | -MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
|---|
| 371 | +MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); |
|---|
| 332 | 372 | MODULE_DESCRIPTION("Analog Devices AD7476 and similar 1-channel ADCs"); |
|---|
| 333 | 373 | MODULE_LICENSE("GPL v2"); |
|---|