.../devicetree/bindings/hwmon/ti,ina4230.yaml | 134 +++ MAINTAINERS | 7 + drivers/hwmon/Kconfig | 11 + drivers/hwmon/Makefile | 1 + drivers/hwmon/ina4230.c | 986 +++++++++++++++++++++ 5 files changed, 1139 insertions(+)
TI INA4230 is a 4-channel power monitor with I2C interface, similar in
operation to INA3221 (3-channel) and INA219 (single-channel) but with
a different register layout, different alerting mechanism and slightly
different support for directly reading calculated current/power/energy
values (pre-multiplied by the device itself and needing only to be scaled
by the driver depending on its selected LSB unit values).
In this initial implementation, the driver supports reading voltage,
current, power and energy values, but does not yet support alerts, which
can be added separately if needed. Also the overflows during hardware
calculations are not yet handled, nor is the support for the device's
internal 32-bit energy counter reset.
An example device tree using this binding and driver is available at [1]
(not currently upstreamed, as the device in question is in engineering
phase and not yet publicly available)
[1] https://github.com/flipperdevices/flipper-linux-kernel/blob/flipper-devel/arch/arm64/boot/dts/rockchip/rk3576-flipper-one-rev-f0b0c1.dts
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
Changes in v5:
- Reworded per-channel subnodes description in the binding for clarity (Sashiko)
- NB: Sashiko's suggestion to allow interrupts in the binding sounds premature,
as the alerts mechanism is not implemented yet and there are no known users
to test it. If anyone has hardware with the alert pins wired to an interrupt
line - please shout and we can test/extend it together
- Avoid division by zero when setting the conversion time with all inputs
disabled (Sashiko)
- Added the missed HWMON_I_ENABLE bits (Sashiko)
- Dropped extra sysfs attributes for reading/writing shunt values, as the
implementation was potentially racy and it's unlikely anyone would resolder
the shunts on a running system (Sashiko)
- Skip pm_runtime_put_noidle() for disabled (not just disconnected) channels
in remove and probe error path to avoid refcount underflow (Sashiko)
- Mark CONFIG2 register as volatile, as the reset bits in it are self-clearing
- NB: Sashiko's inquiry about the update interval being underreported due to
not accounting for the number of averaging samples: no, the hardware still
reports updates after each channels * (vbus_ct + vsh_ct), but the reported
value changes slowly due to the averaging
- NB: Sashiko's inquiry about regmap_noinc_read(): same as Guenter's AI
feedback. No, it doesn't break the byte order, as it uses byte-sized reads
- NB: Sashiko's inquiry about potential falling of ina->reg_config1 out of sync
with the hardware upon failed regmap_write() calls: yes, but it will be
written at the next successful write call, so the worst that can happen is
the averaging / conversion time can be wrong for a while. And it will return
a failed status for the failed write call too, so no big deal.
- NB: Sashiko's inquiry about reg_config1 not being written out during probe:
it is written out when the device is runtime-resumed as the refcount gets
incremented during the probe function
- Link to v4: https://lore.kernel.org/r/20260326-ina4230-v4-0-c1e312c09de7@flipper.net
Changes in v4:
- Aligned the maximum value of ti,maximum-expected-current-microamp property
in the binding with the one expected by the driver (Guenter Roeck)
"2147A ought to be enough for anybody (c)"
- Actually requested the optional vs-supply regulator in the driver (Guenter Roeck)
- Program the ALERT_POL bit according to the value of ti,alert-polarity-active-high
even though the alerts themselves are not yet implemented (Guenter Roeck)
- Added a check for manually disabled channels in the is_enabled() function to
avoid reading invalid data from them (Guenter Roeck)
- Dropped support for the single-shot mode as its operation is not clearly
documented in the datasheet and there is no pressing need to support it (Guenter Roeck)
- NB: AI feedback regarding regmap_noinc_read() producing incorrect byte order on LE
hosts is incorrect, as its implementation does a byte-wise read and doesn't care
about the regmap value width or endianness flags, so it produces a 4-byte output
buffer in the same byte order as the device returns, which is BE in this case
- NB: AI feedback regarding fail-path pm_runtime_put_noidle() potentially being
unbalanced if the probe loop failed early is technically correct but practically
irrelevant, as the driver will simply fail to load, and the usage count won't
decrease beyond zero anyway. The alternatives are cumbersome for no real benefit
- Link to v3: https://lore.kernel.org/r/20260310-ina4230-v3-0-06ab3a77c570@flipper.net
Changes in v3:
- Updated the description of the ti,maximum-expected-current-microamp property
in the binding to clarify how it is used, and drop the irrelevant mention of
the PMbus (Guenter Roeck)
- Use div64_u64() instead of do_div() for the final division in the calibration value
calculation to avoid overflows in the denominator (Guenter Roeck)
- Avoid overflow while scaling the voltage values on 32-bit platforms (Guenter Roeck)
- Use regmap_noinc_read() instead of regmap_raw_read() for reading the energy values
to ensure that the regmap / bus driver don't wander off to adjacent registers
during the read operation (on INA4230 the whole 32 bits should be read from
the same register offset) (Guenter Roeck)
- Remove redundant call to ina4230_set_calibration() in the current read path,
as the calibration value is already set when enabling the channel and restored
across PM changes via regcache_sync() (Guenter Roeck)
- Add missing write_enable() function to make hwmon_in_enable writes work as
advertised in is_visible() (Guenter Roeck)
- Add a check for disabled channels before calling pm_runtime_put_noidle() on them
to avoid refcount underflow due to imbalanced get_sync/put_noidle calls (Guenter Roeck)
- Dropped unused include of linux/debugfs.h
- Add missing return checks on regmap_write() calls
- uO -> uOhm in the error message to avoid confusion
- Move probe-time calibration after enabling runtime PM to avoid it being reverted
by the PM sync
- Link to v2: https://lore.kernel.org/r/20260302-ina4230-v2-0-55b49d19d2ab@flipper.net
Changes in v2:
- Replace u64/u64 division with do_div() (kernel test robot)
- Add an example with ti,maximum-expected-current-microamp property in
bindings (Krzysztof Kozlowski)
- Include the newly added binding in MAINTAINERS file (Krzysztof Kozlowski)
- Use dev_err_probe() where appropriate in the driver (Krzysztof Kozlowski)
- Switch to devm_regmap_field_bulk_alloc() instead of an open-coded loop
- Add a bounds check for the calculated calibration value,
and a corresponding error message
- Link to v1: https://lore.kernel.org/r/20260225-ina4230-v1-0-92b1de981d46@flipper.net
---
Alexey Charkov (2):
dt-bindings: hwmon: Add TI INA4230 4-channel I2C power monitor
hwmon: Add support for TI INA4230 power monitor
.../devicetree/bindings/hwmon/ti,ina4230.yaml | 134 +++
MAINTAINERS | 7 +
drivers/hwmon/Kconfig | 11 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/ina4230.c | 986 +++++++++++++++++++++
5 files changed, 1139 insertions(+)
---
base-commit: 3b058d1aeeeff27a7289529c4944291613b364e9
change-id: 20260219-ina4230-74a02409153d
Best regards,
--
Alexey Charkov <alchark@flipper.net>
On 3/30/26 08:14, Alexey Charkov wrote: > TI INA4230 is a 4-channel power monitor with I2C interface, similar in > operation to INA3221 (3-channel) and INA219 (single-channel) but with > a different register layout, different alerting mechanism and slightly > different support for directly reading calculated current/power/energy > values (pre-multiplied by the device itself and needing only to be scaled > by the driver depending on its selected LSB unit values). > > In this initial implementation, the driver supports reading voltage, > current, power and energy values, but does not yet support alerts, which > can be added separately if needed. Also the overflows during hardware > calculations are not yet handled, nor is the support for the device's > internal 32-bit energy counter reset. > > An example device tree using this binding and driver is available at [1] > (not currently upstreamed, as the device in question is in engineering > phase and not yet publicly available) > > [1] https://github.com/flipperdevices/flipper-linux-kernel/blob/flipper-devel/arch/arm64/boot/dts/rockchip/rk3576-flipper-one-rev-f0b0c1.dts > > Signed-off-by: Alexey Charkov <alchark@flipper.net> > --- > Changes in v5: > - Reworded per-channel subnodes description in the binding for clarity (Sashiko) > - NB: Sashiko's suggestion to allow interrupts in the binding sounds premature, > as the alerts mechanism is not implemented yet and there are no known users > to test it. If anyone has hardware with the alert pins wired to an interrupt > line - please shout and we can test/extend it together The bindings are supposed to be complete, even if not implemented, so I am not sure if the DT maintainers will agree here. We'll see. Thanks, Guenter
On Mon, Mar 30, 2026 at 09:07:32AM -0700, Guenter Roeck wrote: > On 3/30/26 08:14, Alexey Charkov wrote: > > TI INA4230 is a 4-channel power monitor with I2C interface, similar in > > operation to INA3221 (3-channel) and INA219 (single-channel) but with > > a different register layout, different alerting mechanism and slightly > > different support for directly reading calculated current/power/energy > > values (pre-multiplied by the device itself and needing only to be scaled > > by the driver depending on its selected LSB unit values). > > > > In this initial implementation, the driver supports reading voltage, > > current, power and energy values, but does not yet support alerts, which > > can be added separately if needed. Also the overflows during hardware > > calculations are not yet handled, nor is the support for the device's > > internal 32-bit energy counter reset. > > > > An example device tree using this binding and driver is available at [1] > > (not currently upstreamed, as the device in question is in engineering > > phase and not yet publicly available) > > > > [1] https://github.com/flipperdevices/flipper-linux-kernel/blob/flipper-devel/arch/arm64/boot/dts/rockchip/rk3576-flipper-one-rev-f0b0c1.dts > > > > Signed-off-by: Alexey Charkov <alchark@flipper.net> > > --- > > Changes in v5: > > - Reworded per-channel subnodes description in the binding for clarity (Sashiko) > > - NB: Sashiko's suggestion to allow interrupts in the binding sounds premature, > > as the alerts mechanism is not implemented yet and there are no known users > > to test it. If anyone has hardware with the alert pins wired to an interrupt > > line - please shout and we can test/extend it together > > The bindings are supposed to be complete, even if not implemented, so I am not sure > if the DT maintainers will agree here. We'll see. Given ti,alert-polarity-active-high is added seems like the interrupt should be too. And the interrupt can specify the polarity, so is that property really needed? There's alway the possibility that you have some inverter on the board too and the interrupt polarity is not enough, but solve that problem when it actually exists. Rob
On 3/31/26 08:52, Rob Herring wrote: > On Mon, Mar 30, 2026 at 09:07:32AM -0700, Guenter Roeck wrote: >> On 3/30/26 08:14, Alexey Charkov wrote: >>> TI INA4230 is a 4-channel power monitor with I2C interface, similar in >>> operation to INA3221 (3-channel) and INA219 (single-channel) but with >>> a different register layout, different alerting mechanism and slightly >>> different support for directly reading calculated current/power/energy >>> values (pre-multiplied by the device itself and needing only to be scaled >>> by the driver depending on its selected LSB unit values). >>> >>> In this initial implementation, the driver supports reading voltage, >>> current, power and energy values, but does not yet support alerts, which >>> can be added separately if needed. Also the overflows during hardware >>> calculations are not yet handled, nor is the support for the device's >>> internal 32-bit energy counter reset. >>> >>> An example device tree using this binding and driver is available at [1] >>> (not currently upstreamed, as the device in question is in engineering >>> phase and not yet publicly available) >>> >>> [1] https://github.com/flipperdevices/flipper-linux-kernel/blob/flipper-devel/arch/arm64/boot/dts/rockchip/rk3576-flipper-one-rev-f0b0c1.dts >>> >>> Signed-off-by: Alexey Charkov <alchark@flipper.net> >>> --- >>> Changes in v5: >>> - Reworded per-channel subnodes description in the binding for clarity (Sashiko) >>> - NB: Sashiko's suggestion to allow interrupts in the binding sounds premature, >>> as the alerts mechanism is not implemented yet and there are no known users >>> to test it. If anyone has hardware with the alert pins wired to an interrupt >>> line - please shout and we can test/extend it together >> >> The bindings are supposed to be complete, even if not implemented, so I am not sure >> if the DT maintainers will agree here. We'll see. > > Given ti,alert-polarity-active-high is added seems like the interrupt > should be too. And the interrupt can specify the polarity, so is that > property really needed? There's alway the possibility that you have some > inverter on the board too and the interrupt polarity is not enough, but > solve that problem when it actually exists. > The alert pin can be attached to a board interrupt, or (more likely) it can be attached to the I2C controller's alert pin. In the latter case there is no interrupt property. Guenter
On Tue, Mar 31, 2026 at 8:10 PM Guenter Roeck <linux@roeck-us.net> wrote: > > On 3/31/26 08:52, Rob Herring wrote: > > On Mon, Mar 30, 2026 at 09:07:32AM -0700, Guenter Roeck wrote: > >> On 3/30/26 08:14, Alexey Charkov wrote: > >>> TI INA4230 is a 4-channel power monitor with I2C interface, similar in > >>> operation to INA3221 (3-channel) and INA219 (single-channel) but with > >>> a different register layout, different alerting mechanism and slightly > >>> different support for directly reading calculated current/power/energy > >>> values (pre-multiplied by the device itself and needing only to be scaled > >>> by the driver depending on its selected LSB unit values). > >>> > >>> In this initial implementation, the driver supports reading voltage, > >>> current, power and energy values, but does not yet support alerts, which > >>> can be added separately if needed. Also the overflows during hardware > >>> calculations are not yet handled, nor is the support for the device's > >>> internal 32-bit energy counter reset. > >>> > >>> An example device tree using this binding and driver is available at [1] > >>> (not currently upstreamed, as the device in question is in engineering > >>> phase and not yet publicly available) > >>> > >>> [1] https://github.com/flipperdevices/flipper-linux-kernel/blob/flipper-devel/arch/arm64/boot/dts/rockchip/rk3576-flipper-one-rev-f0b0c1.dts > >>> > >>> Signed-off-by: Alexey Charkov <alchark@flipper.net> > >>> --- > >>> Changes in v5: > >>> - Reworded per-channel subnodes description in the binding for clarity (Sashiko) > >>> - NB: Sashiko's suggestion to allow interrupts in the binding sounds premature, > >>> as the alerts mechanism is not implemented yet and there are no known users > >>> to test it. If anyone has hardware with the alert pins wired to an interrupt > >>> line - please shout and we can test/extend it together > >> > >> The bindings are supposed to be complete, even if not implemented, so I am not sure > >> if the DT maintainers will agree here. We'll see. > > > > Given ti,alert-polarity-active-high is added seems like the interrupt > > should be too. And the interrupt can specify the polarity, so is that > > property really needed? There's alway the possibility that you have some > > inverter on the board too and the interrupt polarity is not enough, but > > solve that problem when it actually exists. > > > > The alert pin can be attached to a board interrupt, or (more likely) it can > be attached to the I2C controller's alert pin. In the latter case there is > no interrupt property. Alright, I will add the interrupt property and keep the dedicated flag for alert polarity. Following the logic of binding completeness, should I add a flag for the single-shot mode too, even though I dropped that functionality from the driver in one of the prior iterations? Thanks a lot, Alexey
© 2016 - 2026 Red Hat, Inc.