* [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
@ 2025-11-24 14:48 Romain Gantois
2025-11-24 14:48 ` [PATCH v4 1/6] regulator: dt-bindings: Add Linear Technology LTM8054 regulator Romain Gantois
` (6 more replies)
0 siblings, 7 replies; 24+ messages in thread
From: Romain Gantois @ 2025-11-24 14:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Romain Gantois, Conor Dooley, MyungJoo Ham, Chanwoo Choi,
Guenter Roeck, Peter Rosin, Mariel Tinaco, Lars-Peter Clausen,
Michael Hennerich, Kevin Tsai, Linus Walleij, Dmitry Torokhov,
Eugen Hristev, Vinod Koul, Kishon Vijay Abraham I,
Sebastian Reichel, Chen-Yu Tsai, Support Opensource,
Paul Cercueil, Iskren Chernev, Marek Szyprowski, Matheus Castello,
Saravanan Sekar, Matthias Brugger, AngeloGioacchino Del Regno,
Casey Connolly, Pali Rohár, Orson Zhai, Baolin Wang,
Chunyan Zhang, Amit Kucheria, Thara Gopinath, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Claudiu Beznea,
Jaroslav Kysela, Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
Hello everyone,
This is version four of my series which adds initial support of the Linear
Technology LTM8054 voltage regulator. The driver supports a fixed voltage
and a tunable output current limit using a DAC-controlled pin.
I'd say that the most unusual part of this series is the usage of the IIO
consumer API in a regulator driver. I think this makes sense here, since
the regulator driver has to access a DAC to read/set the output current
limit.
Since the regulator driver writes microvolts and the IIO consumer API takes
millivolts, the reads and writes to the CTL DAC have to be scaled by a
factor of 1000. Scaled reads are already supported in IIO, but scaled
writes are not, which is why I've implemented them in patch 2/4.
Moreover, the IIO read/write operations are done in quite a roundabout way
in the driver's regulator callbacks. This is due to a unsafe locking
interaction: the regulator callbacks are called under regulator lock, which
means they have an active ww_mutex reservation ID. Or, some IIO drivers
will perform regulator operations when read/written to, thus taking a new
ww_mutex reservation ID. Taking two consecutive reservation IDs for the
same ww_mutex context without freeing the first ID is forbidden (and
lockdep will complain about this). The most straightforward solution I've
found is to move the actual IIO read/write operations to a different
thread, and to wait for them to complete with a timeout from the main
callback thread.
Please let me know what you think.
Thanks,
Romain
Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
---
Changes in v4:
- Various style improvements.
- Used namespaced exports for the IIO consumer API.
- Mitigated bug caused by abs() corner case.
- Link to v3: https://lore.kernel.org/r/20251106-ltm8054-driver-v3-0-fd1feae0f65a@bootlin.com
Changes in v3:
- Made IIO operations to an asynchronous context to avoid locking issue.
- Made CTL DAC control optional.
- Make various style adjustments to the LTM8054 driver.
- Link to v2: https://lore.kernel.org/r/20250925-ltm8054-driver-v2-0-bb61a401a0dc@bootlin.com
Changes in v2:
- Refactored iio_convert_processed_to_raw() to match what was done in Hans'
series.
- Added unit tests for IIO division.
- Fixed coding style issues and removed unnecessary casts.
- Link to v1: https://lore.kernel.org/r/20250916-ltm8054-driver-v1-0-fd4e781d33b9@bootlin.com
---
Romain Gantois (6):
regulator: dt-bindings: Add Linear Technology LTM8054 regulator
iio: inkern: Use namespaced exports
iio: add processed write API
iio: test: Add kunit tests for iio_divide_by_value()
regulator: Support the LTM8054 voltage regulator
regulator: ltm8054: Support output current limit control
.../devicetree/bindings/regulator/adi,ltm8054.yaml | 71 ++++
MAINTAINERS | 6 +
drivers/extcon/extcon-adc-jack.c | 1 +
drivers/hwmon/iio_hwmon.c | 1 +
drivers/hwmon/ntc_thermistor.c | 1 +
drivers/iio/adc/envelope-detector.c | 1 +
drivers/iio/afe/iio-rescale.c | 1 +
drivers/iio/buffer/industrialio-buffer-cb.c | 1 +
drivers/iio/buffer/industrialio-hw-consumer.c | 1 +
drivers/iio/dac/ad8460.c | 1 +
drivers/iio/dac/dpot-dac.c | 1 +
drivers/iio/dac/ds4424.c | 1 +
drivers/iio/inkern.c | 187 ++++++++--
drivers/iio/light/cm3605.c | 1 +
drivers/iio/light/gp2ap002.c | 1 +
drivers/iio/multiplexer/iio-mux.c | 1 +
drivers/iio/potentiostat/lmp91000.c | 1 +
drivers/iio/test/Kconfig | 12 +
drivers/iio/test/Makefile | 1 +
drivers/iio/test/iio-test-divide.c | 247 ++++++++++++++
drivers/iio/test/iio-test-multiply.c | 1 +
drivers/input/joystick/adc-joystick.c | 1 +
drivers/input/keyboard/adc-keys.c | 1 +
drivers/input/touchscreen/colibri-vf50-ts.c | 1 +
drivers/input/touchscreen/resistive-adc-touch.c | 1 +
drivers/phy/motorola/phy-cpcap-usb.c | 1 +
drivers/power/supply/ab8500_btemp.c | 1 +
drivers/power/supply/ab8500_charger.c | 1 +
drivers/power/supply/ab8500_fg.c | 1 +
drivers/power/supply/axp20x_ac_power.c | 1 +
drivers/power/supply/axp20x_battery.c | 1 +
drivers/power/supply/axp20x_usb_power.c | 1 +
drivers/power/supply/axp288_fuel_gauge.c | 1 +
drivers/power/supply/cpcap-battery.c | 1 +
drivers/power/supply/cpcap-charger.c | 1 +
drivers/power/supply/da9150-charger.c | 1 +
drivers/power/supply/generic-adc-battery.c | 1 +
drivers/power/supply/ingenic-battery.c | 1 +
drivers/power/supply/intel_dc_ti_battery.c | 1 +
drivers/power/supply/lego_ev3_battery.c | 1 +
drivers/power/supply/lp8788-charger.c | 1 +
drivers/power/supply/max17040_battery.c | 1 +
drivers/power/supply/mp2629_charger.c | 1 +
drivers/power/supply/mt6370-charger.c | 1 +
drivers/power/supply/qcom_smbx.c | 1 +
drivers/power/supply/rn5t618_power.c | 1 +
drivers/power/supply/rx51_battery.c | 1 +
drivers/power/supply/sc27xx_fuel_gauge.c | 1 +
drivers/power/supply/twl4030_charger.c | 1 +
drivers/power/supply/twl4030_madc_battery.c | 1 +
drivers/power/supply/twl6030_charger.c | 1 +
drivers/regulator/Kconfig | 9 +
drivers/regulator/Makefile | 1 +
drivers/regulator/ltm8054-regulator.c | 379 +++++++++++++++++++++
drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 1 +
drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 1 +
drivers/thermal/renesas/rzg3s_thermal.c | 1 +
drivers/thermal/thermal-generic-adc.c | 1 +
include/linux/iio/consumer.h | 36 ++
sound/soc/codecs/audio-iio-aux.c | 1 +
sound/soc/samsung/aries_wm8994.c | 1 +
sound/soc/samsung/midas_wm1811.c | 1 +
sound/soc/stm/stm32_adfsdm.c | 1 +
63 files changed, 972 insertions(+), 30 deletions(-)
---
base-commit: cda7b38e04b41bf0e19deed2999d725f440a5abd
change-id: 20250728-ltm8054-driver-11cfa4741065
Best regards,
--
Romain Gantois <romain.gantois@bootlin.com>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 1/6] regulator: dt-bindings: Add Linear Technology LTM8054 regulator
2025-11-24 14:48 [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Romain Gantois
@ 2025-11-24 14:48 ` Romain Gantois
2025-11-24 14:48 ` [PATCH v4 2/6] iio: inkern: Use namespaced exports Romain Gantois
` (5 subsequent siblings)
6 siblings, 0 replies; 24+ messages in thread
From: Romain Gantois @ 2025-11-24 14:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Romain Gantois, Conor Dooley
The Linear Technology LTM8054 is a Buck-Boost voltage regulator with an
input range of 5V to 36V and an output range of 1.2V to 36V.
The LTM8054's output voltage level is typically set using a voltage divider
between the Vout and FB pins, the FB pin being constantly regulated to
1.2V.
The output current limit of the LTM8054 may be statically set by placing a
sense resistor on a dedicated pin. This limit can then be lowered by
controlling the voltage level on the CTL pin.
Describe the LTM8054 voltage regulator.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
---
.../devicetree/bindings/regulator/adi,ltm8054.yaml | 71 ++++++++++++++++++++++
MAINTAINERS | 5 ++
2 files changed, 76 insertions(+)
diff --git a/Documentation/devicetree/bindings/regulator/adi,ltm8054.yaml b/Documentation/devicetree/bindings/regulator/adi,ltm8054.yaml
new file mode 100644
index 000000000000..a982daecb4cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/adi,ltm8054.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/adi,ltm8054.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices LTM8054 buck-boost regulator
+
+maintainers:
+ - Romain Gantois <romain.gantois@bootlin.com>
+
+description:
+ This regulator operates over an input voltage range of 5V to 36V, and can
+ output from 1.2V to 36V. The output voltage level is typically set with a
+ voltage divider between the Vout pin and the FB pin which is internally
+ regulated to 1.2V.
+
+ The output current of the LTM8054 can be limited by tying the Iout pin to a
+ current sense resistor. This limit can be further lowered by applying a
+ voltage below 1.2V to the CTL pin.
+
+allOf:
+ - $ref: /schemas/regulator/regulator.yaml#
+
+properties:
+ compatible:
+ const: adi,ltm8054
+
+ enable-gpios:
+ description: GPIO connected to the RUN pin.
+ maxItems: 1
+
+ regulator-fb-voltage-divider-ohms:
+ description: Feedback voltage divider resistor values, in Ohms.
+ items:
+ - description: Top resistor value.
+ - description: Bottom resistor value.
+
+ adi,iout-rsense-micro-ohms:
+ description:
+ Value of the output current sense resistor, in micro Ohms.
+
+ io-channels:
+ items:
+ - description: DAC controlling the voltage level of the CTL pin.
+
+ io-channel-names:
+ items:
+ - const: ctl
+
+required:
+ - compatible
+ - regulator-fb-voltage-divider-ohms
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ regulator {
+ compatible = "adi,ltm8054";
+
+ enable-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+
+ regulator-fb-voltage-divider-ohms = <1000000 68000>;
+
+ adi,iout-rsense-micro-ohms = <20000>;
+
+ io-channels = <&dac 1>;
+ io-channel-names = "ctl";
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index b30cdbc270aa..01949aab8240 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14790,6 +14790,11 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/i2c/i2c-mux-ltc4306.txt
F: drivers/i2c/muxes/i2c-mux-ltc4306.c
+LTM8054 REGULATOR DRIVER
+M: Romain Gantois <romain.gantois@bootlin.com>
+S: Maintained
+F: Documentation/devicetree/bindings/regulator/adi,ltm8054.yaml
+
LTP (Linux Test Project)
M: Andrea Cervesato <andrea.cervesato@suse.com>
M: Cyril Hrubis <chrubis@suse.cz>
--
2.51.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 2/6] iio: inkern: Use namespaced exports
2025-11-24 14:48 [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Romain Gantois
2025-11-24 14:48 ` [PATCH v4 1/6] regulator: dt-bindings: Add Linear Technology LTM8054 regulator Romain Gantois
@ 2025-11-24 14:48 ` Romain Gantois
2025-11-24 14:48 ` [PATCH v4 3/6] iio: add processed write API Romain Gantois
` (4 subsequent siblings)
6 siblings, 0 replies; 24+ messages in thread
From: Romain Gantois @ 2025-11-24 14:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Romain Gantois, MyungJoo Ham, Chanwoo Choi, Guenter Roeck,
Peter Rosin, Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich,
Kevin Tsai, Linus Walleij, Dmitry Torokhov, Eugen Hristev,
Vinod Koul, Kishon Vijay Abraham I, Sebastian Reichel,
Chen-Yu Tsai, Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32
Use namespaced exports for IIO consumer API functions.
To: MyungJoo Ham <myungjoo.ham@samsung.com>
To: Chanwoo Choi <cw00.choi@samsung.com>
To: Guenter Roeck <linux@roeck-us.net>
To: Peter Rosin <peda@axentia.se>
To: David Lechner <dlechner@baylibre.com>
To: Mariel Tinaco <Mariel.Tinaco@analog.com>
To: Lars-Peter Clausen <lars@metafoo.de>
To: Michael Hennerich <Michael.Hennerich@analog.com>
To: Kevin Tsai <ktsai@capellamicro.com>
To: Linus Walleij <linus.walleij@linaro.org>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Eugen Hristev <eugen.hristev@linaro.org>
To: Vinod Koul <vkoul@kernel.org>
To: Kishon Vijay Abraham I <kishon@kernel.org>
To: Sebastian Reichel <sre@kernel.org>
To: Chen-Yu Tsai <wens@csie.org>
To: Support Opensource <support.opensource@diasemi.com>
To: Paul Cercueil <paul@crapouillou.net>
To: Iskren Chernev <me@iskren.info>
To: Marek Szyprowski <m.szyprowski@samsung.com>
To: Matheus Castello <matheus@castello.eng.br>
To: Saravanan Sekar <sravanhome@gmail.com>
To: Matthias Brugger <matthias.bgg@gmail.com>
To: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
To: Casey Connolly <casey.connolly@linaro.org>
To: "Pali Rohár" <pali@kernel.org>
To: Orson Zhai <orsonzhai@gmail.com>
To: Baolin Wang <baolin.wang@linux.alibaba.com>
To: Chunyan Zhang <zhang.lyra@gmail.com>
To: Amit Kucheria <amitk@kernel.org>
To: Thara Gopinath <thara.gopinath@gmail.com>
To: "Rafael J. Wysocki" <rafael@kernel.org>
To: Daniel Lezcano <daniel.lezcano@linaro.org>
To: Zhang Rui <rui.zhang@intel.com>
To: Lukasz Luba <lukasz.luba@arm.com>
To: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
To: Jaroslav Kysela <perex@perex.cz>
To: Takashi Iwai <tiwai@suse.com>
To: Sylwester Nawrocki <s.nawrocki@samsung.com>
To: Olivier Moysan <olivier.moysan@foss.st.com>
To: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
To: Maxime Coquelin <mcoquelin.stm32@gmail.com>
To: Alexandre Torgue <alexandre.torgue@foss.st.com>
To: Dixit Parmar <dixitparmar19@gmail.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-hwmon@vger.kernel.org
Cc: linux-input@vger.kernel.org
Cc: linux-phy@lists.infradead.org
Cc: linux-pm@vger.kernel.org
Cc: linux-mips@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-mediatek@lists.infradead.org
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-sound@vger.kernel.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
---
drivers/extcon/extcon-adc-jack.c | 1 +
drivers/hwmon/iio_hwmon.c | 1 +
drivers/hwmon/ntc_thermistor.c | 1 +
drivers/iio/adc/envelope-detector.c | 1 +
drivers/iio/afe/iio-rescale.c | 1 +
drivers/iio/buffer/industrialio-buffer-cb.c | 1 +
drivers/iio/buffer/industrialio-hw-consumer.c | 1 +
drivers/iio/dac/ad8460.c | 1 +
drivers/iio/dac/dpot-dac.c | 1 +
drivers/iio/dac/ds4424.c | 1 +
drivers/iio/inkern.c | 60 ++++++++++++-------------
drivers/iio/light/cm3605.c | 1 +
drivers/iio/light/gp2ap002.c | 1 +
drivers/iio/multiplexer/iio-mux.c | 1 +
drivers/iio/potentiostat/lmp91000.c | 1 +
drivers/iio/test/iio-test-multiply.c | 1 +
drivers/input/joystick/adc-joystick.c | 1 +
drivers/input/keyboard/adc-keys.c | 1 +
drivers/input/touchscreen/colibri-vf50-ts.c | 1 +
drivers/input/touchscreen/resistive-adc-touch.c | 1 +
drivers/phy/motorola/phy-cpcap-usb.c | 1 +
drivers/power/supply/ab8500_btemp.c | 1 +
drivers/power/supply/ab8500_charger.c | 1 +
drivers/power/supply/ab8500_fg.c | 1 +
drivers/power/supply/axp20x_ac_power.c | 1 +
drivers/power/supply/axp20x_battery.c | 1 +
drivers/power/supply/axp20x_usb_power.c | 1 +
drivers/power/supply/axp288_fuel_gauge.c | 1 +
drivers/power/supply/cpcap-battery.c | 1 +
drivers/power/supply/cpcap-charger.c | 1 +
drivers/power/supply/da9150-charger.c | 1 +
drivers/power/supply/generic-adc-battery.c | 1 +
drivers/power/supply/ingenic-battery.c | 1 +
drivers/power/supply/intel_dc_ti_battery.c | 1 +
drivers/power/supply/lego_ev3_battery.c | 1 +
drivers/power/supply/lp8788-charger.c | 1 +
drivers/power/supply/max17040_battery.c | 1 +
drivers/power/supply/mp2629_charger.c | 1 +
drivers/power/supply/mt6370-charger.c | 1 +
drivers/power/supply/qcom_smbx.c | 1 +
drivers/power/supply/rn5t618_power.c | 1 +
drivers/power/supply/rx51_battery.c | 1 +
drivers/power/supply/sc27xx_fuel_gauge.c | 1 +
drivers/power/supply/twl4030_charger.c | 1 +
drivers/power/supply/twl4030_madc_battery.c | 1 +
drivers/power/supply/twl6030_charger.c | 1 +
drivers/thermal/qcom/qcom-spmi-adc-tm5.c | 1 +
drivers/thermal/qcom/qcom-spmi-temp-alarm.c | 1 +
drivers/thermal/renesas/rzg3s_thermal.c | 1 +
drivers/thermal/thermal-generic-adc.c | 1 +
sound/soc/codecs/audio-iio-aux.c | 1 +
sound/soc/samsung/aries_wm8994.c | 1 +
sound/soc/samsung/midas_wm1811.c | 1 +
sound/soc/stm/stm32_adfsdm.c | 1 +
54 files changed, 83 insertions(+), 30 deletions(-)
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c
index 7e3c9f38297b..e735f43dcdeb 100644
--- a/drivers/extcon/extcon-adc-jack.c
+++ b/drivers/extcon/extcon-adc-jack.c
@@ -210,3 +210,4 @@ module_platform_driver(adc_jack_driver);
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
MODULE_DESCRIPTION("ADC Jack extcon driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/hwmon/iio_hwmon.c b/drivers/hwmon/iio_hwmon.c
index e376d4cde5ad..4c7843fbcc50 100644
--- a/drivers/hwmon/iio_hwmon.c
+++ b/drivers/hwmon/iio_hwmon.c
@@ -222,3 +222,4 @@ module_platform_driver(iio_hwmon_driver);
MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("IIO to hwmon driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c
index d21f7266c411..417807fad80b 100644
--- a/drivers/hwmon/ntc_thermistor.c
+++ b/drivers/hwmon/ntc_thermistor.c
@@ -706,3 +706,4 @@ MODULE_DESCRIPTION("NTC Thermistor Driver");
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ntc-thermistor");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/adc/envelope-detector.c b/drivers/iio/adc/envelope-detector.c
index 5b16fe737659..fea20e7e6cd9 100644
--- a/drivers/iio/adc/envelope-detector.c
+++ b/drivers/iio/adc/envelope-detector.c
@@ -406,3 +406,4 @@ module_platform_driver(envelope_detector_driver);
MODULE_DESCRIPTION("Envelope detector using a DAC and a comparator");
MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/afe/iio-rescale.c b/drivers/iio/afe/iio-rescale.c
index ecaf59278c6f..d7f55109af3e 100644
--- a/drivers/iio/afe/iio-rescale.c
+++ b/drivers/iio/afe/iio-rescale.c
@@ -609,3 +609,4 @@ module_platform_driver(rescale_driver);
MODULE_DESCRIPTION("IIO rescale driver");
MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/buffer/industrialio-buffer-cb.c b/drivers/iio/buffer/industrialio-buffer-cb.c
index 3e27385069ed..608ea9afc15a 100644
--- a/drivers/iio/buffer/industrialio-buffer-cb.c
+++ b/drivers/iio/buffer/industrialio-buffer-cb.c
@@ -153,3 +153,4 @@ EXPORT_SYMBOL_GPL(iio_channel_cb_get_iio_dev);
MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
MODULE_DESCRIPTION("Industrial I/O callback buffer");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/buffer/industrialio-hw-consumer.c b/drivers/iio/buffer/industrialio-hw-consumer.c
index 526b2a8d725d..d7ff086ed783 100644
--- a/drivers/iio/buffer/industrialio-hw-consumer.c
+++ b/drivers/iio/buffer/industrialio-hw-consumer.c
@@ -211,3 +211,4 @@ EXPORT_SYMBOL_GPL(iio_hw_consumer_disable);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Hardware consumer buffer the IIO framework");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/dac/ad8460.c b/drivers/iio/dac/ad8460.c
index 6e45686902dd..ad654819ca22 100644
--- a/drivers/iio/dac/ad8460.c
+++ b/drivers/iio/dac/ad8460.c
@@ -955,3 +955,4 @@ MODULE_AUTHOR("Mariel Tinaco <mariel.tinaco@analog.com");
MODULE_DESCRIPTION("AD8460 DAC driver");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/dac/dpot-dac.c b/drivers/iio/dac/dpot-dac.c
index d1b8441051ae..49dbdb7df955 100644
--- a/drivers/iio/dac/dpot-dac.c
+++ b/drivers/iio/dac/dpot-dac.c
@@ -254,3 +254,4 @@ module_platform_driver(dpot_dac_driver);
MODULE_DESCRIPTION("DAC emulation driver using a digital potentiometer");
MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c
index a8198ba4f98a..cfafee3159b1 100644
--- a/drivers/iio/dac/ds4424.c
+++ b/drivers/iio/dac/ds4424.c
@@ -321,3 +321,4 @@ MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>");
MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");
MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 1e5eb5a41271..70b6f589f37a 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -71,7 +71,7 @@ int iio_map_array_register(struct iio_dev *indio_dev, const struct iio_map *maps
iio_map_array_unregister_locked(indio_dev);
return ret;
}
-EXPORT_SYMBOL_GPL(iio_map_array_register);
+EXPORT_SYMBOL_NS_GPL(iio_map_array_register, "IIO_CONSUMER");
/*
* Remove all map entries associated with the given iio device
@@ -81,7 +81,7 @@ int iio_map_array_unregister(struct iio_dev *indio_dev)
guard(mutex)(&iio_map_list_lock);
return iio_map_array_unregister_locked(indio_dev);
}
-EXPORT_SYMBOL_GPL(iio_map_array_unregister);
+EXPORT_SYMBOL_NS_GPL(iio_map_array_unregister, "IIO_CONSUMER");
static void iio_map_array_unregister_cb(void *indio_dev)
{
@@ -99,7 +99,7 @@ int devm_iio_map_array_register(struct device *dev, struct iio_dev *indio_dev,
return devm_add_action_or_reset(dev, iio_map_array_unregister_cb, indio_dev);
}
-EXPORT_SYMBOL_GPL(devm_iio_map_array_register);
+EXPORT_SYMBOL_NS_GPL(devm_iio_map_array_register, "IIO_CONSUMER");
static const struct iio_chan_spec
*iio_chan_spec_from_name(const struct iio_dev *indio_dev, const char *name)
@@ -281,7 +281,7 @@ struct iio_channel *fwnode_iio_channel_get_by_name(struct fwnode_handle *fwnode,
return ERR_PTR(-ENODEV);
}
-EXPORT_SYMBOL_GPL(fwnode_iio_channel_get_by_name);
+EXPORT_SYMBOL_NS_GPL(fwnode_iio_channel_get_by_name, "IIO_CONSUMER");
static struct iio_channel *fwnode_iio_channel_get_all(struct device *dev)
{
@@ -386,7 +386,7 @@ struct iio_channel *iio_channel_get(struct device *dev,
return iio_channel_get_sys(name, channel_name);
}
-EXPORT_SYMBOL_GPL(iio_channel_get);
+EXPORT_SYMBOL_NS_GPL(iio_channel_get, "IIO_CONSUMER");
void iio_channel_release(struct iio_channel *channel)
{
@@ -395,7 +395,7 @@ void iio_channel_release(struct iio_channel *channel)
iio_device_put(channel->indio_dev);
kfree(channel);
}
-EXPORT_SYMBOL_GPL(iio_channel_release);
+EXPORT_SYMBOL_NS_GPL(iio_channel_release, "IIO_CONSUMER");
static void devm_iio_channel_free(void *iio_channel)
{
@@ -418,7 +418,7 @@ struct iio_channel *devm_iio_channel_get(struct device *dev,
return channel;
}
-EXPORT_SYMBOL_GPL(devm_iio_channel_get);
+EXPORT_SYMBOL_NS_GPL(devm_iio_channel_get, "IIO_CONSUMER");
struct iio_channel *devm_fwnode_iio_channel_get_by_name(struct device *dev,
struct fwnode_handle *fwnode,
@@ -437,7 +437,7 @@ struct iio_channel *devm_fwnode_iio_channel_get_by_name(struct device *dev,
return channel;
}
-EXPORT_SYMBOL_GPL(devm_fwnode_iio_channel_get_by_name);
+EXPORT_SYMBOL_NS_GPL(devm_fwnode_iio_channel_get_by_name, "IIO_CONSUMER");
struct iio_channel *iio_channel_get_all(struct device *dev)
{
@@ -506,7 +506,7 @@ struct iio_channel *iio_channel_get_all(struct device *dev)
iio_device_put(chans[i].indio_dev);
return ERR_PTR(ret);
}
-EXPORT_SYMBOL_GPL(iio_channel_get_all);
+EXPORT_SYMBOL_NS_GPL(iio_channel_get_all, "IIO_CONSUMER");
void iio_channel_release_all(struct iio_channel *channels)
{
@@ -518,7 +518,7 @@ void iio_channel_release_all(struct iio_channel *channels)
}
kfree(channels);
}
-EXPORT_SYMBOL_GPL(iio_channel_release_all);
+EXPORT_SYMBOL_NS_GPL(iio_channel_release_all, "IIO_CONSUMER");
static void devm_iio_channel_free_all(void *iio_channels)
{
@@ -541,7 +541,7 @@ struct iio_channel *devm_iio_channel_get_all(struct device *dev)
return channels;
}
-EXPORT_SYMBOL_GPL(devm_iio_channel_get_all);
+EXPORT_SYMBOL_NS_GPL(devm_iio_channel_get_all, "IIO_CONSUMER");
static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
enum iio_chan_info_enum info)
@@ -585,7 +585,7 @@ int iio_read_channel_raw(struct iio_channel *chan, int *val)
return iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
}
-EXPORT_SYMBOL_GPL(iio_read_channel_raw);
+EXPORT_SYMBOL_NS_GPL(iio_read_channel_raw, "IIO_CONSUMER");
int iio_read_channel_average_raw(struct iio_channel *chan, int *val)
{
@@ -597,7 +597,7 @@ int iio_read_channel_average_raw(struct iio_channel *chan, int *val)
return iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_AVERAGE_RAW);
}
-EXPORT_SYMBOL_GPL(iio_read_channel_average_raw);
+EXPORT_SYMBOL_NS_GPL(iio_read_channel_average_raw, "IIO_CONSUMER");
int iio_multiply_value(int *result, s64 multiplier,
unsigned int type, int val, int val2)
@@ -701,7 +701,7 @@ int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
return iio_convert_raw_to_processed_unlocked(chan, raw, processed,
scale);
}
-EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed);
+EXPORT_SYMBOL_NS_GPL(iio_convert_raw_to_processed, "IIO_CONSUMER");
int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2,
enum iio_chan_info_enum attribute)
@@ -714,13 +714,13 @@ int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2,
return iio_channel_read(chan, val, val2, attribute);
}
-EXPORT_SYMBOL_GPL(iio_read_channel_attribute);
+EXPORT_SYMBOL_NS_GPL(iio_read_channel_attribute, "IIO_CONSUMER");
int iio_read_channel_offset(struct iio_channel *chan, int *val, int *val2)
{
return iio_read_channel_attribute(chan, val, val2, IIO_CHAN_INFO_OFFSET);
}
-EXPORT_SYMBOL_GPL(iio_read_channel_offset);
+EXPORT_SYMBOL_NS_GPL(iio_read_channel_offset, "IIO_CONSUMER");
int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
unsigned int scale)
@@ -748,20 +748,20 @@ int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
scale);
}
}
-EXPORT_SYMBOL_GPL(iio_read_channel_processed_scale);
+EXPORT_SYMBOL_NS_GPL(iio_read_channel_processed_scale, "IIO_CONSUMER");
int iio_read_channel_processed(struct iio_channel *chan, int *val)
{
/* This is just a special case with scale factor 1 */
return iio_read_channel_processed_scale(chan, val, 1);
}
-EXPORT_SYMBOL_GPL(iio_read_channel_processed);
+EXPORT_SYMBOL_NS_GPL(iio_read_channel_processed, "IIO_CONSUMER");
int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)
{
return iio_read_channel_attribute(chan, val, val2, IIO_CHAN_INFO_SCALE);
}
-EXPORT_SYMBOL_GPL(iio_read_channel_scale);
+EXPORT_SYMBOL_NS_GPL(iio_read_channel_scale, "IIO_CONSUMER");
static int iio_channel_read_avail(struct iio_channel *chan,
const int **vals, int *type, int *length,
@@ -790,7 +790,7 @@ int iio_read_avail_channel_attribute(struct iio_channel *chan,
return iio_channel_read_avail(chan, vals, type, length, attribute);
}
-EXPORT_SYMBOL_GPL(iio_read_avail_channel_attribute);
+EXPORT_SYMBOL_NS_GPL(iio_read_avail_channel_attribute, "IIO_CONSUMER");
int iio_read_avail_channel_raw(struct iio_channel *chan,
const int **vals, int *length)
@@ -807,7 +807,7 @@ int iio_read_avail_channel_raw(struct iio_channel *chan,
return ret;
}
-EXPORT_SYMBOL_GPL(iio_read_avail_channel_raw);
+EXPORT_SYMBOL_NS_GPL(iio_read_avail_channel_raw, "IIO_CONSUMER");
static int iio_channel_read_max(struct iio_channel *chan,
int *val, int *val2, int *type,
@@ -863,7 +863,7 @@ int iio_read_max_channel_raw(struct iio_channel *chan, int *val)
return iio_channel_read_max(chan, val, NULL, &type, IIO_CHAN_INFO_RAW);
}
-EXPORT_SYMBOL_GPL(iio_read_max_channel_raw);
+EXPORT_SYMBOL_NS_GPL(iio_read_max_channel_raw, "IIO_CONSUMER");
static int iio_channel_read_min(struct iio_channel *chan,
int *val, int *val2, int *type,
@@ -919,7 +919,7 @@ int iio_read_min_channel_raw(struct iio_channel *chan, int *val)
return iio_channel_read_min(chan, val, NULL, &type, IIO_CHAN_INFO_RAW);
}
-EXPORT_SYMBOL_GPL(iio_read_min_channel_raw);
+EXPORT_SYMBOL_NS_GPL(iio_read_min_channel_raw, "IIO_CONSUMER");
int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type)
{
@@ -933,7 +933,7 @@ int iio_get_channel_type(struct iio_channel *chan, enum iio_chan_type *type)
return 0;
}
-EXPORT_SYMBOL_GPL(iio_get_channel_type);
+EXPORT_SYMBOL_NS_GPL(iio_get_channel_type, "IIO_CONSUMER");
static int iio_channel_write(struct iio_channel *chan, int val, int val2,
enum iio_chan_info_enum info)
@@ -957,13 +957,13 @@ int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2,
return iio_channel_write(chan, val, val2, attribute);
}
-EXPORT_SYMBOL_GPL(iio_write_channel_attribute);
+EXPORT_SYMBOL_NS_GPL(iio_write_channel_attribute, "IIO_CONSUMER");
int iio_write_channel_raw(struct iio_channel *chan, int val)
{
return iio_write_channel_attribute(chan, val, 0, IIO_CHAN_INFO_RAW);
}
-EXPORT_SYMBOL_GPL(iio_write_channel_raw);
+EXPORT_SYMBOL_NS_GPL(iio_write_channel_raw, "IIO_CONSUMER");
unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan)
{
@@ -978,7 +978,7 @@ unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan)
return i;
}
-EXPORT_SYMBOL_GPL(iio_get_channel_ext_info_count);
+EXPORT_SYMBOL_NS_GPL(iio_get_channel_ext_info_count, "IIO_CONSUMER");
static const struct iio_chan_spec_ext_info *
iio_lookup_ext_info(const struct iio_channel *chan, const char *attr)
@@ -1013,7 +1013,7 @@ ssize_t iio_read_channel_ext_info(struct iio_channel *chan,
return ext_info->read(chan->indio_dev, ext_info->private,
chan->channel, buf);
}
-EXPORT_SYMBOL_GPL(iio_read_channel_ext_info);
+EXPORT_SYMBOL_NS_GPL(iio_read_channel_ext_info, "IIO_CONSUMER");
ssize_t iio_write_channel_ext_info(struct iio_channel *chan, const char *attr,
const char *buf, size_t len)
@@ -1027,7 +1027,7 @@ ssize_t iio_write_channel_ext_info(struct iio_channel *chan, const char *attr,
return ext_info->write(chan->indio_dev, ext_info->private,
chan->channel, buf, len);
}
-EXPORT_SYMBOL_GPL(iio_write_channel_ext_info);
+EXPORT_SYMBOL_NS_GPL(iio_write_channel_ext_info, "IIO_CONSUMER");
ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf)
{
@@ -1038,4 +1038,4 @@ ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf)
return do_iio_read_channel_label(chan->indio_dev, chan->channel, buf);
}
-EXPORT_SYMBOL_GPL(iio_read_channel_label);
+EXPORT_SYMBOL_NS_GPL(iio_read_channel_label, "IIO_CONSUMER");
diff --git a/drivers/iio/light/cm3605.c b/drivers/iio/light/cm3605.c
index 0c17378e27d1..1bd11292d005 100644
--- a/drivers/iio/light/cm3605.c
+++ b/drivers/iio/light/cm3605.c
@@ -325,3 +325,4 @@ module_platform_driver(cm3605_driver);
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
MODULE_DESCRIPTION("CM3605 ambient light and proximity sensor driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c
index a0d8a58f2704..04b1f6eade0e 100644
--- a/drivers/iio/light/gp2ap002.c
+++ b/drivers/iio/light/gp2ap002.c
@@ -717,3 +717,4 @@ module_i2c_driver(gp2ap002_driver);
MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
MODULE_DESCRIPTION("GP2AP002 ambient light and proximity sensor driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/multiplexer/iio-mux.c b/drivers/iio/multiplexer/iio-mux.c
index b742ca9a99d1..e193913f5af7 100644
--- a/drivers/iio/multiplexer/iio-mux.c
+++ b/drivers/iio/multiplexer/iio-mux.c
@@ -464,3 +464,4 @@ module_platform_driver(mux_driver);
MODULE_DESCRIPTION("IIO multiplexer driver");
MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c
index eccc2a34358f..7d993f2acda4 100644
--- a/drivers/iio/potentiostat/lmp91000.c
+++ b/drivers/iio/potentiostat/lmp91000.c
@@ -423,3 +423,4 @@ module_i2c_driver(lmp91000_driver);
MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
MODULE_DESCRIPTION("LMP91000 digital potentiostat");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/iio/test/iio-test-multiply.c b/drivers/iio/test/iio-test-multiply.c
index 432e279ffe5b..e4c497db4c79 100644
--- a/drivers/iio/test/iio-test-multiply.c
+++ b/drivers/iio/test/iio-test-multiply.c
@@ -210,3 +210,4 @@ MODULE_AUTHOR("Hans de Goede <hans@hansg.org>");
MODULE_DESCRIPTION("Test IIO multiply functions");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("IIO_UNIT_TEST");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/input/joystick/adc-joystick.c b/drivers/input/joystick/adc-joystick.c
index ff44f9978b71..4fa42f88bcfa 100644
--- a/drivers/input/joystick/adc-joystick.c
+++ b/drivers/input/joystick/adc-joystick.c
@@ -329,3 +329,4 @@ module_platform_driver(adc_joystick_driver);
MODULE_DESCRIPTION("Input driver for joysticks connected over ADC");
MODULE_AUTHOR("Artur Rojek <contact@artur-rojek.eu>");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/input/keyboard/adc-keys.c b/drivers/input/keyboard/adc-keys.c
index f1753207429d..d687459a0c80 100644
--- a/drivers/input/keyboard/adc-keys.c
+++ b/drivers/input/keyboard/adc-keys.c
@@ -202,3 +202,4 @@ module_platform_driver(adc_keys_driver);
MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
MODULE_DESCRIPTION("Input driver for resistor ladder connected on ADC");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c
index 98d5b2ba63fb..89c4d7b2b89e 100644
--- a/drivers/input/touchscreen/colibri-vf50-ts.c
+++ b/drivers/input/touchscreen/colibri-vf50-ts.c
@@ -372,3 +372,4 @@ module_platform_driver(vf50_touch_driver);
MODULE_AUTHOR("Sanchayan Maity");
MODULE_DESCRIPTION("Colibri VF50 Touchscreen driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/input/touchscreen/resistive-adc-touch.c b/drivers/input/touchscreen/resistive-adc-touch.c
index 7e761ec73273..2fefd652864c 100644
--- a/drivers/input/touchscreen/resistive-adc-touch.c
+++ b/drivers/input/touchscreen/resistive-adc-touch.c
@@ -301,3 +301,4 @@ module_platform_driver(grts_driver);
MODULE_AUTHOR("Eugen Hristev <eugen.hristev@microchip.com>");
MODULE_DESCRIPTION("Generic ADC Resistive Touch Driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c
index 7cb020dd3423..9591672b0511 100644
--- a/drivers/phy/motorola/phy-cpcap-usb.c
+++ b/drivers/phy/motorola/phy-cpcap-usb.c
@@ -717,3 +717,4 @@ MODULE_ALIAS("platform:cpcap_usb");
MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
MODULE_DESCRIPTION("CPCAP usb phy driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c
index e5202a7b6209..36b0c52a4b8b 100644
--- a/drivers/power/supply/ab8500_btemp.c
+++ b/drivers/power/supply/ab8500_btemp.c
@@ -829,3 +829,4 @@ MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy");
MODULE_ALIAS("platform:ab8500-btemp");
MODULE_DESCRIPTION("AB8500 battery temperature driver");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c
index 5f4537766e5b..6e49d1b28254 100644
--- a/drivers/power/supply/ab8500_charger.c
+++ b/drivers/power/supply/ab8500_charger.c
@@ -3751,3 +3751,4 @@ MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy");
MODULE_ALIAS("platform:ab8500-charger");
MODULE_DESCRIPTION("AB8500 charger management driver");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c
index 9dd99722667a..5fa559f796aa 100644
--- a/drivers/power/supply/ab8500_fg.c
+++ b/drivers/power/supply/ab8500_fg.c
@@ -3252,3 +3252,4 @@ MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Johan Palsson, Karl Komierowski");
MODULE_ALIAS("platform:ab8500-fg");
MODULE_DESCRIPTION("AB8500 Fuel Gauge driver");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/axp20x_ac_power.c b/drivers/power/supply/axp20x_ac_power.c
index 5f6ea416fa30..e9049d6229df 100644
--- a/drivers/power/supply/axp20x_ac_power.c
+++ b/drivers/power/supply/axp20x_ac_power.c
@@ -421,3 +421,4 @@ module_platform_driver(axp20x_ac_power_driver);
MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
MODULE_DESCRIPTION("AXP20X and AXP22X PMICs' AC power supply driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/axp20x_battery.c b/drivers/power/supply/axp20x_battery.c
index 50ca8e110085..ee8701a6e907 100644
--- a/drivers/power/supply/axp20x_battery.c
+++ b/drivers/power/supply/axp20x_battery.c
@@ -1155,3 +1155,4 @@ module_platform_driver(axp20x_batt_driver);
MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs");
MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
index e75d1e377ac1..599adcf84968 100644
--- a/drivers/power/supply/axp20x_usb_power.c
+++ b/drivers/power/supply/axp20x_usb_power.c
@@ -1080,3 +1080,4 @@ module_platform_driver(axp20x_usb_power_driver);
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("AXP20x PMIC USB power supply status driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/axp288_fuel_gauge.c b/drivers/power/supply/axp288_fuel_gauge.c
index a3d71fc72064..c6897dd808fc 100644
--- a/drivers/power/supply/axp288_fuel_gauge.c
+++ b/drivers/power/supply/axp288_fuel_gauge.c
@@ -817,3 +817,4 @@ MODULE_AUTHOR("Ramakrishna Pallala <ramakrishna.pallala@intel.com>");
MODULE_AUTHOR("Todd Brandt <todd.e.brandt@linux.intel.com>");
MODULE_DESCRIPTION("Xpower AXP288 Fuel Gauge Driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/cpcap-battery.c b/drivers/power/supply/cpcap-battery.c
index 8106d1edcbc2..542c3c70e3cb 100644
--- a/drivers/power/supply/cpcap-battery.c
+++ b/drivers/power/supply/cpcap-battery.c
@@ -1176,3 +1176,4 @@ module_platform_driver(cpcap_battery_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
MODULE_DESCRIPTION("CPCAP PMIC Battery Driver");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c
index d0c3008db534..89bc0fc3c9f8 100644
--- a/drivers/power/supply/cpcap-charger.c
+++ b/drivers/power/supply/cpcap-charger.c
@@ -977,3 +977,4 @@ MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
MODULE_DESCRIPTION("CPCAP Battery Charger Interface driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:cpcap-charger");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/da9150-charger.c b/drivers/power/supply/da9150-charger.c
index 27f36ef5b88d..58449df6068c 100644
--- a/drivers/power/supply/da9150-charger.c
+++ b/drivers/power/supply/da9150-charger.c
@@ -644,3 +644,4 @@ module_platform_driver(da9150_charger_driver);
MODULE_DESCRIPTION("Charger Driver for DA9150");
MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/generic-adc-battery.c b/drivers/power/supply/generic-adc-battery.c
index f5f2566b3a32..d18c8ee40405 100644
--- a/drivers/power/supply/generic-adc-battery.c
+++ b/drivers/power/supply/generic-adc-battery.c
@@ -298,3 +298,4 @@ module_platform_driver(gab_driver);
MODULE_AUTHOR("anish kumar <yesanishhere@gmail.com>");
MODULE_DESCRIPTION("generic battery driver using IIO");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/ingenic-battery.c b/drivers/power/supply/ingenic-battery.c
index b111c7ce2be3..5be269f17bff 100644
--- a/drivers/power/supply/ingenic-battery.c
+++ b/drivers/power/supply/ingenic-battery.c
@@ -190,3 +190,4 @@ module_platform_driver(ingenic_battery_driver);
MODULE_DESCRIPTION("Battery driver for Ingenic JZ47xx SoCs");
MODULE_AUTHOR("Artur Rojek <contact@artur-rojek.eu>");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/intel_dc_ti_battery.c b/drivers/power/supply/intel_dc_ti_battery.c
index 56b0c92e9d28..1a16ded563bc 100644
--- a/drivers/power/supply/intel_dc_ti_battery.c
+++ b/drivers/power/supply/intel_dc_ti_battery.c
@@ -387,3 +387,4 @@ MODULE_ALIAS("platform:" DEV_NAME);
MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>");
MODULE_DESCRIPTION("Intel Dollar Cove (TI) battery driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/lego_ev3_battery.c b/drivers/power/supply/lego_ev3_battery.c
index 28454de05761..414816662b06 100644
--- a/drivers/power/supply/lego_ev3_battery.c
+++ b/drivers/power/supply/lego_ev3_battery.c
@@ -231,3 +231,4 @@ module_platform_driver(lego_ev3_battery_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Lechner <david@lechnology.com>");
MODULE_DESCRIPTION("LEGO MINDSTORMS EV3 Battery Driver");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/lp8788-charger.c b/drivers/power/supply/lp8788-charger.c
index f0a680c155c4..8c6ec98362d0 100644
--- a/drivers/power/supply/lp8788-charger.c
+++ b/drivers/power/supply/lp8788-charger.c
@@ -727,3 +727,4 @@ MODULE_DESCRIPTION("TI LP8788 Charger Driver");
MODULE_AUTHOR("Milo Kim");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:lp8788-charger");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/max17040_battery.c b/drivers/power/supply/max17040_battery.c
index c1640bc6accd..1fe658bfecc1 100644
--- a/drivers/power/supply/max17040_battery.c
+++ b/drivers/power/supply/max17040_battery.c
@@ -635,3 +635,4 @@ module_i2c_driver(max17040_i2c_driver);
MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
MODULE_DESCRIPTION("MAX17040 Fuel Gauge");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/mp2629_charger.c b/drivers/power/supply/mp2629_charger.c
index d281c1059629..ed49f9a04c8c 100644
--- a/drivers/power/supply/mp2629_charger.c
+++ b/drivers/power/supply/mp2629_charger.c
@@ -660,3 +660,4 @@ module_platform_driver(mp2629_charger_driver);
MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>");
MODULE_DESCRIPTION("MP2629 Charger driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/mt6370-charger.c b/drivers/power/supply/mt6370-charger.c
index e6db961d5818..2d02fdf37d70 100644
--- a/drivers/power/supply/mt6370-charger.c
+++ b/drivers/power/supply/mt6370-charger.c
@@ -941,3 +941,4 @@ module_platform_driver(mt6370_chg_driver);
MODULE_AUTHOR("ChiaEn Wu <chiaen_wu@richtek.com>");
MODULE_DESCRIPTION("MediaTek MT6370 Charger Driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/qcom_smbx.c b/drivers/power/supply/qcom_smbx.c
index b1cb925581ec..63b88754155c 100644
--- a/drivers/power/supply/qcom_smbx.c
+++ b/drivers/power/supply/qcom_smbx.c
@@ -1050,3 +1050,4 @@ module_platform_driver(qcom_spmi_smb);
MODULE_AUTHOR("Casey Connolly <casey.connolly@linaro.org>");
MODULE_DESCRIPTION("Qualcomm SMB2 Charger Driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/rn5t618_power.c b/drivers/power/supply/rn5t618_power.c
index 40dec55a9f73..a3f30e390c11 100644
--- a/drivers/power/supply/rn5t618_power.c
+++ b/drivers/power/supply/rn5t618_power.c
@@ -821,3 +821,4 @@ module_platform_driver(rn5t618_power_driver);
MODULE_ALIAS("platform:rn5t618-power");
MODULE_DESCRIPTION("Power supply driver for RICOH RN5T618");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/rx51_battery.c b/drivers/power/supply/rx51_battery.c
index b0220ec2d926..57266921dc8e 100644
--- a/drivers/power/supply/rx51_battery.c
+++ b/drivers/power/supply/rx51_battery.c
@@ -246,3 +246,4 @@ MODULE_ALIAS("platform:rx51-battery");
MODULE_AUTHOR("Pali Rohár <pali@kernel.org>");
MODULE_DESCRIPTION("Nokia RX-51 battery driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c
index a7ed9de8a289..1719ec4173e6 100644
--- a/drivers/power/supply/sc27xx_fuel_gauge.c
+++ b/drivers/power/supply/sc27xx_fuel_gauge.c
@@ -1350,3 +1350,4 @@ module_platform_driver(sc27xx_fgu_driver);
MODULE_DESCRIPTION("Spreadtrum SC27XX PMICs Fual Gauge Unit Driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/twl4030_charger.c b/drivers/power/supply/twl4030_charger.c
index 04216b2bfb6c..151f7b24e9b9 100644
--- a/drivers/power/supply/twl4030_charger.c
+++ b/drivers/power/supply/twl4030_charger.c
@@ -1144,3 +1144,4 @@ MODULE_AUTHOR("Gražvydas Ignotas");
MODULE_DESCRIPTION("TWL4030 Battery Charger Interface driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:twl4030_bci");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/twl4030_madc_battery.c b/drivers/power/supply/twl4030_madc_battery.c
index 3935162e350b..9b3785d1643c 100644
--- a/drivers/power/supply/twl4030_madc_battery.c
+++ b/drivers/power/supply/twl4030_madc_battery.c
@@ -237,3 +237,4 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lukas Märdian <lukas@goldelico.com>");
MODULE_DESCRIPTION("twl4030_madc battery driver");
MODULE_ALIAS("platform:twl4030_madc_battery");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/power/supply/twl6030_charger.c b/drivers/power/supply/twl6030_charger.c
index b4ec26ff257c..82911a811f4e 100644
--- a/drivers/power/supply/twl6030_charger.c
+++ b/drivers/power/supply/twl6030_charger.c
@@ -579,3 +579,4 @@ module_platform_driver(twl6030_charger_driver);
MODULE_DESCRIPTION("TWL6030 Battery Charger Interface driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
index d7f2e6ca92c2..bb6222c8cc5f 100644
--- a/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
+++ b/drivers/thermal/qcom/qcom-spmi-adc-tm5.c
@@ -1069,3 +1069,4 @@ module_platform_driver(adc_tm5_driver);
MODULE_DESCRIPTION("SPMI PMIC Thermal Monitor ADC driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
index f39ca0ddd17b..fb003ca96454 100644
--- a/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
+++ b/drivers/thermal/qcom/qcom-spmi-temp-alarm.c
@@ -904,3 +904,4 @@ module_platform_driver(qpnp_tm_driver);
MODULE_ALIAS("platform:spmi-temp-alarm");
MODULE_DESCRIPTION("QPNP PMIC Temperature Alarm driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/thermal/renesas/rzg3s_thermal.c b/drivers/thermal/renesas/rzg3s_thermal.c
index e25e36c99a88..7ced8f76a0ec 100644
--- a/drivers/thermal/renesas/rzg3s_thermal.c
+++ b/drivers/thermal/renesas/rzg3s_thermal.c
@@ -270,3 +270,4 @@ module_platform_driver(rzg3s_thermal_driver);
MODULE_DESCRIPTION("Renesas RZ/G3S Thermal Sensor Unit Driver");
MODULE_AUTHOR("Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/drivers/thermal/thermal-generic-adc.c b/drivers/thermal/thermal-generic-adc.c
index 7c844589b153..cfdb8e674dd2 100644
--- a/drivers/thermal/thermal-generic-adc.c
+++ b/drivers/thermal/thermal-generic-adc.c
@@ -228,3 +228,4 @@ module_platform_driver(gadc_thermal_driver);
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
MODULE_DESCRIPTION("Generic ADC thermal driver using IIO framework with DT");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/sound/soc/codecs/audio-iio-aux.c b/sound/soc/codecs/audio-iio-aux.c
index 588e48044c13..864a5a676495 100644
--- a/sound/soc/codecs/audio-iio-aux.c
+++ b/sound/soc/codecs/audio-iio-aux.c
@@ -312,3 +312,4 @@ module_platform_driver(audio_iio_aux_driver);
MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
MODULE_DESCRIPTION("IIO ALSA SoC aux driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c
index 3723329b266d..b6f0f3c0d393 100644
--- a/sound/soc/samsung/aries_wm8994.c
+++ b/sound/soc/samsung/aries_wm8994.c
@@ -700,3 +700,4 @@ module_platform_driver(aries_audio_driver);
MODULE_DESCRIPTION("ALSA SoC ARIES WM8994");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:aries-audio-wm8994");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/sound/soc/samsung/midas_wm1811.c b/sound/soc/samsung/midas_wm1811.c
index 239e958b88d3..12c4962f901d 100644
--- a/sound/soc/samsung/midas_wm1811.c
+++ b/sound/soc/samsung/midas_wm1811.c
@@ -773,3 +773,4 @@ module_platform_driver(midas_driver);
MODULE_AUTHOR("Simon Shields <simon@lineageos.org>");
MODULE_DESCRIPTION("ASoC support for Midas");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_CONSUMER");
diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
index c914d1c46850..dabcd2759187 100644
--- a/sound/soc/stm/stm32_adfsdm.c
+++ b/sound/soc/stm/stm32_adfsdm.c
@@ -407,3 +407,4 @@ MODULE_DESCRIPTION("stm32 DFSDM DAI driver");
MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:" STM32_ADFSDM_DRV_NAME);
+MODULE_IMPORT_NS("IIO_CONSUMER");
--
2.51.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 3/6] iio: add processed write API
2025-11-24 14:48 [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Romain Gantois
2025-11-24 14:48 ` [PATCH v4 1/6] regulator: dt-bindings: Add Linear Technology LTM8054 regulator Romain Gantois
2025-11-24 14:48 ` [PATCH v4 2/6] iio: inkern: Use namespaced exports Romain Gantois
@ 2025-11-24 14:48 ` Romain Gantois
2025-12-07 18:52 ` Jonathan Cameron
2025-11-24 14:48 ` [PATCH v4 4/6] iio: test: Add kunit tests for iio_divide_by_value() Romain Gantois
` (3 subsequent siblings)
6 siblings, 1 reply; 24+ messages in thread
From: Romain Gantois @ 2025-11-24 14:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Romain Gantois
Add a function to allow IIO consumers to write a processed value to a
channel.
Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
---
drivers/iio/inkern.c | 127 +++++++++++++++++++++++++++++++++++++++++++
include/linux/iio/consumer.h | 36 ++++++++++++
2 files changed, 163 insertions(+)
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 70b6f589f37a..6667e8e7648b 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -635,6 +635,54 @@ int iio_multiply_value(int *result, s64 multiplier,
}
EXPORT_SYMBOL_NS_GPL(iio_multiply_value, "IIO_UNIT_TEST");
+int iio_divide_by_value(int *result, s64 numerator,
+ unsigned int type, int val, int val2)
+{
+ s64 tmp_num, tmp_den;
+
+ switch (type) {
+ case IIO_VAL_INT:
+ tmp_num = numerator;
+ tmp_den = val;
+ break;
+ case IIO_VAL_INT_PLUS_MICRO:
+ tmp_num = numerator * MICRO;
+ /* Cast inside abs() to avoid undefined behavior if val* == -INT_MIN. */
+ tmp_den = abs((s64)val) * MICRO + abs((s64)val2);
+
+ if (val < 0 || val2 < 0)
+ tmp_num *= -1;
+
+ break;
+ case IIO_VAL_INT_PLUS_NANO:
+ tmp_num = numerator * NANO;
+ tmp_den = abs((s64)val) * NANO + abs((s64)val2);
+
+ if (val < 0 || val2 < 0)
+ tmp_num *= -1;
+
+ break;
+ case IIO_VAL_FRACTIONAL:
+ tmp_num = (s64)numerator * (s64)val2;
+ tmp_den = val;
+ break;
+ case IIO_VAL_FRACTIONAL_LOG2:
+ tmp_num = (s64)numerator << val2;
+ tmp_den = val;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!tmp_den)
+ return -EDOM;
+
+ *result = div64_s64(tmp_num, tmp_den);
+
+ return IIO_VAL_INT;
+}
+EXPORT_SYMBOL_NS_GPL(iio_divide_by_value, "IIO_UNIT_TEST");
+
static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
int raw, int *processed,
unsigned int scale)
@@ -703,6 +751,66 @@ int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
}
EXPORT_SYMBOL_NS_GPL(iio_convert_raw_to_processed, "IIO_CONSUMER");
+static int iio_convert_processed_to_raw_unlocked(struct iio_channel *chan,
+ int processed, int *raw,
+ unsigned int scale)
+{
+ int scale_type, scale_val, scale_val2;
+ int offset_type, offset_val, offset_val2;
+ int ret, half_step = 0;
+
+ scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
+ IIO_CHAN_INFO_SCALE);
+ if (scale_type >= 0) {
+ ret = iio_divide_by_value(raw, processed, scale_type, scale_val, scale_val2);
+ if (ret < 0)
+ return ret;
+ } else {
+ *raw = processed;
+ }
+
+ if (!scale)
+ return -EDOM;
+
+ *raw = div_s64(*raw, scale);
+
+ offset_type = iio_channel_read(chan, &offset_val, &offset_val2,
+ IIO_CHAN_INFO_OFFSET);
+
+ switch (offset_type) {
+ case IIO_VAL_INT:
+ case IIO_VAL_INT_PLUS_MICRO:
+ half_step = MICRO / 2;
+ break;
+ case IIO_VAL_INT_PLUS_NANO:
+ half_step = NANO / 2;
+ break;
+ case IIO_VAL_FRACTIONAL:
+ offset_val = DIV_ROUND_CLOSEST(offset_val, offset_val2);
+ break;
+ case IIO_VAL_FRACTIONAL_LOG2:
+ offset_val >>= offset_val2;
+ break;
+ default:
+ if (offset_type >= 0)
+ return -EINVAL;
+
+ offset_val = 0;
+ }
+
+ /* Round fractional part to closest to reduce rounding bias. */
+ if (half_step) {
+ if (offset_val2 >= half_step)
+ *raw -= 1;
+ else if (offset_val2 <= -half_step)
+ *raw += 1;
+ }
+
+ *raw -= offset_val;
+
+ return 0;
+}
+
int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2,
enum iio_chan_info_enum attribute)
{
@@ -1039,3 +1147,22 @@ ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf)
return do_iio_read_channel_label(chan->indio_dev, chan->channel, buf);
}
EXPORT_SYMBOL_NS_GPL(iio_read_channel_label, "IIO_CONSUMER");
+
+int iio_write_channel_processed_scale(struct iio_channel *chan, int val,
+ unsigned int scale)
+{
+ struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
+ int ret, processed;
+
+ guard(mutex)(&iio_dev_opaque->info_exist_lock);
+
+ if (!chan->indio_dev->info)
+ return -ENODEV;
+
+ ret = iio_convert_processed_to_raw_unlocked(chan, val, &processed, scale);
+ if (ret)
+ return ret;
+
+ return iio_channel_write(chan, processed, 0, IIO_CHAN_INFO_RAW);
+}
+EXPORT_SYMBOL_NS_GPL(iio_write_channel_processed_scale, "IIO_CONSUMER");
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index a38b277c2c02..f80ab1b80234 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -399,6 +399,24 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val,
int iio_multiply_value(int *result, s64 multiplier,
unsigned int type, int val, int val2);
+/**
+ * iio_divide_by_value() - Divide by an IIO value
+ * @result: Destination pointer for the division result
+ * @numerator: Numerator.
+ * @type: One of the %IIO_VAL_* constants. This decides how the @val
+ * and @val2 parameters are interpreted.
+ * @val: Denominator.
+ * @val2: Denominator. @val2 use depends on type.
+ *
+ * Divide @numerator by an IIO value, storing the result as
+ * %IIO_VAL_INT. This is typically used for scaling.
+ *
+ * Returns:
+ * %IIO_VAL_INT on success or a negative error-number on failure.
+ */
+int iio_divide_by_value(int *result, s64 numerator,
+ unsigned int type, int val, int val2);
+
/**
* iio_convert_raw_to_processed() - Converts a raw value to a processed value
* @chan: The channel being queried
@@ -469,4 +487,22 @@ ssize_t iio_write_channel_ext_info(struct iio_channel *chan, const char *attr,
*/
ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf);
+/**
+ * iio_write_channel_processed_scale() - scale and write processed value to a given channel
+ * @chan: The channel being queried.
+ * @val: Value to write.
+ * @scale: Processed value is divided by this scale factor during the conversion.
+ *
+ * This function writes a processed value to a channel. A processed value means
+ * that this value will have the correct unit and not some device internal
+ * representation. If the device does not support writing a processed value, the
+ * function will query the channel's scale and offset and write an appropriately
+ * transformed raw value.
+ *
+ * Returns:
+ * 0 or a negative error-number on failure.
+ */
+int iio_write_channel_processed_scale(struct iio_channel *chan, int val,
+ unsigned int scale);
+
#endif
--
2.51.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 4/6] iio: test: Add kunit tests for iio_divide_by_value()
2025-11-24 14:48 [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Romain Gantois
` (2 preceding siblings ...)
2025-11-24 14:48 ` [PATCH v4 3/6] iio: add processed write API Romain Gantois
@ 2025-11-24 14:48 ` Romain Gantois
2025-11-24 14:48 ` [PATCH v4 5/6] regulator: Support the LTM8054 voltage regulator Romain Gantois
` (2 subsequent siblings)
6 siblings, 0 replies; 24+ messages in thread
From: Romain Gantois @ 2025-11-24 14:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Romain Gantois
Add kunit tests for iio_divide_by_value(), these are similar to the
existing tests for iio_multiply_value(), but the operand values used differ
slightly.
Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
---
drivers/iio/test/Kconfig | 12 ++
drivers/iio/test/Makefile | 1 +
drivers/iio/test/iio-test-divide.c | 247 +++++++++++++++++++++++++++++++++++++
3 files changed, 260 insertions(+)
diff --git a/drivers/iio/test/Kconfig b/drivers/iio/test/Kconfig
index 6e65e929791c..3aa1fc78966c 100644
--- a/drivers/iio/test/Kconfig
+++ b/drivers/iio/test/Kconfig
@@ -4,6 +4,18 @@
#
# Keep in alphabetical order
+config IIO_DIVIDE_KUNIT_TEST
+ tristate "Test IIO division functions" if !KUNIT_ALL_TESTS
+ depends on KUNIT
+ default KUNIT_ALL_TESTS
+ help
+ build unit tests for the IIO division functions.
+
+ For more information on KUnit and unit tests in general, please refer
+ to the KUnit documentation in Documentation/dev-tools/kunit/.
+
+ If unsure, say N.
+
config IIO_GTS_KUNIT_TEST
tristate "Test IIO gain-time-scale helpers" if !KUNIT_ALL_TESTS
depends on KUNIT
diff --git a/drivers/iio/test/Makefile b/drivers/iio/test/Makefile
index 0c846bc21acd..16344eedc46a 100644
--- a/drivers/iio/test/Makefile
+++ b/drivers/iio/test/Makefile
@@ -5,6 +5,7 @@
# Keep in alphabetical order
obj-$(CONFIG_IIO_RESCALE_KUNIT_TEST) += iio-test-rescale.o
+obj-$(CONFIG_IIO_DIVIDE_KUNIT_TEST) += iio-test-divide.o
obj-$(CONFIG_IIO_FORMAT_KUNIT_TEST) += iio-test-format.o
obj-$(CONFIG_IIO_GTS_KUNIT_TEST) += iio-test-gts.o
obj-$(CONFIG_IIO_MULTIPLY_KUNIT_TEST) += iio-test-multiply.o
diff --git a/drivers/iio/test/iio-test-divide.c b/drivers/iio/test/iio-test-divide.c
new file mode 100644
index 000000000000..99d759bd9591
--- /dev/null
+++ b/drivers/iio/test/iio-test-divide.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Unit tests for IIO division functions
+ *
+ * Copyright (c) 2025 Bootlin
+ * Based on iio-test-multiply.c which is:
+ * Copyright (c) 2025 Hans de Goede <hans@hansg.org>
+ * Based on iio-test-format.c which is:
+ * Copyright (c) 2020 Lars-Peter Clausen <lars@metafoo.de>
+ */
+
+#include <kunit/test.h>
+#include <linux/iio/consumer.h>
+#include <linux/limits.h>
+#include <linux/units.h>
+
+static void __iio_test_iio_divide_by_integer(struct kunit *test, s64 numerator)
+{
+ int ret, result, val;
+
+ val = 42;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT, val, 0);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator, val));
+
+ val = -23;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT, val, 0);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator, val));
+
+ val = 0;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT, val, 0);
+ KUNIT_EXPECT_EQ(test, ret, -EDOM);
+}
+
+static void iio_test_iio_divide_by_integer(struct kunit *test)
+{
+ __iio_test_iio_divide_by_integer(test, 2000);
+ __iio_test_iio_divide_by_integer(test, -2000);
+}
+
+static void __iio_test_iio_divide_by_fixedpoint(struct kunit *test, s64 numerator)
+{
+ int ret, result, val, val2;
+
+ /* positive >= 1 (1.5) */
+ val = 1;
+ val2 = 500000;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * 10, 15));
+
+ val = 1;
+ val2 = 500000000;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * 10, 15));
+
+ /* positive < 1 (0.5) */
+ val = 0;
+ val2 = 500000;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * 10, 5));
+
+ val = 0;
+ val2 = 500000000;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * 10, 5));
+
+ /* negative <= -1 (-1.5) */
+ val = -1;
+ val2 = 500000;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * -10, 15));
+
+ val = -1;
+ val2 = 500000000;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * -10, 15));
+
+ /* negative > -1 (-0.5) */
+ val = 0;
+ val2 = -500000;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * -10, 5));
+
+ val = 0;
+ val2 = -500000000;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * -10, 5));
+
+ /* Zero */
+ val = 0;
+ val2 = 0;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, -EDOM);
+
+ val = 0;
+ val2 = 0;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, -EDOM);
+
+ /* Limits */
+ val = INT_MIN;
+ val2 = 0;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator, INT_MIN));
+
+ val = INT_MIN;
+ val2 = 0;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator, INT_MIN));
+
+ val = 0;
+ val2 = INT_MIN;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_MICRO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(MICRO * numerator, INT_MIN));
+
+ val = 0;
+ val2 = INT_MIN;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_INT_PLUS_NANO, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(NANO * numerator, INT_MIN));
+}
+
+static void iio_test_iio_divide_by_fixedpoint(struct kunit *test)
+{
+ __iio_test_iio_divide_by_fixedpoint(test, 2000);
+ __iio_test_iio_divide_by_fixedpoint(test, -2000);
+}
+
+static void __iio_test_iio_divide_by_fractional(struct kunit *test, s64 numerator)
+{
+ int ret, result, val, val2;
+
+ /* positive < 1 (1/10)*/
+ val = 1;
+ val2 = 10;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * val2, val));
+
+ /* positive >= 1 (100/3)*/
+ val = 100;
+ val2 = 3;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * val2, val));
+
+ /* negative > -1 (-1/10) */
+ val = -1;
+ val2 = 10;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * val2, val));
+
+ /* negative <= -1 (-200/3)*/
+ val = -200;
+ val2 = 3;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64(numerator * val2, val));
+
+ /* Zero */
+ val = 0;
+ val2 = 0;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, -EDOM);
+}
+
+static void iio_test_iio_divide_by_fractional(struct kunit *test)
+{
+ __iio_test_iio_divide_by_fractional(test, 2000);
+ __iio_test_iio_divide_by_fractional(test, -2000);
+}
+
+static void __iio_test_iio_divide_by_fractional_log2(struct kunit *test, s64 numerator)
+{
+ int ret, result, val, val2;
+
+ /* positive < 1 (123/1024) */
+ val = 123;
+ val2 = 10;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64((numerator * 1024), val));
+
+ /* positive >= 1 (1234567/1024) */
+ val = 1234567;
+ val2 = 10;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64((numerator * 1024), val));
+
+ /* negative > -1 (-123/1024) */
+ val = -123;
+ val2 = 10;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64((numerator * 1024), val));
+
+ /* negative <= -1 (-1234567/1024) */
+ val = -1234567;
+ val2 = 10;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT);
+ KUNIT_EXPECT_EQ(test, result, div_s64((numerator * 1024), val));
+
+ /* Zero */
+ val = 0;
+ val2 = 0;
+ ret = iio_divide_by_value(&result, numerator, IIO_VAL_FRACTIONAL_LOG2, val, val2);
+ KUNIT_EXPECT_EQ(test, ret, -EDOM);
+}
+
+static void iio_test_iio_divide_by_fractional_log2(struct kunit *test)
+{
+ __iio_test_iio_divide_by_fractional_log2(test, 2000);
+ __iio_test_iio_divide_by_fractional_log2(test, -2000);
+}
+
+static struct kunit_case iio_divide_test_cases[] = {
+ KUNIT_CASE(iio_test_iio_divide_by_integer),
+ KUNIT_CASE(iio_test_iio_divide_by_fixedpoint),
+ KUNIT_CASE(iio_test_iio_divide_by_fractional),
+ KUNIT_CASE(iio_test_iio_divide_by_fractional_log2),
+ { }
+};
+
+static struct kunit_suite iio_divide_test_suite = {
+ .name = "iio-divide",
+ .test_cases = iio_divide_test_cases,
+};
+
+kunit_test_suite(iio_divide_test_suite);
+
+MODULE_AUTHOR("Romain Gantois <romain.gantois@bootlin.com>");
+MODULE_DESCRIPTION("Test IIO division functions");
+MODULE_LICENSE("GPL");
--
2.51.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 5/6] regulator: Support the LTM8054 voltage regulator
2025-11-24 14:48 [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Romain Gantois
` (3 preceding siblings ...)
2025-11-24 14:48 ` [PATCH v4 4/6] iio: test: Add kunit tests for iio_divide_by_value() Romain Gantois
@ 2025-11-24 14:48 ` Romain Gantois
2025-11-24 14:48 ` [PATCH v4 6/6] regulator: ltm8054: Support output current limit control Romain Gantois
2025-11-24 14:57 ` [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Guenter Roeck
6 siblings, 0 replies; 24+ messages in thread
From: Romain Gantois @ 2025-11-24 14:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Romain Gantois, Andy Shevchenko
Add a stub driver for the Linear Technology LTM8054 Buck-Boost voltage
regulator. This version only supports enabling/disabling the regulator via
a GPIO, and reporting the output voltage level from the resistor divider
values given in the device tree.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
---
MAINTAINERS | 1 +
drivers/regulator/Kconfig | 8 +++
drivers/regulator/Makefile | 1 +
drivers/regulator/ltm8054-regulator.c | 123 ++++++++++++++++++++++++++++++++++
4 files changed, 133 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 01949aab8240..f8dfa965c11b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14794,6 +14794,7 @@ LTM8054 REGULATOR DRIVER
M: Romain Gantois <romain.gantois@bootlin.com>
S: Maintained
F: Documentation/devicetree/bindings/regulator/adi,ltm8054.yaml
+F: drivers/regulator/ltm8054-regulator.c
LTP (Linux Test Project)
M: Andrea Cervesato <andrea.cervesato@suse.com>
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 0b2dac6f66ad..ab97025c8f94 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -595,6 +595,14 @@ config REGULATOR_LTC3676
This enables support for the LTC3676
8-output regulators controlled via I2C.
+config REGULATOR_LTM8054
+ tristate "LTM8054 Buck-Boost voltage regulator"
+ help
+ This driver provides support for the Analog Devices LTM8054
+ Buck-Boost micromodule regulator. The LTM8054 has an adjustable
+ output current limitation and a feedback pin for setting the
+ output voltage level.
+
config REGULATOR_MAX14577
tristate "Maxim 14577/77836 regulator"
depends on MFD_MAX14577
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 316a84ea92d4..f494a963e5de 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o
obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o
obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
obj-$(CONFIG_REGULATOR_LTC3676) += ltc3676.o
+obj-$(CONFIG_REGULATOR_LTM8054) += ltm8054-regulator.o
obj-$(CONFIG_REGULATOR_MAX14577) += max14577-regulator.o
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
obj-$(CONFIG_REGULATOR_MAX5970) += max5970-regulator.o
diff --git a/drivers/regulator/ltm8054-regulator.c b/drivers/regulator/ltm8054-regulator.c
new file mode 100644
index 000000000000..c432b00d75a4
--- /dev/null
+++ b/drivers/regulator/ltm8054-regulator.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Analog Devices LTM8054 Buck-Boost regulator driver
+ *
+ * Copyright (C) 2025 Bootlin
+ */
+
+#include <linux/array_size.h>
+#include <linux/device.h>
+#include <linux/device/devres.h>
+#include <linux/device/driver.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/gpio/consumer.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/types.h>
+
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+/* The LTM8054 regulates its FB pin to 1.2V */
+#define LTM8054_FB_uV 1200000
+
+struct ltm8054_priv {
+ struct regulator_desc rdesc;
+};
+
+static int ltm8054_scale(unsigned int uV, u32 r1, u32 r2)
+{
+ u64 tmp;
+
+ tmp = (u64)uV * r1;
+ do_div(tmp, r2);
+
+ return uV + tmp;
+}
+
+static const struct regulator_ops ltm8054_regulator_ops = { };
+
+static int ltm8054_of_parse(struct device *dev, struct ltm8054_priv *priv,
+ struct regulator_config *config)
+{
+ u32 r[2];
+ int ret;
+
+ ret = device_property_read_u32_array(dev, "regulator-fb-voltage-divider-ohms",
+ r, ARRAY_SIZE(r));
+ if (ret)
+ return ret;
+
+ priv->rdesc.fixed_uV = ltm8054_scale(LTM8054_FB_uV, r[0], r[1]);
+ priv->rdesc.min_uV = priv->rdesc.fixed_uV;
+ priv->rdesc.n_voltages = 1;
+
+ config->of_node = dev_of_node(dev);
+ config->init_data = of_get_regulator_init_data(dev,
+ config->of_node,
+ &priv->rdesc);
+ if (!config->init_data)
+ return -EINVAL;
+
+ config->ena_gpiod = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
+ if (IS_ERR(config->ena_gpiod))
+ return PTR_ERR(config->ena_gpiod);
+
+ return 0;
+}
+
+static int ltm8054_probe(struct platform_device *pdev)
+{
+ struct regulator_config config = { };
+ struct device *dev = &pdev->dev;
+ struct regulator_dev *rdev;
+ struct ltm8054_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->rdesc.name = "ltm8054-regulator";
+ priv->rdesc.ops = <m8054_regulator_ops;
+ priv->rdesc.type = REGULATOR_VOLTAGE;
+ priv->rdesc.owner = THIS_MODULE;
+
+ config.dev = dev;
+ config.driver_data = priv;
+
+ ret = ltm8054_of_parse(dev, priv, &config);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to parse device tree\n");
+
+ rdev = devm_regulator_register(dev, &priv->rdesc, &config);
+ if (IS_ERR(rdev))
+ return dev_err_probe(dev, PTR_ERR(rdev), "failed to register regulator\n");
+
+ return 0;
+}
+
+static const struct of_device_id ltm8054_of_match[] = {
+ { .compatible = "adi,ltm8054" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ltm8054_of_match);
+
+static struct platform_driver ltm8054_driver = {
+ .probe = ltm8054_probe,
+ .driver = {
+ .name = "ltm8054",
+ .of_match_table = ltm8054_of_match,
+ },
+};
+module_platform_driver(ltm8054_driver);
+
+MODULE_DESCRIPTION("LTM8054 regulator driver");
+MODULE_AUTHOR("Romain Gantois <romain.gantois@bootlin.com>");
+MODULE_LICENSE("GPL");
--
2.51.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 6/6] regulator: ltm8054: Support output current limit control
2025-11-24 14:48 [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Romain Gantois
` (4 preceding siblings ...)
2025-11-24 14:48 ` [PATCH v4 5/6] regulator: Support the LTM8054 voltage regulator Romain Gantois
@ 2025-11-24 14:48 ` Romain Gantois
2025-11-24 14:57 ` [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Guenter Roeck
6 siblings, 0 replies; 24+ messages in thread
From: Romain Gantois @ 2025-11-24 14:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Romain Gantois
The LTM8054 supports setting a fixed output current limit using a sense
resistor connected to a dedicated pin. This limit can then be lowered
dynamically by varying the voltage level of the CTL pin.
Support controlling the LTM8054's output current limit.
Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
---
drivers/regulator/Kconfig | 1 +
drivers/regulator/ltm8054-regulator.c | 260 +++++++++++++++++++++++++++++++++-
2 files changed, 259 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index ab97025c8f94..7b70f640ba25 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -597,6 +597,7 @@ config REGULATOR_LTC3676
config REGULATOR_LTM8054
tristate "LTM8054 Buck-Boost voltage regulator"
+ depends on IIO
help
This driver provides support for the Analog Devices LTM8054
Buck-Boost micromodule regulator. The LTM8054 has an adjustable
diff --git a/drivers/regulator/ltm8054-regulator.c b/drivers/regulator/ltm8054-regulator.c
index c432b00d75a4..4613f3f57860 100644
--- a/drivers/regulator/ltm8054-regulator.c
+++ b/drivers/regulator/ltm8054-regulator.c
@@ -6,6 +6,7 @@
*/
#include <linux/array_size.h>
+#include <linux/completion.h>
#include <linux/device.h>
#include <linux/device/devres.h>
#include <linux/device/driver.h>
@@ -13,12 +14,20 @@
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h>
+#include <linux/iio/consumer.h>
+#include <linux/jiffies.h>
+#include <linux/lockdep.h>
#include <linux/math64.h>
+#include <linux/minmax.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
+#include <linux/string_choices.h>
#include <linux/types.h>
+#include <linux/units.h>
+#include <linux/workqueue.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
@@ -27,7 +36,36 @@
/* The LTM8054 regulates its FB pin to 1.2V */
#define LTM8054_FB_uV 1200000
+/* Threshold voltage between the Vout and Iout pins which triggers current
+ * limiting.
+ */
+#define LTM8054_VOUT_IOUT_MAX_uV 58000
+
+#define LTM8054_MAX_CTL_uV 1200000
+#define LTM8054_MIN_CTL_uV 50000
+
+#define LTM8054_CTL_RW_TIMEOUT msecs_to_jiffies(500)
+
+/* CTL pin read/write transaction */
+struct ltm8054_ctl_pin_work {
+ struct work_struct work;
+ unsigned int ctl_val;
+ int ret;
+ bool write;
+};
+
struct ltm8054_priv {
+ struct device *dev;
+
+ struct iio_channel *ctl_dac;
+ struct ltm8054_ctl_pin_work ctl_work;
+ /* Lock for ctl_work. */
+ struct mutex ctl_work_lock;
+ struct completion ctl_rw_done;
+
+ int min_uA;
+ int max_uA;
+
struct regulator_desc rdesc;
};
@@ -41,14 +79,198 @@ static int ltm8054_scale(unsigned int uV, u32 r1, u32 r2)
return uV + tmp;
}
-static const struct regulator_ops ltm8054_regulator_ops = { };
+static void ltm8054_do_ctl_work(struct work_struct *work)
+{
+ struct ltm8054_ctl_pin_work *ctl_work =
+ container_of_const(work, struct ltm8054_ctl_pin_work, work);
+ struct ltm8054_priv *priv =
+ container_of_const(ctl_work, struct ltm8054_priv, ctl_work);
+ unsigned int val;
+ bool write;
+ int ret;
+
+ lockdep_assert_not_held(&priv->ctl_work_lock);
+
+ scoped_guard(mutex, &priv->ctl_work_lock) {
+ val = ctl_work->ctl_val;
+ write = ctl_work->write;
+ }
+
+ /* Standard IIO voltage unit is mV, scale accordingly. */
+ if (write)
+ ret = iio_write_channel_processed_scale(priv->ctl_dac, val, KILO);
+ else
+ ret = iio_read_channel_processed_scale(priv->ctl_dac, &val, KILO);
+
+ dev_dbg(priv->dev, "%s CTL IO channel, val: %duV\n", str_write_read(write), val);
+
+ scoped_guard(mutex, &priv->ctl_work_lock) {
+ ctl_work->ret = ret;
+ ctl_work->ctl_val = val;
+ }
+
+ complete(&priv->ctl_rw_done);
+}
+
+static int ltm8054_ctl_pin_rw(struct ltm8054_priv *priv, bool write, unsigned int *ctl_val)
+{
+ struct ltm8054_ctl_pin_work *ctl_work = &priv->ctl_work;
+ int ret;
+
+ lockdep_assert_not_held(&priv->ctl_work_lock);
+
+ /*
+ * The get/set_current_limit() callbacks have an active regulator core
+ * reservation ID (obtained with ww_acquire_init()).
+ *
+ * Or, the IO channel driver may call something like
+ * regulator_enable(), meaning this thread would acquire a new
+ * regulator core reservation ID before the current one is dropped
+ * (using ww_acquire_fini()). This is forbidden.
+ *
+ * Thus, perform the IO channel read/write in a different thread, and
+ * wait for it to complete, with a timeout to avoid deadlocking.
+ */
+
+ scoped_guard(mutex, &priv->ctl_work_lock) {
+ if (work_busy(&ctl_work->work))
+ return -EBUSY;
+
+ if (write) {
+ ctl_work->ctl_val = *ctl_val;
+ ctl_work->write = 1;
+ } else {
+ ctl_work->write = 0;
+ }
+
+ schedule_work(&ctl_work->work);
+ }
+
+ ret = wait_for_completion_timeout(&priv->ctl_rw_done, LTM8054_CTL_RW_TIMEOUT);
+ reinit_completion(&priv->ctl_rw_done);
+
+ if (unlikely(!ret))
+ return -ETIMEDOUT;
+
+ scoped_guard(mutex, &priv->ctl_work_lock) {
+ ret = ctl_work->ret;
+
+ if (ret)
+ return ret;
+
+ if (!write)
+ *ctl_val = ctl_work->ctl_val;
+ }
+
+ return 0;
+}
+
+static int ltm8054_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)
+{
+ struct ltm8054_priv *priv = rdev_get_drvdata(rdev);
+ unsigned int ctl_val;
+ u64 vdac_uV;
+
+ min_uA = clamp_t(int, min_uA, priv->min_uA, priv->max_uA);
+
+ /* adjusted current limit = Rsense current limit * CTL pin voltage / max CTL pin voltage */
+ vdac_uV = (u64)min_uA * LTM8054_MAX_CTL_uV;
+ do_div(vdac_uV, priv->max_uA);
+
+ dev_dbg(&rdev->dev,
+ "Setting current limit to %duA, CTL pin to %lluuV\n", min_uA, vdac_uV);
+
+ ctl_val = vdac_uV;
+
+ return ltm8054_ctl_pin_rw(priv, 1, &ctl_val);
+}
+
+static int ltm8054_get_current_limit(struct regulator_dev *rdev)
+{
+ struct ltm8054_priv *priv = rdev_get_drvdata(rdev);
+ unsigned int ctl_val;
+ int ret;
+ u64 uA;
+
+ ret = ltm8054_ctl_pin_rw(priv, 0, &ctl_val);
+ if (ret)
+ return ret;
+
+ uA = (u64)ctl_val * priv->max_uA;
+ do_div(uA, LTM8054_MAX_CTL_uV);
+
+ return uA;
+}
+
+static const struct regulator_ops ltm8054_no_ctl_ops = { };
+
+static const struct regulator_ops ltm8054_ctl_ops = {
+ .set_current_limit = ltm8054_set_current_limit,
+ .get_current_limit = ltm8054_get_current_limit,
+};
+
+static struct iio_channel *ltm8054_init_ctl_dac(struct platform_device *pdev)
+{
+ struct iio_channel *ctl_dac;
+ enum iio_chan_type type;
+ int ret;
+
+ ctl_dac = devm_iio_channel_get(&pdev->dev, "ctl");
+ if (IS_ERR(ctl_dac)) {
+ /*
+ * If the IO channel is not available yet, request probe retry.
+ *
+ * devm_iio_channel_get() will return ENODEV if it can't find
+ * the channel, which will happen if the channel's driver
+ * hasn't probed yet. If it returned any other error code,
+ * then something went wrong with the IO channel, don't retry.
+ */
+ if (PTR_ERR(ctl_dac) == -ENODEV)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ return ctl_dac;
+ }
+
+ ret = iio_get_channel_type(ctl_dac, &type);
+ if (ret)
+ return ERR_PTR(ret);
+
+ if (type != IIO_VOLTAGE)
+ return ERR_PTR(-EINVAL);
+
+ return ctl_dac;
+}
static int ltm8054_of_parse(struct device *dev, struct ltm8054_priv *priv,
struct regulator_config *config)
{
+ u32 rsense;
u32 r[2];
+ u64 tmp;
int ret;
+ ret = device_property_read_u32(dev, "adi,iout-rsense-micro-ohms", &rsense);
+ if (ret)
+ return ret;
+
+ if (rsense == 0)
+ return -EINVAL;
+
+ /* The maximum output current limit is the one set by the Rsense resistor */
+ tmp = (u64)LTM8054_VOUT_IOUT_MAX_uV * MICRO;
+ do_div(tmp, rsense);
+ priv->max_uA = tmp;
+
+ /*
+ * Applying a voltage below LTM8054_MAX_CTL_uV on the CTL pin reduces
+ * the output current limit. If this level drops below
+ * LTM8054_MIN_CTL_uV the regulator stops switching.
+ */
+
+ tmp = (u64)priv->max_uA * LTM8054_MIN_CTL_uV;
+ do_div(tmp, LTM8054_MAX_CTL_uV);
+ priv->min_uA = tmp;
+
ret = device_property_read_u32_array(dev, "regulator-fb-voltage-divider-ohms",
r, ARRAY_SIZE(r));
if (ret)
@@ -58,6 +280,9 @@ static int ltm8054_of_parse(struct device *dev, struct ltm8054_priv *priv,
priv->rdesc.min_uV = priv->rdesc.fixed_uV;
priv->rdesc.n_voltages = 1;
+ dev_dbg(dev, "max_uA: %d min_uA: %d fixed_uV: %d\n",
+ priv->max_uA, priv->min_uA, priv->rdesc.fixed_uV);
+
config->of_node = dev_of_node(dev);
config->init_data = of_get_regulator_init_data(dev,
config->of_node,
@@ -72,23 +297,53 @@ static int ltm8054_of_parse(struct device *dev, struct ltm8054_priv *priv,
return 0;
}
+static void ltm8054_cancel_ctl_work(void *ctl_work)
+{
+ cancel_work_sync(ctl_work);
+}
+
static int ltm8054_probe(struct platform_device *pdev)
{
struct regulator_config config = { };
+ struct iio_channel *ctl_dac = NULL;
struct device *dev = &pdev->dev;
struct regulator_dev *rdev;
struct ltm8054_priv *priv;
int ret;
+ /* Do this first, as it might defer. */
+ if (device_property_match_string(dev, "io-channel-names", "ctl") >= 0) {
+ ctl_dac = ltm8054_init_ctl_dac(pdev);
+ if (IS_ERR(ctl_dac))
+ return dev_err_probe(dev, PTR_ERR(ctl_dac),
+ "failed to initialize CTL DAC\n");
+ }
+
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
+ priv->dev = dev;
priv->rdesc.name = "ltm8054-regulator";
- priv->rdesc.ops = <m8054_regulator_ops;
+ priv->rdesc.ops = <m8054_no_ctl_ops;
priv->rdesc.type = REGULATOR_VOLTAGE;
priv->rdesc.owner = THIS_MODULE;
+ if (ctl_dac) {
+ priv->ctl_dac = ctl_dac;
+
+ INIT_WORK(&priv->ctl_work.work, ltm8054_do_ctl_work);
+ init_completion(&priv->ctl_rw_done);
+
+ devm_add_action_or_reset(priv->dev, ltm8054_cancel_ctl_work, &priv->ctl_work.work);
+
+ ret = devm_mutex_init(priv->dev, &priv->ctl_work_lock);
+ if (ret)
+ return ret;
+
+ priv->rdesc.ops = <m8054_ctl_ops;
+ }
+
config.dev = dev;
config.driver_data = priv;
@@ -121,3 +376,4 @@ module_platform_driver(ltm8054_driver);
MODULE_DESCRIPTION("LTM8054 regulator driver");
MODULE_AUTHOR("Romain Gantois <romain.gantois@bootlin.com>");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_CONSUMER");
--
2.51.2
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-24 14:48 [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Romain Gantois
` (5 preceding siblings ...)
2025-11-24 14:48 ` [PATCH v4 6/6] regulator: ltm8054: Support output current limit control Romain Gantois
@ 2025-11-24 14:57 ` Guenter Roeck
2025-11-24 15:07 ` Andy Shevchenko
2025-11-24 15:13 ` Romain Gantois
6 siblings, 2 replies; 24+ messages in thread
From: Guenter Roeck @ 2025-11-24 14:57 UTC (permalink / raw)
To: Romain Gantois, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Conor Dooley, MyungJoo Ham, Chanwoo Choi, Peter Rosin,
Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich, Kevin Tsai,
Linus Walleij, Dmitry Torokhov, Eugen Hristev, Vinod Koul,
Kishon Vijay Abraham I, Sebastian Reichel, Chen-Yu Tsai,
Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
On 11/24/25 06:48, Romain Gantois wrote:
> Hello everyone,
>
> This is version four of my series which adds initial support of the Linear
> Technology LTM8054 voltage regulator. The driver supports a fixed voltage
> and a tunable output current limit using a DAC-controlled pin.
>
> I'd say that the most unusual part of this series is the usage of the IIO
> consumer API in a regulator driver. I think this makes sense here, since
> the regulator driver has to access a DAC to read/set the output current
> limit.
>
I don't think that is a valid reason. Literally every driver measuring voltages
or current uses a DAC to do it. How else would one convert an analog value
into a digital value ?
Guenter
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-24 14:57 ` [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Guenter Roeck
@ 2025-11-24 15:07 ` Andy Shevchenko
2025-11-24 15:13 ` Romain Gantois
1 sibling, 0 replies; 24+ messages in thread
From: Andy Shevchenko @ 2025-11-24 15:07 UTC (permalink / raw)
To: Guenter Roeck
Cc: Romain Gantois, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Thomas Petazzoni,
linux-kernel, devicetree, linux-iio, Conor Dooley, MyungJoo Ham,
Chanwoo Choi, Peter Rosin, Mariel Tinaco, Lars-Peter Clausen,
Michael Hennerich, Kevin Tsai, Linus Walleij, Dmitry Torokhov,
Eugen Hristev, Vinod Koul, Kishon Vijay Abraham I,
Sebastian Reichel, Chen-Yu Tsai, Support Opensource,
Paul Cercueil, Iskren Chernev, Marek Szyprowski, Matheus Castello,
Saravanan Sekar, Matthias Brugger, AngeloGioacchino Del Regno,
Casey Connolly, Pali Rohár, Orson Zhai, Baolin Wang,
Chunyan Zhang, Amit Kucheria, Thara Gopinath, Rafael J. Wysocki,
Daniel Lezcano, Zhang Rui, Lukasz Luba, Claudiu Beznea,
Jaroslav Kysela, Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32
On Mon, Nov 24, 2025 at 06:57:41AM -0800, Guenter Roeck wrote:
> On 11/24/25 06:48, Romain Gantois wrote:
> >
> > This is version four of my series which adds initial support of the Linear
> > Technology LTM8054 voltage regulator. The driver supports a fixed voltage
> > and a tunable output current limit using a DAC-controlled pin.
> >
> > I'd say that the most unusual part of this series is the usage of the IIO
> > consumer API in a regulator driver. I think this makes sense here, since
> > the regulator driver has to access a DAC to read/set the output current
> > limit.
>
> I don't think that is a valid reason. Literally every driver measuring voltages
> or current uses a DAC to do it. How else would one convert an analog value
> into a digital value ?
While I'm not objecting your vision on this, the ADC is also possible to use to
"measure" the analog signal. DAC approach IIRC considered cheaper solution, but
require an analogue comparator.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-24 14:57 ` [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Guenter Roeck
2025-11-24 15:07 ` Andy Shevchenko
@ 2025-11-24 15:13 ` Romain Gantois
2025-11-24 15:35 ` H. Nikolaus Schaller
2025-11-24 15:40 ` Guenter Roeck
1 sibling, 2 replies; 24+ messages in thread
From: Romain Gantois @ 2025-11-24 15:13 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Guenter Roeck
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Conor Dooley, MyungJoo Ham, Chanwoo Choi, Peter Rosin,
Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich, Kevin Tsai,
Linus Walleij, Dmitry Torokhov, Eugen Hristev, Vinod Koul,
Kishon Vijay Abraham I, Sebastian Reichel, Chen-Yu Tsai,
Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
[-- Attachment #1.1: Type: text/plain, Size: 1359 bytes --]
Hello Guenter,
On Monday, 24 November 2025 15:57:41 CET Guenter Roeck wrote:
> On 11/24/25 06:48, Romain Gantois wrote:
> > Hello everyone,
> >
> > This is version four of my series which adds initial support of the Linear
> > Technology LTM8054 voltage regulator. The driver supports a fixed voltage
> > and a tunable output current limit using a DAC-controlled pin.
> >
> > I'd say that the most unusual part of this series is the usage of the IIO
> > consumer API in a regulator driver. I think this makes sense here, since
> > the regulator driver has to access a DAC to read/set the output current
> > limit.
>
> I don't think that is a valid reason. Literally every driver measuring
> voltages or current uses a DAC to do it. How else would one convert an
> analog value into a digital value ?
Sorry, I don't quite understand your remark. To integrate this voltage
regulator component into the Linux regulator abstraction, I'm providing a
current limit control function. To provide such a function, the voltage level
on a pin has to be controlled. AFAIK, the kernel abstraction used to set
precise voltages on lines is an IO channel.
Do you think that using the IIO consumer API is not correct here? What other
method do you think I should use?
Thanks,
--
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: Type: text/html, Size: 3721 bytes --]
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-24 15:13 ` Romain Gantois
@ 2025-11-24 15:35 ` H. Nikolaus Schaller
2025-11-24 15:57 ` Romain Gantois
2025-11-24 15:40 ` Guenter Roeck
1 sibling, 1 reply; 24+ messages in thread
From: H. Nikolaus Schaller @ 2025-11-24 15:35 UTC (permalink / raw)
To: Romain Gantois
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Guenter Roeck, Thomas Petazzoni, linux-kernel,
devicetree, linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi,
Peter Rosin, Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich,
Kevin Tsai, Linus Walleij, Dmitry Torokhov, Eugen Hristev,
Vinod Koul, Kishon Vijay Abraham I, Sebastian Reichel,
Chen-Yu Tsai, Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
Hi
> Am 24.11.2025 um 16:13 schrieb Romain Gantois <romain.gantois@bootlin.com>:
>
> Hello Guenter,
>
> On Monday, 24 November 2025 15:57:41 CET Guenter Roeck wrote:
> > On 11/24/25 06:48, Romain Gantois wrote:
> > > Hello everyone,
> > >
> > > This is version four of my series which adds initial support of the Linear
> > > Technology LTM8054 voltage regulator. The driver supports a fixed voltage
> > > and a tunable output current limit using a DAC-controlled pin.
> > >
> > > I'd say that the most unusual part of this series is the usage of the IIO
> > > consumer API in a regulator driver. I think this makes sense here, since
> > > the regulator driver has to access a DAC to read/set the output current
> > > limit.
> >
> > I don't think that is a valid reason. Literally every driver measuring
> > voltages or current uses a DAC to do it. How else would one convert an
> > analog value into a digital value ?
>
> Sorry, I don't quite understand your remark. To integrate this voltage
> regulator component into the Linux regulator abstraction, I'm providing a
> current limit control function. To provide such a function, the voltage level
> on a pin has to be controlled. AFAIK, the kernel abstraction used to set
> precise voltages on lines is an IO channel.
I was curious to learn about this topic and looked into the data sheet:
https://www.analog.com/media/en/technical-documentation/data-sheets/8054fa.pdf
As far as I see the LTM8054 does not even have a programming interface.
So is it reasonable to provide a dedicated driver at all?
The figure on page 20 seems to suggest that there is an external DAC
which drives the regulator. And the regulator drives for example a fan.
So I would think of a driver for the specific DAC and ignore the specific
LTM chip at all.
What could be necessary is if you really want to be able to "regulate"
the current going to Vout, some bridge between regulator API and some
IIO DAC.
And enabling/disabling the regulator by some GPIO can be described in
the DT already through a "regulator-fixed".
But this are just my first thoughts as I have not been following this
topic before. Hope it helps.
BR,
Nikolaus
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-24 15:13 ` Romain Gantois
2025-11-24 15:35 ` H. Nikolaus Schaller
@ 2025-11-24 15:40 ` Guenter Roeck
2025-11-24 16:02 ` Romain Gantois
1 sibling, 1 reply; 24+ messages in thread
From: Guenter Roeck @ 2025-11-24 15:40 UTC (permalink / raw)
To: Romain Gantois, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Conor Dooley, MyungJoo Ham, Chanwoo Choi, Peter Rosin,
Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich, Kevin Tsai,
Linus Walleij, Dmitry Torokhov, Eugen Hristev, Vinod Koul,
Kishon Vijay Abraham I, Sebastian Reichel, Chen-Yu Tsai,
Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
On 11/24/25 07:13, Romain Gantois wrote:
> Hello Guenter,
>
>
> On Monday, 24 November 2025 15:57:41 CET Guenter Roeck wrote:
>
> > On 11/24/25 06:48, Romain Gantois wrote:
>
> > > Hello everyone,
>
> > >
>
> > > This is version four of my series which adds initial support of the Linear
>
> > > Technology LTM8054 voltage regulator. The driver supports a fixed voltage
>
> > > and a tunable output current limit using a DAC-controlled pin.
>
> > >
>
> > > I'd say that the most unusual part of this series is the usage of the IIO
>
> > > consumer API in a regulator driver. I think this makes sense here, since
>
> > > the regulator driver has to access a DAC to read/set the output current
>
> > > limit.
>
> >
>
> > I don't think that is a valid reason. Literally every driver measuring
>
> > voltages or current uses a DAC to do it. How else would one convert an
>
> > analog value into a digital value ?
>
>
> Sorry, I don't quite understand your remark. To integrate this voltage
>
> regulator component into the Linux regulator abstraction, I'm providing a
>
> current limit control function. To provide such a function, the voltage level
>
> on a pin has to be controlled. AFAIK, the kernel abstraction used to set
>
> precise voltages on lines is an IO channel.
>
>
> Do you think that using the IIO consumer API is not correct here? What other
>
> method do you think I should use?
>
Ok, I had a look into the datasheet. Unless I am missing something, the chip doesn't
have a digital control or monitoring interface such as I2C or SPI.
At the same time, you copied the hardware monitoring mailing list on this summary and
on (at least) one of the patches, but apparently not on all of them. This lead to my
apparently wrong assumption that iio is used to monitor (not [just] control) something
on the chip. I wrongly assumed that IIO is used to report chip status (voltage, current,
temperature) using an internal DAC. Obviously that was a wrong assumption.
Sorry for that.
Apparently you copied the hwmon mailing list for the introduction of an IIO namespace
and its use in a couple of hwmon drivers in one of the patches. My personal opinion
is that this should not be part of this series but a series of its own. That is just
my personal opinion, though.
Guenter
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-24 15:35 ` H. Nikolaus Schaller
@ 2025-11-24 15:57 ` Romain Gantois
2025-11-24 16:19 ` H. Nikolaus Schaller
0 siblings, 1 reply; 24+ messages in thread
From: Romain Gantois @ 2025-11-24 15:57 UTC (permalink / raw)
To: H. Nikolaus Schaller
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Guenter Roeck, Thomas Petazzoni, linux-kernel,
devicetree, linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi,
Peter Rosin, Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich,
Kevin Tsai, Linus Walleij, Dmitry Torokhov, Eugen Hristev,
Vinod Koul, Kishon Vijay Abraham I, Sebastian Reichel,
Chen-Yu Tsai, Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
[-- Attachment #1.1: Type: text/plain, Size: 2557 bytes --]
Hi Nikolaus,
On Monday, 24 November 2025 16:35:28 CET H. Nikolaus Schaller wrote:
...
> > Sorry, I don't quite understand your remark. To integrate this voltage
> > regulator component into the Linux regulator abstraction, I'm providing a
> > current limit control function. To provide such a function, the voltage
> > level on a pin has to be controlled. AFAIK, the kernel abstraction used
> > to set precise voltages on lines is an IO channel.
>
> I was curious to learn about this topic and looked into the data sheet:
>
> https://www.analog.com/media/en/technical-documentation/data-sheets/8054fa.p
> df
>
> As far as I see the LTM8054 does not even have a programming interface.
> So is it reasonable to provide a dedicated driver at all?
>
> The figure on page 20 seems to suggest that there is an external DAC
> which drives the regulator. And the regulator drives for example a fan.
>
> So I would think of a driver for the specific DAC and ignore the specific
> LTM chip at all.
>
In my use case, the LTM8054 feeds a DC output port on which various devices
may be plugged. Dynamic output current limitation and output voltage level
control for these devices is a requirement, as well as stepped voltage
transitions, thus the need for a proper regulator device.
The LTM8054's feedback pin can be driven by a different DAC, which allows for
dynamic output voltage control. This is a more complex upstreaming topic
however, so I've left it out of this initial series. There are other component
functions which fit in squarely into the regulator framework, such as
input current limit control and soft-start. But I understand that the current
driver might look a bit "bare".
> What could be necessary is if you really want to be able to "regulate"
> the current going to Vout, some bridge between regulator API and some
> IIO DAC.
>
> And enabling/disabling the regulator by some GPIO can be described in
> the DT already through a "regulator-fixed".
>
This is a possibility, but when you bring in all of these other hardware
functions that I mentionned e.g. output voltage control and stepping, you'll
end up with several different devices which look unrelated from userspace, but
actually control the same chip.
Userspace will also have to know about some hardware details to properly
control the DACs, such as the values of the sense and feedback resistors. In
my opinion, this bypasses the kernel's abstraction of hardware.
Thanks,
--
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: Type: text/html, Size: 6687 bytes --]
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-24 15:40 ` Guenter Roeck
@ 2025-11-24 16:02 ` Romain Gantois
0 siblings, 0 replies; 24+ messages in thread
From: Romain Gantois @ 2025-11-24 16:02 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Guenter Roeck
Cc: Thomas Petazzoni, linux-kernel, devicetree, linux-iio,
Conor Dooley, MyungJoo Ham, Chanwoo Choi, Peter Rosin,
Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich, Kevin Tsai,
Linus Walleij, Dmitry Torokhov, Eugen Hristev, Vinod Koul,
Kishon Vijay Abraham I, Sebastian Reichel, Chen-Yu Tsai,
Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
[-- Attachment #1.1: Type: text/plain, Size: 1238 bytes --]
On Monday, 24 November 2025 16:40:37 CET Guenter Roeck wrote:
...
> >
> > Do you think that using the IIO consumer API is not correct here? What
> > other
> >
> > method do you think I should use?
>
> Ok, I had a look into the datasheet. Unless I am missing something, the chip
> doesn't have a digital control or monitoring interface such as I2C or SPI.
>
> At the same time, you copied the hardware monitoring mailing list on this
> summary and on (at least) one of the patches, but apparently not on all of
> them. This lead to my apparently wrong assumption that iio is used to
> monitor (not [just] control) something on the chip. I wrongly assumed that
> IIO is used to report chip status (voltage, current, temperature) using an
> internal DAC. Obviously that was a wrong assumption. Sorry for that.
>
> Apparently you copied the hwmon mailing list for the introduction of an IIO
> namespace and its use in a couple of hwmon drivers in one of the patches.
> My personal opinion is that this should not be part of this series but a
> series of its own. That is just my personal opinion, though.
I understand. I can split it out.
Thanks,
--
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: Type: text/html, Size: 3516 bytes --]
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-24 15:57 ` Romain Gantois
@ 2025-11-24 16:19 ` H. Nikolaus Schaller
2025-11-25 8:41 ` Romain Gantois
2025-11-25 8:49 ` Romain Gantois
0 siblings, 2 replies; 24+ messages in thread
From: H. Nikolaus Schaller @ 2025-11-24 16:19 UTC (permalink / raw)
To: Romain Gantois
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Guenter Roeck, Thomas Petazzoni, linux-kernel,
devicetree, linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi,
Peter Rosin, Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich,
Kevin Tsai, Linus Walleij, Dmitry Torokhov, Eugen Hristev,
Vinod Koul, Kishon Vijay Abraham I, Sebastian Reichel,
Chen-Yu Tsai, Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
Hi,
> Am 24.11.2025 um 16:57 schrieb Romain Gantois <romain.gantois@bootlin.com>:
>
> Hi Nikolaus,
>
> On Monday, 24 November 2025 16:35:28 CET H. Nikolaus Schaller wrote:
> ...
> > > Sorry, I don't quite understand your remark. To integrate this voltage
> > > regulator component into the Linux regulator abstraction, I'm providing a
> > > current limit control function. To provide such a function, the voltage
> > > level on a pin has to be controlled. AFAIK, the kernel abstraction used
> > > to set precise voltages on lines is an IO channel.
> >
> > I was curious to learn about this topic and looked into the data sheet:
> >
> > https://www.analog.com/media/en/technical-documentation/data-sheets/8054fa.p
> > df
> >
> > As far as I see the LTM8054 does not even have a programming interface.
> > So is it reasonable to provide a dedicated driver at all?
> >
> > The figure on page 20 seems to suggest that there is an external DAC
> > which drives the regulator. And the regulator drives for example a fan.
> >
> > So I would think of a driver for the specific DAC and ignore the specific
> > LTM chip at all.
> >
>
> In my use case, the LTM8054 feeds a DC output port on which various devices
> may be plugged. Dynamic output current limitation and output voltage level
> control for these devices is a requirement, as well as stepped voltage
> transitions, thus the need for a proper regulator device.
>
> The LTM8054's feedback pin can be driven by a different DAC, which allows for
> dynamic output voltage control. This is a more complex upstreaming topic
> however, so I've left it out of this initial series. There are other component
> functions which fit in squarely into the regulator framework, such as
> input current limit control and soft-start. But I understand that the current
> driver might look a bit "bare".
So you just want to have some user-space mechanism to control voltage
and current limits? Can't this be done by directly controlling them through
the iio API?
Is this for a device that is already in kernel or planned to be supported?
Or is it "application support" for some SBC?
Are you looking for a virtual "glue" driver to logically combine several low
level functions?
>
> > What could be necessary is if you really want to be able to "regulate"
> > the current going to Vout, some bridge between regulator API and some
> > IIO DAC.
> >
> > And enabling/disabling the regulator by some GPIO can be described in
> > the DT already through a "regulator-fixed".
> >
>
> This is a possibility, but when you bring in all of these other hardware
> functions that I mentionned e.g. output voltage control and stepping, you'll
> end up with several different devices which look unrelated from userspace, but
> actually control the same chip.
That is quite usual... I have often heard: user space must fix this as kernel
just provides basic functions in a harmonized way and integration has to
be tailored to the device anyways :)
> Userspace will also have to know about some hardware details to properly
> control the DACs, such as the values of the sense and feedback resistors. In
> my opinion, this bypasses the kernel's abstraction of hardware.
I came up with this argument several times in the part and got a lot of contrary :)
What I still wonder: does your hardware warrant an upstream driver for a
non-programable chip if a different solution (with help of user-space) already
exist?
Another question: is your scheme generic enough so that it can be expected
that other devices are using it in the same way?
Or could the power controller framework (/sys/class/power_supply) fit better?
There is an API to ask chargers etc. for battery voltage and current limits or
even write them.
There is also "generic-adc-battery" which allows to hook up with arbitrary
iio-adcs for measurements - although you need a DAC in your setup. Maybe an
extension here is a better strategy than a dedicated ltm8054 driver?
BR,
Nikolaus
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-24 16:19 ` H. Nikolaus Schaller
@ 2025-11-25 8:41 ` Romain Gantois
2025-11-25 10:25 ` H. Nikolaus Schaller
2025-11-25 8:49 ` Romain Gantois
1 sibling, 1 reply; 24+ messages in thread
From: Romain Gantois @ 2025-11-25 8:41 UTC (permalink / raw)
To: H. Nikolaus Schaller
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Guenter Roeck, Thomas Petazzoni, linux-kernel,
devicetree, linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi,
Peter Rosin, Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich,
Kevin Tsai, Linus Walleij, Dmitry Torokhov, Eugen Hristev,
Vinod Koul, Kishon Vijay Abraham I, Sebastian Reichel,
Chen-Yu Tsai, Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
[-- Attachment #1.1: Type: text/plain, Size: 3337 bytes --]
On Monday, 24 November 2025 17:19:45 CET H. Nikolaus Schaller wrote:
...
> > The LTM8054's feedback pin can be driven by a different DAC, which allows
> > for dynamic output voltage control. This is a more complex upstreaming
> > topic however, so I've left it out of this initial series. There are
> > other component functions which fit in squarely into the regulator
> > framework, such as input current limit control and soft-start. But I
> > understand that the current driver might look a bit "bare".
>
> So you just want to have some user-space mechanism to control voltage
> and current limits? Can't this be done by directly controlling them through
> the iio API?
>
> Is this for a device that is already in kernel or planned to be supported?
> Or is it "application support" for some SBC?
>
This is planned support for a voltage regulator chip.
> Are you looking for a virtual "glue" driver to logically combine several low
> level functions?
>
I'm looking for a clean userspace abstraction for this component, the low-
level functions in this case are those of a voltage regulator.
> > > What could be necessary is if you really want to be able to "regulate"
> > > the current going to Vout, some bridge between regulator API and some
> > > IIO DAC.
> > >
> > > And enabling/disabling the regulator by some GPIO can be described in
> > > the DT already through a "regulator-fixed".
> >
> > This is a possibility, but when you bring in all of these other hardware
> > functions that I mentionned e.g. output voltage control and stepping,
> > you'll end up with several different devices which look unrelated from
> > userspace, but actually control the same chip.
>
> That is quite usual... I have often heard: user space must fix this as
> kernel just provides basic functions in a harmonized way and integration
> has to be tailored to the device anyways :)
>
IMHO this is not integration, it's BSP work. As far as regulator functions are
concerned, the current status quo is that the kernel handles getting/setting
voltage levels, applying current and voltage constraints and other basic
regulator features.
> > Userspace will also have to know about some hardware details to properly
> > control the DACs, such as the values of the sense and feedback resistors.
> > In my opinion, this bypasses the kernel's abstraction of hardware.
>
> I came up with this argument several times in the part and got a lot of
> contrary :)
>
> What I still wonder: does your hardware warrant an upstream driver for a
> non-programable chip if a different solution (with help of user-space)
> already exist?
>
A different solution does not currently exist (although a userspace-based
solution could be designed). I just think that a kernel-based solution is more
desirable here.
> Another question: is your scheme generic enough so that it can be expected
> that other devices are using it in the same way?
>
Yes, the LTM8054 has a fairly common design as far as buck-boost chips go.
Things like feedback dividers on the output voltage pin are standard practice.
And since the driver doesn't rely on a particular way of integrating the
LTM8054 with other components, it can be reused wherever the same regulator
chip is used.
> Or could the power controller framework (/sys/class/power_supply) fit
> better?
>
[-- Attachment #1.2: Type: text/html, Size: 10604 bytes --]
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-24 16:19 ` H. Nikolaus Schaller
2025-11-25 8:41 ` Romain Gantois
@ 2025-11-25 8:49 ` Romain Gantois
1 sibling, 0 replies; 24+ messages in thread
From: Romain Gantois @ 2025-11-25 8:49 UTC (permalink / raw)
To: H. Nikolaus Schaller
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Guenter Roeck, Thomas Petazzoni, linux-kernel,
devicetree, linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi,
Peter Rosin, Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich,
Kevin Tsai, Linus Walleij, Dmitry Torokhov, Eugen Hristev,
Vinod Koul, Kishon Vijay Abraham I, Sebastian Reichel,
Chen-Yu Tsai, Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
[-- Attachment #1: Type: text/plain, Size: 4139 bytes --]
Re-sending this because my mailer messed up the formatting on the first try...
Sorry if you're receiving this twice.
On Monday, 24 November 2025 17:19:45 CET H. Nikolaus Schaller wrote:
...
> > The LTM8054's feedback pin can be driven by a different DAC, which allows
> > for dynamic output voltage control. This is a more complex upstreaming
> > topic however, so I've left it out of this initial series. There are
> > other component functions which fit in squarely into the regulator
> > framework, such as input current limit control and soft-start. But I
> > understand that the current driver might look a bit "bare".
>
> So you just want to have some user-space mechanism to control voltage
> and current limits? Can't this be done by directly controlling them through
> the iio API?
>
> Is this for a device that is already in kernel or planned to be supported?
> Or is it "application support" for some SBC?
>
This is planned support for a voltage regulator chip.
> Are you looking for a virtual "glue" driver to logically combine several low
> level functions?
>
I'm looking for a clean userspace abstraction for this component, the low-
level functions in this case are those of a voltage regulator.
> > > What could be necessary is if you really want to be able to "regulate"
> > > the current going to Vout, some bridge between regulator API and some
> > > IIO DAC.
> > >
> > > And enabling/disabling the regulator by some GPIO can be described in
> > > the DT already through a "regulator-fixed".
> >
> > This is a possibility, but when you bring in all of these other hardware
> > functions that I mentionned e.g. output voltage control and stepping,
> > you'll end up with several different devices which look unrelated from
> > userspace, but actually control the same chip.
>
> That is quite usual... I have often heard: user space must fix this as
> kernel just provides basic functions in a harmonized way and integration
> has to be tailored to the device anyways :)
>
IMHO this is not integration, it's BSP work. As far as regulator functions are
concerned, the current status quo is that the kernel handles getting/setting
voltage levels, applying current and voltage constraints and other basic
regulator features.
> > Userspace will also have to know about some hardware details to properly
> > control the DACs, such as the values of the sense and feedback resistors.
> > In my opinion, this bypasses the kernel's abstraction of hardware.
>
> I came up with this argument several times in the part and got a lot of
> contrary :)
>
> What I still wonder: does your hardware warrant an upstream driver for a
> non-programable chip if a different solution (with help of user-space)
> already exist?
>
A different solution does not currently exist (although a userspace-based
solution could be designed). I just think that a kernel-based solution is more
desirable here.
> Another question: is your scheme generic enough so that it can be expected
> that other devices are using it in the same way?
>
Yes, the LTM8054 has a fairly common design as far as buck-boost chips go.
Things like feedback dividers on the output voltage pin are standard practice.
And since the driver doesn't rely on a particular way of integrating the
LTM8054 with other components, it can be reused wherever the same regulator
chip is used.
> Or could the power controller framework (/sys/class/power_supply) fit
> better?
>
I don't think the power supply abstraction is relevant here. The LTM8054 is a
voltage regulator, it doesn't have charge, capacity, temperature monitoring,
power limitation, or other power supply class features.
> There is an API to ask chargers etc. for battery voltage and current limits
> or even write them.
>
> There is also "generic-adc-battery" which allows to hook up with arbitrary
> iio-adcs for measurements - although you need a DAC in your setup. Maybe an
> extension here is a better strategy than a dedicated ltm8054 driver?
What if the LTM8054 is not used to supply a battery?
Thanks,
--
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-25 8:41 ` Romain Gantois
@ 2025-11-25 10:25 ` H. Nikolaus Schaller
2025-11-25 16:37 ` Guenter Roeck
2025-11-27 15:06 ` Romain Gantois
0 siblings, 2 replies; 24+ messages in thread
From: H. Nikolaus Schaller @ 2025-11-25 10:25 UTC (permalink / raw)
To: Romain Gantois
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Guenter Roeck, Thomas Petazzoni, linux-kernel,
devicetree, linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi,
Peter Rosin, Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich,
Kevin Tsai, Linus Walleij, Dmitry Torokhov, Eugen Hristev,
Vinod Koul, Kishon Vijay Abraham I, Sebastian Reichel,
Chen-Yu Tsai, Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
Hi,
> Am 25.11.2025 um 09:41 schrieb Romain Gantois <romain.gantois@bootlin.com>:
>
>
> This is planned support for a voltage regulator chip.
Well, but one which is not by itself programmable. So IMHO, it does not support that chip,
but the circuit it is used in.
>
> > Are you looking for a virtual "glue" driver to logically combine several low
> > level functions?
> >
>
> I'm looking for a clean userspace abstraction for this component, the low-
> level functions in this case are those of a voltage regulator.
As far as I understood it has
- constant voltage
- current can be limited
- it can be turned on/off
That means it is a fixed-regulator (for constant voltage and turn on/off)
and a mechanism to program the current limit (iio-dac). Both have clean
userspace abstraction.
What am I missing?
> > What I still wonder: does your hardware warrant an upstream driver for a
> > non-programable chip if a different solution (with help of user-space)
> > already exist?
> >
>
> A different solution does not currently exist (although a userspace-based
> solution could be designed). I just think that a kernel-based solution is more
> desirable here.
I agree, but that is a common discussion :) For example, years ago I had a long
discussion if there should be touchscreen pre-calibration in kernel, which is
desirable to get it almost right after boot, or if it is user-space... In the
end it was rejected.
>
> > Another question: is your scheme generic enough so that it can be expected
> > that other devices are using it in the same way?
> >
>
> Yes, the LTM8054 has a fairly common design as far as buck-boost chips go.
> Things like feedback dividers on the output voltage pin are standard practice.
Yes, I know - but how is this related to the kernel or a driver? To my knowledge
feedback dividers are never relevant for kernel drivers for buck regulators,
especially if they are fixed and can not be programmed. They end up in a specification
of regulator-min-microvolt and regulator-max-microvolt.
So I still wonder why they must be made available to the kernel and user-space.
If you look for example into the schematics of a PocketBeagle 2
(https://docs.beagleboard.org/pocketbeagle-2.pdf).
Figure 3.23 on page 26 shows a 3.3V step-down converter with enable and feedback
resistors (560k/124k).
Still, this regulator is represented not by a dedicated TLV62595 driver but:
https://elixir.bootlin.com/linux/v6.18-rc7/source/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2.dts#L91
Well, it does not have a controllable current limit, just a builtin one.
(And a gpio-control could be added by using a regulator-gpio driver).
> And since the driver doesn't rely on a particular way of integrating the
> LTM8054 with other components, it can be reused wherever the same regulator
> chip is used.
That are my questions:
- what is so different with an LTM8054 to other buck regulators that it needs a dedicated driver
- is the feature to control current limit by a DAC to the LTM8054 or is it the DAC (in software perspective)
- does it need a conversion factor from mA to binary value? Why is this needed in kernel?
- are there similar designs planned for this chip or already in use which run Linux?
> > Or could the power controller framework (/sys/class/power_supply) fit
> > better?
> >
>
> I don't think the power supply abstraction is relevant here. The LTM8054 is a
> voltage regulator, it doesn't have charge, capacity, temperature monitoring,
> power limitation, or other power supply class features.
By current limitation you also have power limitation. Yes, it does not
need to provide charge, capacity, temperature but IMHO they are not all mandatory.
It is just a suggestion to look around if there are different abstractions
that already exist and can be used.
>
> > There is an API to ask chargers etc. for battery voltage and current limits
> > or even write them.
> >
> > There is also "generic-adc-battery" which allows to hook up with arbitrary
> > iio-adcs for measurements - although you need a DAC in your setup. Maybe an
> > extension here is a better strategy than a dedicated ltm8054 driver?
>
>
> What if the LTM8054 is not used to supply a battery?
The question remains if you want to solve something for a single board which
happens to have an LTM8054 or if you are solving a more general design pattern.
In summary my view is that the LTM8054 is just a "fixed-regulator" which
gets an additional current-limiter feature by adding a DAC chip (which needs a
driver of course). So software control is required not by the LTM8054 but by
adding a DAC chip.
Another suggestion: what extending the "regulator-fixed", "regulator-gpio",
"regulator-fixed-clock" pattern by some "regulator-gpio-iio-dac-current-limiter"
driver to make it independent of your specific chip?
By the way, are you aware of this feature of the regulator-gpio driver?
https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/regulator/gpio-regulator.c#L97
Just to note: I am neither maintainer nor doing any decisions on this, just asking
questions for curiosity and from experience and giving hints for alternative approaches,
where I hope they help to find the really best solution.
Best regards,
Nikolaus
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-25 10:25 ` H. Nikolaus Schaller
@ 2025-11-25 16:37 ` Guenter Roeck
2025-12-07 18:48 ` Jonathan Cameron
2025-11-27 15:06 ` Romain Gantois
1 sibling, 1 reply; 24+ messages in thread
From: Guenter Roeck @ 2025-11-25 16:37 UTC (permalink / raw)
To: H. Nikolaus Schaller, Romain Gantois
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Thomas Petazzoni, linux-kernel, devicetree,
linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi, Peter Rosin,
Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich, Kevin Tsai,
Linus Walleij, Dmitry Torokhov, Eugen Hristev, Vinod Koul,
Kishon Vijay Abraham I, Sebastian Reichel, Chen-Yu Tsai,
Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
On 11/25/25 02:25, H. Nikolaus Schaller wrote:
...
> Another suggestion: what extending the "regulator-fixed", "regulator-gpio",
> "regulator-fixed-clock" pattern by some "regulator-gpio-iio-dac-current-limiter"
> driver to make it independent of your specific chip?
>
The name is terrible ;-), but that is what I would have suggested as well.
I don't see anything chip specific in this code. If there is a need for
a regulator driver which uses gpio to enable it and a DAC for current limiting,
it should be made generic.
> By the way, are you aware of this feature of the regulator-gpio driver?
>
> https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/regulator/gpio-regulator.c#L97
>
> Just to note: I am neither maintainer nor doing any decisions on this, just asking
> questions for curiosity and from experience and giving hints for alternative approaches,
> where I hope they help to find the really best solution.
>
Same here.
Thanks,
Guenter
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-25 10:25 ` H. Nikolaus Schaller
2025-11-25 16:37 ` Guenter Roeck
@ 2025-11-27 15:06 ` Romain Gantois
1 sibling, 0 replies; 24+ messages in thread
From: Romain Gantois @ 2025-11-27 15:06 UTC (permalink / raw)
To: H. Nikolaus Schaller
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Guenter Roeck, Thomas Petazzoni, linux-kernel,
devicetree, linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi,
Peter Rosin, Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich,
Kevin Tsai, Linus Walleij, Dmitry Torokhov, Eugen Hristev,
Vinod Koul, Kishon Vijay Abraham I, Sebastian Reichel,
Chen-Yu Tsai, Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
[-- Attachment #1: Type: text/plain, Size: 2608 bytes --]
On Tuesday, 25 November 2025 11:25:24 CET H. Nikolaus Schaller wrote:
> Hi,
>
> > Am 25.11.2025 um 09:41 schrieb Romain Gantois
> > <romain.gantois@bootlin.com>:
> >
> >
> > This is planned support for a voltage regulator chip.
>
> Well, but one which is not by itself programmable. So IMHO, it does not
> support that chip, but the circuit it is used in.
>
The boundary is a bit blurry in this case, sure.
> > > Are you looking for a virtual "glue" driver to logically combine several
> > > low level functions?
> >
> > I'm looking for a clean userspace abstraction for this component, the low-
> > level functions in this case are those of a voltage regulator.
>
> As far as I understood it has
> - constant voltage
> - current can be limited
> - it can be turned on/off
>
> That means it is a fixed-regulator (for constant voltage and turn on/off)
> and a mechanism to program the current limit (iio-dac). Both have clean
> userspace abstraction.
>
> What am I missing?
>
In my case, the regulator has a DAC tapping into the feedback divider with
allows modifying the output voltage level. This isn't specific to the LTM8054
though, you can theoretically do this with any regulator chip that has a
feedback pin.
...
> The question remains if you want to solve something for a single board which
> happens to have an LTM8054 or if you are solving a more general design
> pattern.
>
> In summary my view is that the LTM8054 is just a "fixed-regulator" which
> gets an additional current-limiter feature by adding a DAC chip (which needs
> a driver of course). So software control is required not by the LTM8054 but
> by adding a DAC chip.
>
> Another suggestion: what extending the "regulator-fixed", "regulator-gpio",
> "regulator-fixed-clock" pattern by some
> "regulator-gpio-iio-dac-current-limiter" driver to make it independent of
> your specific chip?
>
> By the way, are you aware of this feature of the regulator-gpio driver?
>
> https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/regulator/gpio-reg
> ulator.c#L97
>
That could be a preferable solution given that similar current limit and
output voltage limit control methods could apply to other regulator chips...
I'll have to think about it some more.
> Just to note: I am neither maintainer nor doing any decisions on this, just
> asking questions for curiosity and from experience and giving hints for
> alternative approaches, where I hope they help to find the really best
> solution.
Sure, I appreciate that.
Thanks,
--
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-11-25 16:37 ` Guenter Roeck
@ 2025-12-07 18:48 ` Jonathan Cameron
2025-12-08 8:57 ` Romain Gantois
0 siblings, 1 reply; 24+ messages in thread
From: Jonathan Cameron @ 2025-12-07 18:48 UTC (permalink / raw)
To: Guenter Roeck
Cc: H. Nikolaus Schaller, Romain Gantois, Liam Girdwood, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, David Lechner,
Nuno Sá, Andy Shevchenko, Thomas Petazzoni, linux-kernel,
devicetree, linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi,
Peter Rosin, Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich,
Kevin Tsai, Linus Walleij, Dmitry Torokhov, Eugen Hristev,
Vinod Koul, Kishon Vijay Abraham I, Sebastian Reichel,
Chen-Yu Tsai, Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
On Tue, 25 Nov 2025 08:37:20 -0800
Guenter Roeck <linux@roeck-us.net> wrote:
> On 11/25/25 02:25, H. Nikolaus Schaller wrote:
> ...
> > Another suggestion: what extending the "regulator-fixed", "regulator-gpio",
> > "regulator-fixed-clock" pattern by some "regulator-gpio-iio-dac-current-limiter"
> > driver to make it independent of your specific chip?
> >
> The name is terrible ;-), but that is what I would have suggested as well.
> I don't see anything chip specific in this code. If there is a need for
> a regulator driver which uses gpio to enable it and a DAC for current limiting,
> it should be made generic.
Agreed - something generic is the ideal way to go.
However, before going too far it is worth exploring what are common circuits with
these things to identify what parameters we need to describe how the DAC channel
is used - e.g is linear scaling enough? You'll need to that to define a DT
binding. If it turns out to be too complex, then fallback to specific
compatibles in a generic driver to cover the ones that don't fit with a common
scheme. A similar case we already have is discrete components as analog front
ends for ADCs - mostly they fall into a few categories and we have drivers
covering those, but some are very odd indeed and for those ones we do have a
driver even though they don't have anything to control as such - most extreme
case being when it's a non linear analog sensor.
The mention of a DAC as part of the analog feedback circuit sounds harder
too generalise but that's specific to this particular buck-boost device,
it's board specific so probably doesn't change the above.
>
> > By the way, are you aware of this feature of the regulator-gpio driver?
> >
> > https://elixir.bootlin.com/linux/v6.18-rc7/source/drivers/regulator/gpio-regulator.c#L97
> >
> > Just to note: I am neither maintainer nor doing any decisions on this, just asking
> > questions for curiosity and from experience and giving hints for alternative approaches,
> > where I hope they help to find the really best solution.
> >
> Same here.
Only covering the thing you are consuming so not my problem to maintain either ;)
Jonathan
>
> Thanks,
> Guenter
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 3/6] iio: add processed write API
2025-11-24 14:48 ` [PATCH v4 3/6] iio: add processed write API Romain Gantois
@ 2025-12-07 18:52 ` Jonathan Cameron
2025-12-08 8:44 ` Romain Gantois
0 siblings, 1 reply; 24+ messages in thread
From: Jonathan Cameron @ 2025-12-07 18:52 UTC (permalink / raw)
To: Romain Gantois
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, David Lechner, Nuno Sá, Andy Shevchenko,
Thomas Petazzoni, linux-kernel, devicetree, linux-iio
On Mon, 24 Nov 2025 15:48:07 +0100
Romain Gantois <romain.gantois@bootlin.com> wrote:
> Add a function to allow IIO consumers to write a processed value to a
> channel.
>
> Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
I'm lazy so I'll just ask the question rather than try to find an answer.
Is there any existing consumer of DAC channels that can use this?
It might be easier to land as a refactor than with the new driver and
reduce what is in the more controversial patch for the regulator.
Jonathan
> ---
> drivers/iio/inkern.c | 127 +++++++++++++++++++++++++++++++++++++++++++
> include/linux/iio/consumer.h | 36 ++++++++++++
> 2 files changed, 163 insertions(+)
>
> diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
> index 70b6f589f37a..6667e8e7648b 100644
> --- a/drivers/iio/inkern.c
> +++ b/drivers/iio/inkern.c
> @@ -635,6 +635,54 @@ int iio_multiply_value(int *result, s64 multiplier,
> }
> EXPORT_SYMBOL_NS_GPL(iio_multiply_value, "IIO_UNIT_TEST");
>
> +int iio_divide_by_value(int *result, s64 numerator,
> + unsigned int type, int val, int val2)
> +{
> + s64 tmp_num, tmp_den;
> +
> + switch (type) {
> + case IIO_VAL_INT:
> + tmp_num = numerator;
> + tmp_den = val;
> + break;
> + case IIO_VAL_INT_PLUS_MICRO:
> + tmp_num = numerator * MICRO;
> + /* Cast inside abs() to avoid undefined behavior if val* == -INT_MIN. */
> + tmp_den = abs((s64)val) * MICRO + abs((s64)val2);
> +
> + if (val < 0 || val2 < 0)
> + tmp_num *= -1;
> +
> + break;
> + case IIO_VAL_INT_PLUS_NANO:
> + tmp_num = numerator * NANO;
> + tmp_den = abs((s64)val) * NANO + abs((s64)val2);
> +
> + if (val < 0 || val2 < 0)
> + tmp_num *= -1;
> +
> + break;
> + case IIO_VAL_FRACTIONAL:
> + tmp_num = (s64)numerator * (s64)val2;
> + tmp_den = val;
> + break;
> + case IIO_VAL_FRACTIONAL_LOG2:
> + tmp_num = (s64)numerator << val2;
> + tmp_den = val;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + if (!tmp_den)
> + return -EDOM;
> +
> + *result = div64_s64(tmp_num, tmp_den);
> +
> + return IIO_VAL_INT;
> +}
> +EXPORT_SYMBOL_NS_GPL(iio_divide_by_value, "IIO_UNIT_TEST");
> +
> static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
> int raw, int *processed,
> unsigned int scale)
> @@ -703,6 +751,66 @@ int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
> }
> EXPORT_SYMBOL_NS_GPL(iio_convert_raw_to_processed, "IIO_CONSUMER");
>
> +static int iio_convert_processed_to_raw_unlocked(struct iio_channel *chan,
> + int processed, int *raw,
> + unsigned int scale)
> +{
> + int scale_type, scale_val, scale_val2;
> + int offset_type, offset_val, offset_val2;
> + int ret, half_step = 0;
> +
> + scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
> + IIO_CHAN_INFO_SCALE);
> + if (scale_type >= 0) {
> + ret = iio_divide_by_value(raw, processed, scale_type, scale_val, scale_val2);
> + if (ret < 0)
> + return ret;
> + } else {
> + *raw = processed;
> + }
> +
> + if (!scale)
> + return -EDOM;
> +
> + *raw = div_s64(*raw, scale);
> +
> + offset_type = iio_channel_read(chan, &offset_val, &offset_val2,
> + IIO_CHAN_INFO_OFFSET);
> +
> + switch (offset_type) {
> + case IIO_VAL_INT:
> + case IIO_VAL_INT_PLUS_MICRO:
> + half_step = MICRO / 2;
> + break;
> + case IIO_VAL_INT_PLUS_NANO:
> + half_step = NANO / 2;
> + break;
> + case IIO_VAL_FRACTIONAL:
> + offset_val = DIV_ROUND_CLOSEST(offset_val, offset_val2);
> + break;
> + case IIO_VAL_FRACTIONAL_LOG2:
> + offset_val >>= offset_val2;
> + break;
> + default:
> + if (offset_type >= 0)
> + return -EINVAL;
> +
> + offset_val = 0;
> + }
> +
> + /* Round fractional part to closest to reduce rounding bias. */
> + if (half_step) {
> + if (offset_val2 >= half_step)
> + *raw -= 1;
> + else if (offset_val2 <= -half_step)
> + *raw += 1;
> + }
> +
> + *raw -= offset_val;
> +
> + return 0;
> +}
> +
> int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2,
> enum iio_chan_info_enum attribute)
> {
> @@ -1039,3 +1147,22 @@ ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf)
> return do_iio_read_channel_label(chan->indio_dev, chan->channel, buf);
> }
> EXPORT_SYMBOL_NS_GPL(iio_read_channel_label, "IIO_CONSUMER");
> +
> +int iio_write_channel_processed_scale(struct iio_channel *chan, int val,
> + unsigned int scale)
> +{
> + struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
> + int ret, processed;
> +
> + guard(mutex)(&iio_dev_opaque->info_exist_lock);
> +
> + if (!chan->indio_dev->info)
> + return -ENODEV;
> +
> + ret = iio_convert_processed_to_raw_unlocked(chan, val, &processed, scale);
> + if (ret)
> + return ret;
> +
> + return iio_channel_write(chan, processed, 0, IIO_CHAN_INFO_RAW);
> +}
> +EXPORT_SYMBOL_NS_GPL(iio_write_channel_processed_scale, "IIO_CONSUMER");
> diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
> index a38b277c2c02..f80ab1b80234 100644
> --- a/include/linux/iio/consumer.h
> +++ b/include/linux/iio/consumer.h
> @@ -399,6 +399,24 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val,
> int iio_multiply_value(int *result, s64 multiplier,
> unsigned int type, int val, int val2);
>
> +/**
> + * iio_divide_by_value() - Divide by an IIO value
> + * @result: Destination pointer for the division result
> + * @numerator: Numerator.
> + * @type: One of the %IIO_VAL_* constants. This decides how the @val
> + * and @val2 parameters are interpreted.
> + * @val: Denominator.
> + * @val2: Denominator. @val2 use depends on type.
> + *
> + * Divide @numerator by an IIO value, storing the result as
> + * %IIO_VAL_INT. This is typically used for scaling.
> + *
> + * Returns:
> + * %IIO_VAL_INT on success or a negative error-number on failure.
> + */
> +int iio_divide_by_value(int *result, s64 numerator,
> + unsigned int type, int val, int val2);
> +
> /**
> * iio_convert_raw_to_processed() - Converts a raw value to a processed value
> * @chan: The channel being queried
> @@ -469,4 +487,22 @@ ssize_t iio_write_channel_ext_info(struct iio_channel *chan, const char *attr,
> */
> ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf);
>
> +/**
> + * iio_write_channel_processed_scale() - scale and write processed value to a given channel
> + * @chan: The channel being queried.
> + * @val: Value to write.
> + * @scale: Processed value is divided by this scale factor during the conversion.
> + *
> + * This function writes a processed value to a channel. A processed value means
> + * that this value will have the correct unit and not some device internal
> + * representation. If the device does not support writing a processed value, the
> + * function will query the channel's scale and offset and write an appropriately
> + * transformed raw value.
> + *
> + * Returns:
> + * 0 or a negative error-number on failure.
> + */
> +int iio_write_channel_processed_scale(struct iio_channel *chan, int val,
> + unsigned int scale);
> +
> #endif
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 3/6] iio: add processed write API
2025-12-07 18:52 ` Jonathan Cameron
@ 2025-12-08 8:44 ` Romain Gantois
0 siblings, 0 replies; 24+ messages in thread
From: Romain Gantois @ 2025-12-08 8:44 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, David Lechner, Nuno Sá, Andy Shevchenko,
Thomas Petazzoni, linux-kernel, devicetree, linux-iio
[-- Attachment #1: Type: text/plain, Size: 1317 bytes --]
Hello Jonathan,
On Sunday, 7 December 2025 19:52:16 CET Jonathan Cameron wrote:
> On Mon, 24 Nov 2025 15:48:07 +0100
>
> Romain Gantois <romain.gantois@bootlin.com> wrote:
> > Add a function to allow IIO consumers to write a processed value to a
> > channel.
> >
> > Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
>
> I'm lazy so I'll just ask the question rather than try to find an answer.
> Is there any existing consumer of DAC channels that can use this?
I'm currently considering upstreaming an extension of iio-rescale which
supports writing to the channel. This could be used to represent some frontend
to a DAC output e.g. an OpAmp inverter, which would be useful for my regulator
use case. At first glance, this looks like it could require this processed
write API, but I'm not 100% sure yet.
> It might be easier to land as a refactor than with the new driver and
> reduce what is in the more controversial patch for the regulator.
Agreed. For now, I'll be sidelining the regulator driver and focusing on
upstreaming support for IIO channels with analog front ends, so that there is
at least a way for userspace to directly write the require current/voltage
levels to an IIO channel.
Thanks,
--
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/6] Add support for the LTM8054 voltage regulator
2025-12-07 18:48 ` Jonathan Cameron
@ 2025-12-08 8:57 ` Romain Gantois
0 siblings, 0 replies; 24+ messages in thread
From: Romain Gantois @ 2025-12-08 8:57 UTC (permalink / raw)
To: Guenter Roeck, Jonathan Cameron
Cc: H. Nikolaus Schaller, Liam Girdwood, Mark Brown, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, David Lechner, Nuno Sá,
Andy Shevchenko, Thomas Petazzoni, linux-kernel, devicetree,
linux-iio, Conor Dooley, MyungJoo Ham, Chanwoo Choi, Peter Rosin,
Mariel Tinaco, Lars-Peter Clausen, Michael Hennerich, Kevin Tsai,
Linus Walleij, Dmitry Torokhov, Eugen Hristev, Vinod Koul,
Kishon Vijay Abraham I, Sebastian Reichel, Chen-Yu Tsai,
Support Opensource, Paul Cercueil, Iskren Chernev,
Marek Szyprowski, Matheus Castello, Saravanan Sekar,
Matthias Brugger, AngeloGioacchino Del Regno, Casey Connolly,
Pali Rohár, Orson Zhai, Baolin Wang, Chunyan Zhang,
Amit Kucheria, Thara Gopinath, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Claudiu Beznea, Jaroslav Kysela,
Takashi Iwai, Sylwester Nawrocki, Olivier Moysan,
Arnaud Pouliquen, Maxime Coquelin, Alexandre Torgue, Dixit Parmar,
linux-hwmon, linux-input, linux-phy, linux-pm, linux-mips,
linux-arm-kernel, linux-mediatek, linux-arm-msm, linux-sound,
linux-stm32, Andy Shevchenko
[-- Attachment #1.1: Type: text/plain, Size: 2582 bytes --]
On Sunday, 7 December 2025 19:48:18 CET Jonathan Cameron wrote:
> On Tue, 25 Nov 2025 08:37:20 -0800
>
> Guenter Roeck <linux@roeck-us.net> wrote:
> > On 11/25/25 02:25, H. Nikolaus Schaller wrote:
> > ...
> >
> > > Another suggestion: what extending the "regulator-fixed",
> > > "regulator-gpio",
> > > "regulator-fixed-clock" pattern by some
> > > "regulator-gpio-iio-dac-current-limiter" driver to make it independent
> > > of your specific chip?
> >
> > The name is terrible ;-), but that is what I would have suggested as well.
> > I don't see anything chip specific in this code. If there is a need for
> > a regulator driver which uses gpio to enable it and a DAC for current
> > limiting, it should be made generic.
>
> Agreed - something generic is the ideal way to go.
>
> However, before going too far it is worth exploring what are common circuits
> with these things to identify what parameters we need to describe how the
> DAC channel is used - e.g is linear scaling enough? You'll need to that to
> define a DT binding. If it turns out to be too complex, then fallback to
> specific compatibles in a generic driver to cover the ones that don't fit
> with a common scheme. A similar case we already have is discrete
> components as analog front ends for ADCs - mostly they fall into a few
> categories and we have drivers covering those, but some are very odd indeed
> and for those ones we do have a driver even though they don't have anything
> to control as such - most extreme case being when it's a non linear analog
> sensor.
>
I actually did use a modified version of iio-rescale in my downstream code. My
use case includes an OpAmp inverter circuit placed in front of a DAC, and it's
useful for me to be able to describe this in a modular fashion, as two IIO
device tree nodes representing respectively the DAC and the OpAmp circuit
front-end.
Moreover, the LTM8054 takes a voltage on its CTL pin and infers a current
limit from it. This is also something which could be represented as a sort of
AFE node.
LTM8054 output voltage control:
+---+ +------------+ +--------------------+
|DAC+->Inverter AFE+->Feedback circuit AFE|
+---+ +------------+ +--------------------+
LTM8054 output current limit control:
+---+ +--------------------+
|DAC+->Voltage-controller |
+---+ |current limiter AFE |
+--------------------+
Thanks,
--
Romain Gantois, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: Type: text/html, Size: 7606 bytes --]
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2025-12-08 8:57 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-24 14:48 [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Romain Gantois
2025-11-24 14:48 ` [PATCH v4 1/6] regulator: dt-bindings: Add Linear Technology LTM8054 regulator Romain Gantois
2025-11-24 14:48 ` [PATCH v4 2/6] iio: inkern: Use namespaced exports Romain Gantois
2025-11-24 14:48 ` [PATCH v4 3/6] iio: add processed write API Romain Gantois
2025-12-07 18:52 ` Jonathan Cameron
2025-12-08 8:44 ` Romain Gantois
2025-11-24 14:48 ` [PATCH v4 4/6] iio: test: Add kunit tests for iio_divide_by_value() Romain Gantois
2025-11-24 14:48 ` [PATCH v4 5/6] regulator: Support the LTM8054 voltage regulator Romain Gantois
2025-11-24 14:48 ` [PATCH v4 6/6] regulator: ltm8054: Support output current limit control Romain Gantois
2025-11-24 14:57 ` [PATCH v4 0/6] Add support for the LTM8054 voltage regulator Guenter Roeck
2025-11-24 15:07 ` Andy Shevchenko
2025-11-24 15:13 ` Romain Gantois
2025-11-24 15:35 ` H. Nikolaus Schaller
2025-11-24 15:57 ` Romain Gantois
2025-11-24 16:19 ` H. Nikolaus Schaller
2025-11-25 8:41 ` Romain Gantois
2025-11-25 10:25 ` H. Nikolaus Schaller
2025-11-25 16:37 ` Guenter Roeck
2025-12-07 18:48 ` Jonathan Cameron
2025-12-08 8:57 ` Romain Gantois
2025-11-27 15:06 ` Romain Gantois
2025-11-25 8:49 ` Romain Gantois
2025-11-24 15:40 ` Guenter Roeck
2025-11-24 16:02 ` Romain Gantois
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).