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

iio: mxs-lradc: compute temperature from channel 8 and 9

The mxs LRADC is able to read an internal die temperature sensor. The
temperature has to be calculated from the value read on channel 8 and channel 9.
To be able to expose the result to hwmon, implement iio channel 8 as
(channel 9 - channel 8). Then, implement IIO_CHAN_INFO_SCALE and
IIO_CHAN_INFO_OFFSET so that it can be processed by hwmon through the in kernel
provider/consumer mechanism.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>

authored by

Alexandre Belloni and committed by
Jonathan Cameron
c8231a9a 098d3bec

+78 -13
+78 -13
drivers/staging/iio/adc/mxs-lradc.c
··· 759 759 /* 760 760 * Raw I/O operations 761 761 */ 762 - static int mxs_lradc_read_raw(struct iio_dev *iio_dev, 763 - const struct iio_chan_spec *chan, 764 - int *val, int *val2, long m) 762 + static int mxs_lradc_read_single(struct iio_dev *iio_dev, int chan, int *val) 765 763 { 766 764 struct mxs_lradc *lradc = iio_priv(iio_dev); 767 765 int ret; 768 - 769 - if (m != IIO_CHAN_INFO_RAW) 770 - return -EINVAL; 771 - 772 - /* Check for invalid channel */ 773 - if (chan->channel > LRADC_MAX_TOTAL_CHANS) 774 - return -EINVAL; 775 766 776 767 /* 777 768 * See if there is no buffered operation in progess. If there is, simply ··· 788 797 789 798 /* Clean the slot's previous content, then set new one. */ 790 799 mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0), LRADC_CTRL4); 791 - mxs_lradc_reg_set(lradc, chan->channel, LRADC_CTRL4); 800 + mxs_lradc_reg_set(lradc, chan, LRADC_CTRL4); 792 801 793 802 mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(0)); 794 803 ··· 813 822 mutex_unlock(&lradc->lock); 814 823 815 824 return ret; 825 + } 826 + 827 + static int mxs_lradc_read_temp(struct iio_dev *iio_dev, int *val) 828 + { 829 + int ret, min, max; 830 + 831 + ret = mxs_lradc_read_single(iio_dev, 8, &min); 832 + if (ret != IIO_VAL_INT) 833 + return ret; 834 + 835 + ret = mxs_lradc_read_single(iio_dev, 9, &max); 836 + if (ret != IIO_VAL_INT) 837 + return ret; 838 + 839 + *val = max - min; 840 + 841 + return IIO_VAL_INT; 842 + } 843 + 844 + static int mxs_lradc_read_raw(struct iio_dev *iio_dev, 845 + const struct iio_chan_spec *chan, 846 + int *val, int *val2, long m) 847 + { 848 + /* Check for invalid channel */ 849 + if (chan->channel > LRADC_MAX_TOTAL_CHANS) 850 + return -EINVAL; 851 + 852 + switch (m) { 853 + case IIO_CHAN_INFO_RAW: 854 + if (chan->type == IIO_TEMP) 855 + return mxs_lradc_read_temp(iio_dev, val); 856 + 857 + return mxs_lradc_read_single(iio_dev, chan->channel, val); 858 + 859 + case IIO_CHAN_INFO_SCALE: 860 + if (chan->type == IIO_TEMP) { 861 + /* From the datasheet, we have to multiply by 1.012 and 862 + * divide by 4 863 + */ 864 + *val = 0; 865 + *val2 = 253000; 866 + return IIO_VAL_INT_PLUS_MICRO; 867 + } 868 + 869 + return -EINVAL; 870 + 871 + case IIO_CHAN_INFO_OFFSET: 872 + if (chan->type == IIO_TEMP) { 873 + /* The calculated value from the ADC is in Kelvin, we 874 + * want Celsius for hwmon so the offset is 875 + * -272.15 * scale 876 + */ 877 + *val = -1075; 878 + *val2 = 691699; 879 + 880 + return IIO_VAL_INT_PLUS_MICRO; 881 + } 882 + 883 + return -EINVAL; 884 + 885 + default: 886 + break; 887 + } 888 + 889 + return -EINVAL; 816 890 } 817 891 818 892 static const struct iio_info mxs_lradc_iio_info = { ··· 1207 1151 MXS_ADC_CHAN(5, IIO_VOLTAGE), 1208 1152 MXS_ADC_CHAN(6, IIO_VOLTAGE), 1209 1153 MXS_ADC_CHAN(7, IIO_VOLTAGE), /* VBATT */ 1210 - MXS_ADC_CHAN(8, IIO_TEMP), /* Temp sense 0 */ 1211 - MXS_ADC_CHAN(9, IIO_TEMP), /* Temp sense 1 */ 1154 + /* Combined Temperature sensors */ 1155 + { 1156 + .type = IIO_TEMP, 1157 + .indexed = 1, 1158 + .scan_index = 8, 1159 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 1160 + BIT(IIO_CHAN_INFO_OFFSET) | 1161 + BIT(IIO_CHAN_INFO_SCALE), 1162 + .channel = 8, 1163 + .scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,}, 1164 + }, 1212 1165 MXS_ADC_CHAN(10, IIO_VOLTAGE), /* VDDIO */ 1213 1166 MXS_ADC_CHAN(11, IIO_VOLTAGE), /* VTH */ 1214 1167 MXS_ADC_CHAN(12, IIO_VOLTAGE), /* VDDA */