Register an IIO channel to allow reading the temperature using the IIO interface.
Signed-off-by: Luca Weiss <[email protected]> --- drivers/thermal/thermal-generic-adc.c | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c index ee3d0aa31406..14aef682e0fb 100644 --- a/drivers/thermal/thermal-generic-adc.c +++ b/drivers/thermal/thermal-generic-adc.c @@ -7,6 +7,7 @@ * Author: Laxman Dewangan <[email protected]> */ #include <linux/iio/consumer.h> +#include <linux/iio/iio.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h> @@ -23,6 +24,10 @@ struct gadc_thermal_info { int nlookup_table; }; +struct gadc_iio { + struct gadc_thermal_info *gti; +}; + static int gadc_thermal_adc_to_temp(struct gadc_thermal_info *gti, int val) { int temp, temp_hi, temp_lo, adc_hi, adc_lo; @@ -115,10 +120,44 @@ static int gadc_thermal_read_linear_lookup_table(struct device *dev, return 0; } +static int gadc_adc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct gadc_iio *data = iio_priv(indio_dev); + int iio_val; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + ret = iio_read_channel_processed(data->gti->channel, &iio_val); + if (ret < 0) + return ret; + + *val = gadc_thermal_adc_to_temp(data->gti, iio_val); + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static const struct iio_info gadc_adc_info = { + .read_raw = &gadc_adc_read_raw, +}; + +static const struct iio_chan_spec gadc_adc_channels[] = { + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), + }, +}; + static int gadc_thermal_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct gadc_thermal_info *gti; + struct iio_dev *indio_dev; + struct gadc_iio *data; int ret; if (!dev->of_node) { @@ -153,6 +192,23 @@ static int gadc_thermal_probe(struct platform_device *pdev) devm_thermal_add_hwmon_sysfs(dev, gti->tz_dev); + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + data->gti = gti; + + indio_dev->name = pdev->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &gadc_adc_info; + indio_dev->channels = gadc_adc_channels; + indio_dev->num_channels = ARRAY_SIZE(gadc_adc_channels); + + ret = devm_iio_device_register(dev, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to register IIO device\n"); + return 0; } -- 2.51.0

