From: Liam Beguin <lvb@xxxxxxxxxx> Add temperature rescaling support to the IIO Analog Front End driver. This series includes minor bug fixes and adds support for RTD temperature sensors as well as temperature transducers. At first I tried to use iio_convert_raw_to_processed() to get more precision out of processed values but ran into issues when one of my ADCs didn't provide a scale. I tried to address this in the first two patches. When adding offset support to iio-rescale, I also noticed that iio_read_channel_processed() assumes that the offset is always an integer which I tried to address in the third patch without breaking valid implicit truncations. As was suggested by Jonathan [1], I started implementing Kunit tests for some of these cases[2]. It's pretty far from being ready but it still helped test things faster this time around! I'll send another series with the tests once I've cleaned it up and figured out how to avoid copying part of the driver... [1] https://patchwork.kernel.org/project/linux-iio/patch/20210701010034.303088-5-liambeguin@xxxxxxxxx/#24290449 [2] https://git.sr.ht/~liambeguin/Linux/commit/iio-rescale-test/v1 Changes since v4: - only use gcd() when necessary in overflow mitigation - fix INT_PLUS_{MICRO,NANO} support - apply Reviewed-by - fix temperature-transducer bindings Changes since v3: - drop unnecessary fallthrough statements - drop redundant local variables in some calculations - fix s64 divisions on 32bit platforms by using do_div - add comment describing iio-rescaler offset calculation - drop unnecessary MAINTAINERS entry Changes since v2: - don't break implicit offset truncations - make a best effort to get a valid value for fractional types - drop return value change in iio_convert_raw_to_processed_unlocked() - don't rely on processed value for offset calculation - add INT_PLUS_{MICRO,NANO} support in iio-rescale - revert generic implementation in favor of temperature-sense-rtd and temperature-transducer - add separate section to MAINTAINERS file Changes since v1: - rebase on latest iio `testing` branch - also apply consumer scale on integer channel scale types - don't break implicit truncation in processed channel offset calculation - drop temperature AFE flavors in favor of a simpler generic implementation Thanks for your time Liam Beguin (10): iio: inkern: apply consumer scale on IIO_VAL_INT cases iio: inkern: apply consumer scale when no channel scale is available iio: inkern: make a best effort on offset calculation iio: afe: rescale: reduce risk of integer overflow iio: afe: rescale: add INT_PLUS_{MICRO,NANO} support iio: afe: rescale: add offset support iio: afe: rescale: add RTD temperature sensor support iio: afe: rescale: add temperature transducers dt-bindings: iio: afe: add bindings for temperature-sense-rtd dt-bindings: iio: afe: add bindings for temperature transducers .../iio/afe/temperature-sense-rtd.yaml | 101 ++++++++++ .../iio/afe/temperature-transducer.yaml | 114 +++++++++++ drivers/iio/afe/iio-rescale.c | 183 +++++++++++++++++- drivers/iio/inkern.c | 40 +++- 4 files changed, 426 insertions(+), 12 deletions(-) create mode 100644 Documentation/devicetree/bindings/iio/afe/temperature-sense-rtd.yaml create mode 100644 Documentation/devicetree/bindings/iio/afe/temperature-transducer.yaml Range-diff against v4: -: ------------ > 1: 42a7a1047edc iio: inkern: apply consumer scale on IIO_VAL_INT cases -: ------------ > 2: a1cd89fdad11 iio: inkern: apply consumer scale when no channel scale is available -: ------------ > 3: ed0721fb6bd1 iio: inkern: make a best effort on offset calculation 1: e23e6cb26b92 ! 4: 7b3e374eb7ad iio: afe: rescale: reduce risk of integer overflow @@ Commit message Reduce the risk of integer overflow by doing the scale calculation with 64bit integers and looking for a Greatest Common Divider for both parts - of the fractional value. + of the fractional value when required. Signed-off-by: Liam Beguin <lvb@xxxxxxxxxx> @@ drivers/iio/afe/iio-rescale.c: static int rescale_read_raw(struct iio_dev *indio - *val2 *= rescale->denominator; + tmp = (s64)*val * rescale->numerator; + tmp2 = (s64)*val2 * rescale->denominator; -+ factor = gcd(tmp, tmp2); -+ do_div(tmp, factor); ++ if (check_mul_overflow(*val, rescale->numerator, (s32 *)&tmp) || ++ check_mul_overflow(*val2, rescale->denominator, (s32 *)&tmp2)) { ++ factor = gcd(tmp, tmp2); ++ do_div(tmp, factor); ++ do_div(tmp2, factor); ++ } + *val = tmp; -+ do_div(tmp2, factor); + *val2 = tmp2; return ret; case IIO_VAL_INT: 2: 28203b672942 ! 5: 1d334090e974 iio: afe: rescale: add INT_PLUS_{MICRO,NANO} support @@ Metadata ## Commit message ## iio: afe: rescale: add INT_PLUS_{MICRO,NANO} support - Add IIO_VAL_INT_PLUS_{NANO,MICRO} scaling support. - Scale the integer part and the decimal parts individually and keep the - original scaling type. + Some ADCs use IIO_VAL_INT_PLUS_{NANO,MICRO} scale types. + Add support for these to allow using the iio-rescaler with them. Signed-off-by: Liam Beguin <lvb@xxxxxxxxxx> @@ drivers/iio/afe/iio-rescale.c: static int rescale_read_raw(struct iio_dev *indio *val = tmp; return ret; + case IIO_VAL_INT_PLUS_NANO: ++ tmp = ((s64)*val * 1000000000LL + *val2) * rescale->numerator; ++ do_div(tmp, rescale->denominator); ++ ++ *val = div_s64(tmp, 1000000000LL); ++ *val2 = tmp - *val * 1000000000LL; ++ return ret; + case IIO_VAL_INT_PLUS_MICRO: -+ tmp = (s64)*val * rescale->numerator; -+ *val = div_s64(tmp, rescale->denominator); -+ tmp = (s64)*val2 * rescale->numerator; -+ *val2 = div_s64(tmp, rescale->denominator); ++ tmp = ((s64)*val * 1000000LL + *val2) * rescale->numerator; ++ do_div(tmp, rescale->denominator); ++ ++ *val = div_s64(tmp, 1000000LL); ++ *val2 = tmp - *val * 1000000LL; + return ret; default: + dev_err(&indio_dev->dev, "unsupported type %d\n", ret); 3: a6c944ae0f99 = 6: 61873203c140 iio: afe: rescale: add offset support 4: cc5eb96512d5 = 7: 4e6117b9c663 iio: afe: rescale: add RTD temperature sensor support 5: d8aa257aad35 = 8: bc647d45e293 iio: afe: rescale: add temperature transducers 6: f038d6a08ea2 ! 9: 570b418eed85 dt-bindings: iio: afe: add bindings for temperature-sense-rtd @@ Commit message voltage across an RTD resistor such as a PT1000. Signed-off-by: Liam Beguin <lvb@xxxxxxxxxx> + Reviewed-by: Rob Herring <robh@xxxxxxxxxx> ## Documentation/devicetree/bindings/iio/afe/temperature-sense-rtd.yaml (new) ## @@ 7: 1db42cb25254 ! 10: 3c44ea89754e dt-bindings: iio: afe: add bindings for temperature transducers @@ Documentation/devicetree/bindings/iio/afe/temperature-transducer.yaml (new) + + sense-offset-millicelsius: + description: | -+ Temperature offset. The default is <0>. ++ Temperature offset. + This offset is commonly used to convert from Kelvins to degrees Celsius. + In that case, sense-offset-millicelsius would be set to <(-273150)>. ++ default: 0 + + sense-resistor-ohms: + description: | -+ The sense resistor. Defaults to <1>. -+ Set sense-resistor-ohms to <1> when using a temperature to voltage -+ transducer. ++ The sense resistor. ++ By default sense-resistor-ohms cancels out the resistor making the ++ circuit behave like a temperature transducer. ++ default: 1 + + alpha-ppm-per-celsius: + description: | @@ Documentation/devicetree/bindings/iio/afe/temperature-transducer.yaml (new) + datasheet. + +additionalProperties: false ++ +required: + - compatible + - io-channels base-commit: 6cbb3aa0f9d5d23221df787cf36f74d3866fdb78 -- 2.30.1.489.g328c10930387