* [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC
@ 2026-05-04 18:24 Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 01/13] dt-bindings: iio: adc: add mt6323 PMIC AUXADC Roman Vivchar via B4 Relay
` (12 more replies)
0 siblings, 13 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:24 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
This series adds support for AUXADC, EFUSE and thermal drivers for the
MediaTek mt6323 PMIC
Usually vendor downstream kernels for devices with mt6323 include various
useful drivers like AUXADC, thermal, fuel gauge etc. Bring it to the
upstream kernel by rewriting some drivers from 3.18 vendor tree.
Currently dt-bindings limit some values like ADC channel count and names
to what mt6323 has, but the drivers were designed in a way to support
other PMICs like mt6358 (which has very similar thermal logic).
Tested on the MediaTek mt6572 and mt8163 SoCs, both paired with mt6323.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
Roman Vivchar (13):
dt-bindings: iio: adc: add mt6323 PMIC AUXADC
dt-bindings: nvmem: add mt6323 PMIC EFUSE
dt-bindings: thermal: add mt6323 PMIC thermal
iio: adc: mediatek: add mt6323 PMIC AUXADC driver
nvmem: add mt6323 PMIC EFUSE driver
thermal: mediatek: add pmic thermal support
mfd: mt6397-core: add mt6323 AUXADC support
mfd: mt6397-core: add support for mt6323 efuse
mfd: mt6397-core: add support for mt6323 thermal
ARM: dts: mediatek: mt6323: add support for AUXADC
ARM: dts: mediatek: mt6323: add support for EFUSE
ARM: dts: mediatek: mt6323: add support for thermal
MAINTAINERS: add mt6323 drivers maintainer
.../bindings/iio/adc/mediatek,mt6323-auxadc.yaml | 39 +++
.../bindings/nvmem/mediatek,mt6323-efuse.yaml | 42 +++
.../bindings/thermal/mediatek,mt6323-thermal.yaml | 63 ++++
MAINTAINERS | 18 +
arch/arm/boot/dts/mediatek/mt6323.dtsi | 42 +++
drivers/iio/adc/Kconfig | 11 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/mt6323-auxadc.c | 372 +++++++++++++++++++++
drivers/mfd/mt6397-core.c | 9 +
drivers/nvmem/Kconfig | 11 +
drivers/nvmem/Makefile | 2 +
drivers/nvmem/mt6323-efuse.c | 86 +++++
drivers/thermal/mediatek/Kconfig | 9 +
drivers/thermal/mediatek/Makefile | 1 +
drivers/thermal/mediatek/pmic_thermal.c | 274 +++++++++++++++
.../dt-bindings/iio/adc/mediatek,mt6323-auxadc.h | 16 +
16 files changed, 996 insertions(+)
---
base-commit: 028ef9c96e96197026887c0f092424679298aae8
change-id: 20260502-mt6323-94e1f2d2abb3
Best regards,
--
Roman Vivchar <rva333@protonmail.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 01/13] dt-bindings: iio: adc: add mt6323 PMIC AUXADC
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
@ 2026-05-04 18:24 ` Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 02/13] dt-bindings: nvmem: add mt6323 PMIC EFUSE Roman Vivchar via B4 Relay
` (11 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:24 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
The MediaTek mt6323 PMIC includes an AUXADC used for battery voltage,
temperature, and other internal measurements.
Add the devicetree binding documentation and the associated header file
defining the ADC channel constants.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
.../bindings/iio/adc/mediatek,mt6323-auxadc.yaml | 39 ++++++++++++++++++++++
.../dt-bindings/iio/adc/mediatek,mt6323-auxadc.h | 16 +++++++++
2 files changed, 55 insertions(+)
diff --git a/Documentation/devicetree/bindings/iio/adc/mediatek,mt6323-auxadc.yaml b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6323-auxadc.yaml
new file mode 100644
index 000000000000..7dc1ac8bf253
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6323-auxadc.yaml
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/mediatek,mt6323-auxadc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek MT6323 PMIC AUXADC
+
+maintainers:
+ - Roman Vivchar <rva333@protonmail.com>
+
+description: >
+ The Auxiliary Analog/Digital Converter (AUXADC) is an ADC found
+ in the MediaTek MT6323 PMIC, performing various PMIC related measurements
+ such as battery and PMIC internal voltage regulators temperatures,
+ accessory detection resistance (usually, for a 3.5mm audio jack)
+ other than voltages for various PMIC internal components.
+
+properties:
+ compatible:
+ const: mediatek,mt6323-auxadc
+
+ "#io-channel-cells":
+ const: 1
+
+required:
+ - compatible
+ - "#io-channel-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/iio/adc/mediatek,mt6323-auxadc.h>
+
+ adc {
+ compatible = "mediatek,mt6323-auxadc";
+ #io-channel-cells = <1>;
+ };
diff --git a/include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h b/include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h
new file mode 100644
index 000000000000..c12a21e7ddea
--- /dev/null
+++ b/include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef _DT_BINDINGS_MEDIATEK_MT6323_AUXADC_H
+#define _DT_BINDINGS_MEDIATEK_MT6323_AUXADC_H
+
+#define MT6323_AUXADC_BATON2 0
+#define MT6323_AUXADC_CH6 1
+#define MT6323_AUXADC_BAT_TEMP 2
+#define MT6323_AUXADC_CHIP_TEMP 3
+#define MT6323_AUXADC_VCDT 4
+#define MT6323_AUXADC_BATON1 5
+#define MT6323_AUXADC_ISENSE 6
+#define MT6323_AUXADC_BATSNS 7
+#define MT6323_AUXADC_ACCDET 8
+
+#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 02/13] dt-bindings: nvmem: add mt6323 PMIC EFUSE
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 01/13] dt-bindings: iio: adc: add mt6323 PMIC AUXADC Roman Vivchar via B4 Relay
@ 2026-05-04 18:24 ` Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 03/13] dt-bindings: thermal: add mt6323 PMIC thermal Roman Vivchar via B4 Relay
` (10 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:24 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
The MediaTek mt6323 PMIC includes an EFUSE used for storing calibration
data.
Add the device tree binding documentation for the MediaTek mt6323 EFUSE.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
.../bindings/nvmem/mediatek,mt6323-efuse.yaml | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/Documentation/devicetree/bindings/nvmem/mediatek,mt6323-efuse.yaml b/Documentation/devicetree/bindings/nvmem/mediatek,mt6323-efuse.yaml
new file mode 100644
index 000000000000..eb2437b0c1f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/mediatek,mt6323-efuse.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/mediatek,mt6323-efuse.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek MT6323 PMIC EFUSE
+
+description: |
+ MT6323 efuse is used for storing calibration data, such as thermal sensor
+ calibration.
+
+maintainers:
+ - Roman Vivchar <rva333@protonmail.com>
+
+allOf:
+ - $ref: nvmem.yaml#
+
+properties:
+ compatible:
+ const: mediatek,mt6323-efuse
+
+required:
+ - compatible
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ mt6323_efuse: efuse {
+ compatible = "mediatek,mt6323-efuse";
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mt6323_thermal_calibration_data: thermal-data@14 {
+ reg = <0x14 0x4>;
+ };
+ };
+ };
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 03/13] dt-bindings: thermal: add mt6323 PMIC thermal
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 01/13] dt-bindings: iio: adc: add mt6323 PMIC AUXADC Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 02/13] dt-bindings: nvmem: add mt6323 PMIC EFUSE Roman Vivchar via B4 Relay
@ 2026-05-04 18:24 ` Roman Vivchar via B4 Relay
2026-05-04 19:41 ` Rob Herring (Arm)
2026-05-05 14:05 ` Rob Herring
2026-05-04 18:24 ` [PATCH 04/13] iio: adc: mediatek: add mt6323 PMIC AUXADC driver Roman Vivchar via B4 Relay
` (9 subsequent siblings)
12 siblings, 2 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:24 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
The MediaTek mt6323 PMIC temperature can be read using AUXADC channel.
Add the devicetree binding documentation for the MediaTek mt6323 thermal.
Due similarities with newer PMICs like mt6358, which include more than
one thermal sensor, the #thermal-sensor-cells should be set to 1, to
avoid breaking devicetree ABI in future.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
.../bindings/thermal/mediatek,mt6323-thermal.yaml | 63 ++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/Documentation/devicetree/bindings/thermal/mediatek,mt6323-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,mt6323-thermal.yaml
new file mode 100644
index 000000000000..1882816ba274
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/mediatek,mt6323-thermal.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/mediatek,mt6323-thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek PMIC thermal
+
+maintainers:
+ - Roman Vivchar <rva333@protonmail.com>
+
+description:
+ The MediaTek PMIC thermal sensor uses an AUXADC channel to read raw
+ temperature data and applies calibration data from NVMEM.
+
+allOf:
+ - $ref: thermal-sensor.yaml#
+
+properties:
+ compatible:
+ const: mediatek,mt6323-thermal
+
+ io-channels:
+ description: >
+ IIO channel for the AUXADC to read raw data from.
+ maxItems: 1
+
+ io-channel-names:
+ const: vts
+
+ nvmem-cells:
+ description: >
+ NVMEM cell with phandle to the calibration data provided by the
+ NVMEM device. If unspecified default values will be used.
+ maxItems: 1
+
+ nvmem-cell-names:
+ const: calibration-data
+
+ "#thermal-sensor-cells":
+ const: 1
+
+required:
+ - compatible
+ - io-channels
+ - io-channel-names
+ - "#thermal-sensor-cells"
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/iio/adc/mediatek,mt6323-auxadc.h>
+
+ mt6323_thermal: thermal {
+ compatible = "mediatek,mt6323-thermal";
+ nvmem-cells = <&mt6323_thermal_calibration_data>;
+ nvmem-cell-names = "calibration-data";
+
+ io-channels = <&mt6323_adc MT6323_AUXADC_CHIP_TEMP>;
+ io-channel-names = "vts";
+ #thermal-sensor-cells = <1>;
+ };
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 04/13] iio: adc: mediatek: add mt6323 PMIC AUXADC driver
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
` (2 preceding siblings ...)
2026-05-04 18:24 ` [PATCH 03/13] dt-bindings: thermal: add mt6323 PMIC thermal Roman Vivchar via B4 Relay
@ 2026-05-04 18:24 ` Roman Vivchar via B4 Relay
2026-05-05 7:53 ` Andy Shevchenko
2026-05-04 18:24 ` [PATCH 05/13] nvmem: add mt6323 PMIC EFUSE driver Roman Vivchar via B4 Relay
` (8 subsequent siblings)
12 siblings, 1 reply; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:24 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
The mt6323 AUXADC is a 15-bit ADC used for system monitoring. This driver
provides support for reading various channels including battery and
charger voltages, battery and chip temperature, current sensing and
accessory detection.
Add a driver for the AUXADC found in the MediaTek mt6323 PMIC.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
drivers/iio/adc/Kconfig | 11 ++
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/mt6323-auxadc.c | 372 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 384 insertions(+)
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 60038ae8dfc4..a03614b46041 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -1137,6 +1137,17 @@ config MCP3911
This driver can also be built as a module. If so, the module will be
called mcp3911.
+config MEDIATEK_MT6323_AUXADC
+ tristate "MediaTek MT6323 PMIC AUXADC driver"
+ depends on MFD_MT6397
+ help
+ Say yes here to enable support for MediaTek MT6323 PMIC Auxiliary ADC.
+ This driver provides multiple channels for system monitoring,
+ such as battery voltage, PMIC temperature, and others.
+
+ This driver can also be built as a module. If so, the module will be
+ called mt6323-auxadc.
+
config MEDIATEK_MT6359_AUXADC
tristate "MediaTek MT6359 PMIC AUXADC driver"
depends on MFD_MT6397
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index c76550415ff1..58161750d6e3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
obj-$(CONFIG_MCP3564) += mcp3564.o
obj-$(CONFIG_MCP3911) += mcp3911.o
+obj-$(CONFIG_MEDIATEK_MT6323_AUXADC) += mt6323-auxadc.o
obj-$(CONFIG_MEDIATEK_MT6359_AUXADC) += mt6359-auxadc.o
obj-$(CONFIG_MEDIATEK_MT6360_ADC) += mt6360-adc.o
obj-$(CONFIG_MEDIATEK_MT6370_ADC) += mt6370-adc.o
diff --git a/drivers/iio/adc/mt6323-auxadc.c b/drivers/iio/adc/mt6323-auxadc.c
new file mode 100644
index 000000000000..97b4ad4e7b47
--- /dev/null
+++ b/drivers/iio/adc/mt6323-auxadc.c
@@ -0,0 +1,372 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Roman Vivchar <rva333@protonmail.com>
+ *
+ * Based on drivers/iio/adc/mt6359-auxadc.c
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/cleanup.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include <linux/mfd/mt6397/core.h>
+#include <linux/mfd/mt6323/registers.h>
+
+#include <dt-bindings/iio/adc/mediatek,mt6323-auxadc.h>
+
+#define AUXADC_RSTB_SEL BIT(7)
+#define AUXADC_RSTB_SW BIT(5)
+
+#define AUXADC_CTL_CK BIT(5)
+
+#define AUXADC_TRIM_CH2 (3 << 10)
+#define AUXADC_TRIM_CH4 (3 << 8)
+#define AUXADC_TRIM_CH5 (3 << 4)
+#define AUXADC_TRIM_CH6 (3 << 2)
+
+#define AUXADC_VREF18_ENB_MD BIT(15)
+#define AUXADC_MD_STATUS BIT(0)
+
+#define AUXADC_GPS_STATUS BIT(1)
+
+#define AUXADC_VREF18_SELB BIT(1)
+#define AUXADC_DECI_GDLY_SEL BIT(0)
+
+#define AUXADC_VBUF_EN BIT(4)
+
+#define AUXADC_DECI_GDLY_MASK GENMASK(15, 14)
+#define AUXADC_ADC19_BUSY_MASK GENMASK(15, 0)
+#define AUXADC_RDY_MASK BIT(15)
+#define AUXADC_DATA_MASK GENMASK(14, 0)
+#define AUXADC_OSR_MASK GENMASK(12, 10)
+#define AUXADC_LOW_CHANNEL_MASK GENMASK(9, 0)
+#define AUXADC_AUDIO_CHANNEL_MASK GENMASK(8, 0)
+
+#define MTK_PMIC_IIO_CHAN(_name, _idx, _ch_type) \
+ { .type = _ch_type, \
+ .indexed = 1, \
+ .channel = _idx, \
+ .address = _idx, \
+ .datasheet_name = __stringify(_name), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) }
+
+static const struct iio_chan_spec mt6323_auxadc_channels[] = {
+ MTK_PMIC_IIO_CHAN(baton2, MT6323_AUXADC_BATON2, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(ch6, MT6323_AUXADC_CH6, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(bat_temp, MT6323_AUXADC_BAT_TEMP, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(chip_temp, MT6323_AUXADC_CHIP_TEMP, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(vcdt, MT6323_AUXADC_VCDT, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(baton1, MT6323_AUXADC_BATON1, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(isense, MT6323_AUXADC_ISENSE, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(batsns, MT6323_AUXADC_BATSNS, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(accdet, MT6323_AUXADC_ACCDET, IIO_VOLTAGE),
+};
+
+/**
+ * struct mt6323_auxadc - Main driver structure
+ * @dev: Device pointer
+ * @regmap: Regmap from PWRAP
+ * @lock: Mutex to serialize AUXADC reading vs configuration
+ */
+struct mt6323_auxadc {
+ struct device *dev;
+ struct regmap *regmap;
+ struct mutex lock;
+};
+
+static u32 mt6323_auxadc_channel_to_reg(unsigned long channel)
+{
+ switch (channel) {
+ case 0:
+ return MT6323_AUXADC_ADC6;
+ case 1:
+ return MT6323_AUXADC_ADC11;
+ case 2:
+ return MT6323_AUXADC_ADC5;
+ case 3:
+ return MT6323_AUXADC_ADC4;
+ case 4:
+ return MT6323_AUXADC_ADC2;
+ case 5:
+ return MT6323_AUXADC_ADC3;
+ case 6:
+ return MT6323_AUXADC_ADC1;
+ case 7:
+ return MT6323_AUXADC_ADC0;
+ case 8:
+ return MT6323_AUXADC_ADC7;
+ default:
+ return MT6323_AUXADC_ADC17;
+ }
+}
+
+static int mt6323_auxadc_check_if_stuck(struct mt6323_auxadc *auxadc)
+{
+ int i, ret;
+ u32 val;
+
+ for (i = 0; i < 50; i++) {
+ ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON19, &val);
+ if (ret)
+ return ret;
+
+ if (FIELD_GET(AUXADC_DECI_GDLY_MASK, val)) {
+ ret = regmap_read(auxadc->regmap, MT6323_AUXADC_ADC19,
+ &val);
+ if (ret)
+ return ret;
+
+ if (!FIELD_GET(AUXADC_ADC19_BUSY_MASK, val)) {
+ ret = regmap_update_bits(
+ auxadc->regmap, MT6323_AUXADC_CON19,
+ FIELD_PREP(AUXADC_DECI_GDLY_MASK, 3),
+ 0x0);
+ if (ret)
+ return ret;
+ }
+ } else {
+ return 0;
+ }
+
+ fsleep(10);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int mt6323_auxadc_request(struct mt6323_auxadc *auxadc,
+ unsigned long channel)
+{
+ int ret;
+ u32 pmic_val, adc_val;
+
+ if (channel < 9) {
+ ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON11,
+ AUXADC_VBUF_EN, AUXADC_VBUF_EN);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON22,
+ &pmic_val);
+ if (ret)
+ return ret;
+
+ adc_val = FIELD_GET(AUXADC_LOW_CHANNEL_MASK, pmic_val);
+ adc_val &= ~BIT(channel);
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON22,
+ AUXADC_LOW_CHANNEL_MASK, adc_val);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON22,
+ &pmic_val);
+ if (ret)
+ return ret;
+
+ adc_val = FIELD_GET(AUXADC_LOW_CHANNEL_MASK, pmic_val);
+ adc_val |= BIT(channel);
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON22,
+ AUXADC_LOW_CHANNEL_MASK, adc_val);
+
+ } else {
+ ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON23,
+ &pmic_val);
+ if (ret)
+ return ret;
+
+ adc_val = FIELD_GET(AUXADC_AUDIO_CHANNEL_MASK, pmic_val);
+ adc_val &= ~BIT(channel - 9);
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON23,
+ AUXADC_AUDIO_CHANNEL_MASK, adc_val);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON23,
+ &pmic_val);
+ if (ret)
+ return ret;
+
+ adc_val = FIELD_GET(AUXADC_AUDIO_CHANNEL_MASK, pmic_val);
+ adc_val |= BIT(channel - 9);
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON23,
+ AUXADC_AUDIO_CHANNEL_MASK, adc_val);
+ }
+
+ return ret;
+}
+
+static int mt6323_auxadc_read(struct mt6323_auxadc *auxadc,
+ const struct iio_chan_spec *chan, int *out)
+{
+ int ret;
+ u32 reg = mt6323_auxadc_channel_to_reg(chan->address);
+ u32 val;
+
+ ret = regmap_read_poll_timeout(auxadc->regmap, reg, val,
+ (val & AUXADC_RDY_MASK), 1000, 100000);
+ if (ret)
+ return ret;
+
+ *out = FIELD_GET(AUXADC_DATA_MASK, val);
+
+ return 0;
+}
+
+static int mt6323_auxadc_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, int *val,
+ int *val2, long mask)
+{
+ struct mt6323_auxadc *auxadc = iio_priv(indio_dev);
+ int ret, mult = 1;
+
+ if (mask == IIO_CHAN_INFO_RAW) {
+ scoped_guard(mutex, &auxadc->lock)
+ {
+ ret = mt6323_auxadc_check_if_stuck(auxadc);
+ if (ret)
+ return ret;
+
+ ret = mt6323_auxadc_request(auxadc, chan->address);
+ if (ret)
+ return ret;
+
+ usleep_range(300, 500);
+
+ ret = mt6323_auxadc_read(auxadc, chan, val);
+ if (ret)
+ return ret;
+ return IIO_VAL_INT;
+ }
+ } else if (mask == IIO_CHAN_INFO_SCALE) {
+ if (chan->channel == MT6323_AUXADC_ISENSE ||
+ chan->address == MT6323_AUXADC_BATSNS)
+ mult = 4;
+
+ *val = mult * 1800;
+ *val2 = 32768;
+
+ return IIO_VAL_FRACTIONAL;
+ } else
+ return -EINVAL;
+}
+
+static int mt6323_auxadc_init(struct mt6323_auxadc *auxadc)
+{
+ int ret;
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_STRUP_CON10,
+ AUXADC_RSTB_SW | AUXADC_RSTB_SEL,
+ AUXADC_RSTB_SW | AUXADC_RSTB_SEL);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_TOP_CKPDN2,
+ AUXADC_CTL_CK, AUXADC_CTL_CK);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON10,
+ AUXADC_TRIM_CH2 | AUXADC_TRIM_CH4 |
+ AUXADC_TRIM_CH5 | AUXADC_TRIM_CH6,
+ AUXADC_TRIM_CH2 | AUXADC_TRIM_CH4 |
+ AUXADC_TRIM_CH5 | AUXADC_TRIM_CH6);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON27,
+ AUXADC_VREF18_ENB_MD | AUXADC_MD_STATUS,
+ AUXADC_VREF18_ENB_MD | AUXADC_MD_STATUS);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON19,
+ AUXADC_GPS_STATUS, AUXADC_GPS_STATUS);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON26,
+ AUXADC_VREF18_SELB | AUXADC_DECI_GDLY_SEL,
+ AUXADC_VREF18_SELB | AUXADC_DECI_GDLY_SEL);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON9,
+ AUXADC_OSR_MASK,
+ FIELD_PREP(AUXADC_OSR_MASK, 3));
+ return ret;
+}
+
+static const struct iio_info mt6323_auxadc_iio_info = {
+ .read_raw = mt6323_auxadc_read_raw,
+};
+
+static int mt6323_auxadc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mt6323_auxadc *auxadc;
+ struct iio_dev *iio;
+ struct regmap *regmap;
+ int ret;
+
+ /* mfd->pwrap regmap */
+ regmap = dev_get_regmap(dev->parent->parent, NULL);
+ if (!regmap)
+ return dev_err_probe(dev, -ENODEV, "failed to get regmap\n");
+
+ iio = devm_iio_device_alloc(dev, sizeof(*auxadc));
+ if (!iio)
+ return -ENOMEM;
+
+ auxadc = iio_priv(iio);
+ auxadc->regmap = regmap;
+ auxadc->dev = dev;
+ mutex_init(&auxadc->lock);
+
+ ret = mt6323_auxadc_init(auxadc);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to initialize auxadc\n");
+
+ iio->name = "mt6323-auxadc";
+ iio->info = &mt6323_auxadc_iio_info;
+ iio->modes = INDIO_DIRECT_MODE;
+ iio->channels = mt6323_auxadc_channels;
+ iio->num_channels = ARRAY_SIZE(mt6323_auxadc_channels);
+
+ ret = devm_iio_device_register(dev, iio);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to register iio device\n");
+
+ return 0;
+}
+
+static const struct of_device_id mt6323_auxadc_of_match[] = {
+ { .compatible = "mediatek,mt6323-auxadc" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mt6323_auxadc_of_match);
+
+static struct platform_driver mt6323_auxadc_driver = {
+ .driver = {
+ .name = "mt6323-auxadc",
+ .of_match_table = mt6323_auxadc_of_match,
+ },
+ .probe = mt6323_auxadc_probe,
+};
+module_platform_driver(mt6323_auxadc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MediaTek MT6323 PMIC AUXADC Driver");
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 05/13] nvmem: add mt6323 PMIC EFUSE driver
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
` (3 preceding siblings ...)
2026-05-04 18:24 ` [PATCH 04/13] iio: adc: mediatek: add mt6323 PMIC AUXADC driver Roman Vivchar via B4 Relay
@ 2026-05-04 18:24 ` Roman Vivchar via B4 Relay
2026-05-05 7:59 ` Andy Shevchenko
2026-05-04 18:24 ` [PATCH 06/13] thermal: mediatek: add pmic thermal support Roman Vivchar via B4 Relay
` (7 subsequent siblings)
12 siblings, 1 reply; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:24 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
Add support for the EFUSE controller found in the Mediatek MT6323 PMIC.
The MT6323 EFUSE stores 24 bytes of hardware-related data, such as
thermal sensor calibration values.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
drivers/nvmem/Kconfig | 11 ++++++
drivers/nvmem/Makefile | 2 ++
drivers/nvmem/mt6323-efuse.c | 86 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 99 insertions(+)
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 74ddbd0f79b0..db248a3c4e87 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -227,6 +227,17 @@ config NVMEM_MTK_EFUSE
This driver can also be built as a module. If so, the module
will be called efuse-mtk.
+config NVMEM_MT6323_EFUSE
+ tristate "Mediatek MT6323 PMIC EFUSE support"
+ depends on ARCH_MEDIATEK || COMPILE_TEST
+ depends on MFD_MT6397
+ help
+ This is a driver to access hardware related data like sensor
+ calibration, etc.
+
+ This driver can also be built as a module. If so, the module
+ will be called efuse-mt6323.
+
config NVMEM_MXS_OCOTP
tristate "Freescale MXS On-Chip OTP Memory Support"
depends on ARCH_MXS || COMPILE_TEST
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 7252b8ec88d4..0e2b73f42b25 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -48,6 +48,8 @@ obj-$(CONFIG_NVMEM_MICROCHIP_OTPC) += nvmem-microchip-otpc.o
nvmem-microchip-otpc-y := microchip-otpc.o
obj-$(CONFIG_NVMEM_MTK_EFUSE) += nvmem_mtk-efuse.o
nvmem_mtk-efuse-y := mtk-efuse.o
+obj-$(CONFIG_NVMEM_MT6323_EFUSE) += nvmem_mt6323-efuse.o
+nvmem_mt6323-efuse-y := mt6323-efuse.o
obj-$(CONFIG_NVMEM_MXS_OCOTP) += nvmem-mxs-ocotp.o
nvmem-mxs-ocotp-y := mxs-ocotp.o
obj-$(CONFIG_NVMEM_NINTENDO_OTP) += nvmem-nintendo-otp.o
diff --git a/drivers/nvmem/mt6323-efuse.c b/drivers/nvmem/mt6323-efuse.c
new file mode 100644
index 000000000000..0c1b405fbc89
--- /dev/null
+++ b/drivers/nvmem/mt6323-efuse.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2026 Roman Vivchar <rva333@protonmail.com>
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/mfd/mt6323/registers.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#define MT6323_EFUSE_DOUT_BASE MT6323_EFUSE_DOUT_0_15
+#define MT6323_EFUSE_SIZE 24
+
+struct mt6323_efuse {
+ struct regmap *regmap;
+};
+
+static int mt6323_efuse_read(void *context, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct mt6323_efuse *efuse = context;
+ u32 tmp;
+ u16 *buf = val;
+ int i, ret;
+
+ for (i = 0; i < bytes; i += 2) {
+ ret = regmap_read(efuse->regmap,
+ MT6323_EFUSE_DOUT_BASE + offset + i, &tmp);
+ if (ret)
+ return ret;
+ buf[i / 2] = tmp;
+ }
+ return 0;
+}
+
+static int mt6323_efuse_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mt6323_efuse *priv;
+ struct nvmem_config config = {
+ .name = "mt6323-efuse",
+ .stride = 2,
+ .word_size = 2,
+ .size = MT6323_EFUSE_SIZE,
+ .reg_read = mt6323_efuse_read,
+ };
+ struct nvmem_device *nvmem;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ /* efuse -> mfd -> pwrap */
+ priv->regmap = dev_get_regmap(dev->parent->parent, NULL);
+ if (!priv->regmap)
+ return -ENODEV;
+
+ config.dev = dev;
+ config.priv = priv;
+
+ nvmem = devm_nvmem_register(dev, &config);
+ return PTR_ERR_OR_ZERO(nvmem);
+}
+
+static const struct of_device_id mt6323_efuse_of_match[] = {
+ { .compatible = "mediatek,mt6323-efuse" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt6323_efuse_of_match);
+
+static struct platform_driver mt6323_efuse_driver = {
+ .probe = mt6323_efuse_probe,
+ .driver = {
+ .name = "mt6323-efuse",
+ .of_match_table = mt6323_efuse_of_match,
+ },
+};
+module_platform_driver(mt6323_efuse_driver);
+
+MODULE_DESCRIPTION("Mediatek MT6323 PMIC EFUSE driver");
+MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 06/13] thermal: mediatek: add pmic thermal support
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
` (4 preceding siblings ...)
2026-05-04 18:24 ` [PATCH 05/13] nvmem: add mt6323 PMIC EFUSE driver Roman Vivchar via B4 Relay
@ 2026-05-04 18:24 ` Roman Vivchar via B4 Relay
2026-05-05 8:16 ` Andy Shevchenko
2026-05-04 18:24 ` [PATCH 07/13] mfd: mt6397-core: add mt6323 AUXADC support Roman Vivchar via B4 Relay
` (6 subsequent siblings)
12 siblings, 1 reply; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:24 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
Add a new driver to support thermal monitoring on MediaTek PMICs.
The driver retrieves calibration data from EFUSE, calculates the
temperature using a linear interpolation, and registers the device with
the thermal framework.
Initial support is added for the mt6323 PMIC.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
drivers/thermal/mediatek/Kconfig | 9 ++
drivers/thermal/mediatek/Makefile | 1 +
drivers/thermal/mediatek/pmic_thermal.c | 274 ++++++++++++++++++++++++++++++++
3 files changed, 284 insertions(+)
diff --git a/drivers/thermal/mediatek/Kconfig b/drivers/thermal/mediatek/Kconfig
index d82c86d9be56..f2da7d14a01a 100644
--- a/drivers/thermal/mediatek/Kconfig
+++ b/drivers/thermal/mediatek/Kconfig
@@ -34,4 +34,13 @@ config MTK_LVTS_THERMAL_DEBUGFS
help
Enable this option to debug the internals of the device driver.
+config MTK_PMIC_THERMAL
+ tristate "AUXADC temperature sensor driver for MediaTek PMICs"
+ depends on MFD_MT6397
+ help
+ Enable this option if you want to get PMIC temperature
+ information for MediaTek platforms.
+ This driver configures thermal controllers to collect
+ temperature via AUXADC interface.
+
endif
diff --git a/drivers/thermal/mediatek/Makefile b/drivers/thermal/mediatek/Makefile
index 1c6daa1e644b..22fce58aafd2 100644
--- a/drivers/thermal/mediatek/Makefile
+++ b/drivers/thermal/mediatek/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_MTK_SOC_THERMAL) += auxadc_thermal.o
obj-$(CONFIG_MTK_LVTS_THERMAL) += lvts_thermal.o
+obj-$(CONFIG_MTK_PMIC_THERMAL) += pmic_thermal.o
diff --git a/drivers/thermal/mediatek/pmic_thermal.c b/drivers/thermal/mediatek/pmic_thermal.c
new file mode 100644
index 000000000000..1dce106a28c3
--- /dev/null
+++ b/drivers/thermal/mediatek/pmic_thermal.c
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 Roman Vivchar <rva333@protonmail.com>
+ *
+ * Based on drivers/thermal/mediatek/auxadc_thermal.c
+ */
+
+#include <linux/err.h>
+#include <linux/iio/consumer.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/thermal.h>
+
+#include <linux/mfd/mt6323/registers.h>
+
+#define MAX_SENSORS 1
+
+#define MT6323_TEMP_MIN -20000
+#define MT6323_TEMP_MAX 150000
+
+/* Layout of the fuses providing the calibration data */
+#define CALIB_BUF0_VTS(x) (((x) >> 8) & 0xff)
+#define CALIB_BUF0_DEGC_CALI(x) (((x) >> 2) & 0x3f)
+#define CALIB_BUF0_ADC_CALI_EN(x) (((x) >> 1) & 0x1)
+
+#define CALIB_BUF1_ID_20(x) (((x) >> 14) & 0x1)
+#define CALIB_BUF1_ID_10(x) (((x) >> 12) & 0x1)
+#define CALIB_BUF1_O_SLOPE_20(x) (((((x) >> 11) & 0x7) << 3) + (((x) >> 6) & 0x7))
+#define CALIB_BUF1_O_SLOPE_10(x) (((x) >> 6) & 0x3f)
+#define CALIB_BUF1_O_SLOPE_SIGN(x) (((x) >> 5) & 0x1)
+#define CALIB_BUF1_VTS(x) ((((x) >> 0) & 0x1f) << 8)
+
+#define MT6323_CALIBRATION 171
+
+struct mtk_pmic_thermal;
+
+struct mtk_thermal_data {
+ const char *const *sensors;
+ s32 num_sensors;
+ const int cali_val;
+
+ int (*extract_efuse)(struct mtk_pmic_thermal *mt, u16 *buf);
+ void (*precalc)(struct mtk_pmic_thermal *mt, s32 vts, s32 degc_cali,
+ s32 o_slope, s32 o_slope_sign);
+};
+
+struct mtk_pmic_sensor {
+ struct mtk_pmic_thermal *mt;
+ int id;
+ struct iio_channel *adc_channel;
+ struct thermal_zone_device *tzdev;
+};
+
+struct mtk_pmic_thermal {
+ struct device *dev;
+ struct regmap *regmap;
+ struct mtk_pmic_sensor sensors[MAX_SENSORS];
+
+ s32 t_slope1;
+ s32 t_slope2;
+ s32 t_intercept;
+
+ const struct mtk_thermal_data *data;
+};
+
+static bool mtk_pmic_thermal_temp_is_valid(int temp)
+{
+ return (temp >= MT6323_TEMP_MIN) && (temp <= MT6323_TEMP_MAX);
+}
+
+static int mtk_pmic_read_temp(struct thermal_zone_device *tz, int *temperature)
+{
+ struct mtk_pmic_sensor *sensor = thermal_zone_device_priv(tz);
+ int ret, raw, temp;
+
+ ret = iio_read_channel_processed(sensor->adc_channel, &raw);
+ if (ret < 0) {
+ dev_err(sensor->mt->dev, "failed to read iio channel: %d\n",
+ ret);
+ return ret;
+ }
+
+ temp = sensor->mt->t_intercept +
+ ((sensor->mt->t_slope1 * raw) / sensor->mt->t_slope2);
+
+ if (!mtk_pmic_thermal_temp_is_valid(temp))
+ return -EINVAL;
+
+ *temperature = temp;
+ return 0;
+}
+
+static const struct thermal_zone_device_ops mtk_pmic_thermal_ops = {
+ .get_temp = mtk_pmic_read_temp,
+};
+
+static void mtk_pmic_thermal_precalc_mt6323(struct mtk_pmic_thermal *mt,
+ s32 vts, s32 degc_cali, s32 o_slope,
+ s32 o_slope_sign)
+{
+ s32 vbe_t;
+
+ mt->t_slope1 = 100 * 1000;
+
+ if (o_slope_sign == 0)
+ mt->t_slope2 = -(mt->data->cali_val + o_slope);
+ else
+ mt->t_slope2 = -(mt->data->cali_val - o_slope);
+
+ vbe_t = -1 * (((vts + 9102) * 1800) / 32768) * 1000;
+
+ if (o_slope_sign == 0)
+ mt->t_intercept =
+ (vbe_t * 100) / -(mt->data->cali_val + o_slope);
+ else
+ mt->t_intercept =
+ (vbe_t * 100) / -(mt->data->cali_val - o_slope);
+
+ mt->t_intercept += (degc_cali * (1000 / 2));
+}
+
+static int mtk_pmic_thermal_extract_efuse_mt6323(struct mtk_pmic_thermal *mt,
+ u16 *buf)
+{
+ u32 reg;
+ s32 vts, degc_cali, o_slope, o_slope_sign, id;
+ int ret;
+
+ if (!CALIB_BUF0_ADC_CALI_EN(buf[0]))
+ return -EINVAL;
+
+ vts = CALIB_BUF1_VTS(buf[1]) + CALIB_BUF0_VTS(buf[0]);
+ degc_cali = CALIB_BUF0_DEGC_CALI(buf[0]);
+ o_slope_sign = CALIB_BUF1_O_SLOPE_SIGN(buf[1]);
+
+ ret = regmap_read(mt->regmap, MT6323_CID, ®);
+ if (ret) {
+ dev_err(mt->dev, "failed to read chip id\n");
+ return ret;
+ }
+
+ if (reg == 0x1023) {
+ o_slope = CALIB_BUF1_O_SLOPE_10(buf[1]);
+ id = CALIB_BUF1_ID_10(buf[1]);
+ } else if (reg == 0x2023) {
+ o_slope = CALIB_BUF1_O_SLOPE_20(buf[1]);
+ id = CALIB_BUF1_ID_20(buf[1]);
+ } else {
+ dev_err(mt->dev, "invalid chip id: 0x%x\n", reg);
+ return -EINVAL;
+ }
+
+ if (id == 0)
+ o_slope = 0;
+
+ mt->data->precalc(mt, vts, degc_cali, o_slope, o_slope_sign);
+
+ return 0;
+}
+
+static int mtk_pmic_thermal_get_calib_data(struct device *dev,
+ struct mtk_pmic_thermal *mt)
+{
+ struct nvmem_cell *cell;
+ void *buf;
+ size_t len;
+ int ret;
+
+ cell = nvmem_cell_get(dev, "calibration-data");
+ if (IS_ERR(cell))
+ return PTR_ERR(cell);
+
+ buf = nvmem_cell_read(cell, &len);
+ nvmem_cell_put(cell);
+
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+
+ if (len < 2 * sizeof(u16)) {
+ dev_warn(dev, "invalid calibration data length\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = mt->data->extract_efuse(mt, buf);
+ if (ret) {
+ dev_info(dev, "device not calibrated, using default values\n");
+ mt->data->precalc(mt, 3698, 50, 0, 0);
+ ret = 0;
+ }
+
+out:
+ kfree(buf);
+ return ret;
+}
+
+static int mtk_pmic_thermal_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mtk_pmic_thermal *mt;
+ int i, ret;
+
+ mt = devm_kzalloc(dev, sizeof(*mt), GFP_KERNEL);
+ if (!mt)
+ return -ENOMEM;
+
+ mt->regmap = dev_get_regmap(dev->parent->parent, NULL);
+ if (!mt->regmap)
+ return dev_err_probe(dev, -ENODEV, "failed to get regmap");
+
+ mt->dev = dev;
+ mt->data = of_device_get_match_data(dev);
+
+ ret = mtk_pmic_thermal_get_calib_data(dev, mt);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < mt->data->num_sensors; i++) {
+ struct mtk_pmic_sensor *sensor = &mt->sensors[i];
+
+ sensor->id = i;
+ sensor->mt = mt;
+
+ sensor->adc_channel =
+ devm_iio_channel_get(dev, mt->data->sensors[i]);
+ if (IS_ERR(sensor->adc_channel))
+ return dev_err_probe(dev, PTR_ERR(sensor->adc_channel),
+ "failed to get channel %s\n",
+ mt->data->sensors[i]);
+
+ sensor->tzdev = devm_thermal_of_zone_register(
+ dev, i, sensor, &mtk_pmic_thermal_ops);
+ if (IS_ERR(sensor->tzdev))
+ return dev_err_probe(
+ dev, PTR_ERR(sensor->tzdev),
+ "failed to register thermal zone %d\n", i);
+ }
+
+ return 0;
+}
+
+static const char *const mt6323_adc_channels[] = { "vts" };
+
+static const struct mtk_thermal_data mt6323_thermal_data = {
+ .sensors = mt6323_adc_channels,
+ .num_sensors = ARRAY_SIZE(mt6323_adc_channels),
+ .cali_val = MT6323_CALIBRATION,
+ .extract_efuse = mtk_pmic_thermal_extract_efuse_mt6323,
+ .precalc = mtk_pmic_thermal_precalc_mt6323,
+};
+
+static const struct of_device_id mtk_pmic_thermal_of_match[] = {
+ { .compatible = "mediatek,mt6323-thermal",
+ .data = &mt6323_thermal_data },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mtk_pmic_thermal_of_match);
+
+static struct platform_driver mtk_pmic_thermal_driver = {
+ .probe = mtk_pmic_thermal_probe,
+ .driver = {
+ .name = "mtk-pmic-thermal",
+ .of_match_table = mtk_pmic_thermal_of_match,
+ },
+};
+module_platform_driver(mtk_pmic_thermal_driver);
+
+MODULE_DESCRIPTION("MediaTek PMIC thermal driver");
+MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 07/13] mfd: mt6397-core: add mt6323 AUXADC support
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
` (5 preceding siblings ...)
2026-05-04 18:24 ` [PATCH 06/13] thermal: mediatek: add pmic thermal support Roman Vivchar via B4 Relay
@ 2026-05-04 18:24 ` Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 08/13] mfd: mt6397-core: add support for mt6323 efuse Roman Vivchar via B4 Relay
` (5 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:24 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
The mt6323 PMIC includes an AUXADC. Register the AUXADC in the mt6323
devices array to allow the corresponding driver to probe using compatible
string.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
drivers/mfd/mt6397-core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 3e58d0764c7e..013b0857fb54 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -125,6 +125,9 @@ static const struct resource mt6323_pwrc_resources[] = {
static const struct mfd_cell mt6323_devs[] = {
{
+ .name = "mt6323-auxadc",
+ .of_compatible = "mediatek,mt6323-auxadc",
+ }, {
.name = "mt6323-rtc",
.num_resources = ARRAY_SIZE(mt6323_rtc_resources),
.resources = mt6323_rtc_resources,
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 08/13] mfd: mt6397-core: add support for mt6323 efuse
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
` (6 preceding siblings ...)
2026-05-04 18:24 ` [PATCH 07/13] mfd: mt6397-core: add mt6323 AUXADC support Roman Vivchar via B4 Relay
@ 2026-05-04 18:25 ` Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 09/13] mfd: mt6397-core: add support for mt6323 thermal Roman Vivchar via B4 Relay
` (4 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
The mt6323 PMIC includes an EFUSE. Register the EFUSE in the mt6323
devices array to allow the corresponding driver to probe using compatible
string.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
drivers/mfd/mt6397-core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 013b0857fb54..2d9419b80a5c 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -127,6 +127,9 @@ static const struct mfd_cell mt6323_devs[] = {
{
.name = "mt6323-auxadc",
.of_compatible = "mediatek,mt6323-auxadc",
+ }, {
+ .name = "mt6323-efuse",
+ .of_compatible = "mediatek,mt6323-efuse",
}, {
.name = "mt6323-rtc",
.num_resources = ARRAY_SIZE(mt6323_rtc_resources),
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 09/13] mfd: mt6397-core: add support for mt6323 thermal
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
` (7 preceding siblings ...)
2026-05-04 18:25 ` [PATCH 08/13] mfd: mt6397-core: add support for mt6323 efuse Roman Vivchar via B4 Relay
@ 2026-05-04 18:25 ` Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 10/13] ARM: dts: mediatek: mt6323: add support for AUXADC Roman Vivchar via B4 Relay
` (3 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
The mt6323 PMIC temperature can be measured using AUXADC channel.
Register the thermal in the mt6323 devices array to allow the
corresponding driver to probe using compatible string.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
drivers/mfd/mt6397-core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 2d9419b80a5c..061ac242f1f8 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -151,6 +151,9 @@ static const struct mfd_cell mt6323_devs[] = {
.num_resources = ARRAY_SIZE(mt6323_pwrc_resources),
.resources = mt6323_pwrc_resources,
.of_compatible = "mediatek,mt6323-pwrc"
+ }, {
+ .name = "mt6323-thermal",
+ .of_compatible = "mediatek,mt6323-thermal",
},
};
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 10/13] ARM: dts: mediatek: mt6323: add support for AUXADC
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
` (8 preceding siblings ...)
2026-05-04 18:25 ` [PATCH 09/13] mfd: mt6397-core: add support for mt6323 thermal Roman Vivchar via B4 Relay
@ 2026-05-04 18:25 ` Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 11/13] ARM: dts: mediatek: mt6323: add support for EFUSE Roman Vivchar via B4 Relay
` (2 subsequent siblings)
12 siblings, 0 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
Add the devicetree node for the mt6323 AUXADC.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
arch/arm/boot/dts/mediatek/mt6323.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/mediatek/mt6323.dtsi b/arch/arm/boot/dts/mediatek/mt6323.dtsi
index c230c865116d..c070f4b0936c 100644
--- a/arch/arm/boot/dts/mediatek/mt6323.dtsi
+++ b/arch/arm/boot/dts/mediatek/mt6323.dtsi
@@ -14,6 +14,11 @@ pmic: mt6323 {
interrupt-controller;
#interrupt-cells = <2>;
+ mt6323_adc: adc {
+ compatible = "mediatek,mt6323-auxadc";
+ #io-channel-cells = <1>;
+ };
+
mt6323_leds: leds {
compatible = "mediatek,mt6323-led";
#address-cells = <1>;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 11/13] ARM: dts: mediatek: mt6323: add support for EFUSE
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
` (9 preceding siblings ...)
2026-05-04 18:25 ` [PATCH 10/13] ARM: dts: mediatek: mt6323: add support for AUXADC Roman Vivchar via B4 Relay
@ 2026-05-04 18:25 ` Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 12/13] ARM: dts: mediatek: mt6323: add support for thermal Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 13/13] MAINTAINERS: add mt6323 drivers maintainer Roman Vivchar via B4 Relay
12 siblings, 0 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
Add the efuse node for the mt6323 efuse.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
arch/arm/boot/dts/mediatek/mt6323.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/mediatek/mt6323.dtsi b/arch/arm/boot/dts/mediatek/mt6323.dtsi
index c070f4b0936c..3fe6a5e35e70 100644
--- a/arch/arm/boot/dts/mediatek/mt6323.dtsi
+++ b/arch/arm/boot/dts/mediatek/mt6323.dtsi
@@ -19,6 +19,12 @@ mt6323_adc: adc {
#io-channel-cells = <1>;
};
+ mt6323_efuse: efuse {
+ compatible = "mediatek,mt6323-efuse";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
mt6323_leds: leds {
compatible = "mediatek,mt6323-led";
#address-cells = <1>;
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 12/13] ARM: dts: mediatek: mt6323: add support for thermal
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
` (10 preceding siblings ...)
2026-05-04 18:25 ` [PATCH 11/13] ARM: dts: mediatek: mt6323: add support for EFUSE Roman Vivchar via B4 Relay
@ 2026-05-04 18:25 ` Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 13/13] MAINTAINERS: add mt6323 drivers maintainer Roman Vivchar via B4 Relay
12 siblings, 0 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
Add the devicetree node for the mt6323 thermal.
Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
arch/arm/boot/dts/mediatek/mt6323.dtsi | 35 ++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/mediatek/mt6323.dtsi b/arch/arm/boot/dts/mediatek/mt6323.dtsi
index 3fe6a5e35e70..bdfa177aa1e3 100644
--- a/arch/arm/boot/dts/mediatek/mt6323.dtsi
+++ b/arch/arm/boot/dts/mediatek/mt6323.dtsi
@@ -6,6 +6,8 @@
*
*/
+#include <dt-bindings/iio/adc/mediatek,mt6323-auxadc.h>
+
&pwrap {
pmic: mt6323 {
compatible = "mediatek,mt6323";
@@ -21,8 +23,16 @@ mt6323_adc: adc {
mt6323_efuse: efuse {
compatible = "mediatek,mt6323-efuse";
- #address-cells = <1>;
- #size-cells = <1>;
+
+ nvmem-layout {
+ compatible = "fixed-layout";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ mt6323_thermal_calibration_data: thermal-data@14 {
+ reg = <0x14 0x4>;
+ };
+ };
};
mt6323_leds: leds {
@@ -276,5 +286,26 @@ power-controller {
rtc {
compatible = "mediatek,mt6323-rtc";
};
+
+ mt6323_thermal: thermal {
+ compatible = "mediatek,mt6323-thermal";
+ nvmem-cells = <&mt6323_thermal_calibration_data>;
+ nvmem-cell-names = "calibration-data";
+
+ io-channels = <&mt6323_adc MT6323_AUXADC_CHIP_TEMP>;
+ io-channel-names = "vts";
+ #thermal-sensor-cells = <1>;
+ };
+ };
+};
+
+/ {
+ thermal-zones {
+ pmic_vts_thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <1000>;
+
+ thermal-sensors = <&mt6323_thermal 0>;
+ };
};
};
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 13/13] MAINTAINERS: add mt6323 drivers maintainer
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
` (11 preceding siblings ...)
2026-05-04 18:25 ` [PATCH 12/13] ARM: dts: mediatek: mt6323: add support for thermal Roman Vivchar via B4 Relay
@ 2026-05-04 18:25 ` Roman Vivchar via B4 Relay
12 siblings, 0 replies; 20+ messages in thread
From: Roman Vivchar via B4 Relay @ 2026-05-04 18:25 UTC (permalink / raw)
To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale, Roman Vivchar
From: Roman Vivchar <rva333@protonmail.com>
Add myself as MediaTek mt6323 AUXADC, EFUSE and thermal driver maintainer.
Signed-off-by: Roman Vivchar <rva333@protonmail.com>
---
MAINTAINERS | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index d1cc0e12fe1f..53493a24d00a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16337,6 +16337,18 @@ S: Orphan
F: Documentation/devicetree/bindings/mtd/mediatek,mtk-nfc.yaml
F: drivers/mtd/nand/raw/mtk_*
+MEDIATEK PMIC AUXADC DRIVER
+M: Roman Vivchar <rva333@protonmail.com>
+S: Maintained
+F: Documentation/devicetree/bindings/iio/adc/mediatek,mt6323-auxadc.yaml
+F: drivers/iio/adc/mt6323-auxadc.c
+
+MEDIATEK PMIC EFUSE DRIVER
+M: Roman Vivchar <rva333@protonmail.com>
+S: Maintained
+F: Documentation/devicetree/bindings/nvmem/mediatek,mt6323-efuse.yaml
+F: drivers/nvmem/mt6323-efuse.c
+
MEDIATEK PMIC LED DRIVER
M: Sen Chu <sen.chu@mediatek.com>
M: Sean Wang <sean.wang@mediatek.com>
@@ -16345,6 +16357,12 @@ S: Maintained
F: Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml
F: drivers/leds/leds-mt6323.c
+MEDIATEK PMIC THERMAL DRIVER
+M: Roman Vivchar <rva333@protonmail.com>
+S: Maintained
+F: Documentation/devicetree/bindings/thermal/mediatek,mt6323-thermal.yaml
+F: drivers/thermal/mediatek/pmic_thermal.c
+
MEDIATEK RANDOM NUMBER GENERATOR SUPPORT
M: Sean Wang <sean.wang@mediatek.com>
S: Maintained
--
2.53.0
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 03/13] dt-bindings: thermal: add mt6323 PMIC thermal
2026-05-04 18:24 ` [PATCH 03/13] dt-bindings: thermal: add mt6323 PMIC thermal Roman Vivchar via B4 Relay
@ 2026-05-04 19:41 ` Rob Herring (Arm)
2026-05-05 14:05 ` Rob Herring
1 sibling, 0 replies; 20+ messages in thread
From: Rob Herring (Arm) @ 2026-05-04 19:41 UTC (permalink / raw)
To: Roman Vivchar
Cc: David Lechner, AngeloGioacchino Del Regno, linux-pm, Lee Jones,
Nuno Sá, Zhang Rui, Ben Grisdale, Conor Dooley,
Matthias Brugger, Rafael J. Wysocki, Krzysztof Kozlowski,
Daniel Lezcano, linux-mediatek, Andy Shevchenko, linux-kernel,
devicetree, linux-arm-kernel, Jonathan Cameron, Lukasz Luba,
Srinivas Kandagatla, linux-iio
On Mon, 04 May 2026 21:24:55 +0300, Roman Vivchar wrote:
> The MediaTek mt6323 PMIC temperature can be read using AUXADC channel.
>
> Add the devicetree binding documentation for the MediaTek mt6323 thermal.
> Due similarities with newer PMICs like mt6358, which include more than
> one thermal sensor, the #thermal-sensor-cells should be set to 1, to
> avoid breaking devicetree ABI in future.
>
> Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
> Signed-off-by: Roman Vivchar <rva333@protonmail.com>
> ---
> .../bindings/thermal/mediatek,mt6323-thermal.yaml | 63 ++++++++++++++++++++++
> 1 file changed, 63 insertions(+)
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
./Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.yaml:52:2: [warning] wrong indentation: expected 2 but found 1 (indentation)
./Documentation/devicetree/bindings/arm/mediatek/mediatek,audsys.yaml:84:1: [warning] too many blank lines (2 > 1) (empty-lines)
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/net/renesas,ether.example.dtb: ethernet-phy@1 (ethernet-phy-id0022.1537): compatible: ['ethernet-phy-id0022.1537', 'ethernet-phy-ieee802.3-c22'] is too long
from schema $id: http://devicetree.org/schemas/net/micrel.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/20260504-mt6323-v1-3-799b58b355ff@protonmail.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 04/13] iio: adc: mediatek: add mt6323 PMIC AUXADC driver
2026-05-04 18:24 ` [PATCH 04/13] iio: adc: mediatek: add mt6323 PMIC AUXADC driver Roman Vivchar via B4 Relay
@ 2026-05-05 7:53 ` Andy Shevchenko
0 siblings, 0 replies; 20+ messages in thread
From: Andy Shevchenko @ 2026-05-05 7:53 UTC (permalink / raw)
To: rva333
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones, linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale
On Mon, May 04, 2026 at 09:24:56PM +0300, Roman Vivchar via B4 Relay wrote:
> The mt6323 AUXADC is a 15-bit ADC used for system monitoring. This driver
> provides support for reading various channels including battery and
> charger voltages, battery and chip temperature, current sensing and
> accessory detection.
>
> Add a driver for the AUXADC found in the MediaTek mt6323 PMIC.
...
> +#include <linux/bitfield.h>
> +#include <linux/bits.h>
> +#include <linux/cleanup.h>
> +#include <linux/delay.h>
> +#include <linux/iio/iio.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/regmap.h>
> +#include <linux/types.h>
Follow IWYU. At least stringify.h is missing.
...
> +#define MTK_PMIC_IIO_CHAN(_name, _idx, _ch_type) \
> + { .type = _ch_type, \
> + .indexed = 1, \
> + .channel = _idx, \
> + .address = _idx, \
> + .datasheet_name = __stringify(_name), \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
> + BIT(IIO_CHAN_INFO_SCALE) }
Make {} each to occupy a single line.
...
> +/**
> + * struct mt6323_auxadc - Main driver structure
> + * @dev: Device pointer
> + * @regmap: Regmap from PWRAP
> + * @lock: Mutex to serialize AUXADC reading vs configuration
*
* ...put struct decription here... See below why.
*
> + */
> +struct mt6323_auxadc {
> + struct device *dev;
> + struct regmap *regmap;
Do you need both? Are they different? (I mean that regmap may be derived from
device and vice versa depending on the case.)
Ok, it seems the dev is the current platform device, while regmap comes from
parent->parent to it (2 levels up!). This needs a good comment in the struct
description explaining the hierarchy.
> + struct mutex lock;
> +};
...
> +static int mt6323_auxadc_check_if_stuck(struct mt6323_auxadc *auxadc)
> +{
> + int i, ret;
Why is 'i' signed?
> + u32 val;
> +
> + for (i = 0; i < 50; i++) {
Magic 50 and the whole thing is reinvention of something from iopoll.h.
> + ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON19, &val);
> + if (ret)
> + return ret;
> +
> + if (FIELD_GET(AUXADC_DECI_GDLY_MASK, val)) {
> + ret = regmap_read(auxadc->regmap, MT6323_AUXADC_ADC19,
> + &val);
> + if (ret)
> + return ret;
> +
> + if (!FIELD_GET(AUXADC_ADC19_BUSY_MASK, val)) {
> + ret = regmap_update_bits(
Bad indentation, there is a room for parameter on the previous line.
> + auxadc->regmap, MT6323_AUXADC_CON19,
> + FIELD_PREP(AUXADC_DECI_GDLY_MASK, 3),
> + 0x0);
> + if (ret)
> + return ret;
> + }
> + } else {
> + return 0;
> + }
> +
> + fsleep(10);
> + }
> +
> + return -ETIMEDOUT;
> +}
TL;DR: Find a suitable macro in iopoll.h and use it.
...
> +static int mt6323_auxadc_request(struct mt6323_auxadc *auxadc,
> + unsigned long channel)
> +{
> + int ret;
> + u32 pmic_val, adc_val;
> +
> + if (channel < 9) {
> + ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON11,
> + AUXADC_VBUF_EN, AUXADC_VBUF_EN);
> + if (ret)
> + return ret;
> +
> + ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON22,
> + &pmic_val);
> + if (ret)
> + return ret;
> +
> + adc_val = FIELD_GET(AUXADC_LOW_CHANNEL_MASK, pmic_val);
> + adc_val &= ~BIT(channel);
We also have FIELD_MODIFY(). Use it in all cases where appropriate.
> + ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON22,
> + AUXADC_LOW_CHANNEL_MASK, adc_val);
> + if (ret)
> + return ret;
> +
> + ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON22,
> + &pmic_val);
> + if (ret)
> + return ret;
> +
> + adc_val = FIELD_GET(AUXADC_LOW_CHANNEL_MASK, pmic_val);
> + adc_val |= BIT(channel);
> +
> + ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON22,
> + AUXADC_LOW_CHANNEL_MASK, adc_val);
> +
Stray blank line.
> + } else {
Redundant 'else' as this may be returned directly. So, refactor each branch to
a helper and use this as a small wrapper.
if (channel < 9)
return ...helper_for_chan_<_9...;
return ...otherwise...;
> + ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON23,
> + &pmic_val);
> + if (ret)
> + return ret;
> +
> + adc_val = FIELD_GET(AUXADC_AUDIO_CHANNEL_MASK, pmic_val);
> + adc_val &= ~BIT(channel - 9);
> +
> + ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON23,
> + AUXADC_AUDIO_CHANNEL_MASK, adc_val);
> + if (ret)
> + return ret;
> +
> + ret = regmap_read(auxadc->regmap, MT6323_AUXADC_CON23,
> + &pmic_val);
> + if (ret)
> + return ret;
> +
> + adc_val = FIELD_GET(AUXADC_AUDIO_CHANNEL_MASK, pmic_val);
> + adc_val |= BIT(channel - 9);
> +
> + ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON23,
> + AUXADC_AUDIO_CHANNEL_MASK, adc_val);
> + }
> +
> + return ret;
> +}
...
> +static int mt6323_auxadc_read(struct mt6323_auxadc *auxadc,
> + const struct iio_chan_spec *chan, int *out)
> +{
> + int ret;
> + u32 reg = mt6323_auxadc_channel_to_reg(chan->address);
> + u32 val;
> +
> + ret = regmap_read_poll_timeout(auxadc->regmap, reg, val,
> + (val & AUXADC_RDY_MASK), 1000, 100000);
Redundant parentheses, also use multipliers from time.h
struct regmap *map = ... // use this trick elsewhere as well
ret = regmap_read_poll_timeout(map, reg, val, val & AUXADC_RDY_MASK,
1 * USEC_PER_MSEC, 100 * USEC_PER_MSEC);
> + if (ret)
> + return ret;
> +
> + *out = FIELD_GET(AUXADC_DATA_MASK, val);
> +
> + return 0;
> +}
...
> +static int mt6323_auxadc_read_raw(struct iio_dev *indio_dev,
> + const struct iio_chan_spec *chan, int *val,
> + int *val2, long mask)
> +{
> + struct mt6323_auxadc *auxadc = iio_priv(indio_dev);
> + int ret, mult = 1;
> +
> + if (mask == IIO_CHAN_INFO_RAW) {
> + scoped_guard(mutex, &auxadc->lock)
> + {
Why? It's not a switch-case, the guard()() should be fine.
> + ret = mt6323_auxadc_check_if_stuck(auxadc);
> + if (ret)
> + return ret;
> +
> + ret = mt6323_auxadc_request(auxadc, chan->address);
> + if (ret)
> + return ret;
> +
> + usleep_range(300, 500);
We have fsleep().
> + ret = mt6323_auxadc_read(auxadc, chan, val);
> + if (ret)
> + return ret;
> + return IIO_VAL_INT;
> + }
> + } else if (mask == IIO_CHAN_INFO_SCALE) {
> + if (chan->channel == MT6323_AUXADC_ISENSE ||
> + chan->address == MT6323_AUXADC_BATSNS)
> + mult = 4;
> +
> + *val = mult * 1800;
> + *val2 = 32768;
> +
> + return IIO_VAL_FRACTIONAL;
> + } else
> + return -EINVAL;
> +}
...
> + ret = regmap_update_bits(auxadc->regmap, MT6323_AUXADC_CON10,
> + AUXADC_TRIM_CH2 | AUXADC_TRIM_CH4 |
> + AUXADC_TRIM_CH5 | AUXADC_TRIM_CH6,
> + AUXADC_TRIM_CH2 | AUXADC_TRIM_CH4 |
> + AUXADC_TRIM_CH5 | AUXADC_TRIM_CH6);
> + if (ret)
> + return ret;
We have _set_bits()/_clear_bits()/_assign_bits() of regmap API. Use them here
and in many other cases in this driver (and probably in the entire series.
I'm not going to comment each of the cases.
...
> +static int mt6323_auxadc_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct mt6323_auxadc *auxadc;
> + struct iio_dev *iio;
> + struct regmap *regmap;
> + int ret;
> +
> + /* mfd->pwrap regmap */
> + regmap = dev_get_regmap(dev->parent->parent, NULL);
> + if (!regmap)
> + return dev_err_probe(dev, -ENODEV, "failed to get regmap\n");
> +
> + iio = devm_iio_device_alloc(dev, sizeof(*auxadc));
> + if (!iio)
> + return -ENOMEM;
> +
> + auxadc = iio_priv(iio);
> + auxadc->regmap = regmap;
> + auxadc->dev = dev;
> + mutex_init(&auxadc->lock);
devm.
> + ret = mt6323_auxadc_init(auxadc);
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to initialize auxadc\n");
> +
> + iio->name = "mt6323-auxadc";
> + iio->info = &mt6323_auxadc_iio_info;
> + iio->modes = INDIO_DIRECT_MODE;
> + iio->channels = mt6323_auxadc_channels;
> + iio->num_channels = ARRAY_SIZE(mt6323_auxadc_channels);
> +
> + ret = devm_iio_device_register(dev, iio);
> + if (ret)
> + return dev_err_probe(dev, ret,
> + "failed to register iio device\n");
One line
> + return 0;
> +}
...
> +static const struct of_device_id mt6323_auxadc_of_match[] = {
> + { .compatible = "mediatek,mt6323-auxadc" },
> + {}
IIRC we use { } (with space) in IIO for the terminator entry in ID tables.
> +};
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 05/13] nvmem: add mt6323 PMIC EFUSE driver
2026-05-04 18:24 ` [PATCH 05/13] nvmem: add mt6323 PMIC EFUSE driver Roman Vivchar via B4 Relay
@ 2026-05-05 7:59 ` Andy Shevchenko
2026-05-05 16:24 ` Roman Vivchar
0 siblings, 1 reply; 20+ messages in thread
From: Andy Shevchenko @ 2026-05-05 7:59 UTC (permalink / raw)
To: rva333
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones, linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale
On Mon, May 04, 2026 at 09:24:57PM +0300, Roman Vivchar via B4 Relay wrote:
> Add support for the EFUSE controller found in the Mediatek MT6323 PMIC.
> The MT6323 EFUSE stores 24 bytes of hardware-related data, such as
> thermal sensor calibration values.
Besides below comments, check for the similar issues that previous patches in
the series have.
...
> +#include <linux/device.h>
Not needed as platform_device.h implies this ("is this good or bad?" is a
different story).
> +#include <linux/io.h>
> +#include <linux/mfd/mt6323/registers.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/platform_device.h>
> +#include <linux/property.h>
> +#include <linux/regmap.h>
Follow IWYU. At least missing types.h.
...
> +struct mt6323_efuse {
> + struct regmap *regmap;
> +};
Do you really need a custom wrapper data structure? Can't regmap be used
directly?
...
> +static int mt6323_efuse_read(void *context, unsigned int offset, void *val,
> + size_t bytes)
> +{
> + struct mt6323_efuse *efuse = context;
> + u32 tmp;
> + u16 *buf = val;
Really? CPU order all the time?
> + int i, ret;
Why is 'i' signed?
> + for (i = 0; i < bytes; i += 2) {
sizeof()?
And since 'i' is used only inside the loop
for (size_t i = 0; i < bytes; i += sizeof(*buf)) {
> + ret = regmap_read(efuse->regmap,
> + MT6323_EFUSE_DOUT_BASE + offset + i, &tmp);
> + if (ret)
> + return ret;
> + buf[i / 2] = tmp;
> + }
+ blank line.
Isn't this reimplementation of bulk read? Why the latter may not be used?
> + return 0;
> +}
...
> +static const struct of_device_id mt6323_efuse_of_match[] = {
> + { .compatible = "mediatek,mt6323-efuse" },
> + { /* sentinel */ },
Having trailing comma in the terminator is nonsense. Do we expect anything
behind it?
> +};
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 06/13] thermal: mediatek: add pmic thermal support
2026-05-04 18:24 ` [PATCH 06/13] thermal: mediatek: add pmic thermal support Roman Vivchar via B4 Relay
@ 2026-05-05 8:16 ` Andy Shevchenko
0 siblings, 0 replies; 20+ messages in thread
From: Andy Shevchenko @ 2026-05-05 8:16 UTC (permalink / raw)
To: rva333
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones, linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale
On Mon, May 04, 2026 at 09:24:58PM +0300, Roman Vivchar via B4 Relay wrote:
> Add a new driver to support thermal monitoring on MediaTek PMICs.
>
> The driver retrieves calibration data from EFUSE, calculates the
> temperature using a linear interpolation, and registers the device with
> the thermal framework.
>
> Initial support is added for the mt6323 PMIC.
First of all, please take into account the comments given against previous
patches.
...
> +config MTK_PMIC_THERMAL
> + tristate "AUXADC temperature sensor driver for MediaTek PMICs"
> + depends on MFD_MT6397
> + help
> + Enable this option if you want to get PMIC temperature
> + information for MediaTek platforms.
> + This driver configures thermal controllers to collect
> + temperature via AUXADC interface.
Don't we want to tell user how the module will be called in case of M choice?
...
> +#include <linux/err.h>
> +#include <linux/iio/consumer.h>
> +#include <linux/kernel.h>
No way your driver uses this header.
> +#include <linux/module.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/thermal.h>
Please, follow IWYU.
> +#include <linux/mfd/mt6323/registers.h>
...
> +#define MT6323_TEMP_MIN -20000
> +#define MT6323_TEMP_MAX 150000
Don't you want to use units.h multipliers?
...
> +/* Layout of the fuses providing the calibration data */
> +#define CALIB_BUF0_VTS(x) (((x) >> 8) & 0xff)
> +#define CALIB_BUF0_DEGC_CALI(x) (((x) >> 2) & 0x3f)
> +#define CALIB_BUF0_ADC_CALI_EN(x) (((x) >> 1) & 0x1)
> +
> +#define CALIB_BUF1_ID_20(x) (((x) >> 14) & 0x1)
> +#define CALIB_BUF1_ID_10(x) (((x) >> 12) & 0x1)
> +#define CALIB_BUF1_O_SLOPE_20(x) (((((x) >> 11) & 0x7) << 3) + (((x) >> 6) & 0x7))
> +#define CALIB_BUF1_O_SLOPE_10(x) (((x) >> 6) & 0x3f)
> +#define CALIB_BUF1_O_SLOPE_SIGN(x) (((x) >> 5) & 0x1)
> +#define CALIB_BUF1_VTS(x) ((((x) >> 0) & 0x1f) << 8)
Why not use BIT() and GENMASK() as appropriate? But better, why not use
bitfield.h APIs?
...
> +struct mtk_thermal_data {
> + const char *const *sensors;
> + s32 num_sensors;
> + const int cali_val;
What exactly does 'const' benefit here with?
> + int (*extract_efuse)(struct mtk_pmic_thermal *mt, u16 *buf);
> + void (*precalc)(struct mtk_pmic_thermal *mt, s32 vts, s32 degc_cali,
> + s32 o_slope, s32 o_slope_sign);
> +};
...
> +struct mtk_pmic_sensor {
> + struct mtk_pmic_thermal *mt;
> + int id;
> + struct iio_channel *adc_channel;
> + struct thermal_zone_device *tzdev;
> +};
Can you confirm with `pahole` that this is the best layout (taking into account
the use in the below data structure)?
> +struct mtk_pmic_thermal {
> + struct device *dev;
> + struct regmap *regmap;
> + struct mtk_pmic_sensor sensors[MAX_SENSORS];
> +
> + s32 t_slope1;
> + s32 t_slope2;
> + s32 t_intercept;
> +
> + const struct mtk_thermal_data *data;
> +};
...
> +static int mtk_pmic_read_temp(struct thermal_zone_device *tz, int *temperature)
> +{
> + struct mtk_pmic_sensor *sensor = thermal_zone_device_priv(tz);
> + int ret, raw, temp;
> +
> + ret = iio_read_channel_processed(sensor->adc_channel, &raw);
> + if (ret < 0) {
> + dev_err(sensor->mt->dev, "failed to read iio channel: %d\n",
> + ret);
> + return ret;
> + }
> +
> + temp = sensor->mt->t_intercept +
> + ((sensor->mt->t_slope1 * raw) / sensor->mt->t_slope2);
Too many parentheses.
> + if (!mtk_pmic_thermal_temp_is_valid(temp))
> + return -EINVAL;
> +
> + *temperature = temp;
> + return 0;
> +}
...
> +static void mtk_pmic_thermal_precalc_mt6323(struct mtk_pmic_thermal *mt,
> + s32 vts, s32 degc_cali, s32 o_slope,
> + s32 o_slope_sign)
> +{
> + s32 vbe_t;
> +
> + mt->t_slope1 = 100 * 1000;
magic1 * magic2...
> + if (o_slope_sign == 0)
> + mt->t_slope2 = -(mt->data->cali_val + o_slope);
> + else
> + mt->t_slope2 = -(mt->data->cali_val - o_slope);
> +
> + vbe_t = -1 * (((vts + 9102) * 1800) / 32768) * 1000;
More magics...
> + if (o_slope_sign == 0)
> + mt->t_intercept =
> + (vbe_t * 100) / -(mt->data->cali_val + o_slope);
> + else
> + mt->t_intercept =
> + (vbe_t * 100) / -(mt->data->cali_val - o_slope);
> +
> + mt->t_intercept += (degc_cali * (1000 / 2));
Too many parentheses.
> +}
This entire function misses a lot of comments and formulas with the references
to the datasheet.
...
> +{
> + struct nvmem_cell *cell;
> + void *buf;
> + size_t len;
> + int ret;
> +
> + cell = nvmem_cell_get(dev, "calibration-data");
> + if (IS_ERR(cell))
> + return PTR_ERR(cell);
> +
> + buf = nvmem_cell_read(cell, &len);
> + nvmem_cell_put(cell);
> +
> + if (IS_ERR(buf))
> + return PTR_ERR(buf);
> +
> + if (len < 2 * sizeof(u16)) {
> + dev_warn(dev, "invalid calibration data length\n");
And? Is it fatal error or not?
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + ret = mt->data->extract_efuse(mt, buf);
> + if (ret) {
> + dev_info(dev, "device not calibrated, using default values\n");
> + mt->data->precalc(mt, 3698, 50, 0, 0);
> + ret = 0;
> + }
> +out:
> + kfree(buf);
> + return ret;
Why not use __free() from cleanup.h?
> +}
...
> +static int mtk_pmic_thermal_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct mtk_pmic_thermal *mt;
> + int i, ret;
> +
> + mt = devm_kzalloc(dev, sizeof(*mt), GFP_KERNEL);
> + if (!mt)
> + return -ENOMEM;
> +
> + mt->regmap = dev_get_regmap(dev->parent->parent, NULL);
> + if (!mt->regmap)
> + return dev_err_probe(dev, -ENODEV, "failed to get regmap");
> +
> + mt->dev = dev;
> + mt->data = of_device_get_match_data(dev);
property.h instead of of.h and use just device_get_match_data().
> + ret = mtk_pmic_thermal_get_calib_data(dev, mt);
> + if (ret)
> + return ret;
> + for (i = 0; i < mt->data->num_sensors; i++) {
'i' is not used outside the loop:
for (unsigned int i = 0; i < mt->data->num_sensors; i++) {
> + struct mtk_pmic_sensor *sensor = &mt->sensors[i];
> +
> + sensor->id = i;
> + sensor->mt = mt;
> +
> + sensor->adc_channel =
> + devm_iio_channel_get(dev, mt->data->sensors[i]);
> + if (IS_ERR(sensor->adc_channel))
> + return dev_err_probe(dev, PTR_ERR(sensor->adc_channel),
> + "failed to get channel %s\n",
> + mt->data->sensors[i]);
> + sensor->tzdev = devm_thermal_of_zone_register(
> + dev, i, sensor, &mtk_pmic_thermal_ops);
> + if (IS_ERR(sensor->tzdev))
> + return dev_err_probe(
> + dev, PTR_ERR(sensor->tzdev),
What a broken indentation in the whole stanza...
> + "failed to register thermal zone %d\n", i);
> + }
> + return 0;
> +}
...
> +static const struct of_device_id mtk_pmic_thermal_of_match[] = {
> + { .compatible = "mediatek,mt6323-thermal",
> + .data = &mt6323_thermal_data },
> + { /* sentinel */ },
Nonsense trailing comma.
> +};
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 03/13] dt-bindings: thermal: add mt6323 PMIC thermal
2026-05-04 18:24 ` [PATCH 03/13] dt-bindings: thermal: add mt6323 PMIC thermal Roman Vivchar via B4 Relay
2026-05-04 19:41 ` Rob Herring (Arm)
@ 2026-05-05 14:05 ` Rob Herring
1 sibling, 0 replies; 20+ messages in thread
From: Rob Herring @ 2026-05-05 14:05 UTC (permalink / raw)
To: Roman Vivchar
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones, linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale
On Mon, May 04, 2026 at 09:24:55PM +0300, Roman Vivchar wrote:
> The MediaTek mt6323 PMIC temperature can be read using AUXADC channel.
>
> Add the devicetree binding documentation for the MediaTek mt6323 thermal.
> Due similarities with newer PMICs like mt6358, which include more than
> one thermal sensor, the #thermal-sensor-cells should be set to 1, to
> avoid breaking devicetree ABI in future.
>
> Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
> Signed-off-by: Roman Vivchar <rva333@protonmail.com>
> ---
> .../bindings/thermal/mediatek,mt6323-thermal.yaml | 63 ++++++++++++++++++++++
> 1 file changed, 63 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/thermal/mediatek,mt6323-thermal.yaml b/Documentation/devicetree/bindings/thermal/mediatek,mt6323-thermal.yaml
> new file mode 100644
> index 000000000000..1882816ba274
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/mediatek,mt6323-thermal.yaml
> @@ -0,0 +1,63 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/thermal/mediatek,mt6323-thermal.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek PMIC thermal
> +
> +maintainers:
> + - Roman Vivchar <rva333@protonmail.com>
> +
> +description:
> + The MediaTek PMIC thermal sensor uses an AUXADC channel to read raw
> + temperature data and applies calibration data from NVMEM.
> +
> +allOf:
> + - $ref: thermal-sensor.yaml#
> +
> +properties:
> + compatible:
> + const: mediatek,mt6323-thermal
> +
> + io-channels:
> + description: >
Don't need '>'.
> + IIO channel for the AUXADC to read raw data from.
> + maxItems: 1
> +
> + io-channel-names:
> + const: vts
-names properties are pointless for a single entry.
> +
> + nvmem-cells:
> + description: >
> + NVMEM cell with phandle to the calibration data provided by the
> + NVMEM device. If unspecified default values will be used.
Drop. Don't need generic descriptions.
> + maxItems: 1
> +
> + nvmem-cell-names:
> + const: calibration-data
> +
> + "#thermal-sensor-cells":
> + const: 1
> +
> +required:
> + - compatible
> + - io-channels
> + - io-channel-names
> + - "#thermal-sensor-cells"
> +
> +unevaluatedProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/iio/adc/mediatek,mt6323-auxadc.h>
> +
> + mt6323_thermal: thermal {
Drop unused labels.
> + compatible = "mediatek,mt6323-thermal";
> + nvmem-cells = <&mt6323_thermal_calibration_data>;
> + nvmem-cell-names = "calibration-data";
> +
> + io-channels = <&mt6323_adc MT6323_AUXADC_CHIP_TEMP>;
> + io-channel-names = "vts";
> + #thermal-sensor-cells = <1>;
> + };
>
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 05/13] nvmem: add mt6323 PMIC EFUSE driver
2026-05-05 7:59 ` Andy Shevchenko
@ 2026-05-05 16:24 ` Roman Vivchar
0 siblings, 0 replies; 20+ messages in thread
From: Roman Vivchar @ 2026-05-05 16:24 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Srinivas Kandagatla,
Rafael J. Wysocki, Daniel Lezcano, Zhang Rui, Lukasz Luba,
Lee Jones, linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, linux-pm, Ben Grisdale
On Tuesday, May 5th, 2026 at 11:00 AM, Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> On Mon, May 04, 2026 at 09:24:57PM +0300, Roman Vivchar via B4 Relay wrote:
>
> > Add support for the EFUSE controller found in the Mediatek MT6323 PMIC.
> > The MT6323 EFUSE stores 24 bytes of hardware-related data, such as
> > thermal sensor calibration values.
>
> Besides below comments, check for the similar issues that previous patches in
> the series have.
>
> ...
>
> > +#include <linux/device.h>
>
> Not needed as platform_device.h implies this ("is this good or bad?" is a
> different story).
>
> > +#include <linux/io.h>
> > +#include <linux/mfd/mt6323/registers.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/module.h>
> > +#include <linux/nvmem-provider.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/property.h>
> > +#include <linux/regmap.h>
>
> Follow IWYU. At least missing types.h.
>
> ...
>
> > +struct mt6323_efuse {
> > + struct regmap *regmap;
> > +};
>
> Do you really need a custom wrapper data structure? Can't regmap be used
> directly?
>
> ...
>
> > +static int mt6323_efuse_read(void *context, unsigned int offset, void *val,
> > + size_t bytes)
> > +{
> > + struct mt6323_efuse *efuse = context;
> > + u32 tmp;
>
> > + u16 *buf = val;
>
> Really? CPU order all the time?
>
> > + int i, ret;
>
> Why is 'i' signed?
>
> > + for (i = 0; i < bytes; i += 2) {
>
> sizeof()?
>
> And since 'i' is used only inside the loop
>
> for (size_t i = 0; i < bytes; i += sizeof(*buf)) {
>
> > + ret = regmap_read(efuse->regmap,
> > + MT6323_EFUSE_DOUT_BASE + offset + i, &tmp);
> > + if (ret)
> > + return ret;
> > + buf[i / 2] = tmp;
> > + }
>
> + blank line.
>
> Isn't this reimplementation of bulk read? Why the latter may not be used?
Yes, but the PWRAP (the regmap which the driver uses) doesn't support read
callback, only reg_read is implemented in the driver.
It hits the map->cache_type == REGCACHE_NONE in the regmap_read_raw, and falls
for the !map->read check, so regmap_bulk_read neither the regmap_read_raw
can be used.
Technically the PMIC is not continuous address space, but rather non-MMIO FSM,
so it makes sense to not implement the read callback. I guess the custom
implementation is fine then?
All other suggestions will be applied for v2.
>
> > + return 0;
> > +}
>
> ...
>
> > +static const struct of_device_id mt6323_efuse_of_match[] = {
> > + { .compatible = "mediatek,mt6323-efuse" },
> > + { /* sentinel */ },
>
> Having trailing comma in the terminator is nonsense. Do we expect anything
> behind it?
>
> > +};
>
> --
> With Best Regards,
> Andy Shevchenko
>
>
>
Best regards,
Roman
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2026-05-05 16:24 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-04 18:24 [PATCH 00/13] add AUXADC, EFUSE and thermal drivers for the MediaTek mt6323 PMIC Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 01/13] dt-bindings: iio: adc: add mt6323 PMIC AUXADC Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 02/13] dt-bindings: nvmem: add mt6323 PMIC EFUSE Roman Vivchar via B4 Relay
2026-05-04 18:24 ` [PATCH 03/13] dt-bindings: thermal: add mt6323 PMIC thermal Roman Vivchar via B4 Relay
2026-05-04 19:41 ` Rob Herring (Arm)
2026-05-05 14:05 ` Rob Herring
2026-05-04 18:24 ` [PATCH 04/13] iio: adc: mediatek: add mt6323 PMIC AUXADC driver Roman Vivchar via B4 Relay
2026-05-05 7:53 ` Andy Shevchenko
2026-05-04 18:24 ` [PATCH 05/13] nvmem: add mt6323 PMIC EFUSE driver Roman Vivchar via B4 Relay
2026-05-05 7:59 ` Andy Shevchenko
2026-05-05 16:24 ` Roman Vivchar
2026-05-04 18:24 ` [PATCH 06/13] thermal: mediatek: add pmic thermal support Roman Vivchar via B4 Relay
2026-05-05 8:16 ` Andy Shevchenko
2026-05-04 18:24 ` [PATCH 07/13] mfd: mt6397-core: add mt6323 AUXADC support Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 08/13] mfd: mt6397-core: add support for mt6323 efuse Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 09/13] mfd: mt6397-core: add support for mt6323 thermal Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 10/13] ARM: dts: mediatek: mt6323: add support for AUXADC Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 11/13] ARM: dts: mediatek: mt6323: add support for EFUSE Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 12/13] ARM: dts: mediatek: mt6323: add support for thermal Roman Vivchar via B4 Relay
2026-05-04 18:25 ` [PATCH 13/13] MAINTAINERS: add mt6323 drivers maintainer Roman Vivchar via B4 Relay
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox