| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * AD7785/AD7792/AD7793/AD7794/AD7795 SPI ADC driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2011-2012 Analog Devices Inc. |
|---|
| 5 | | - * |
|---|
| 6 | | - * Licensed under the GPL-2. |
|---|
| 7 | 6 | */ |
|---|
| 8 | 7 | |
|---|
| 9 | 8 | #include <linux/interrupt.h> |
|---|
| .. | .. |
|---|
| 207 | 206 | .has_registers = true, |
|---|
| 208 | 207 | .addr_shift = 3, |
|---|
| 209 | 208 | .read_mask = BIT(6), |
|---|
| 209 | + .irq_flags = IRQF_TRIGGER_FALLING, |
|---|
| 210 | 210 | }; |
|---|
| 211 | 211 | |
|---|
| 212 | 212 | static const struct ad_sd_calib_data ad7793_calib_arr[6] = { |
|---|
| .. | .. |
|---|
| 355 | 355 | static IIO_CONST_ATTR_NAMED(sampling_frequency_available_ad7797, |
|---|
| 356 | 356 | sampling_frequency_available, "123 62 50 33 17 16 12 10 8 6 4"); |
|---|
| 357 | 357 | |
|---|
| 358 | | -static ssize_t ad7793_show_scale_available(struct device *dev, |
|---|
| 359 | | - struct device_attribute *attr, char *buf) |
|---|
| 358 | +static int ad7793_read_avail(struct iio_dev *indio_dev, |
|---|
| 359 | + struct iio_chan_spec const *chan, |
|---|
| 360 | + const int **vals, int *type, int *length, |
|---|
| 361 | + long mask) |
|---|
| 360 | 362 | { |
|---|
| 361 | | - struct iio_dev *indio_dev = dev_to_iio_dev(dev); |
|---|
| 362 | 363 | struct ad7793_state *st = iio_priv(indio_dev); |
|---|
| 363 | | - int i, len = 0; |
|---|
| 364 | 364 | |
|---|
| 365 | | - for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) |
|---|
| 366 | | - len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0], |
|---|
| 367 | | - st->scale_avail[i][1]); |
|---|
| 365 | + switch (mask) { |
|---|
| 366 | + case IIO_CHAN_INFO_SCALE: |
|---|
| 367 | + *vals = (int *)st->scale_avail; |
|---|
| 368 | + *type = IIO_VAL_INT_PLUS_NANO; |
|---|
| 369 | + /* Values are stored in a 2D matrix */ |
|---|
| 370 | + *length = ARRAY_SIZE(st->scale_avail) * 2; |
|---|
| 368 | 371 | |
|---|
| 369 | | - len += sprintf(buf + len, "\n"); |
|---|
| 370 | | - |
|---|
| 371 | | - return len; |
|---|
| 372 | + return IIO_AVAIL_LIST; |
|---|
| 373 | + default: |
|---|
| 374 | + return -EINVAL; |
|---|
| 375 | + } |
|---|
| 372 | 376 | } |
|---|
| 373 | | - |
|---|
| 374 | | -static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, |
|---|
| 375 | | - in_voltage-voltage_scale_available, S_IRUGO, |
|---|
| 376 | | - ad7793_show_scale_available, NULL, 0); |
|---|
| 377 | 377 | |
|---|
| 378 | 378 | static struct attribute *ad7793_attributes[] = { |
|---|
| 379 | 379 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, |
|---|
| 380 | | - &iio_dev_attr_in_m_in_scale_available.dev_attr.attr, |
|---|
| 381 | 380 | NULL |
|---|
| 382 | 381 | }; |
|---|
| 383 | 382 | |
|---|
| .. | .. |
|---|
| 535 | 534 | .read_raw = &ad7793_read_raw, |
|---|
| 536 | 535 | .write_raw = &ad7793_write_raw, |
|---|
| 537 | 536 | .write_raw_get_fmt = &ad7793_write_raw_get_fmt, |
|---|
| 537 | + .read_avail = ad7793_read_avail, |
|---|
| 538 | 538 | .attrs = &ad7793_attribute_group, |
|---|
| 539 | 539 | .validate_trigger = ad_sd_validate_trigger, |
|---|
| 540 | 540 | }; |
|---|
| .. | .. |
|---|
| 547 | 547 | .validate_trigger = ad_sd_validate_trigger, |
|---|
| 548 | 548 | }; |
|---|
| 549 | 549 | |
|---|
| 550 | +#define __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ |
|---|
| 551 | + _storagebits, _shift, _extend_name, _type, _mask_type_av, _mask_all) \ |
|---|
| 552 | + { \ |
|---|
| 553 | + .type = (_type), \ |
|---|
| 554 | + .differential = (_channel2 == -1 ? 0 : 1), \ |
|---|
| 555 | + .indexed = 1, \ |
|---|
| 556 | + .channel = (_channel1), \ |
|---|
| 557 | + .channel2 = (_channel2), \ |
|---|
| 558 | + .address = (_address), \ |
|---|
| 559 | + .extend_name = (_extend_name), \ |
|---|
| 560 | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
|---|
| 561 | + BIT(IIO_CHAN_INFO_OFFSET), \ |
|---|
| 562 | + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
|---|
| 563 | + .info_mask_shared_by_type_available = (_mask_type_av), \ |
|---|
| 564 | + .info_mask_shared_by_all = _mask_all, \ |
|---|
| 565 | + .scan_index = (_si), \ |
|---|
| 566 | + .scan_type = { \ |
|---|
| 567 | + .sign = 'u', \ |
|---|
| 568 | + .realbits = (_bits), \ |
|---|
| 569 | + .storagebits = (_storagebits), \ |
|---|
| 570 | + .shift = (_shift), \ |
|---|
| 571 | + .endianness = IIO_BE, \ |
|---|
| 572 | + }, \ |
|---|
| 573 | + } |
|---|
| 574 | + |
|---|
| 575 | +#define AD7793_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ |
|---|
| 576 | + _storagebits, _shift) \ |
|---|
| 577 | + __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ |
|---|
| 578 | + _storagebits, _shift, NULL, IIO_VOLTAGE, \ |
|---|
| 579 | + BIT(IIO_CHAN_INFO_SCALE), \ |
|---|
| 580 | + BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
|---|
| 581 | + |
|---|
| 582 | +#define AD7793_SHORTED_CHANNEL(_si, _channel, _address, _bits, \ |
|---|
| 583 | + _storagebits, _shift) \ |
|---|
| 584 | + __AD7793_CHANNEL(_si, _channel, _channel, _address, _bits, \ |
|---|
| 585 | + _storagebits, _shift, "shorted", IIO_VOLTAGE, \ |
|---|
| 586 | + BIT(IIO_CHAN_INFO_SCALE), \ |
|---|
| 587 | + BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
|---|
| 588 | + |
|---|
| 589 | +#define AD7793_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \ |
|---|
| 590 | + __AD7793_CHANNEL(_si, 0, -1, _address, _bits, \ |
|---|
| 591 | + _storagebits, _shift, NULL, IIO_TEMP, \ |
|---|
| 592 | + 0, \ |
|---|
| 593 | + BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
|---|
| 594 | + |
|---|
| 595 | +#define AD7793_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \ |
|---|
| 596 | + _shift) \ |
|---|
| 597 | + __AD7793_CHANNEL(_si, _channel, -1, _address, _bits, \ |
|---|
| 598 | + _storagebits, _shift, "supply", IIO_VOLTAGE, \ |
|---|
| 599 | + 0, \ |
|---|
| 600 | + BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
|---|
| 601 | + |
|---|
| 602 | +#define AD7797_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ |
|---|
| 603 | + _storagebits, _shift) \ |
|---|
| 604 | + __AD7793_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ |
|---|
| 605 | + _storagebits, _shift, NULL, IIO_VOLTAGE, \ |
|---|
| 606 | + 0, \ |
|---|
| 607 | + BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
|---|
| 608 | + |
|---|
| 609 | +#define AD7797_SHORTED_CHANNEL(_si, _channel, _address, _bits, \ |
|---|
| 610 | + _storagebits, _shift) \ |
|---|
| 611 | + __AD7793_CHANNEL(_si, _channel, _channel, _address, _bits, \ |
|---|
| 612 | + _storagebits, _shift, "shorted", IIO_VOLTAGE, \ |
|---|
| 613 | + 0, \ |
|---|
| 614 | + BIT(IIO_CHAN_INFO_SAMP_FREQ)) |
|---|
| 615 | + |
|---|
| 550 | 616 | #define DECLARE_AD7793_CHANNELS(_name, _b, _sb, _s) \ |
|---|
| 551 | 617 | const struct iio_chan_spec _name##_channels[] = { \ |
|---|
| 552 | | - AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \ |
|---|
| 553 | | - AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \ |
|---|
| 554 | | - AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \ |
|---|
| 555 | | - AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \ |
|---|
| 556 | | - AD_SD_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \ |
|---|
| 557 | | - AD_SD_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \ |
|---|
| 618 | + AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), (_s)), \ |
|---|
| 619 | + AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), (_s)), \ |
|---|
| 620 | + AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), (_s)), \ |
|---|
| 621 | + AD7793_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), (_s)), \ |
|---|
| 622 | + AD7793_TEMP_CHANNEL(4, AD7793_CH_TEMP, (_b), (_sb), (_s)), \ |
|---|
| 623 | + AD7793_SUPPLY_CHANNEL(5, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), (_s)), \ |
|---|
| 558 | 624 | IIO_CHAN_SOFT_TIMESTAMP(6), \ |
|---|
| 559 | 625 | } |
|---|
| 560 | 626 | |
|---|
| 561 | 627 | #define DECLARE_AD7795_CHANNELS(_name, _b, _sb) \ |
|---|
| 562 | 628 | const struct iio_chan_spec _name##_channels[] = { \ |
|---|
| 563 | | - AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ |
|---|
| 564 | | - AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ |
|---|
| 565 | | - AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ |
|---|
| 566 | | - AD_SD_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \ |
|---|
| 567 | | - AD_SD_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \ |
|---|
| 568 | | - AD_SD_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \ |
|---|
| 569 | | - AD_SD_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ |
|---|
| 570 | | - AD_SD_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \ |
|---|
| 571 | | - AD_SD_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ |
|---|
| 629 | + AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ |
|---|
| 630 | + AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ |
|---|
| 631 | + AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ |
|---|
| 632 | + AD7793_DIFF_CHANNEL(3, 3, 3, AD7795_CH_AIN4P_AIN4M, (_b), (_sb), 0), \ |
|---|
| 633 | + AD7793_DIFF_CHANNEL(4, 4, 4, AD7795_CH_AIN5P_AIN5M, (_b), (_sb), 0), \ |
|---|
| 634 | + AD7793_DIFF_CHANNEL(5, 5, 5, AD7795_CH_AIN6P_AIN6M, (_b), (_sb), 0), \ |
|---|
| 635 | + AD7793_SHORTED_CHANNEL(6, 0, AD7795_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ |
|---|
| 636 | + AD7793_TEMP_CHANNEL(7, AD7793_CH_TEMP, (_b), (_sb), 0), \ |
|---|
| 637 | + AD7793_SUPPLY_CHANNEL(8, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ |
|---|
| 572 | 638 | IIO_CHAN_SOFT_TIMESTAMP(9), \ |
|---|
| 573 | 639 | } |
|---|
| 574 | 640 | |
|---|
| 575 | 641 | #define DECLARE_AD7797_CHANNELS(_name, _b, _sb) \ |
|---|
| 576 | 642 | const struct iio_chan_spec _name##_channels[] = { \ |
|---|
| 577 | | - AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ |
|---|
| 578 | | - AD_SD_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ |
|---|
| 579 | | - AD_SD_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0), \ |
|---|
| 580 | | - AD_SD_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ |
|---|
| 643 | + AD7797_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ |
|---|
| 644 | + AD7797_SHORTED_CHANNEL(1, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ |
|---|
| 645 | + AD7793_TEMP_CHANNEL(2, AD7793_CH_TEMP, (_b), (_sb), 0), \ |
|---|
| 646 | + AD7793_SUPPLY_CHANNEL(3, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ |
|---|
| 581 | 647 | IIO_CHAN_SOFT_TIMESTAMP(4), \ |
|---|
| 582 | 648 | } |
|---|
| 583 | 649 | |
|---|
| 584 | 650 | #define DECLARE_AD7799_CHANNELS(_name, _b, _sb) \ |
|---|
| 585 | 651 | const struct iio_chan_spec _name##_channels[] = { \ |
|---|
| 586 | | - AD_SD_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ |
|---|
| 587 | | - AD_SD_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ |
|---|
| 588 | | - AD_SD_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ |
|---|
| 589 | | - AD_SD_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ |
|---|
| 590 | | - AD_SD_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ |
|---|
| 652 | + AD7793_DIFF_CHANNEL(0, 0, 0, AD7793_CH_AIN1P_AIN1M, (_b), (_sb), 0), \ |
|---|
| 653 | + AD7793_DIFF_CHANNEL(1, 1, 1, AD7793_CH_AIN2P_AIN2M, (_b), (_sb), 0), \ |
|---|
| 654 | + AD7793_DIFF_CHANNEL(2, 2, 2, AD7793_CH_AIN3P_AIN3M, (_b), (_sb), 0), \ |
|---|
| 655 | + AD7793_SHORTED_CHANNEL(3, 0, AD7793_CH_AIN1M_AIN1M, (_b), (_sb), 0), \ |
|---|
| 656 | + AD7793_SUPPLY_CHANNEL(4, 3, AD7793_CH_AVDD_MONITOR, (_b), (_sb), 0), \ |
|---|
| 591 | 657 | IIO_CHAN_SOFT_TIMESTAMP(5), \ |
|---|
| 592 | 658 | } |
|---|
| 593 | 659 | |
|---|
| .. | .. |
|---|
| 753 | 819 | |
|---|
| 754 | 820 | spi_set_drvdata(spi, indio_dev); |
|---|
| 755 | 821 | |
|---|
| 756 | | - indio_dev->dev.parent = &spi->dev; |
|---|
| 757 | | - indio_dev->dev.of_node = spi->dev.of_node; |
|---|
| 758 | 822 | indio_dev->name = spi_get_device_id(spi)->name; |
|---|
| 759 | 823 | indio_dev->modes = INDIO_DIRECT_MODE; |
|---|
| 760 | 824 | indio_dev->channels = st->chip_info->channels; |
|---|
| .. | .. |
|---|
| 823 | 887 | }; |
|---|
| 824 | 888 | module_spi_driver(ad7793_driver); |
|---|
| 825 | 889 | |
|---|
| 826 | | -MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
|---|
| 890 | +MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); |
|---|
| 827 | 891 | MODULE_DESCRIPTION("Analog Devices AD7793 and similar ADCs"); |
|---|
| 828 | 892 | MODULE_LICENSE("GPL v2"); |
|---|