* [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver
@ 2025-02-21 9:09 Eason Yang
2025-02-21 9:09 ` [PATCH v4 1/2] dt-bindings: iio: adc: add NCT7201 ADCs Eason Yang
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Eason Yang @ 2025-02-21 9:09 UTC (permalink / raw)
To: avifishman70, tmaimon77, tali.perry1, venture, yuenn,
benjaminfair, jic23, lars, robh, krzk+dt, conor+dt, nuno.sa,
dlechner, javier.carrasco.cruz, andriy.shevchenko, gstols,
olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3,
marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille,
ramona.nechita, herve.codina, chanh, KWLIU, yhyang2
Cc: openbmc, linux-iio, devicetree, linux-kernel, Eason Yang
Change since version 4:
- Fix comments
- Add interrupts and reset-gpios to the DT example
- Use the FIELD_PREP and FIELD_GET
- Add use_single_write in regmap_config
- Use regmap_access_table
Change since version 3:
- Fix comments
- Don't put nct720"x" in the name, just call it nct7201
- Remove differential inputs until conversions are finished
- Add NCT7201_ prefix in all macros and avoid the tables
- Correct event threshold values in raw units
- Add with and without interrupt callback function to have the event
config part and one that doesn't
- Remove print an error message if regmap_wirte failed case
Change since version 2:
- Remvoe read-vin-data-size property, default use read word vin data
- Use regmap instead of i2c smbus API
- IIO should be IIO_CHAN_INFO_RAW and _SCALE not _PROCESSED
- Use dev_xxx_probe in probe function and dev_xxx in other functions
- Use devm_iio_device_register replace of iio_device_register
- Use guard(mutex) replace of mutex_lock
- Use get_unaligned_le16 conversion API
Changes since version 1:
- Add new property in iio:adc binding document
- Add new driver for Nuvoton NCT720x driver
Eason Yang (2):
dt-bindings: iio: adc: add NCT7201 ADCs
iio: adc: add support for Nuvoton NCT7201
.../bindings/iio/adc/nuvoton,nct7201.yaml | 57 ++
MAINTAINERS | 2 +
drivers/iio/adc/Kconfig | 11 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/nct7201.c | 487 ++++++++++++++++++
5 files changed, 558 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml
create mode 100644 drivers/iio/adc/nct7201.c
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v4 1/2] dt-bindings: iio: adc: add NCT7201 ADCs 2025-02-21 9:09 [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver Eason Yang @ 2025-02-21 9:09 ` Eason Yang 2025-02-21 15:56 ` David Lechner 2025-02-21 16:56 ` Conor Dooley 2025-02-21 9:09 ` [PATCH v4 2/2] iio: adc: add support for Nuvoton NCT7201 Eason Yang 2025-02-22 15:25 ` [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver Jonathan Cameron 2 siblings, 2 replies; 11+ messages in thread From: Eason Yang @ 2025-02-21 9:09 UTC (permalink / raw) To: avifishman70, tmaimon77, tali.perry1, venture, yuenn, benjaminfair, jic23, lars, robh, krzk+dt, conor+dt, nuno.sa, dlechner, javier.carrasco.cruz, andriy.shevchenko, gstols, olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3, marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille, ramona.nechita, herve.codina, chanh, KWLIU, yhyang2 Cc: openbmc, linux-iio, devicetree, linux-kernel, Eason Yang Add a binding specification for the Nuvoton NCT7201/NCT7202 up to 12-bit ADCs with I2C interface. Signed-off-by: Eason Yang <j2anfernee@gmail.com> --- .../bindings/iio/adc/nuvoton,nct7201.yaml | 57 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 58 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml b/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml new file mode 100644 index 000000000000..830c37fd9f22 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/nuvoton,nct7201.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton nct7201 and similar ADCs + +maintainers: + - Eason Yang <j2anfernee@gmail.com> + +description: | + The NCT7201/NCT7202 is a Nuvoton Hardware Monitor IC, contains up to 12 voltage + monitoring channels, with SMBus interface, and up to 4 sets SMBus address + selection by ADDR connection. It also provides ALERT# signal for event + notification and reset input RSTIN# to recover it from a fault condition. + +properties: + compatible: + enum: + - nuvoton,nct7201 + - nuvoton,nct7202 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + reset-gpios: + maxItems: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/interrupt-controller/irq.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + adc@1d { + compatible = "nuvoton,nct7202"; + reg = <0x1d>; + interrupt-parent = <&gpio3>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpio3 28 GPIO_ACTIVE_LOW>; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 3864d473f52f..fdc4aa5c7eff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2831,6 +2831,7 @@ L: openbmc@lists.ozlabs.org (moderated for non-subscribers) S: Supported F: Documentation/devicetree/bindings/*/*/*npcm* F: Documentation/devicetree/bindings/*/*npcm* +F: Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml F: Documentation/devicetree/bindings/rtc/nuvoton,nct3018y.yaml F: arch/arm/boot/dts/nuvoton/nuvoton-npcm* F: arch/arm/mach-npcm/ -- 2.34.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: iio: adc: add NCT7201 ADCs 2025-02-21 9:09 ` [PATCH v4 1/2] dt-bindings: iio: adc: add NCT7201 ADCs Eason Yang @ 2025-02-21 15:56 ` David Lechner 2025-04-07 13:41 ` Yu-Hsian Yang 2025-02-21 16:56 ` Conor Dooley 1 sibling, 1 reply; 11+ messages in thread From: David Lechner @ 2025-02-21 15:56 UTC (permalink / raw) To: Eason Yang, avifishman70, tmaimon77, tali.perry1, venture, yuenn, benjaminfair, jic23, lars, robh, krzk+dt, conor+dt, nuno.sa, javier.carrasco.cruz, andriy.shevchenko, gstols, olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3, marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille, ramona.nechita, herve.codina, chanh, KWLIU, yhyang2 Cc: openbmc, linux-iio, devicetree, linux-kernel On 2/21/25 3:09 AM, Eason Yang wrote: > Add a binding specification for the Nuvoton NCT7201/NCT7202 up to 12-bit > ADCs with I2C interface. > > Signed-off-by: Eason Yang <j2anfernee@gmail.com> > --- > .../bindings/iio/adc/nuvoton,nct7201.yaml | 57 +++++++++++++++++++ > MAINTAINERS | 1 + > 2 files changed, 58 insertions(+) > create mode 100644 Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > > diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml b/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > new file mode 100644 > index 000000000000..830c37fd9f22 > --- /dev/null > +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > @@ -0,0 +1,57 @@ > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/iio/adc/nuvoton,nct7201.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Nuvoton nct7201 and similar ADCs > + > +maintainers: > + - Eason Yang <j2anfernee@gmail.com> > + > +description: | > + The NCT7201/NCT7202 is a Nuvoton Hardware Monitor IC, contains up to 12 voltage > + monitoring channels, with SMBus interface, and up to 4 sets SMBus address > + selection by ADDR connection. It also provides ALERT# signal for event > + notification and reset input RSTIN# to recover it from a fault condition. > + > +properties: > + compatible: > + enum: > + - nuvoton,nct7201 > + - nuvoton,nct7202 > + > + reg: > + maxItems: 1 > + > + interrupts: > + maxItems: 1 > + > + reset-gpios: > + maxItems: 1 > + Maybe this was brought up before, but no power supply? > +required: > + - compatible > + - reg > + > +additionalProperties: false > + > +examples: > + - | > + > + #include <dt-bindings/gpio/gpio.h> > + #include <dt-bindings/interrupt-controller/irq.h> > + > + i2c { > + #address-cells = <1>; > + #size-cells = <0>; > + > + adc@1d { > + compatible = "nuvoton,nct7202"; > + reg = <0x1d>; > + interrupt-parent = <&gpio3>; > + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; > + reset-gpios = <&gpio3 28 GPIO_ACTIVE_LOW>; > + }; > + }; > +... > diff --git a/MAINTAINERS b/MAINTAINERS > index 3864d473f52f..fdc4aa5c7eff 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2831,6 +2831,7 @@ L: openbmc@lists.ozlabs.org (moderated for non-subscribers) > S: Supported > F: Documentation/devicetree/bindings/*/*/*npcm* > F: Documentation/devicetree/bindings/*/*npcm* > +F: Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml This (ARM/NUVOTON NPCM ARCHITECTURE) doesn't look like the right place for adding a stand-alone chip. You will need to start a new section like: NUVOTON NCT7201 IIO DRIVER > F: Documentation/devicetree/bindings/rtc/nuvoton,nct3018y.yaml > F: arch/arm/boot/dts/nuvoton/nuvoton-npcm* > F: arch/arm/mach-npcm/ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: iio: adc: add NCT7201 ADCs 2025-02-21 15:56 ` David Lechner @ 2025-04-07 13:41 ` Yu-Hsian Yang 0 siblings, 0 replies; 11+ messages in thread From: Yu-Hsian Yang @ 2025-04-07 13:41 UTC (permalink / raw) To: David Lechner Cc: avifishman70, tmaimon77, tali.perry1, venture, yuenn, benjaminfair, jic23, lars, robh, krzk+dt, conor+dt, nuno.sa, javier.carrasco.cruz, andriy.shevchenko, gstols, olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3, marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille, ramona.nechita, herve.codina, chanh, KWLIU, yhyang2, openbmc, linux-iio, devicetree, linux-kernel Dear David Lechner, Thanks again for the review, I'll do the changes here and send next patch. David Lechner <dlechner@baylibre.com> 於 2025年2月21日 週五 下午11:56寫道: > > On 2/21/25 3:09 AM, Eason Yang wrote: > > Add a binding specification for the Nuvoton NCT7201/NCT7202 up to 12-bit > > ADCs with I2C interface. > > > > Signed-off-by: Eason Yang <j2anfernee@gmail.com> > > --- > > .../bindings/iio/adc/nuvoton,nct7201.yaml | 57 +++++++++++++++++++ > > MAINTAINERS | 1 + > > 2 files changed, 58 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > > > > diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml b/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > > new file mode 100644 > > index 000000000000..830c37fd9f22 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > > @@ -0,0 +1,57 @@ > > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/iio/adc/nuvoton,nct7201.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: Nuvoton nct7201 and similar ADCs > > + > > +maintainers: > > + - Eason Yang <j2anfernee@gmail.com> > > + > > +description: | > > + The NCT7201/NCT7202 is a Nuvoton Hardware Monitor IC, contains up to 12 voltage > > + monitoring channels, with SMBus interface, and up to 4 sets SMBus address > > + selection by ADDR connection. It also provides ALERT# signal for event > > + notification and reset input RSTIN# to recover it from a fault condition. > > + > > +properties: > > + compatible: > > + enum: > > + - nuvoton,nct7201 > > + - nuvoton,nct7202 > > + > > + reg: > > + maxItems: 1 > > + > > + interrupts: > > + maxItems: 1 > > + > > + reset-gpios: > > + maxItems: 1 > > + > > Maybe this was brought up before, but no power supply? > vdd-supply: description: A 3.3V to supply that powers the chip. vref-supply: description: The regulator supply for the ADC reference voltage. > > +required: > > + - compatible > > + - reg > > + > > +additionalProperties: false > > + > > +examples: > > + - | > > + > > + #include <dt-bindings/gpio/gpio.h> > > + #include <dt-bindings/interrupt-controller/irq.h> > > + > > + i2c { > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + adc@1d { > > + compatible = "nuvoton,nct7202"; > > + reg = <0x1d>; vdd-supply = <&vdd>; vref-supply = <&vref>; > > + interrupt-parent = <&gpio3>; > > + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; > > + reset-gpios = <&gpio3 28 GPIO_ACTIVE_LOW>; > > + }; > > + }; > > +... > > diff --git a/MAINTAINERS b/MAINTAINERS > > index 3864d473f52f..fdc4aa5c7eff 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -2831,6 +2831,7 @@ L: openbmc@lists.ozlabs.org (moderated for non-subscribers) > > S: Supported > > F: Documentation/devicetree/bindings/*/*/*npcm* > > F: Documentation/devicetree/bindings/*/*npcm* > > +F: Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml Remove F: Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > > This (ARM/NUVOTON NPCM ARCHITECTURE) doesn't look like the right place for > adding a stand-alone chip. You will need to start a new section like: > > NUVOTON NCT7201 IIO DRIVER > NUVOTON NCT7201 IIO DRIVER M: Eason Yang <j2anfernee@gmail.com> L: linux-iio@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml F: drivers/iio/adc/nct7201.c > > F: Documentation/devicetree/bindings/rtc/nuvoton,nct3018y.yaml > > F: arch/arm/boot/dts/nuvoton/nuvoton-npcm* > > F: arch/arm/mach-npcm/ > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 1/2] dt-bindings: iio: adc: add NCT7201 ADCs 2025-02-21 9:09 ` [PATCH v4 1/2] dt-bindings: iio: adc: add NCT7201 ADCs Eason Yang 2025-02-21 15:56 ` David Lechner @ 2025-02-21 16:56 ` Conor Dooley 1 sibling, 0 replies; 11+ messages in thread From: Conor Dooley @ 2025-02-21 16:56 UTC (permalink / raw) To: Eason Yang Cc: avifishman70, tmaimon77, tali.perry1, venture, yuenn, benjaminfair, jic23, lars, robh, krzk+dt, conor+dt, nuno.sa, dlechner, javier.carrasco.cruz, andriy.shevchenko, gstols, olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3, marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille, ramona.nechita, herve.codina, chanh, KWLIU, yhyang2, openbmc, linux-iio, devicetree, linux-kernel [-- Attachment #1: Type: text/plain, Size: 3014 bytes --] On Fri, Feb 21, 2025 at 05:09:17PM +0800, Eason Yang wrote: > Add a binding specification for the Nuvoton NCT7201/NCT7202 up to 12-bit > ADCs with I2C interface. > > Signed-off-by: Eason Yang <j2anfernee@gmail.com> > --- > .../bindings/iio/adc/nuvoton,nct7201.yaml | 57 +++++++++++++++++++ > MAINTAINERS | 1 + > 2 files changed, 58 insertions(+) > create mode 100644 Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > > diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml b/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > new file mode 100644 > index 000000000000..830c37fd9f22 > --- /dev/null > +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > @@ -0,0 +1,57 @@ > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/iio/adc/nuvoton,nct7201.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Nuvoton nct7201 and similar ADCs > + > +maintainers: > + - Eason Yang <j2anfernee@gmail.com> > + > +description: | > + The NCT7201/NCT7202 is a Nuvoton Hardware Monitor IC, contains up to 12 voltage > + monitoring channels, with SMBus interface, and up to 4 sets SMBus address > + selection by ADDR connection. It also provides ALERT# signal for event > + notification and reset input RSTIN# to recover it from a fault condition. > + > +properties: > + compatible: > + enum: > + - nuvoton,nct7201 > + - nuvoton,nct7202 When you respin, please add a note about what differs between these devices that requires different handling in the driver. Cheers, Conor. > + > + reg: > + maxItems: 1 > + > + interrupts: > + maxItems: 1 > + > + reset-gpios: > + maxItems: 1 > + > +required: > + - compatible > + - reg > + > +additionalProperties: false > + > +examples: > + - | > + > + #include <dt-bindings/gpio/gpio.h> > + #include <dt-bindings/interrupt-controller/irq.h> > + > + i2c { > + #address-cells = <1>; > + #size-cells = <0>; > + > + adc@1d { > + compatible = "nuvoton,nct7202"; > + reg = <0x1d>; > + interrupt-parent = <&gpio3>; > + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; > + reset-gpios = <&gpio3 28 GPIO_ACTIVE_LOW>; > + }; > + }; > +... > diff --git a/MAINTAINERS b/MAINTAINERS > index 3864d473f52f..fdc4aa5c7eff 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2831,6 +2831,7 @@ L: openbmc@lists.ozlabs.org (moderated for non-subscribers) > S: Supported > F: Documentation/devicetree/bindings/*/*/*npcm* > F: Documentation/devicetree/bindings/*/*npcm* > +F: Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > F: Documentation/devicetree/bindings/rtc/nuvoton,nct3018y.yaml > F: arch/arm/boot/dts/nuvoton/nuvoton-npcm* > F: arch/arm/mach-npcm/ > -- > 2.34.1 > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 2/2] iio: adc: add support for Nuvoton NCT7201 2025-02-21 9:09 [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver Eason Yang 2025-02-21 9:09 ` [PATCH v4 1/2] dt-bindings: iio: adc: add NCT7201 ADCs Eason Yang @ 2025-02-21 9:09 ` Eason Yang 2025-02-21 16:30 ` David Lechner ` (2 more replies) 2025-02-22 15:25 ` [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver Jonathan Cameron 2 siblings, 3 replies; 11+ messages in thread From: Eason Yang @ 2025-02-21 9:09 UTC (permalink / raw) To: avifishman70, tmaimon77, tali.perry1, venture, yuenn, benjaminfair, jic23, lars, robh, krzk+dt, conor+dt, nuno.sa, dlechner, javier.carrasco.cruz, andriy.shevchenko, gstols, olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3, marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille, ramona.nechita, herve.codina, chanh, KWLIU, yhyang2 Cc: openbmc, linux-iio, devicetree, linux-kernel, Eason Yang Add Nuvoton NCT7201/NCT7202 system voltage monitor 12-bit ADC driver NCT7201/NCT7202 supports up to 12 analog voltage monitor inputs and up to 4 SMBus addresses by ADDR pin. Meanwhile, ALERT# hardware event pins for independent alarm signals, and the all threshold values could be set for system protection without any timing delay. It also supports reset input RSTIN# to recover system from a fault condition. Currently, only single-edge mode conversion and threshold events support. Signed-off-by: Eason Yang <j2anfernee@gmail.com> --- MAINTAINERS | 1 + drivers/iio/adc/Kconfig | 11 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/nct7201.c | 487 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 500 insertions(+) create mode 100644 drivers/iio/adc/nct7201.c diff --git a/MAINTAINERS b/MAINTAINERS index fdc4aa5c7eff..389cbbdae1a7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2838,6 +2838,7 @@ F: arch/arm/mach-npcm/ F: arch/arm64/boot/dts/nuvoton/ F: drivers/*/*/*npcm* F: drivers/*/*npcm* +F: drivers/iio/adc/nct7201.c F: drivers/rtc/rtc-nct3018y.c F: include/dt-bindings/clock/nuvoton,npcm7xx-clock.h F: include/dt-bindings/clock/nuvoton,npcm845-clk.h diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 849c90203071..d97eccb1c685 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -1048,6 +1048,17 @@ config NAU7802 To compile this driver as a module, choose M here: the module will be called nau7802. +config NCT7201 + tristate "Nuvoton NCT7201 and NCT7202 Power Monitor" + depends on I2C + select REGMAP_I2C + help + Say yes here to build support for Nuvoton NCT7201 and NCT7202 + Voltage Monitor. + + This driver can also be built as a module. If so, the module + will be called nct7201. + config NPCM_ADC tristate "Nuvoton NPCM ADC driver" depends on ARCH_NPCM || COMPILE_TEST diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index ee19afba62b7..0108472e141c 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -94,6 +94,7 @@ obj-$(CONFIG_MESON_SARADC) += meson_saradc.o obj-$(CONFIG_MP2629_ADC) += mp2629_adc.o obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o obj-$(CONFIG_NAU7802) += nau7802.o +obj-$(CONFIG_NCT7201) += nct7201.o obj-$(CONFIG_NPCM_ADC) += npcm_adc.o obj-$(CONFIG_PAC1921) += pac1921.o obj-$(CONFIG_PAC1934) += pac1934.o diff --git a/drivers/iio/adc/nct7201.c b/drivers/iio/adc/nct7201.c new file mode 100644 index 000000000000..c5d1540bcc00 --- /dev/null +++ b/drivers/iio/adc/nct7201.c @@ -0,0 +1,487 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Driver for Nuvoton nct7201 and nct7202 power monitor chips. + * + * Copyright (c) 2024-2025 Nuvoton Technology corporation. + */ + +#include <linux/array_size.h> +#include <linux/bits.h> +#include <linux/cleanup.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/init.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/regmap.h> +#include <linux/types.h> +#include <linux/unaligned.h> + +#include <linux/iio/events.h> +#include <linux/iio/iio.h> + +#define NCT7201_VIN_MAX 12 +#define NCT7201_IN_SCALING 4995 +#define NCT7201_IN_SCALING_FACTOR 10000 + +#define NCT7201_REG_INTERRUPT_STATUS_1 0x0C +#define NCT7201_REG_INTERRUPT_STATUS_2 0x0D +#define NCT7201_REG_VOLT_LOW_BYTE 0x0F +#define NCT7201_REG_CONFIGURATION 0x10 +#define NCT7201_BIT_CONFIGURATION_START BIT(0) +#define NCT7201_BIT_CONFIGURATION_ALERT_MSK BIT(1) +#define NCT7201_BIT_CONFIGURATION_CONV_RATE BIT(2) +#define NCT7201_BIT_CONFIGURATION_RESET BIT(7) + +#define NCT7201_REG_ADVANCED_CONFIGURATION 0x11 +#define NCT7201_BIT_ADVANCED_CONF_MOD_ALERT BIT(0) +#define NCT7201_BIT_ADVANCED_CONF_MOD_STS BIT(1) +#define NCT7201_BIT_ADVANCED_CONF_FAULT_QUEUE BIT(2) +#define NCT7201_BIT_ADVANCED_CONF_EN_DEEP_SHUTDOWN BIT(4) +#define NCT7201_BIT_ADVANCED_CONF_EN_SMB_TIMEOUT BIT(5) +#define NCT7201_BIT_ADVANCED_CONF_MOD_RSTIN BIT(7) + +#define NCT7201_REG_CHANNEL_INPUT_MODE 0x12 +#define NCT7201_REG_CHANNEL_ENABLE_1 0x13 +#define NCT7201_REG_CHANNEL_ENABLE_1_MASK GENMASK(7, 0) +#define NCT7201_REG_CHANNEL_ENABLE_2 0x14 +#define NCT7201_REG_CHANNEL_ENABLE_2_MASK GENMASK(3, 0) +#define NCT7201_REG_INTERRUPT_MASK_1 0x15 +#define NCT7201_REG_INTERRUPT_MASK_2 0x16 +#define NCT7201_REG_BUSY_STATUS 0x1E +#define NCT7201_BIT_BUSY BIT(0) +#define NCT7201_BIT_PWR_UP BIT(1) +#define NCT7201_REG_ONE_SHOT 0x1F +#define NCT7201_REG_SMUS_ADDRESS 0xFC +#define NCT7201_REG_VIN_MASK GENMASK(15, 3) + +#define NCT7201_REG_VIN(i) (i) +#define NCT7201_REG_VIN_HIGH_LIMIT(i) (0x20 + (i) * 2) +#define NCT7201_REG_VIN_LOW_LIMIT(i) (0x21 + (i) * 2) + +static const struct regmap_range nct7201_read_reg_range[] = { + regmap_reg_range(NCT7201_REG_INTERRUPT_STATUS_1, NCT7201_REG_BUSY_STATUS), + regmap_reg_range(NCT7201_REG_SMUS_ADDRESS, NCT7201_REG_SMUS_ADDRESS), +}; + +static const struct regmap_access_table nct7201_readable_regs_tbl = { + .yes_ranges = nct7201_read_reg_range, + .n_yes_ranges = ARRAY_SIZE(nct7201_read_reg_range), +}; + +static const struct regmap_range nct7201_write_reg_range[] = { + regmap_reg_range(NCT7201_REG_CONFIGURATION, NCT7201_REG_INTERRUPT_MASK_2), + regmap_reg_range(NCT7201_REG_ONE_SHOT, NCT7201_REG_ONE_SHOT), +}; + +static const struct regmap_access_table nct7201_writeable_regs_tbl = { + .yes_ranges = nct7201_write_reg_range, + .n_yes_ranges = ARRAY_SIZE(nct7201_write_reg_range), +}; + +static const struct regmap_range nct7201_read_vin_reg_range[] = { + regmap_reg_range(NCT7201_REG_VIN(0), NCT7201_REG_VIN(NCT7201_VIN_MAX - 1)), + regmap_reg_range(NCT7201_REG_VIN_HIGH_LIMIT(0), + NCT7201_REG_VIN_LOW_LIMIT(NCT7201_VIN_MAX - 1)), +}; + +static const struct regmap_access_table nct7201_readable_vin_regs_tbl = { + .yes_ranges = nct7201_read_vin_reg_range, + .n_yes_ranges = ARRAY_SIZE(nct7201_read_vin_reg_range), +}; + +static const struct regmap_range nct7201_write_vin_reg_range[] = { + regmap_reg_range(NCT7201_REG_VIN_HIGH_LIMIT(0), + NCT7201_REG_VIN_LOW_LIMIT(NCT7201_VIN_MAX - 1)), +}; + +static const struct regmap_access_table nct7201_writeable_vin_regs_tbl = { + .yes_ranges = nct7201_write_vin_reg_range, + .n_yes_ranges = ARRAY_SIZE(nct7201_write_vin_reg_range), +}; + +static const struct regmap_config nct7201_regmap8_config = { + .name = "vin-data-read-byte", + .reg_bits = 8, + .val_bits = 8, + .use_single_write = true, + .max_register = 0xff, + .rd_table = &nct7201_readable_regs_tbl, + .wr_table = &nct7201_writeable_regs_tbl, +}; + +static const struct regmap_config nct7201_regmap16_config = { + .name = "vin-data-read-word", + .reg_bits = 8, + .val_bits = 16, + .max_register = 0xff, + .rd_table = &nct7201_readable_vin_regs_tbl, + .wr_table = &nct7201_writeable_vin_regs_tbl, +}; + +struct nct7201_chip_info { + struct i2c_client *client; + struct mutex access_lock; + struct regmap *regmap; + struct regmap *regmap16; + int num_vin_channels; + u16 vin_mask; +}; + +struct nct7201_adc_model_data { + const char *model_name; + const struct iio_chan_spec *channels; + const int num_channels; + int num_vin_channels; +}; + +static const struct iio_event_spec nct7201_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, +}; + +#define NCT7201_VOLTAGE_CHANNEL(chan, addr) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = chan, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .address = addr, \ + .event_spec = nct7201_events, \ + .num_event_specs = ARRAY_SIZE(nct7201_events), \ + } + +static const struct iio_chan_spec nct7201_channels[] = { + NCT7201_VOLTAGE_CHANNEL(1, 0), + NCT7201_VOLTAGE_CHANNEL(2, 1), + NCT7201_VOLTAGE_CHANNEL(3, 2), + NCT7201_VOLTAGE_CHANNEL(4, 3), + NCT7201_VOLTAGE_CHANNEL(5, 4), + NCT7201_VOLTAGE_CHANNEL(6, 5), + NCT7201_VOLTAGE_CHANNEL(7, 6), + NCT7201_VOLTAGE_CHANNEL(8, 7), +}; + +static const struct iio_chan_spec nct7202_channels[] = { + NCT7201_VOLTAGE_CHANNEL(1, 0), + NCT7201_VOLTAGE_CHANNEL(2, 1), + NCT7201_VOLTAGE_CHANNEL(3, 2), + NCT7201_VOLTAGE_CHANNEL(4, 3), + NCT7201_VOLTAGE_CHANNEL(5, 4), + NCT7201_VOLTAGE_CHANNEL(6, 5), + NCT7201_VOLTAGE_CHANNEL(7, 6), + NCT7201_VOLTAGE_CHANNEL(8, 7), + NCT7201_VOLTAGE_CHANNEL(9, 8), + NCT7201_VOLTAGE_CHANNEL(10, 9), + NCT7201_VOLTAGE_CHANNEL(11, 10), + NCT7201_VOLTAGE_CHANNEL(12, 11), +}; + +static int nct7201_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + u16 volt; + unsigned int value; + int err; + struct nct7201_chip_info *chip = iio_priv(indio_dev); + + if (chan->type != IIO_VOLTAGE) + return -EOPNOTSUPP; + + guard(mutex)(&chip->access_lock); + switch (mask) { + case IIO_CHAN_INFO_RAW: + err = regmap_read(chip->regmap16, NCT7201_REG_VIN(chan->address), &value); + if (err < 0) + return err; + volt = value; + *val = FIELD_GET(NCT7201_REG_VIN_MASK, volt); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + /* From the datasheet, we have to multiply by 0.0004995 */ + *val = 0; + *val2 = 499500; + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } +} + +static int nct7201_read_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) +{ + struct nct7201_chip_info *chip = iio_priv(indio_dev); + u16 volt; + unsigned int value; + int err; + + if (chan->type != IIO_VOLTAGE) + return -EOPNOTSUPP; + + if (info != IIO_EV_INFO_VALUE) + return -EINVAL; + + if (dir == IIO_EV_DIR_FALLING) { + err = regmap_read(chip->regmap16, NCT7201_REG_VIN_LOW_LIMIT(chan->address), + &value); + if (err < 0) + return err; + volt = value; + } else { + err = regmap_read(chip->regmap16, NCT7201_REG_VIN_HIGH_LIMIT(chan->address), + &value); + if (err < 0) + return err; + volt = value; + } + + *val = FIELD_GET(NCT7201_REG_VIN_MASK, volt); + + return IIO_VAL_INT; +} + +static int nct7201_write_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int val, int val2) +{ + struct nct7201_chip_info *chip = iio_priv(indio_dev); + + if (chan->type != IIO_VOLTAGE) + return -EOPNOTSUPP; + + if (info != IIO_EV_INFO_VALUE) + return -EOPNOTSUPP; + + if (dir == IIO_EV_DIR_FALLING) + regmap_write(chip->regmap16, NCT7201_REG_VIN_LOW_LIMIT(chan->address), + FIELD_PREP(NCT7201_REG_VIN_MASK, val)); + else + regmap_write(chip->regmap16, NCT7201_REG_VIN_HIGH_LIMIT(chan->address), + FIELD_PREP(NCT7201_REG_VIN_MASK, val)); + + return 0; +} + +static int nct7201_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct nct7201_chip_info *chip = iio_priv(indio_dev); + + if (chan->type != IIO_VOLTAGE) + return -EOPNOTSUPP; + + return !!(chip->vin_mask & BIT(chan->address)); +} + +static int nct7201_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + bool state) +{ + struct nct7201_chip_info *chip = iio_priv(indio_dev); + unsigned int mask; + + if (chan->type != IIO_VOLTAGE) + return -EOPNOTSUPP; + + mask = BIT(chan->address); + + if (!state && (chip->vin_mask & mask)) + chip->vin_mask &= ~mask; + else if (state && !(chip->vin_mask & mask)) + chip->vin_mask |= mask; + + if (chip->num_vin_channels <= 8) + regmap_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, chip->vin_mask); + else + regmap_bulk_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, + &chip->vin_mask, sizeof(chip->vin_mask)); + + return 0; +} + +static const struct iio_info nct7201_info = { + .read_raw = nct7201_read_raw, + .read_event_config = nct7201_read_event_config, + .write_event_config = nct7201_write_event_config, + .read_event_value = nct7201_read_event_value, + .write_event_value = nct7201_write_event_value, +}; + +static const struct iio_info nct7201_info_no_irq = { + .read_raw = nct7201_read_raw, +}; + +static const struct nct7201_adc_model_data nct7201_model_data = { + .model_name = "nct7201", + .channels = nct7201_channels, + .num_channels = ARRAY_SIZE(nct7201_channels), + .num_vin_channels = 8, +}; + +static const struct nct7201_adc_model_data nct7202_model_data = { + .model_name = "nct7202", + .channels = nct7202_channels, + .num_channels = ARRAY_SIZE(nct7202_channels), + .num_vin_channels = 12, +}; + +static int nct7201_init_chip(struct nct7201_chip_info *chip) +{ + u8 data[2]; + unsigned int value; + int err; + + regmap_write(chip->regmap, NCT7201_REG_CONFIGURATION, + NCT7201_BIT_CONFIGURATION_RESET); + + /* + * After about 25 msecs, the device should be ready and then + * the Power Up bit will be set to 1. If not, wait for it. + */ + mdelay(25); + err = regmap_read(chip->regmap, NCT7201_REG_BUSY_STATUS, &value); + if (err < 0) + return err; + if (!(value & NCT7201_BIT_PWR_UP)) + return dev_err_probe(&chip->client->dev, -EIO, + "Failed to power up after reset\n"); + + /* Enable Channel */ + if (chip->num_vin_channels <= 8) { + data[0] = NCT7201_REG_CHANNEL_ENABLE_1_MASK; + err = regmap_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, data[0]); + if (err < 0) + return dev_err_probe(&chip->client->dev, -EIO, + "Failed to write NCT7201_REG_CHANNEL_ENABLE_1\n"); + } else { + data[0] = NCT7201_REG_CHANNEL_ENABLE_1_MASK; + data[1] = NCT7201_REG_CHANNEL_ENABLE_2_MASK; + err = regmap_bulk_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, + data, ARRAY_SIZE(data)); + if (err < 0) + return dev_err_probe(&chip->client->dev, -EIO, + "Failed to write NCT7201_REG_CHANNEL_ENABLE_1 and NCT7201_REG_CHANNEL_ENABLE_2\n"); + } + + value = get_unaligned_le16(data); + chip->vin_mask = value; + + /* Start monitoring if needed */ + err = regmap_read(chip->regmap, NCT7201_REG_CONFIGURATION, &value); + if (err < 0) + return dev_err_probe(&chip->client->dev, -EIO, + "Failed to read NCT7201_REG_CONFIGURATION\n"); + + regmap_set_bits(chip->regmap, NCT7201_REG_CONFIGURATION, NCT7201_BIT_CONFIGURATION_START); + + return 0; +} + +static int nct7201_probe(struct i2c_client *client) +{ + const struct nct7201_adc_model_data *model_data; + struct nct7201_chip_info *chip; + struct iio_dev *indio_dev; + int ret; + + model_data = i2c_get_match_data(client); + if (!model_data) + return -EINVAL; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); + if (!indio_dev) + return -ENOMEM; + chip = iio_priv(indio_dev); + + chip->regmap = devm_regmap_init_i2c(client, &nct7201_regmap8_config); + if (IS_ERR(chip->regmap)) + return dev_err_probe(&client->dev, PTR_ERR(chip->regmap), + "Failed to init regmap\n"); + + chip->regmap16 = devm_regmap_init_i2c(client, &nct7201_regmap16_config); + if (IS_ERR(chip->regmap16)) + return dev_err_probe(&client->dev, PTR_ERR(chip->regmap16), + "Failed to init regmap16\n"); + + chip->num_vin_channels = model_data->num_vin_channels; + + ret = devm_mutex_init(&client->dev, &chip->access_lock); + if (ret) + return ret; + + chip->client = client; + + ret = nct7201_init_chip(chip); + if (ret < 0) + return ret; + + indio_dev->name = model_data->model_name; + indio_dev->channels = model_data->channels; + indio_dev->num_channels = model_data->num_channels; + if (client->irq) + indio_dev->info = &nct7201_info; + else + indio_dev->info = &nct7201_info_no_irq; + indio_dev->modes = INDIO_DIRECT_MODE; + + return devm_iio_device_register(&client->dev, indio_dev); +} + +static const struct i2c_device_id nct7201_id[] = { + { .name = "nct7201", .driver_data = (kernel_ulong_t)&nct7201_model_data }, + { .name = "nct7202", .driver_data = (kernel_ulong_t)&nct7202_model_data }, + { } +}; +MODULE_DEVICE_TABLE(i2c, nct7201_id); + +static const struct of_device_id nct7201_of_match[] = { + { + .compatible = "nuvoton,nct7201", + .data = &nct7201_model_data, + }, + { + .compatible = "nuvoton,nct7202", + .data = &nct7202_model_data, + }, + { } +}; +MODULE_DEVICE_TABLE(of, nct7201_of_match); + +static struct i2c_driver nct7201_driver = { + .driver = { + .name = "nct7201", + .of_match_table = nct7201_of_match, + }, + .probe = nct7201_probe, + .id_table = nct7201_id, +}; +module_i2c_driver(nct7201_driver); + +MODULE_AUTHOR("Eason Yang <j2anfernee@gmail.com>"); +MODULE_DESCRIPTION("Nuvoton NCT7201 voltage monitor driver"); +MODULE_LICENSE("GPL"); -- 2.34.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 2/2] iio: adc: add support for Nuvoton NCT7201 2025-02-21 9:09 ` [PATCH v4 2/2] iio: adc: add support for Nuvoton NCT7201 Eason Yang @ 2025-02-21 16:30 ` David Lechner 2025-02-22 15:56 ` Jonathan Cameron 2025-02-25 21:11 ` Paul Menzel 2 siblings, 0 replies; 11+ messages in thread From: David Lechner @ 2025-02-21 16:30 UTC (permalink / raw) To: Eason Yang, avifishman70, tmaimon77, tali.perry1, venture, yuenn, benjaminfair, jic23, lars, robh, krzk+dt, conor+dt, nuno.sa, javier.carrasco.cruz, andriy.shevchenko, gstols, olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3, marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille, ramona.nechita, herve.codina, chanh, KWLIU, yhyang2 Cc: openbmc, linux-iio, devicetree, linux-kernel On 2/21/25 3:09 AM, Eason Yang wrote: > Add Nuvoton NCT7201/NCT7202 system voltage monitor 12-bit ADC driver > > NCT7201/NCT7202 supports up to 12 analog voltage monitor inputs and up to > 4 SMBus addresses by ADDR pin. Meanwhile, ALERT# hardware event pins for > independent alarm signals, and the all threshold values could be set for > system protection without any timing delay. It also supports reset input > RSTIN# to recover system from a fault condition. > > Currently, only single-edge mode conversion and threshold events support. > > Signed-off-by: Eason Yang <j2anfernee@gmail.com> > --- > MAINTAINERS | 1 + > drivers/iio/adc/Kconfig | 11 + > drivers/iio/adc/Makefile | 1 + > drivers/iio/adc/nct7201.c | 487 ++++++++++++++++++++++++++++++++++++++ > 4 files changed, 500 insertions(+) > create mode 100644 drivers/iio/adc/nct7201.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index fdc4aa5c7eff..389cbbdae1a7 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2838,6 +2838,7 @@ F: arch/arm/mach-npcm/ > F: arch/arm64/boot/dts/nuvoton/ > F: drivers/*/*/*npcm* > F: drivers/*/*npcm* > +F: drivers/iio/adc/nct7201.c Same comment as DT bindings, this is ARM/NUVOTON NPCM ARCHITECTURE. We need a new section for this chip since it is stand-alone. > F: drivers/rtc/rtc-nct3018y.c > F: include/dt-bindings/clock/nuvoton,npcm7xx-clock.h > F: include/dt-bindings/clock/nuvoton,npcm845-clk.h ... > diff --git a/drivers/iio/adc/nct7201.c b/drivers/iio/adc/nct7201.c > new file mode 100644 > index 000000000000..c5d1540bcc00 > --- /dev/null > +++ b/drivers/iio/adc/nct7201.c > @@ -0,0 +1,487 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Driver for Nuvoton nct7201 and nct7202 power monitor chips. > + * > + * Copyright (c) 2024-2025 Nuvoton Technology corporation. > + */ > + > +#include <linux/array_size.h> > +#include <linux/bits.h> > +#include <linux/cleanup.h> > +#include <linux/delay.h> > +#include <linux/device.h> > +#include <linux/err.h> > +#include <linux/i2c.h> > +#include <linux/init.h> Are we really using something from the init header? > +#include <linux/mod_devicetable.h> > +#include <linux/module.h> > +#include <linux/mutex.h> > +#include <linux/regmap.h> > +#include <linux/types.h> > +#include <linux/unaligned.h> > + > +#include <linux/iio/events.h> > +#include <linux/iio/iio.h> > + ... > +static int nct7201_read_raw(struct iio_dev *indio_dev, > + struct iio_chan_spec const *chan, > + int *val, int *val2, long mask) > +{ > + u16 volt; > + unsigned int value; > + int err; > + struct nct7201_chip_info *chip = iio_priv(indio_dev); > + > + if (chan->type != IIO_VOLTAGE) > + return -EOPNOTSUPP; > + > + guard(mutex)(&chip->access_lock); The regmap should already have an intneral lock, so this mutex seems reduandnt in it's current usage. > + switch (mask) { > + case IIO_CHAN_INFO_RAW: > + err = regmap_read(chip->regmap16, NCT7201_REG_VIN(chan->address), &value); > + if (err < 0) > + return err; > + volt = value; > + *val = FIELD_GET(NCT7201_REG_VIN_MASK, volt); > + return IIO_VAL_INT; > + case IIO_CHAN_INFO_SCALE: > + /* From the datasheet, we have to multiply by 0.0004995 */ > + *val = 0; > + *val2 = 499500; > + return IIO_VAL_INT_PLUS_NANO; > + default: > + return -EINVAL; > + } > +} > + > +static int nct7201_read_event_value(struct iio_dev *indio_dev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir, > + enum iio_event_info info, > + int *val, int *val2) > +{ > + struct nct7201_chip_info *chip = iio_priv(indio_dev); > + u16 volt; > + unsigned int value; > + int err; > + > + if (chan->type != IIO_VOLTAGE) > + return -EOPNOTSUPP; > + > + if (info != IIO_EV_INFO_VALUE) > + return -EINVAL; > + > + if (dir == IIO_EV_DIR_FALLING) { > + err = regmap_read(chip->regmap16, NCT7201_REG_VIN_LOW_LIMIT(chan->address), > + &value); > + if (err < 0) > + return err; > + volt = value; Assigning to volt seems reduant. We can just pass value to FIELD_GET() below. > + } else { > + err = regmap_read(chip->regmap16, NCT7201_REG_VIN_HIGH_LIMIT(chan->address), > + &value); > + if (err < 0) > + return err; > + volt = value; > + } > + > + *val = FIELD_GET(NCT7201_REG_VIN_MASK, volt); > + > + return IIO_VAL_INT; > +} > + > +static int nct7201_write_event_value(struct iio_dev *indio_dev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir, > + enum iio_event_info info, > + int val, int val2) > +{ > + struct nct7201_chip_info *chip = iio_priv(indio_dev); > + > + if (chan->type != IIO_VOLTAGE) > + return -EOPNOTSUPP; > + > + if (info != IIO_EV_INFO_VALUE) > + return -EOPNOTSUPP; > + > + if (dir == IIO_EV_DIR_FALLING) > + regmap_write(chip->regmap16, NCT7201_REG_VIN_LOW_LIMIT(chan->address), > + FIELD_PREP(NCT7201_REG_VIN_MASK, val)); No error checking? Could just return here directly. > + else > + regmap_write(chip->regmap16, NCT7201_REG_VIN_HIGH_LIMIT(chan->address), > + FIELD_PREP(NCT7201_REG_VIN_MASK, val)); > + > + return 0; > +} > + ... > +static int nct7201_write_event_config(struct iio_dev *indio_dev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir, > + bool state) > +{ > + struct nct7201_chip_info *chip = iio_priv(indio_dev); > + unsigned int mask; > + > + if (chan->type != IIO_VOLTAGE) > + return -EOPNOTSUPP; > + > + mask = BIT(chan->address); > + > + if (!state && (chip->vin_mask & mask)) > + chip->vin_mask &= ~mask; > + else if (state && !(chip->vin_mask & mask)) > + chip->vin_mask |= mask; This would be easier to read as: if (state) chip->vin_mask |= mask; else chip->vin_mask &= ~mask; > + > + if (chip->num_vin_channels <= 8) > + regmap_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, chip->vin_mask); No error checking? > + else > + regmap_bulk_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, > + &chip->vin_mask, sizeof(chip->vin_mask)); > + > + return 0; > +} > + ... > +static int nct7201_init_chip(struct nct7201_chip_info *chip) > +{ > + u8 data[2]; > + unsigned int value; > + int err; > + > + regmap_write(chip->regmap, NCT7201_REG_CONFIGURATION, > + NCT7201_BIT_CONFIGURATION_RESET); Check error return? > + > + /* > + * After about 25 msecs, the device should be ready and then > + * the Power Up bit will be set to 1. If not, wait for it. > + */ > + mdelay(25); > + err = regmap_read(chip->regmap, NCT7201_REG_BUSY_STATUS, &value); > + if (err < 0) > + return err; > + if (!(value & NCT7201_BIT_PWR_UP)) > + return dev_err_probe(&chip->client->dev, -EIO, > + "Failed to power up after reset\n"); > + > + /* Enable Channel */ > + if (chip->num_vin_channels <= 8) { > + data[0] = NCT7201_REG_CHANNEL_ENABLE_1_MASK; > + err = regmap_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, data[0]); > + if (err < 0) > + return dev_err_probe(&chip->client->dev, -EIO, > + "Failed to write NCT7201_REG_CHANNEL_ENABLE_1\n"); > + } else { > + data[0] = NCT7201_REG_CHANNEL_ENABLE_1_MASK; > + data[1] = NCT7201_REG_CHANNEL_ENABLE_2_MASK; > + err = regmap_bulk_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, > + data, ARRAY_SIZE(data)); > + if (err < 0) > + return dev_err_probe(&chip->client->dev, -EIO, > + "Failed to write NCT7201_REG_CHANNEL_ENABLE_1 and NCT7201_REG_CHANNEL_ENABLE_2\n"); > + } > + > + value = get_unaligned_le16(data); Does it matter that data[1] may be uninitialized and contain random value here? > + chip->vin_mask = value; Don't really need the intermediate value assignment here. > + > + /* Start monitoring if needed */ > + err = regmap_read(chip->regmap, NCT7201_REG_CONFIGURATION, &value); > + if (err < 0) > + return dev_err_probe(&chip->client->dev, -EIO, > + "Failed to read NCT7201_REG_CONFIGURATION\n"); > + > + regmap_set_bits(chip->regmap, NCT7201_REG_CONFIGURATION, NCT7201_BIT_CONFIGURATION_START); > + > + return 0; > +} > + ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 2/2] iio: adc: add support for Nuvoton NCT7201 2025-02-21 9:09 ` [PATCH v4 2/2] iio: adc: add support for Nuvoton NCT7201 Eason Yang 2025-02-21 16:30 ` David Lechner @ 2025-02-22 15:56 ` Jonathan Cameron 2025-02-25 21:11 ` Paul Menzel 2 siblings, 0 replies; 11+ messages in thread From: Jonathan Cameron @ 2025-02-22 15:56 UTC (permalink / raw) To: Eason Yang Cc: avifishman70, tmaimon77, tali.perry1, venture, yuenn, benjaminfair, lars, robh, krzk+dt, conor+dt, nuno.sa, dlechner, javier.carrasco.cruz, andriy.shevchenko, gstols, olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3, marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille, ramona.nechita, herve.codina, chanh, KWLIU, yhyang2, openbmc, linux-iio, devicetree, linux-kernel On Fri, 21 Feb 2025 17:09:18 +0800 Eason Yang <j2anfernee@gmail.com> wrote: > Add Nuvoton NCT7201/NCT7202 system voltage monitor 12-bit ADC driver > > NCT7201/NCT7202 supports up to 12 analog voltage monitor inputs and up to > 4 SMBus addresses by ADDR pin. Meanwhile, ALERT# hardware event pins for > independent alarm signals, and the all threshold values could be set for > system protection without any timing delay. It also supports reset input > RSTIN# to recover system from a fault condition. > > Currently, only single-edge mode conversion and threshold events support. > > Signed-off-by: Eason Yang <j2anfernee@gmail.com> Hi Eason A few comments from me. May well overlap in some places with other feedback. Jonathan > diff --git a/drivers/iio/adc/nct7201.c b/drivers/iio/adc/nct7201.c > new file mode 100644 > index 000000000000..c5d1540bcc00 > --- /dev/null > +++ b/drivers/iio/adc/nct7201.c > @@ -0,0 +1,487 @@ > + > +#define NCT7201_VOLTAGE_CHANNEL(chan, addr) \ > + { \ > + .type = IIO_VOLTAGE, \ > + .indexed = 1, \ > + .channel = chan, \ > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ > + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ > + .address = addr, \ > + .event_spec = nct7201_events, \ > + .num_event_specs = ARRAY_SIZE(nct7201_events), \ > + } > + > +static const struct iio_chan_spec nct7201_channels[] = { > + NCT7201_VOLTAGE_CHANNEL(1, 0), > + NCT7201_VOLTAGE_CHANNEL(2, 1), > + NCT7201_VOLTAGE_CHANNEL(3, 2), > + NCT7201_VOLTAGE_CHANNEL(4, 3), > + NCT7201_VOLTAGE_CHANNEL(5, 4), > + NCT7201_VOLTAGE_CHANNEL(6, 5), > + NCT7201_VOLTAGE_CHANNEL(7, 6), > + NCT7201_VOLTAGE_CHANNEL(8, 7), > +}; > + > +static const struct iio_chan_spec nct7202_channels[] = { > + NCT7201_VOLTAGE_CHANNEL(1, 0), > + NCT7201_VOLTAGE_CHANNEL(2, 1), > + NCT7201_VOLTAGE_CHANNEL(3, 2), > + NCT7201_VOLTAGE_CHANNEL(4, 3), > + NCT7201_VOLTAGE_CHANNEL(5, 4), > + NCT7201_VOLTAGE_CHANNEL(6, 5), > + NCT7201_VOLTAGE_CHANNEL(7, 6), > + NCT7201_VOLTAGE_CHANNEL(8, 7), > + NCT7201_VOLTAGE_CHANNEL(9, 8), > + NCT7201_VOLTAGE_CHANNEL(10, 9), > + NCT7201_VOLTAGE_CHANNEL(11, 10), > + NCT7201_VOLTAGE_CHANNEL(12, 11), We normally number channels from 0 which would simplify this but I don't really mind if you want to keep the offset of 1. Maybe just have one macro parameter though and do the +1 in the macro. > +}; > +static int nct7201_read_event_value(struct iio_dev *indio_dev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir, > + enum iio_event_info info, > + int *val, int *val2) > +{ > + struct nct7201_chip_info *chip = iio_priv(indio_dev); > + u16 volt; > + unsigned int value; > + int err; > + > + if (chan->type != IIO_VOLTAGE) > + return -EOPNOTSUPP; > + > + if (info != IIO_EV_INFO_VALUE) > + return -EINVAL; > + > + if (dir == IIO_EV_DIR_FALLING) { > + err = regmap_read(chip->regmap16, NCT7201_REG_VIN_LOW_LIMIT(chan->address), > + &value); > + if (err < 0) > + return err; > + volt = value; > + } else { > + err = regmap_read(chip->regmap16, NCT7201_REG_VIN_HIGH_LIMIT(chan->address), > + &value); > + if (err < 0) > + return err; > + volt = value; No real point in assigning to volt here, > + } > + > + *val = FIELD_GET(NCT7201_REG_VIN_MASK, volt); > + > + return IIO_VAL_INT; > +} > + > +static int nct7201_write_event_value(struct iio_dev *indio_dev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir, > + enum iio_event_info info, > + int val, int val2) > +{ > + struct nct7201_chip_info *chip = iio_priv(indio_dev); > + > + if (chan->type != IIO_VOLTAGE) > + return -EOPNOTSUPP; > + > + if (info != IIO_EV_INFO_VALUE) > + return -EOPNOTSUPP; > + > + if (dir == IIO_EV_DIR_FALLING) > + regmap_write(chip->regmap16, NCT7201_REG_VIN_LOW_LIMIT(chan->address), > + FIELD_PREP(NCT7201_REG_VIN_MASK, val)); > + else > + regmap_write(chip->regmap16, NCT7201_REG_VIN_HIGH_LIMIT(chan->address), > + FIELD_PREP(NCT7201_REG_VIN_MASK, val)); Check for error returns. > + > + return 0; > +} > + > +static int nct7201_read_event_config(struct iio_dev *indio_dev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir) > +{ > + struct nct7201_chip_info *chip = iio_priv(indio_dev); > + > + if (chan->type != IIO_VOLTAGE) > + return -EOPNOTSUPP; > + > + return !!(chip->vin_mask & BIT(chan->address)); > +} > + > +static int nct7201_write_event_config(struct iio_dev *indio_dev, > + const struct iio_chan_spec *chan, > + enum iio_event_type type, > + enum iio_event_direction dir, > + bool state) > +{ > + struct nct7201_chip_info *chip = iio_priv(indio_dev); > + unsigned int mask; > + > + if (chan->type != IIO_VOLTAGE) > + return -EOPNOTSUPP; > + > + mask = BIT(chan->address); > + > + if (!state && (chip->vin_mask & mask)) > + chip->vin_mask &= ~mask; > + else if (state && !(chip->vin_mask & mask)) > + chip->vin_mask |= mask; > + > + if (chip->num_vin_channels <= 8) > + regmap_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, chip->vin_mask); > + else > + regmap_bulk_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, > + &chip->vin_mask, sizeof(chip->vin_mask)); Check errors on these writes. > + > + return 0; > +} > +static int nct7201_init_chip(struct nct7201_chip_info *chip) > +{ > + u8 data[2]; > + unsigned int value; > + int err; > + > + regmap_write(chip->regmap, NCT7201_REG_CONFIGURATION, > + NCT7201_BIT_CONFIGURATION_RESET); Check for errors on all accesses to the device. It can get fiddly in paths where you are already handling an error but that's not the case here. > + > + /* > + * After about 25 msecs, the device should be ready and then > + * the Power Up bit will be set to 1. If not, wait for it. Wrap to 80 chars. > + */ > + mdelay(25); > + err = regmap_read(chip->regmap, NCT7201_REG_BUSY_STATUS, &value); > + if (err < 0) > + return err; > + if (!(value & NCT7201_BIT_PWR_UP)) > + return dev_err_probe(&chip->client->dev, -EIO, > + "Failed to power up after reset\n"); > + > + /* Enable Channel */ > + if (chip->num_vin_channels <= 8) { > + data[0] = NCT7201_REG_CHANNEL_ENABLE_1_MASK; > + err = regmap_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, data[0]); > + if (err < 0) > + return dev_err_probe(&chip->client->dev, -EIO, > + "Failed to write NCT7201_REG_CHANNEL_ENABLE_1\n"); > + } else { > + data[0] = NCT7201_REG_CHANNEL_ENABLE_1_MASK; > + data[1] = NCT7201_REG_CHANNEL_ENABLE_2_MASK; > + err = regmap_bulk_write(chip->regmap, NCT7201_REG_CHANNEL_ENABLE_1, > + data, ARRAY_SIZE(data)); > + if (err < 0) > + return dev_err_probe(&chip->client->dev, -EIO, > + "Failed to write NCT7201_REG_CHANNEL_ENABLE_1 and NCT7201_REG_CHANNEL_ENABLE_2\n"); > + } > + > + value = get_unaligned_le16(data); > + chip->vin_mask = value; Local variable doesn't seem to add any benefits so just assign vin_mask directly. > + > + /* Start monitoring if needed */ > + err = regmap_read(chip->regmap, NCT7201_REG_CONFIGURATION, &value); > + if (err < 0) > + return dev_err_probe(&chip->client->dev, -EIO, > + "Failed to read NCT7201_REG_CONFIGURATION\n"); > + > + regmap_set_bits(chip->regmap, NCT7201_REG_CONFIGURATION, NCT7201_BIT_CONFIGURATION_START); > + > + return 0; > +} > + > +static int nct7201_probe(struct i2c_client *client) > +{ > + const struct nct7201_adc_model_data *model_data; > + struct nct7201_chip_info *chip; > + struct iio_dev *indio_dev; > + int ret; > + > + model_data = i2c_get_match_data(client); > + if (!model_data) > + return -EINVAL; > + > + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip)); > + if (!indio_dev) > + return -ENOMEM; > + chip = iio_priv(indio_dev); > + > + chip->regmap = devm_regmap_init_i2c(client, &nct7201_regmap8_config); > + if (IS_ERR(chip->regmap)) > + return dev_err_probe(&client->dev, PTR_ERR(chip->regmap), > + "Failed to init regmap\n"); Where it doesn't lead to really long lines, align all parameters to just after the opening bracket. > + > + chip->regmap16 = devm_regmap_init_i2c(client, &nct7201_regmap16_config); > + if (IS_ERR(chip->regmap16)) > + return dev_err_probe(&client->dev, PTR_ERR(chip->regmap16), > + "Failed to init regmap16\n"); > + > + chip->num_vin_channels = model_data->num_vin_channels; > + > + ret = devm_mutex_init(&client->dev, &chip->access_lock); > + if (ret) > + return ret; > + > + chip->client = client; > + > + ret = nct7201_init_chip(chip); > + if (ret < 0) > + return ret; > + > + indio_dev->name = model_data->model_name; > + indio_dev->channels = model_data->channels; > + indio_dev->num_channels = model_data->num_channels; > + if (client->irq) > + indio_dev->info = &nct7201_info; > + else > + indio_dev->info = &nct7201_info_no_irq; > + indio_dev->modes = INDIO_DIRECT_MODE; > + > + return devm_iio_device_register(&client->dev, indio_dev); > +} ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 2/2] iio: adc: add support for Nuvoton NCT7201 2025-02-21 9:09 ` [PATCH v4 2/2] iio: adc: add support for Nuvoton NCT7201 Eason Yang 2025-02-21 16:30 ` David Lechner 2025-02-22 15:56 ` Jonathan Cameron @ 2025-02-25 21:11 ` Paul Menzel 2 siblings, 0 replies; 11+ messages in thread From: Paul Menzel @ 2025-02-25 21:11 UTC (permalink / raw) To: Eason Yang Cc: avifishman70, tmaimon77, tali.perry1, venture, yuenn, benjaminfair, jic23, lars, robh, krzk+dt, conor+dt, nuno.sa, dlechner, javier.carrasco.cruz, andriy.shevchenko, gstols, olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3, marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille, ramona.nechita, herve.codina, chanh, kwliu, yhyang2, linux-iio, devicetree, openbmc, linux-kernel Dear Eason, Thank you for your patch. Am 21.02.25 um 10:09 schrieb Eason Yang: > Add Nuvoton NCT7201/NCT7202 system voltage monitor 12-bit ADC driver > > NCT7201/NCT7202 supports up to 12 analog voltage monitor inputs and up to > 4 SMBus addresses by ADDR pin. Meanwhile, ALERT# hardware event pins for > independent alarm signals, and the all threshold values could be set for … and all the threshold values … > system protection without any timing delay. It also supports reset input > RSTIN# to recover system from a fault condition. > > Currently, only single-edge mode conversion and threshold events support. … are supported. It’d be great if you added a datasheet name and revision, and, if publicly available, a URL. > Signed-off-by: Eason Yang <j2anfernee@gmail.com> > --- > MAINTAINERS | 1 + > drivers/iio/adc/Kconfig | 11 + > drivers/iio/adc/Makefile | 1 + > drivers/iio/adc/nct7201.c | 487 ++++++++++++++++++++++++++++++++++++++ > 4 files changed, 500 insertions(+) > create mode 100644 drivers/iio/adc/nct7201.c […] Kind regards, Paul ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver 2025-02-21 9:09 [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver Eason Yang 2025-02-21 9:09 ` [PATCH v4 1/2] dt-bindings: iio: adc: add NCT7201 ADCs Eason Yang 2025-02-21 9:09 ` [PATCH v4 2/2] iio: adc: add support for Nuvoton NCT7201 Eason Yang @ 2025-02-22 15:25 ` Jonathan Cameron 2025-04-07 13:51 ` Yu-Hsian Yang 2 siblings, 1 reply; 11+ messages in thread From: Jonathan Cameron @ 2025-02-22 15:25 UTC (permalink / raw) To: Eason Yang Cc: avifishman70, tmaimon77, tali.perry1, venture, yuenn, benjaminfair, lars, robh, krzk+dt, conor+dt, nuno.sa, dlechner, javier.carrasco.cruz, andriy.shevchenko, gstols, olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3, marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille, ramona.nechita, herve.codina, chanh, KWLIU, yhyang2, openbmc, linux-iio, devicetree, linux-kernel On Fri, 21 Feb 2025 17:09:16 +0800 Eason Yang <j2anfernee@gmail.com> wrote: Hi Eason, Not sure if I asked this before, but this is a device that seems to be typically used for hardware monitoring and there are a number of similar sounding device in drivers/hwmon/ That raises a couple of questions: 1) Is it compatible with any of those existing drivers? 2) Why IIO rather than HWMON? There isn't normally a problem with having a hardware monitoring related device supported by IIO, it is just good to know if your usecase makes that a good idea. We have the iio-hwmon bridge driver to solve the problem of a device than can be used either as a generic ADC or as a hwmon type monitoring device (which tends to have more alarms etc) Jonathan > Change since version 4: > - Fix comments > - Add interrupts and reset-gpios to the DT example > - Use the FIELD_PREP and FIELD_GET > - Add use_single_write in regmap_config > - Use regmap_access_table > > Change since version 3: > - Fix comments > - Don't put nct720"x" in the name, just call it nct7201 > - Remove differential inputs until conversions are finished > - Add NCT7201_ prefix in all macros and avoid the tables > - Correct event threshold values in raw units > - Add with and without interrupt callback function to have the event > config part and one that doesn't > - Remove print an error message if regmap_wirte failed case > > Change since version 2: > - Remvoe read-vin-data-size property, default use read word vin data > - Use regmap instead of i2c smbus API > - IIO should be IIO_CHAN_INFO_RAW and _SCALE not _PROCESSED > - Use dev_xxx_probe in probe function and dev_xxx in other functions > - Use devm_iio_device_register replace of iio_device_register > - Use guard(mutex) replace of mutex_lock > - Use get_unaligned_le16 conversion API > > Changes since version 1: > - Add new property in iio:adc binding document > - Add new driver for Nuvoton NCT720x driver > > Eason Yang (2): > dt-bindings: iio: adc: add NCT7201 ADCs > iio: adc: add support for Nuvoton NCT7201 > > .../bindings/iio/adc/nuvoton,nct7201.yaml | 57 ++ > MAINTAINERS | 2 + > drivers/iio/adc/Kconfig | 11 + > drivers/iio/adc/Makefile | 1 + > drivers/iio/adc/nct7201.c | 487 ++++++++++++++++++ > 5 files changed, 558 insertions(+) > create mode 100644 Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > create mode 100644 drivers/iio/adc/nct7201.c > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver 2025-02-22 15:25 ` [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver Jonathan Cameron @ 2025-04-07 13:51 ` Yu-Hsian Yang 0 siblings, 0 replies; 11+ messages in thread From: Yu-Hsian Yang @ 2025-04-07 13:51 UTC (permalink / raw) To: Jonathan Cameron Cc: avifishman70, tmaimon77, tali.perry1, venture, yuenn, benjaminfair, lars, robh, krzk+dt, conor+dt, nuno.sa, dlechner, javier.carrasco.cruz, andriy.shevchenko, gstols, olivier.moysan, mitrutzceclan, tgamblin, matteomartelli3, marcelo.schmitt, alisadariana, joao.goncalves, thomas.bonnefille, ramona.nechita, herve.codina, chanh, KWLIU, yhyang2, openbmc, linux-iio, devicetree, linux-kernel Dear Jonathan, Thanks again for the review Jonathan Cameron <jic23@kernel.org> 於 2025年2月22日 週六 下午11:25寫道: > > On Fri, 21 Feb 2025 17:09:16 +0800 > Eason Yang <j2anfernee@gmail.com> wrote: > > Hi Eason, > > Not sure if I asked this before, but this is a device that seems > to be typically used for hardware monitoring and there are a number > of similar sounding device in drivers/hwmon/ > > That raises a couple of questions: > 1) Is it compatible with any of those existing drivers? No, we need a new driver to do the ADC conversion for NCT7201/NCT7202. > 2) Why IIO rather than HWMON? A driver for NCT7201 with more functionality is available in the iio adc subsystem. If the chip is used for hardware monitoring, the iio->hwmon bridge should be used. > > There isn't normally a problem with having a hardware monitoring > related device supported by IIO, it is just good to know if your > usecase makes that a good idea. We have the iio-hwmon bridge > driver to solve the problem of a device than can be used either > as a generic ADC or as a hwmon type monitoring device (which tends > to have more alarms etc) Yes, we also verify the iio-hwmon bridge. > > Jonathan > > > > Change since version 4: > > - Fix comments > > - Add interrupts and reset-gpios to the DT example > > - Use the FIELD_PREP and FIELD_GET > > - Add use_single_write in regmap_config > > - Use regmap_access_table > > > > Change since version 3: > > - Fix comments > > - Don't put nct720"x" in the name, just call it nct7201 > > - Remove differential inputs until conversions are finished > > - Add NCT7201_ prefix in all macros and avoid the tables > > - Correct event threshold values in raw units > > - Add with and without interrupt callback function to have the event > > config part and one that doesn't > > - Remove print an error message if regmap_wirte failed case > > > > Change since version 2: > > - Remvoe read-vin-data-size property, default use read word vin data > > - Use regmap instead of i2c smbus API > > - IIO should be IIO_CHAN_INFO_RAW and _SCALE not _PROCESSED > > - Use dev_xxx_probe in probe function and dev_xxx in other functions > > - Use devm_iio_device_register replace of iio_device_register > > - Use guard(mutex) replace of mutex_lock > > - Use get_unaligned_le16 conversion API > > > > Changes since version 1: > > - Add new property in iio:adc binding document > > - Add new driver for Nuvoton NCT720x driver > > > > Eason Yang (2): > > dt-bindings: iio: adc: add NCT7201 ADCs > > iio: adc: add support for Nuvoton NCT7201 > > > > .../bindings/iio/adc/nuvoton,nct7201.yaml | 57 ++ > > MAINTAINERS | 2 + > > drivers/iio/adc/Kconfig | 11 + > > drivers/iio/adc/Makefile | 1 + > > drivers/iio/adc/nct7201.c | 487 ++++++++++++++++++ > > 5 files changed, 558 insertions(+) > > create mode 100644 Documentation/devicetree/bindings/iio/adc/nuvoton,nct7201.yaml > > create mode 100644 drivers/iio/adc/nct7201.c > > > ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-04-07 13:52 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-02-21 9:09 [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver Eason Yang 2025-02-21 9:09 ` [PATCH v4 1/2] dt-bindings: iio: adc: add NCT7201 ADCs Eason Yang 2025-02-21 15:56 ` David Lechner 2025-04-07 13:41 ` Yu-Hsian Yang 2025-02-21 16:56 ` Conor Dooley 2025-02-21 9:09 ` [PATCH v4 2/2] iio: adc: add support for Nuvoton NCT7201 Eason Yang 2025-02-21 16:30 ` David Lechner 2025-02-22 15:56 ` Jonathan Cameron 2025-02-25 21:11 ` Paul Menzel 2025-02-22 15:25 ` [PATCH v4 0/2] iio: adc: add Nuvoton NCT7201 ADC driver Jonathan Cameron 2025-04-07 13:51 ` Yu-Hsian Yang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox