[PATCH v10 0/2] Add MAX14001/MAX14002 support

Marilene Andrade Garcia posted 2 patches 1 month ago
There is a newer version of this series
.../bindings/iio/adc/adi,max14001.yaml        |  79 ++++
MAINTAINERS                                   |   9 +
drivers/iio/adc/Kconfig                       |  10 +
drivers/iio/adc/Makefile                      |   1 +
drivers/iio/adc/max14001.c                    | 355 ++++++++++++++++++
5 files changed, 454 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/adc/adi,max14001.yaml
create mode 100644 drivers/iio/adc/max14001.c
[PATCH v10 0/2] Add MAX14001/MAX14002 support
Posted by Marilene Andrade Garcia 1 month ago
Hello everyone,

Thank you for your input on how to handle the situation with the driver code. 
Kim, I also apologize for the unexpected situation involving your previous 
code.

Based on the suggestions, I applied my v1 code changes to v9 of Kim’s code, 
resulting in this v10 version that combines both. 
Compared to v9, the updates are:

- Added support for max14002.
- Added a function to write a single register, since the write enable 
register must be updated before writing to any others and updated again 
afterward.
- Renamed the init function to better reflect its purpose, which is to 
disable the memory verification fault. I also replaced the one-by-one 
handling of registers verification values with a loop, since they are in 
sequential ascending order.
- Replaced the old regulator APIs with the new ones.
- Updated the device tree documentation to align with the datasheet 
nomenclature for voltage suppliers.
- Used IIO_CHAN_INFO_AVERAGE_RAW to return the filtered average of ADC 
readings.

One of the reviews I received about my v1 version suggested using a custom 
regmap. I attempted to implement that, but I feel that most of the default 
regmap functions (e.g., regmap_update_bits) would need to be overridden 
because of the unique way this device handles communication, such as 
inverting bits before sending a message, updating the write enable register 
before writing any other register, and updating it again afterward. However, 
as I am still new to the IIO kernel code, I may be missing something. If you 
could provide further explanation or an example, I would be grateful.

Regarding locking, Kim’s original code implemented it, and it remains in 
the driver.

I still have a question about using _mean_raw (IIO_CHAN_INFO_AVERAGE_RAW) 
to read the register containing the latest filtered average ADC readings. 
Should I create a v11 version with a patch to include in_voltageY_mean_raw 
in the file /linux/Documentation/ABI/testing/sysfs-bus-iio? 
The idea is to use in_voltageY_mean_raw to return the filtered average and 
also to set how many ADC readings (0, 2, 4, or 8) are included in the mean 
calculation. Any feedback on using IIO_CHAN_INFO_AVERAGE_RAW this way would 
be appreciated.

The v10 changes were tested on a Raspberry Pi 5 using a modified kernel 
(rpi-6.12). The MAX14001PMB evaluation board, which contains two MAX14001 
devices, was used for testing. One device measures current, and the other 
measures voltage. The evaluation board introduces an offset to allow 
measuring negative values. These board-specific characteristics were not 
included in the driver code (neither the offset nor the current channel 
capability), but they were considered in the calculation of the values read 
by the devices. Should the code that applies these board configuration 
parameters be added as an additional driver file inside the IIO subsystem, 
or should it remain only in a user application?

I plan to continue sending patches to cover all the features of the device. 
This includes adding interrupt handling for faults and for when the signal 
exceeds the upper or lower threshold, implementing the inrush current 
feature, and completing the filtered average reading functionality by 
adding the ability to set the number of readings used in the mean 
calculation.

And I would like to thank again my GSoC mentors Marcelo Schmitt, Ceclan 
Dumitru, Jonathan Santos and Dragos Bogdan for their help with the code.

Thank you for your time,
Best regards,
Marilene Andrade Garcia.

