Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: ad7124: Implement temperature measurement

If the maximal count of channels the driver supports isn't fully
utilized, add an attribute providing the internal temperature.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://patch.msgid.link/433211af8ac3f02dee58586ecb51d2e98246a095.1733504533.git.u.kleine-koenig@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Uwe Kleine-König and committed by
Jonathan Cameron
6eaf3f60 abc61acd

+91 -21
+91 -21
drivers/iio/adc/ad7124.c
··· 95 95 #define AD7124_MAX_CONFIGS 8 96 96 #define AD7124_MAX_CHANNELS 16 97 97 98 + /* AD7124 input sources */ 99 + #define AD7124_INPUT_TEMPSENSOR 16 100 + #define AD7124_INPUT_AVSS 17 101 + 98 102 enum ad7124_ids { 99 103 ID_AD7124_4, 100 104 ID_AD7124_8, ··· 593 589 594 590 return IIO_VAL_INT; 595 591 case IIO_CHAN_INFO_SCALE: 596 - mutex_lock(&st->cfgs_lock); 592 + switch (chan->type) { 593 + case IIO_VOLTAGE: 594 + mutex_lock(&st->cfgs_lock); 597 595 598 - idx = st->channels[chan->address].cfg.pga_bits; 599 - *val = st->channels[chan->address].cfg.vref_mv; 600 - if (st->channels[chan->address].cfg.bipolar) 601 - *val2 = chan->scan_type.realbits - 1 + idx; 602 - else 603 - *val2 = chan->scan_type.realbits + idx; 596 + idx = st->channels[chan->address].cfg.pga_bits; 597 + *val = st->channels[chan->address].cfg.vref_mv; 598 + if (st->channels[chan->address].cfg.bipolar) 599 + *val2 = chan->scan_type.realbits - 1 + idx; 600 + else 601 + *val2 = chan->scan_type.realbits + idx; 604 602 605 - mutex_unlock(&st->cfgs_lock); 606 - return IIO_VAL_FRACTIONAL_LOG2; 603 + mutex_unlock(&st->cfgs_lock); 604 + return IIO_VAL_FRACTIONAL_LOG2; 605 + 606 + case IIO_TEMP: 607 + /* 608 + * According to the data sheet 609 + * Temperature (°C) 610 + * = ((Conversion − 0x800000)/13584) − 272.5 611 + * = (Conversion − 0x800000 - 13584 * 272.5) / 13584 612 + * = (Conversion − 12090248) / 13584 613 + * So scale with 1000/13584 to yield °mC. Reduce by 8 to 614 + * 125/1698. 615 + */ 616 + *val = 125; 617 + *val2 = 1698; 618 + return IIO_VAL_FRACTIONAL; 619 + 620 + default: 621 + return -EINVAL; 622 + } 623 + 607 624 case IIO_CHAN_INFO_OFFSET: 608 - mutex_lock(&st->cfgs_lock); 609 - if (st->channels[chan->address].cfg.bipolar) 610 - *val = -(1 << (chan->scan_type.realbits - 1)); 611 - else 612 - *val = 0; 625 + switch (chan->type) { 626 + case IIO_VOLTAGE: 627 + mutex_lock(&st->cfgs_lock); 628 + if (st->channels[chan->address].cfg.bipolar) 629 + *val = -(1 << (chan->scan_type.realbits - 1)); 630 + else 631 + *val = 0; 613 632 614 - mutex_unlock(&st->cfgs_lock); 615 - return IIO_VAL_INT; 633 + mutex_unlock(&st->cfgs_lock); 634 + return IIO_VAL_INT; 635 + 636 + case IIO_TEMP: 637 + /* see calculation above */ 638 + *val = -12090248; 639 + return IIO_VAL_INT; 640 + 641 + default: 642 + return -EINVAL; 643 + } 644 + 616 645 case IIO_CHAN_INFO_SAMP_FREQ: 617 646 mutex_lock(&st->cfgs_lock); 618 647 *val = st->channels[chan->address].cfg.odr; ··· 863 826 struct ad7124_channel *channels; 864 827 struct iio_chan_spec *chan; 865 828 unsigned int ain[2], channel = 0, tmp; 829 + unsigned int num_channels; 866 830 int ret; 867 831 868 - st->num_channels = device_get_child_node_count(dev); 869 - if (!st->num_channels) 870 - return dev_err_probe(dev, -ENODEV, "no channel children\n"); 832 + num_channels = device_get_child_node_count(dev); 871 833 872 834 /* 873 835 * The driver assigns each logical channel defined in the device tree ··· 875 839 * CHANNEL_15) as an additional channel register. The driver could be 876 840 * improved to lift this limitation. 877 841 */ 878 - if (st->num_channels > AD7124_MAX_CHANNELS) 842 + if (num_channels > AD7124_MAX_CHANNELS) 879 843 return dev_err_probe(dev, -EINVAL, "Too many channels defined\n"); 844 + 845 + /* Add one for temperature */ 846 + st->num_channels = min(num_channels + 1, AD7124_MAX_CHANNELS); 880 847 881 848 chan = devm_kcalloc(indio_dev->dev.parent, st->num_channels, 882 849 sizeof(*chan), GFP_KERNEL); ··· 901 862 return dev_err_probe(dev, ret, 902 863 "Failed to parse reg property of %pfwP\n", child); 903 864 904 - if (channel >= indio_dev->num_channels) 865 + if (channel >= num_channels) 905 866 return dev_err_probe(dev, -EINVAL, 906 867 "Channel index >= number of channels in %pfwP\n", child); 907 868 ··· 939 900 chan[channel].scan_index = channel; 940 901 chan[channel].channel = ain[0]; 941 902 chan[channel].channel2 = ain[1]; 903 + } 904 + 905 + if (num_channels < AD7124_MAX_CHANNELS) { 906 + st->channels[num_channels] = (struct ad7124_channel) { 907 + .nr = num_channels, 908 + .ain = AD7124_CHANNEL_AINP(AD7124_INPUT_TEMPSENSOR) | 909 + AD7124_CHANNEL_AINM(AD7124_INPUT_AVSS), 910 + .cfg = { 911 + .bipolar = true, 912 + }, 913 + }; 914 + 915 + chan[num_channels] = (struct iio_chan_spec) { 916 + .type = IIO_TEMP, 917 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 918 + BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET) | 919 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 920 + .scan_type = { 921 + /* 922 + * You might find it strange that a bipolar 923 + * measurement yields an unsigned value, but 924 + * this matches the device's manual. 925 + */ 926 + .sign = 'u', 927 + .realbits = 24, 928 + .storagebits = 32, 929 + .endianness = IIO_BE, 930 + }, 931 + .address = num_channels, 932 + .scan_index = num_channels, 933 + }; 942 934 } 943 935 944 936 return 0;