.. | .. |
---|
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"); |
---|