Marilene Andrade Garcia (2):
  dt-bindings: iio: adc: add max14001
  iio: adc: max14001: New driver

 .../bindings/iio/adc/adi,max14001.yaml        |  79 ++++
 MAINTAINERS                                   |   9 +
 drivers/iio/adc/Kconfig                       |  10 +
 drivers/iio/adc/Makefile                      |   1 +
 drivers/iio/adc/max14001.c                    | 355 ++++++++++++++++++
 5 files changed, 454 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/adc/adi,max14001.yaml
 create mode 100644 drivers/iio/adc/max14001.c


base-commit: d1487b0b78720b86ec2a2ac7acc683ec90627e5b
-- 
2.34.1

Re: [PATCH v10 0/2] Add MAX14001/MAX14002 support
Posted by David Lechner 1 month ago
On 9/2/25 8:14 AM, Marilene Andrade Garcia wrote:
> Hello everyone,
> 
> Thank you for your input on how to handle the situation with the driver code. 
> Kim, I also apologize for the unexpected situation involving your previous 
> code.
> 
> Based on the suggestions, I applied my v1 code changes to v9 of Kim’s code, 
> resulting in this v10 version that combines both. 
> Compared to v9, the updates are:
> 
> - Added support for max14002.
> - Added a function to write a single register, since the write enable 
> register must be updated before writing to any others and updated again 
> afterward.
> - Renamed the init function to better reflect its purpose, which is to 
> disable the memory verification fault. I also replaced the one-by-one 
> handling of registers verification values with a loop, since they are in 
> sequential ascending order.
> - Replaced the old regulator APIs with the new ones.
> - Updated the device tree documentation to align with the datasheet 
> nomenclature for voltage suppliers.
> - Used IIO_CHAN_INFO_AVERAGE_RAW to return the filtered average of ADC 
> readings.
> 
> One of the reviews I received about my v1 version suggested using a custom 
> regmap. I attempted to implement that, but I feel that most of the default 
> regmap functions (e.g., regmap_update_bits) would need to be overridden 

Usually, you only need to implement one read and one write function for
a custom regmap bus and the core code regmap code will use those for
all of it's function calls. Since you already have a read and write
function, it shouldn't be too hard to adapt them to the regmap bus
callback signatures.

> because of the unique way this device handles communication, such as 
> inverting bits before sending a message, updating the write enable register 
> before writing any other register, and updating it again afterward. However, 
> as I am still new to the IIO kernel code, I may be missing something. If you 
> could provide further explanation or an example, I would be grateful.
> 
> Regarding locking, Kim’s original code implemented it, and it remains in 
> the driver.
> 
> I still have a question about using _mean_raw (IIO_CHAN_INFO_AVERAGE_RAW) 
> to read the register containing the latest filtered average ADC readings. 
> Should I create a v11 version with a patch to include in_voltageY_mean_raw 
> in the file /linux/Documentation/ABI/testing/sysfs-bus-iio? 

There is already "/sys/bus/iio/devices/iio:deviceX/in_Y_mean_raw" which
I think is intended to cover that.

> The idea is to use in_voltageY_mean_raw to return the filtered average and 
> also to set how many ADC readings (0, 2, 4, or 8) are included in the mean 
> calculation. Any feedback on using IIO_CHAN_INFO_AVERAGE_RAW this way would 
> be appreciated.
> 
> The v10 changes were tested on a Raspberry Pi 5 using a modified kernel 
> (rpi-6.12). The MAX14001PMB evaluation board, which contains two MAX14001 
> devices, was used for testing. One device measures current, and the other 
> measures voltage. The evaluation board introduces an offset to allow 
> measuring negative values. These board-specific characteristics were not 
> included in the driver code (neither the offset nor the current channel 
> capability), but they were considered in the calculation of the values read 
> by the devices. Should the code that applies these board configuration 
> parameters be added as an additional driver file inside the IIO subsystem, 
> or should it remain only in a user application?

These features are provided by extra analog frontend (AFE) circuitry
so the are outside of the scope of this driver.

There is an iio/afe/iio-rescale.c driver that can be used to handle this
kind of circuitry. It has "current-sense-amplifier" and "current-sense-shunt".
I didn't look at the eval board schematic in detail to see which one is
the right one for this case. There isn't one for the voltage offset case
though. So if you have some extra time, you could consider adding that.

You will need to add #io-cells to the DT bindings for the MAX chips
so that we can connect it in the devcie tree to the frontend.

    amplifier {
        compatible = "current-sense-amplifier";
        io-channels = <&eval_adc_1>;

        sense-resistor-micro-ohms = <?>;
        sense-gain-mult = <?>;
    };

> 
> I plan to continue sending patches to cover all the features of the device. 
> This includes adding interrupt handling for faults and for when the signal 
> exceeds the upper or lower threshold, implementing the inrush current 
> feature, and completing the filtered average reading functionality by 
> adding the ability to set the number of readings used in the mean 
> calculation.
> 
> And I would like to thank again my GSoC mentors Marcelo Schmitt, Ceclan 
> Dumitru, Jonathan Santos and Dragos Bogdan for their help with the code.
> 
> Thank you for your time,
> Best regards,
> Marilene Andrade Garcia.
> 
> Marilene Andrade Garcia (2):
>   dt-bindings: iio: adc: add max14001
>   iio: adc: max14001: New driver
> 
>  .../bindings/iio/adc/adi,max14001.yaml        |  79 ++++
>  MAINTAINERS                                   |   9 +
>  drivers/iio/adc/Kconfig                       |  10 +
>  drivers/iio/adc/Makefile                      |   1 +
>  drivers/iio/adc/max14001.c                    | 355 ++++++++++++++++++
>  5 files changed, 454 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/adc/adi,max14001.yaml
>  create mode 100644 drivers/iio/adc/max14001.c
> 
> 
> base-commit: d1487b0b78720b86ec2a2ac7acc683ec90627e5b

Re: [PATCH v10 0/2] Add MAX14001/MAX14002 support
Posted by Jonathan Cameron 4 weeks, 1 day ago
> 
> > because of the unique way this device handles communication, such as 
> > inverting bits before sending a message, updating the write enable register 
> > before writing any other register, and updating it again afterward. However, 
> > as I am still new to the IIO kernel code, I may be missing something. If you 
> > could provide further explanation or an example, I would be grateful.
> > 
> > Regarding locking, Kim’s original code implemented it, and it remains in 
> > the driver.
> > 
> > I still have a question about using _mean_raw (IIO_CHAN_INFO_AVERAGE_RAW) 
> > to read the register containing the latest filtered average ADC readings. 
> > Should I create a v11 version with a patch to include in_voltageY_mean_raw 
> > in the file /linux/Documentation/ABI/testing/sysfs-bus-iio?   
> 
> There is already "/sys/bus/iio/devices/iio:deviceX/in_Y_mean_raw" which
> I think is intended to cover that.
> 
> > The idea is to use in_voltageY_mean_raw to return the filtered average and 
> > also to set how many ADC readings (0, 2, 4, or 8) are included in the mean 

0 is an odd value, I assume 1 given average of 0 readings is effectively undefined.

> > calculation. Any feedback on using IIO_CHAN_INFO_AVERAGE_RAW this way would 
> > be appreciated.

Sorry I missed this question in earlier versions.  I'm terrible at reading
cover letters!

Definitely don't use the in_voltage_mean_raw value for the control of the averaging
width.  That is too obscure and normal convention is read and write of
sysfs attributes should see effectively the same value (or not all
either read or write)

This is a little unusual as normally when we see this sort of thing it
easily maps to oversampling but in this case it's a moving window average
rather than a downsampling style.

So a few options come to mind.
1. Treat it as a filter on a channel. Describe with 3dB point and type as
   box filter.
   We probably want to describe it as an additional channel to do this or
   we could have assumption that to read unfiltered, you set the
   filter 3dB to inf (see other discussion ongoing about that).

2. Add another attribute to add richer info to the in_voltage_mean_raw
   Something like in_voltage_mean_num.
   Bit of a special case but we have had the mean_raw interface a long time
   so we can't get rid of that and it seems illogical to force use of filter
   ABI to control it.

> > 
Other stuff from David followed but I have nothing to add to that.

Jonathan