* [PATCH v1 1/4] regulator: dt-bindings: maxim,max8907: Document io-channel-cells property
2026-11-08 9:56 [PATCH v1 0/4] iio: adc: Add support for MAX8907 ADC cell Svyatoslav Ryhel
@ 2026-11-08 9:56 ` Svyatoslav Ryhel
2026-11-08 10:40 ` Mark Brown
2026-11-08 20:46 ` Jonathan Cameron
2026-11-08 9:56 ` [PATCH v1 2/4] mfd: max8907: Add ADC client support Svyatoslav Ryhel
` (2 subsequent siblings)
3 siblings, 2 replies; 8+ messages in thread
From: Svyatoslav Ryhel @ 2026-11-08 9:56 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Lee Jones, Svyatoslav Ryhel
Cc: linux-kernel, devicetree, linux-iio, mfd
The Maxim MAX8907 has a built-in 8-channel ADC. It does not require any
Device Tree (DT) based configuration and is folded into the main PMIC
node. Document this behavior.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
Documentation/devicetree/bindings/regulator/maxim,max8907.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max8907.yaml b/Documentation/devicetree/bindings/regulator/maxim,max8907.yaml
index ee1a305d1c210..ccdeb9ba21e26 100644
--- a/Documentation/devicetree/bindings/regulator/maxim,max8907.yaml
+++ b/Documentation/devicetree/bindings/regulator/maxim,max8907.yaml
@@ -27,6 +27,9 @@ properties:
system-power-controller: true
+ "#io-channel-cells":
+ const: 1
+
mbatt-supply:
description:
The input supply for MBATT, BBAT, SDBY, VRTC.
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v1 1/4] regulator: dt-bindings: maxim,max8907: Document io-channel-cells property
2026-11-08 9:56 ` [PATCH v1 1/4] regulator: dt-bindings: maxim,max8907: Document io-channel-cells property Svyatoslav Ryhel
@ 2026-11-08 10:40 ` Mark Brown
2026-11-08 20:46 ` Jonathan Cameron
1 sibling, 0 replies; 8+ messages in thread
From: Mark Brown @ 2026-11-08 10:40 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Lee Jones, linux-kernel, devicetree, linux-iio,
mfd
[-- Attachment #1: Type: text/plain, Size: 287 bytes --]
On Sun, Nov 08, 2026 at 11:56:31AM +0200, Svyatoslav Ryhel wrote:
> The Maxim MAX8907 has a built-in 8-channel ADC. It does not require any
> Device Tree (DT) based configuration and is folded into the main PMIC
> node. Document this behavior.
Acked-by: Mark Brown <broonie@kernel.org>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 1/4] regulator: dt-bindings: maxim,max8907: Document io-channel-cells property
2026-11-08 9:56 ` [PATCH v1 1/4] regulator: dt-bindings: maxim,max8907: Document io-channel-cells property Svyatoslav Ryhel
2026-11-08 10:40 ` Mark Brown
@ 2026-11-08 20:46 ` Jonathan Cameron
1 sibling, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2026-11-08 20:46 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, David Lechner, Nuno Sá,
Andy Shevchenko, Lee Jones, linux-kernel, devicetree, linux-iio,
mfd
On Sun, 8 Nov 2026 11:56:31 +0200
Svyatoslav Ryhel <clamor95@gmail.com> wrote:
> The Maxim MAX8907 has a built-in 8-channel ADC. It does not require any
> Device Tree (DT) based configuration and is folded into the main PMIC
> node. Document this behavior.
The actual addition here is to allow other devices in DT to consume
the channels. There is nothing stopping you having an ADC driver
without that which would need nothing at all in DT.
So this patch description is not accurate. The actual change is fine.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> ---
> Documentation/devicetree/bindings/regulator/maxim,max8907.yaml | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/regulator/maxim,max8907.yaml b/Documentation/devicetree/bindings/regulator/maxim,max8907.yaml
> index ee1a305d1c210..ccdeb9ba21e26 100644
> --- a/Documentation/devicetree/bindings/regulator/maxim,max8907.yaml
> +++ b/Documentation/devicetree/bindings/regulator/maxim,max8907.yaml
> @@ -27,6 +27,9 @@ properties:
>
> system-power-controller: true
>
> + "#io-channel-cells":
> + const: 1
> +
> mbatt-supply:
> description:
> The input supply for MBATT, BBAT, SDBY, VRTC.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 2/4] mfd: max8907: Add ADC client support
2026-11-08 9:56 [PATCH v1 0/4] iio: adc: Add support for MAX8907 ADC cell Svyatoslav Ryhel
2026-11-08 9:56 ` [PATCH v1 1/4] regulator: dt-bindings: maxim,max8907: Document io-channel-cells property Svyatoslav Ryhel
@ 2026-11-08 9:56 ` Svyatoslav Ryhel
2026-11-08 20:51 ` Jonathan Cameron
2026-11-08 9:56 ` [PATCH v1 3/4] iio: adc: Add support for MAX8907 ADC cell Svyatoslav Ryhel
2026-11-08 9:56 ` [PATCH v1 4/4] mfd: max8907: Add " Svyatoslav Ryhel
3 siblings, 1 reply; 8+ messages in thread
From: Svyatoslav Ryhel @ 2026-11-08 9:56 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Lee Jones, Svyatoslav Ryhel
Cc: linux-kernel, devicetree, linux-iio, mfd
The Maxim MAX8907 has an 8-channel ADC at a fixed location. Add client
support for it along with its regmap and interrupts.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/mfd/max8907.c | 74 +++++++++++++++++++++++++++++++++++++
include/linux/mfd/max8907.h | 53 ++++++++++++++++++++++++++
2 files changed, 127 insertions(+)
diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c
index 826d7768fd8d0..86579729111ee 100644
--- a/drivers/mfd/max8907.c
+++ b/drivers/mfd/max8907.c
@@ -113,6 +113,48 @@ static const struct regmap_config max8907_regmap_rtc_config = {
.cache_type = REGCACHE_MAPLE,
};
+static bool max8907_adc_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX8907_REG_TSC_STA_INT:
+ case MAX8907_REG_AUX1_MSB ... MAX8907_REG_TDIE_LSB:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool max8907_adc_is_precious_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX8907_REG_TSC_STA_INT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool max8907_adc_is_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MAX8907_REG_TSC_STA_INT:
+ case MAX8907_REG_AUX1_MSB ... MAX8907_REG_TDIE_LSB:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static const struct regmap_config max8907_regmap_adc_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .volatile_reg = max8907_adc_is_volatile_reg,
+ .precious_reg = max8907_adc_is_precious_reg,
+ .writeable_reg = max8907_adc_is_writeable_reg,
+ .max_register = MAX8907_REG_TDIE_MEASURE,
+ .cache_type = REGCACHE_MAPLE,
+};
+
static const struct regmap_irq max8907_chg_irqs[] = {
{ .reg_offset = 0, .mask = 1 << 0, },
{ .reg_offset = 0, .mask = 1 << 1, },
@@ -175,6 +217,20 @@ static const struct regmap_irq_chip max8907_rtc_irq_chip = {
.num_irqs = ARRAY_SIZE(max8907_rtc_irqs),
};
+static const struct regmap_irq max8907_adc_irqs[] = {
+ { .reg_offset = 0, .mask = BIT(0), },
+ { .reg_offset = 0, .mask = BIT(1), },
+};
+
+static const struct regmap_irq_chip max8907_adc_irq_chip = {
+ .name = "max8907 adc",
+ .status_base = MAX8907_REG_TSC_STA_INT,
+ .mask_base = MAX8907_REG_TSC_INT_MASK,
+ .num_regs = 1,
+ .irqs = max8907_adc_irqs,
+ .num_irqs = ARRAY_SIZE(max8907_adc_irqs),
+};
+
static int max8907_power_off(struct sys_off_data *data)
{
struct max8907 *max8907 = data->cb_data;
@@ -220,6 +276,18 @@ static int max8907_i2c_probe(struct i2c_client *i2c)
return dev_err_probe(dev, PTR_ERR(max8907->regmap_rtc),
"RTC regmap init failed\n");
+ max8907->i2c_adc = devm_i2c_new_dummy_device(dev, i2c->adapter, MAX8907_ADC_I2C_ADDR);
+ if (IS_ERR(max8907->i2c_adc))
+ return PTR_ERR(max8907->i2c_adc);
+
+ i2c_set_clientdata(max8907->i2c_adc, max8907);
+
+ max8907->regmap_adc = devm_regmap_init_i2c(max8907->i2c_adc,
+ &max8907_regmap_adc_config);
+ if (IS_ERR(max8907->regmap_adc))
+ return dev_err_probe(dev, PTR_ERR(max8907->regmap_adc),
+ "ADC regmap init failed\n");
+
ret = devm_regmap_add_irq_chip(dev, max8907->regmap_gen, max8907->i2c_gen->irq,
IRQF_ONESHOT | IRQF_SHARED, -1, &max8907_chg_irq_chip,
&max8907->irqc_chg);
@@ -238,6 +306,12 @@ static int max8907_i2c_probe(struct i2c_client *i2c)
if (ret)
return dev_err_probe(dev, ret, "Failed to add rtc irq chip\n");
+ ret = devm_regmap_add_irq_chip(dev, max8907->regmap_adc, max8907->i2c_gen->irq,
+ IRQF_ONESHOT | IRQF_SHARED, -1, &max8907_adc_irq_chip,
+ &max8907->irqc_adc);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add adc irq chip\n");
+
ret = devm_mfd_add_devices(dev, -1, max8907_cells, ARRAY_SIZE(max8907_cells),
NULL, 0, NULL);
if (ret)
diff --git a/include/linux/mfd/max8907.h b/include/linux/mfd/max8907.h
index 35b2ede54f856..cf304afc782d6 100644
--- a/include/linux/mfd/max8907.h
+++ b/include/linux/mfd/max8907.h
@@ -153,6 +153,51 @@
#define MAX8907_REG_MPL_CNTL 0x1E
/* ADC and Touch Screen Controller register map */
+#define MAX8907_REG_TSC_STA_INT 0x00
+#define MAX8907_REG_TSC_INT_MASK 0x01
+#define MAX8907_REG_TSC_CNFG1 0x02
+#define MAX8907_REG_TSC_CNFG2 0x03
+#define MAX8907_REG_TSC_CNFG3 0x04
+#define MAX8907_REG_ADC_RES_CNFG1 0x06
+#define MAX8907_REG_ADC_AVG_CNFG1 0x07
+#define MAX8907_REG_ADC_ACQ_CNFG1 0x08
+#define MAX8907_REG_ADC_ACQ_CNFG2 0x09
+#define MAX8907_REG_ADC_SCHED 0x10
+#define MAX8907_REG_X_MSB 0x50
+#define MAX8907_REG_X_LSB 0x51
+#define MAX8907_REG_Y_MSB 0x52
+#define MAX8907_REG_Y_LSB 0x53
+#define MAX8907_REG_Z1_MSB 0x54
+#define MAX8907_REG_Z1_LSB 0x55
+#define MAX8907_REG_Z2_MSB 0x56
+#define MAX8907_REG_Z2_LSB 0x57
+#define MAX8907_REG_AUX1_MSB 0x60
+#define MAX8907_REG_AUX1_LSB 0x61
+#define MAX8907_REG_AUX2_MSB 0x62
+#define MAX8907_REG_AUX2_LSB 0x63
+#define MAX8907_REG_VCHG_MSB 0x64
+#define MAX8907_REG_VCHG_LSB 0x65
+#define MAX8907_REG_VBBATT_MSB 0x66
+#define MAX8907_REG_VBBATT_LSB 0x67
+#define MAX8907_REG_VMBATT_MSB 0x68
+#define MAX8907_REG_VMBATT_LSB 0x69
+#define MAX8907_REG_ISNS_MSB 0x6A
+#define MAX8907_REG_ISNS_LSB 0x6B
+#define MAX8907_REG_THM_MSB 0x6C
+#define MAX8907_REG_THM_LSB 0x6D
+#define MAX8907_REG_TDIE_MSB 0x6E
+#define MAX8907_REG_TDIE_LSB 0x6F
+
+#define MAX8907_REG_AUX1_MEASURE 0xC0
+#define MAX8907_REG_AUX2_MEASURE 0xC8
+#define MAX8907_REG_VCHG_MEASURE 0xD0
+#define MAX8907_REG_VBBATT_MEASURE 0xD8
+#define MAX8907_REG_VMBATT_MEASURE 0xE0
+#define MAX8907_REG_ISNS_MEASURE 0xE8
+#define MAX8907_REG_THM_MEASURE 0xF0
+#define MAX8907_REG_TDIE_MEASURE 0xF8
+
+/* Regulator stride */
#define MAX8907_CTL 0
#define MAX8907_SEQCNT 1
#define MAX8907_VOUT 2
@@ -165,6 +210,8 @@
#define MAX8907_MASK_OUT5V_ENSRC 0x0E
#define MAX8907_MASK_OUT5V_EN 0x01
#define MAX8907_MASK_POWER_OFF 0x40
+#define MAX8907_MASK_RST_CFG_INT_REF_EN 0x01
+#define MAX8907_MASK_NREF_OK 0x10
/* Regulator IDs */
#define MAX8907_MBATT 0
@@ -225,6 +272,9 @@ enum {
MAX8907_IRQ_RTC_ALARM1 = 0,
MAX8907_IRQ_RTC_ALARM0,
+
+ MAX8907_IRQ_TSC_STICK = 0,
+ MAX8907_IRQ_TSC_NSTICK,
};
struct regmap_irq_chips_data;
@@ -234,11 +284,14 @@ struct max8907 {
struct mutex irq_lock;
struct i2c_client *i2c_gen;
struct i2c_client *i2c_rtc;
+ struct i2c_client *i2c_adc;
struct regmap *regmap_gen;
struct regmap *regmap_rtc;
+ struct regmap *regmap_adc;
struct regmap_irq_chip_data *irqc_chg;
struct regmap_irq_chip_data *irqc_on_off;
struct regmap_irq_chip_data *irqc_rtc;
+ struct regmap_irq_chip_data *irqc_adc;
};
#endif
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v1 2/4] mfd: max8907: Add ADC client support
2026-11-08 9:56 ` [PATCH v1 2/4] mfd: max8907: Add ADC client support Svyatoslav Ryhel
@ 2026-11-08 20:51 ` Jonathan Cameron
0 siblings, 0 replies; 8+ messages in thread
From: Jonathan Cameron @ 2026-11-08 20:51 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, David Lechner, Nuno Sá,
Andy Shevchenko, Lee Jones, linux-kernel, devicetree, linux-iio,
mfd
On Sun, 8 Nov 2026 11:56:32 +0200
Svyatoslav Ryhel <clamor95@gmail.com> wrote:
> The Maxim MAX8907 has an 8-channel ADC at a fixed location. Add client
> support for it along with its regmap and interrupts.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> diff --git a/include/linux/mfd/max8907.h b/include/linux/mfd/max8907.h
> index 35b2ede54f856..cf304afc782d6 100644
> --- a/include/linux/mfd/max8907.h
> +++ b/include/linux/mfd/max8907.h
> @@ -153,6 +153,51 @@
> #define MAX8907_REG_MPL_CNTL 0x1E
>
> /* ADC and Touch Screen Controller register map */
> +#define MAX8907_REG_TSC_STA_INT 0x00
> +#define MAX8907_REG_TSC_INT_MASK 0x01
> +#define MAX8907_REG_TSC_CNFG1 0x02
> +#define MAX8907_REG_TSC_CNFG2 0x03
....
> +/* Regulator stride */
I'm not sure what this means. Stride of what? Seems to
be some offsets in the register address.
> #define MAX8907_CTL 0
> #define MAX8907_SEQCNT 1
> #define MAX8907_VOUT 2
> @@ -165,6 +210,8 @@
> #define MAX8907_MASK_OUT5V_ENSRC 0x0E
> #define MAX8907_MASK_OUT5V_EN 0x01
> #define MAX8907_MASK_POWER_OFF 0x40
> +#define MAX8907_MASK_RST_CFG_INT_REF_EN 0x01
> +#define MAX8907_MASK_NREF_OK 0x10
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 3/4] iio: adc: Add support for MAX8907 ADC cell
2026-11-08 9:56 [PATCH v1 0/4] iio: adc: Add support for MAX8907 ADC cell Svyatoslav Ryhel
2026-11-08 9:56 ` [PATCH v1 1/4] regulator: dt-bindings: maxim,max8907: Document io-channel-cells property Svyatoslav Ryhel
2026-11-08 9:56 ` [PATCH v1 2/4] mfd: max8907: Add ADC client support Svyatoslav Ryhel
@ 2026-11-08 9:56 ` Svyatoslav Ryhel
2026-11-08 9:56 ` [PATCH v1 4/4] mfd: max8907: Add " Svyatoslav Ryhel
3 siblings, 0 replies; 8+ messages in thread
From: Svyatoslav Ryhel @ 2026-11-08 9:56 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Lee Jones, Svyatoslav Ryhel
Cc: linux-kernel, devicetree, linux-iio, mfd
The MAX8907 PMIC has a dedicated ADC cell, which provides 8 ADC channels
with information about different parts of the power system, including the
battery, charger/plug, jack and thermal readings.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/iio/adc/Kconfig | 10 ++
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/max8907-adc.c | 195 ++++++++++++++++++++++++++++++++++
3 files changed, 206 insertions(+)
create mode 100644 drivers/iio/adc/max8907-adc.c
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index a802d8ee4dd9c..25b094575a5d3 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -1166,6 +1166,16 @@ config MAX77541_ADC
To compile this driver as a module, choose M here:
the module will be called max77541-adc.
+config MAX8907_ADC
+ tristate "Maxim MAX8907 ADC driver"
+ depends on MFD_MAX8907
+ help
+ Say yes here to build support for 8 channel 12-bit ADC
+ interface found in the Maxim MAX8907 PMIC.
+
+ To compile this driver as a module, choose M here:
+ the module will be called max8907-adc.
+
config MAX9611
tristate "Maxim max9611/max9612 ADC driver"
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 9e82c21dbd374..12247d8e0aa29 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_MAX14001) += max14001.o
obj-$(CONFIG_MAX34408) += max34408.o
obj-$(CONFIG_MAX40080) += max40080.o
obj-$(CONFIG_MAX77541_ADC) += max77541-adc.o
+obj-$(CONFIG_MAX8907_ADC) += max8907-adc.o
obj-$(CONFIG_MAX9611) += max9611.o
obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
diff --git a/drivers/iio/adc/max8907-adc.c b/drivers/iio/adc/max8907-adc.c
new file mode 100644
index 0000000000000..d1acb5bc95c15
--- /dev/null
+++ b/drivers/iio/adc/max8907-adc.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/iio/iio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/max8907.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+/* MAX8907_ADC_RES_CNFG1 */
+#define RES_AUX1 BIT(7)
+#define RES_AUX2 BIT(6)
+#define RES_VCHG BIT(5)
+#define RES_VBBATT BIT(4)
+#define RES_VMBATT BIT(3)
+#define RES_ISNS BIT(2)
+#define RES_THM BIT(1)
+#define RES_TDIE BIT(0)
+
+/* MAX8907_ADC_AVG_CNFG1 */
+#define AVG_AUX1_EN BIT(7)
+#define AVG_AUX2_EN BIT(6)
+#define AVG_VCHG_EN BIT(5)
+#define AVG_VBBATT_EN BIT(4)
+#define AVG_VMBATT_EN BIT(3)
+#define AVG_ISNS_EN BIT(2)
+#define AVG_THM_EN BIT(1)
+#define AVG_TDIE_EN BIT(0)
+
+/* MAX8907_ADC_ACQ_CNFG1 */
+#define T_ACQ_AUX1 BIT(7)
+#define T_ACQ_AUX2 BIT(5)
+#define T_ACQ_VCHG BIT(3)
+#define T_ACQ_VBBATT BIT(1)
+
+/* MAX8907_ADC_ACQ_CNFG2 */
+#define T_ACQ_VMBATT BIT(6)
+#define T_ACQ_ISNS BIT(4)
+#define T_ACQ_THM BIT(2)
+#define T_ACQ_TDIE BIT(0)
+
+/* MAX8907_ADC_SCHED */
+#define AUTOSCH_ENABLE BIT(1)
+#define AUTOSCH_TIME BIT(0)
+
+#define TO_REG(n) ((n) & 0xff)
+#define TO_MEASURE(n) (((n) >> 8) & 0xff)
+
+enum {
+ TDIE, THM, ISNS, VMBATT, VBBATT, VCHG, AUX2, AUX1
+};
+
+static const u32 max8907_default_ref[] = {
+ 4096, 4096, 4096, 8192, 8192, 8192, 2500, 4096
+};
+
+#define MAX8907_CHAN(_type, _idname, _datasheet_name) { \
+ .type = (_type), \
+ .address = MAX8907_REG_##_idname##_MSB | \
+ MAX8907_REG_##_idname##_MEASURE << 8, \
+ .indexed = 1, \
+ .channel = (_idname), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .scan_index = (_idname), \
+ .scan_type = { \
+ .format = IIO_SCAN_FORMAT_UNSIGNED_INT, \
+ .realbits = 12, \
+ .storagebits = 16, \
+ .endianness = IIO_CPU, \
+ }, \
+ .datasheet_name = (_datasheet_name), \
+}
+
+static const struct iio_chan_spec max8907_adc_channels[] = {
+ MAX8907_CHAN(IIO_VOLTAGE, TDIE, "tdiode"),
+ MAX8907_CHAN(IIO_VOLTAGE, THM, "thermistor"),
+ MAX8907_CHAN(IIO_CURRENT, ISNS, "isense"),
+ MAX8907_CHAN(IIO_VOLTAGE, VMBATT, "vmbatt"),
+ MAX8907_CHAN(IIO_VOLTAGE, VBBATT, "vbbatt"),
+ MAX8907_CHAN(IIO_VOLTAGE, VCHG, "vcharge"),
+ MAX8907_CHAN(IIO_VOLTAGE, AUX2, "aux2"),
+ MAX8907_CHAN(IIO_VOLTAGE, AUX1, "aux1"),
+};
+
+static int max8907_adc_read(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct regmap **regmap = iio_priv(indio_dev);
+ unsigned char data[2] = { 0, 0 };
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = regmap_write(*regmap, TO_MEASURE(chan->address), 0);
+ if (ret)
+ return ret;
+
+ ret = regmap_bulk_read(*regmap, TO_REG(chan->address), data, 2);
+ if (ret)
+ return ret;
+
+ *val = ((data[0] << 8) | data[1]) >> 4;
+
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ *val = max8907_default_ref[chan->channel];
+ *val2 = chan->scan_type.realbits;
+
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info max8907_adc_info = {
+ .read_raw = &max8907_adc_read,
+};
+
+static int max8907_adc_init(struct regmap *regmap)
+{
+ u32 value;
+ int ret;
+
+ /* Enable internal voltage reference. Exact purpose of bits is not known. */
+ ret = regmap_update_bits(regmap, MAX8907_REG_TSC_CNFG1, GENMASK(1, 0), BIT(1));
+ if (ret)
+ return ret;
+
+ /* Check for internal reference IRQ */
+ ret = regmap_read_poll_timeout(regmap, MAX8907_REG_TSC_STA_INT, value,
+ !(value & MAX8907_MASK_NREF_OK), 0, 1000);
+ if (ret)
+ return ret;
+
+ /* Enable ADC scheduler with 1 second interval */
+ ret = regmap_update_bits(regmap, MAX8907_REG_ADC_SCHED,
+ AUTOSCH_ENABLE | AUTOSCH_TIME, AUTOSCH_TIME);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int max8907_adc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct max8907 *max8907 = dev_get_drvdata(dev->parent);
+ struct iio_dev *indio_dev;
+ struct regmap **regmap;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*regmap));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ regmap = iio_priv(indio_dev);
+
+ *regmap = max8907->regmap_adc;
+
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = max8907_adc_channels;
+ indio_dev->num_channels = ARRAY_SIZE(max8907_adc_channels);
+ indio_dev->name = dev_name(dev);
+ indio_dev->info = &max8907_adc_info;
+
+ iio_device_set_parent(indio_dev, dev->parent);
+
+ /* Enable ADCREF */
+ ret = regmap_set_bits(max8907->regmap_gen, MAX8907_REG_RESET_CNFG,
+ MAX8907_MASK_RST_CFG_INT_REF_EN);
+ if (ret)
+ return ret;
+
+ ret = max8907_adc_init(max8907->regmap_adc);
+ if (ret)
+ return ret;
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+
+static struct platform_driver max8907_adc_driver = {
+ .driver.name = "max8907-adc",
+ .probe = max8907_adc_probe,
+};
+module_platform_driver(max8907_adc_driver);
+
+MODULE_ALIAS("platform:max8907-adc");
+MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>");
+MODULE_DESCRIPTION("MAX8907 ADC driver");
+MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v1 4/4] mfd: max8907: Add ADC cell
2026-11-08 9:56 [PATCH v1 0/4] iio: adc: Add support for MAX8907 ADC cell Svyatoslav Ryhel
` (2 preceding siblings ...)
2026-11-08 9:56 ` [PATCH v1 3/4] iio: adc: Add support for MAX8907 ADC cell Svyatoslav Ryhel
@ 2026-11-08 9:56 ` Svyatoslav Ryhel
3 siblings, 0 replies; 8+ messages in thread
From: Svyatoslav Ryhel @ 2026-11-08 9:56 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Lee Jones, Svyatoslav Ryhel
Cc: linux-kernel, devicetree, linux-iio, mfd
Add the ADC cell name to the list of MAX8907 cells.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/mfd/max8907.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c
index 86579729111ee..f6b584b002e02 100644
--- a/drivers/mfd/max8907.c
+++ b/drivers/mfd/max8907.c
@@ -20,6 +20,7 @@
#include <linux/slab.h>
static const struct mfd_cell max8907_cells[] = {
+ { .name = "max8907-adc", },
{ .name = "max8907-leds", },
{ .name = "max8907-regulator", },
{ .name = "max8907-rtc", },
--
2.53.0
^ permalink raw reply [flat|nested] 8+ messages in thread