aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/adc/ad7793.c116
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
133struct ad7793_chip_info { 140struct 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
139struct ad7793_state { 147struct 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
159static struct ad7793_state *ad_sigma_delta_to_ad7793(struct ad_sigma_delta *sd) 169static 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
218static 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
208static int ad7793_setup(struct iio_dev *indio_dev, 246static 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) \
573const 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
528static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4); 582static DECLARE_AD7793_CHANNELS(ad7785, 20, 32, 4);
529static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0); 583static DECLARE_AD7793_CHANNELS(ad7792, 16, 32, 0);
530static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0); 584static DECLARE_AD7793_CHANNELS(ad7793, 24, 32, 0);
531static DECLARE_AD7795_CHANNELS(ad7794, 16, 32); 585static DECLARE_AD7795_CHANNELS(ad7794, 16, 32);
532static DECLARE_AD7795_CHANNELS(ad7795, 24, 32); 586static DECLARE_AD7795_CHANNELS(ad7795, 24, 32);
587static DECLARE_AD7799_CHANNELS(ad7798, 16, 16);
588static DECLARE_AD7799_CHANNELS(ad7799, 24, 32);
533 589
534static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { 590static 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};
676MODULE_DEVICE_TABLE(spi, ad7793_id); 764MODULE_DEVICE_TABLE(spi, ad7793_id);