diff options
Diffstat (limited to 'drivers/iio')
-rw-r--r-- | drivers/iio/adc/ad7793.c | 116 |
1 files changed, 102 insertions, 14 deletions
diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c index a109e686b9f7..91a5f7aa1ef1 100644 --- a/drivers/iio/adc/ad7793.c +++ b/drivers/iio/adc/ad7793.c | |||
@@ -106,6 +106,8 @@ | |||
106 | #define AD7793_ID 0xB | 106 | #define AD7793_ID 0xB |
107 | #define AD7794_ID 0xF | 107 | #define AD7794_ID 0xF |
108 | #define AD7795_ID 0xF | 108 | #define AD7795_ID 0xF |
109 | #define AD7798_ID 0x8 | ||
110 | #define AD7799_ID 0x9 | ||
109 | #define AD7793_ID_MASK 0xF | 111 | #define AD7793_ID_MASK 0xF |
110 | 112 | ||
111 | /* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */ | 113 | /* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */ |
@@ -130,10 +132,16 @@ | |||
130 | * The DOUT/RDY output must also be wired to an interrupt capable GPIO. | 132 | * The DOUT/RDY output must also be wired to an interrupt capable GPIO. |
131 | */ | 133 | */ |
132 | 134 | ||
135 | #define AD7793_FLAG_HAS_CLKSEL BIT(0) | ||
136 | #define AD7793_FLAG_HAS_REFSEL BIT(1) | ||
137 | #define AD7793_FLAG_HAS_VBIAS BIT(2) | ||
138 | #define AD7793_HAS_EXITATION_CURRENT BIT(3) | ||
139 | |||
133 | struct ad7793_chip_info { | 140 | struct ad7793_chip_info { |
134 | unsigned int id; | 141 | unsigned int id; |
135 | const struct iio_chan_spec *channels; | 142 | const struct iio_chan_spec *channels; |
136 | unsigned int num_channels; | 143 | unsigned int num_channels; |
144 | unsigned int flags; | ||
137 | }; | 145 | }; |
138 | 146 | ||
139 | struct ad7793_state { | 147 | struct ad7793_state { |
@@ -154,6 +162,8 @@ enum ad7793_supported_device_ids { | |||
154 | ID_AD7793, | 162 | ID_AD7793, |
155 | ID_AD7794, | 163 | ID_AD7794, |
156 | ID_AD7795, | 164 | ID_AD7795, |
165 | ID_AD7798, | ||
166 | ID_AD7799, | ||
157 | }; | 167 | }; |
158 | 168 | ||
159 | static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd) | 169 | static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd) |
@@ -205,6 +215,34 @@ static int ad7793_calibrate_all(struct ad7793_state *st) | |||
205 | ARRAY_SIZE(ad7793_calib_arr)); | 215 | ARRAY_SIZE(ad7793_calib_arr)); |
206 | } | 216 | } |
207 | 217 | ||
218 | static int ad7793_check_platform_data(struct ad7793_state *st, | ||
219 | const struct ad7793_platform_data *pdata) | ||
220 | { | ||
221 | if ((pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT1 || | ||
222 | pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT2) && | ||
223 | ((pdata->exitation_current != AD7793_IX_10uA) && | ||
224 | (pdata->exitation_current != AD7793_IX_210uA))) | ||
225 | return -EINVAL; | ||
226 | |||
227 | if (!(st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL) && | ||
228 | pdata->clock_src != AD7793_CLK_SRC_INT) | ||
229 | return -EINVAL; | ||
230 | |||
231 | if (!(st->chip_info->flags & AD7793_FLAG_HAS_REFSEL) && | ||
232 | pdata->refsel != AD7793_REFSEL_REFIN1) | ||
233 | return -EINVAL; | ||
234 | |||
235 | if (!(st->chip_info->flags & AD7793_FLAG_HAS_VBIAS) && | ||
236 | pdata->bias_voltage != AD7793_BIAS_VOLTAGE_DISABLED) | ||
237 | return -EINVAL; | ||
238 | |||
239 | if (!(st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) && | ||
240 | pdata->exitation_current != AD7793_IX_DISABLED) | ||
241 | return -EINVAL; | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
208 | static int ad7793_setup(struct iio_dev *indio_dev, | 246 | static int ad7793_setup(struct iio_dev *indio_dev, |
209 | const struct ad7793_platform_data *pdata, | 247 | const struct ad7793_platform_data *pdata, |
210 | unsigned int vref_mv) | 248 | unsigned int vref_mv) |
@@ -214,11 +252,9 @@ static int ad7793_setup(struct iio_dev *indio_dev, | |||
214 | unsigned long long scale_uv; | 252 | unsigned long long scale_uv; |
215 | u32 id; | 253 | u32 id; |
216 | 254 | ||
217 | if ((pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT1 || | 255 | ret = ad7793_check_platform_data(st, pdata); |
218 | pdata->current_source_direction == AD7793_IEXEC1_IEXEC2_IOUT2) && | 256 | if (ret) |
219 | ((pdata->exitation_current != AD7793_IX_10uA) && | 257 | return ret; |
220 | (pdata->exitation_current != AD7793_IX_210uA))) | ||
221 | return -EINVAL; | ||
222 | 258 | ||
223 | /* reset the serial interface */ | 259 | /* reset the serial interface */ |
224 | ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret)); | 260 | ret = spi_write(st->sd.spi, (u8 *)&ret, sizeof(ret)); |
@@ -239,12 +275,18 @@ static int ad7793_setup(struct iio_dev *indio_dev, | |||
239 | } | 275 | } |
240 | 276 | ||
241 | st->mode = AD7793_MODE_RATE(1); | 277 | st->mode = AD7793_MODE_RATE(1); |
242 | st->mode |= AD7793_MODE_CLKSRC(pdata->clock_src); | 278 | st->conf = 0; |
243 | st->conf = AD7793_CONF_REFSEL(pdata->refsel); | 279 | |
244 | st->conf |= AD7793_CONF_VBIAS(pdata->bias_voltage); | 280 | if (st->chip_info->flags & AD7793_FLAG_HAS_CLKSEL) |
281 | st->mode |= AD7793_MODE_CLKSRC(pdata->clock_src); | ||
282 | if (st->chip_info->flags & AD7793_FLAG_HAS_REFSEL) | ||
283 | st->conf |= AD7793_CONF_REFSEL(pdata->refsel); | ||
284 | if (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS) | ||
285 | st->conf |= AD7793_CONF_VBIAS(pdata->bias_voltage); | ||
245 | if (pdata->buffered) | 286 | if (pdata->buffered) |
246 | st->conf |= AD7793_CONF_BUF; | 287 | st->conf |= AD7793_CONF_BUF; |
247 | if (pdata->boost_enable) | 288 | if (pdata->boost_enable && |
289 | (st->chip_info->flags & AD7793_FLAG_HAS_VBIAS)) | ||
248 | st->conf |= AD7793_CONF_BOOST; | 290 | st->conf |= AD7793_CONF_BOOST; |
249 | if (pdata->burnout_current) | 291 | if (pdata->burnout_current) |
250 | st->conf |= AD7793_CONF_BO_EN; | 292 | st->conf |= AD7793_CONF_BO_EN; |
@@ -259,11 +301,13 @@ static int ad7793_setup(struct iio_dev *indio_dev, | |||
259 | if (ret) | 301 | if (ret) |
260 | goto out; | 302 | goto out; |
261 | 303 | ||
262 | ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, 1, | 304 | if (st->chip_info->flags & AD7793_HAS_EXITATION_CURRENT) { |
263 | pdata->exitation_current | | 305 | ret = ad_sd_write_reg(&st->sd, AD7793_REG_IO, 1, |
264 | (pdata->current_source_direction << 2)); | 306 | pdata->exitation_current | |
265 | if (ret) | 307 | (pdata->current_source_direction << 2)); |
266 | goto out; | 308 | if (ret) |
309 | goto out; | ||
310 | } | ||
267 | 311 | ||
268 | ret = ad7793_calibrate_all(st); | 312 | ret = ad7793_calibrate_all(st); |
269 | if (ret) | 313 | if (ret) |
@@ -525,37 +569,79 @@ const struct iio_chan_spec _name##_channels[] = { \ | |||
525 | IIO_CHAN_SOFT_TIMESTAMP(9), \ | 569 | IIO_CHAN_SOFT_TIMESTAMP(9), \ |
526 | } | 570 | } |
527 | 571 | ||
572 | #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \ | ||
573 | const struct iio_chan_spec _name##_channels[] = { \ | ||
574 | AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ | ||
575 | AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ | ||
576 | AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ | ||
577 | AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ | ||
578 | AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ | ||
579 | IIO_CHAN_SOFT_TIMESTAMP(5), \ | ||
580 | } | ||
581 | |||
528 | static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4); | 582 | static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4); |
529 | static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0); | 583 | static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0); |
530 | static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0); | 584 | static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0); |
531 | static DECLARE_AD7795_CHANNELS(ad7794, 16, 32); | 585 | static DECLARE_AD7795_CHANNELS(ad7794, 16, 32); |
532 | static DECLARE_AD7795_CHANNELS(ad7795, 24, 32); | 586 | static DECLARE_AD7795_CHANNELS(ad7795, 24, 32); |
587 | static DECLARE_AD7799_CHANNELS(ad7798, 16, 16); | ||
588 | static DECLARE_AD7799_CHANNELS(ad7799, 24, 32); | ||
533 | 589 | ||
534 | static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | 590 | static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { |
535 | [ID_AD7785] = { | 591 | [ID_AD7785] = { |
536 | .id = AD7785_ID, | 592 | .id = AD7785_ID, |
537 | .channels = ad7785_channels, | 593 | .channels = ad7785_channels, |
538 | .num_channels = ARRAY_SIZE(ad7785_channels), | 594 | .num_channels = ARRAY_SIZE(ad7785_channels), |
595 | .flags = AD7793_FLAG_HAS_CLKSEL | | ||
596 | AD7793_FLAG_HAS_REFSEL | | ||
597 | AD7793_FLAG_HAS_VBIAS | | ||
598 | AD7793_HAS_EXITATION_CURRENT, | ||
539 | }, | 599 | }, |
540 | [ID_AD7792] = { | 600 | [ID_AD7792] = { |
541 | .id = AD7792_ID, | 601 | .id = AD7792_ID, |
542 | .channels = ad7792_channels, | 602 | .channels = ad7792_channels, |
543 | .num_channels = ARRAY_SIZE(ad7792_channels), | 603 | .num_channels = ARRAY_SIZE(ad7792_channels), |
604 | .flags = AD7793_FLAG_HAS_CLKSEL | | ||
605 | AD7793_FLAG_HAS_REFSEL | | ||
606 | AD7793_FLAG_HAS_VBIAS | | ||
607 | AD7793_HAS_EXITATION_CURRENT, | ||
544 | }, | 608 | }, |
545 | [ID_AD7793] = { | 609 | [ID_AD7793] = { |
546 | .id = AD7793_ID, | 610 | .id = AD7793_ID, |
547 | .channels = ad7793_channels, | 611 | .channels = ad7793_channels, |
548 | .num_channels = ARRAY_SIZE(ad7793_channels), | 612 | .num_channels = ARRAY_SIZE(ad7793_channels), |
613 | .flags = AD7793_FLAG_HAS_CLKSEL | | ||
614 | AD7793_FLAG_HAS_REFSEL | | ||
615 | AD7793_FLAG_HAS_VBIAS | | ||
616 | AD7793_HAS_EXITATION_CURRENT, | ||
549 | }, | 617 | }, |
550 | [ID_AD7794] = { | 618 | [ID_AD7794] = { |
551 | .id = AD7794_ID, | 619 | .id = AD7794_ID, |
552 | .channels = ad7794_channels, | 620 | .channels = ad7794_channels, |
553 | .num_channels = ARRAY_SIZE(ad7794_channels), | 621 | .num_channels = ARRAY_SIZE(ad7794_channels), |
622 | .flags = AD7793_FLAG_HAS_CLKSEL | | ||
623 | AD7793_FLAG_HAS_REFSEL | | ||
624 | AD7793_FLAG_HAS_VBIAS | | ||
625 | AD7793_HAS_EXITATION_CURRENT, | ||
554 | }, | 626 | }, |
555 | [ID_AD7795] = { | 627 | [ID_AD7795] = { |
556 | .id = AD7795_ID, | 628 | .id = AD7795_ID, |
557 | .channels = ad7795_channels, | 629 | .channels = ad7795_channels, |
558 | .num_channels = ARRAY_SIZE(ad7795_channels), | 630 | .num_channels = ARRAY_SIZE(ad7795_channels), |
631 | .flags = AD7793_FLAG_HAS_CLKSEL | | ||
632 | AD7793_FLAG_HAS_REFSEL | | ||
633 | AD7793_FLAG_HAS_VBIAS | | ||
634 | AD7793_HAS_EXITATION_CURRENT, | ||
635 | }, | ||
636 | [ID_AD7798] = { | ||
637 | .id = AD7798_ID, | ||
638 | .channels = ad7798_channels, | ||
639 | .num_channels = ARRAY_SIZE(ad7798_channels), | ||
640 | }, | ||
641 | [ID_AD7799] = { | ||
642 | .id = AD7799_ID, | ||
643 | .channels = ad7799_channels, | ||
644 | .num_channels = ARRAY_SIZE(ad7799_channels), | ||
559 | }, | 645 | }, |
560 | }; | 646 | }; |
561 | 647 | ||
@@ -671,6 +757,8 @@ static const struct spi_device_id ad7793_id[] = { | |||
671 | {"ad7793", ID_AD7793}, | 757 | {"ad7793", ID_AD7793}, |
672 | {"ad7794", ID_AD7794}, | 758 | {"ad7794", ID_AD7794}, |
673 | {"ad7795", ID_AD7795}, | 759 | {"ad7795", ID_AD7795}, |
760 | {"ad7798", ID_AD7798}, | ||
761 | {"ad7799", ID_AD7799}, | ||
674 | {} | 762 | {} |
675 | }; | 763 | }; |
676 | MODULE_DEVICE_TABLE(spi, ad7793_id); | 764 | MODULE_DEVICE_TABLE(spi, ad7793_id); |