Subject: [PATCH v2 0/5] MediaTek MT6357/8/9 PMIC Auxiliary ADC support

Changes in v2:
- Dropped 'mfd: mt6397-core: Add support for AUXADCs on MT6357/58/59 PMICs'
as Lee J already applied it;
- Added patch to describe the ADC subnode in the MT6357 MFD binding
and moved the example node from mediatek,mt6359-auxadc.yaml to
mediatek,mt6357.yaml
- Added 8-bits {s8,u8}_fract to math.h
- Addressed reviewer comments on mt6359-auxadc driver

AngeloGioacchino Del Regno (5):
dt-bindings: iio: adc: Add MediaTek MT6359 PMIC AUXADC
dt-bindings: mfd: mediatek,mt6357: Describe Auxiliary ADC subdev
math.h: Add unsigned 8 bits fractional numbers type
iio: adc: Add support for MediaTek MT6357/8/9 Auxiliary ADC
arm64: dts: mediatek: Add ADC node on MT6357, MT6358, MT6359 PMICs

.../iio/adc/mediatek,mt6359-auxadc.yaml | 33 +
.../bindings/mfd/mediatek,mt6357.yaml | 10 +
arch/arm64/boot/dts/mediatek/mt6357.dtsi | 5 +
arch/arm64/boot/dts/mediatek/mt6358.dtsi | 5 +
arch/arm64/boot/dts/mediatek/mt6359.dtsi | 5 +
drivers/iio/adc/Kconfig | 12 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/mt6359-auxadc.c | 606 ++++++++++++++++++
.../iio/adc/mediatek,mt6357-auxadc.h | 21 +
.../iio/adc/mediatek,mt6358-auxadc.h | 22 +
.../iio/adc/mediatek,mt6359-auxadc.h | 22 +
include/linux/math.h | 2 +
12 files changed, 744 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
create mode 100644 drivers/iio/adc/mt6359-auxadc.c
create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6357-auxadc.h
create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6358-auxadc.h
create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6359-auxadc.h

--
2.45.1



Subject: [PATCH v2 1/5] dt-bindings: iio: adc: Add MediaTek MT6359 PMIC AUXADC

Add a new binding for the MT6350 Series (MT6357/8/9) PMIC AUXADC,
providing various ADC channels for both internal temperatures and
voltages, audio accessory detection (hp/mic/hp+mic and buttons,
usually on a 3.5mm jack) other than some basic battery statistics
on boards where the battery is managed by this PMIC.

Also add the necessary dt-binding headers for devicetree consumers.

Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
.../iio/adc/mediatek,mt6359-auxadc.yaml | 33 +++++++++++++++++++
.../iio/adc/mediatek,mt6357-auxadc.h | 21 ++++++++++++
.../iio/adc/mediatek,mt6358-auxadc.h | 22 +++++++++++++
.../iio/adc/mediatek,mt6359-auxadc.h | 22 +++++++++++++
4 files changed, 98 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6357-auxadc.h
create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6358-auxadc.h
create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6359-auxadc.h

diff --git a/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
new file mode 100644
index 000000000000..6497c416094d
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/mediatek,mt6359-auxadc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek MT6350 series PMIC AUXADC
+
+maintainers:
+ - AngeloGioacchino Del Regno <[email protected]>
+
+description:
+ The Auxiliary Analog/Digital Converter (AUXADC) is an ADC found
+ in some MediaTek PMICs, 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:
+ enum:
+ - mediatek,mt6357-auxadc
+ - mediatek,mt6358-auxadc
+ - mediatek,mt6359-auxadc
+
+ "#io-channel-cells":
+ const: 1
+
+required:
+ - compatible
+ - "#io-channel-cells"
+
+additionalProperties: false
diff --git a/include/dt-bindings/iio/adc/mediatek,mt6357-auxadc.h b/include/dt-bindings/iio/adc/mediatek,mt6357-auxadc.h
new file mode 100644
index 000000000000..03ebb1d23953
--- /dev/null
+++ b/include/dt-bindings/iio/adc/mediatek,mt6357-auxadc.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+
+#ifndef _DT_BINDINGS_MEDIATEK_MT6357_AUXADC_H
+#define _DT_BINDINGS_MEDIATEK_MT6357_AUXADC_H
+
+/* ADC Channel Index */
+#define MT6357_AUXADC_BATADC 0
+#define MT6357_AUXADC_ISENSE 1
+#define MT6357_AUXADC_VCDT 2
+#define MT6357_AUXADC_BAT_TEMP 3
+#define MT6357_AUXADC_CHIP_TEMP 4
+#define MT6357_AUXADC_ACCDET 5
+#define MT6357_AUXADC_VDCXO 6
+#define MT6357_AUXADC_TSX_TEMP 7
+#define MT6357_AUXADC_HPOFS_CAL 8
+#define MT6357_AUXADC_DCXO_TEMP 9
+#define MT6357_AUXADC_VCORE_TEMP 10
+#define MT6357_AUXADC_VPROC_TEMP 11
+#define MT6357_AUXADC_VBAT 12
+
+#endif
diff --git a/include/dt-bindings/iio/adc/mediatek,mt6358-auxadc.h b/include/dt-bindings/iio/adc/mediatek,mt6358-auxadc.h
new file mode 100644
index 000000000000..efa08398fafd
--- /dev/null
+++ b/include/dt-bindings/iio/adc/mediatek,mt6358-auxadc.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+
+#ifndef _DT_BINDINGS_MEDIATEK_MT6358_AUXADC_H
+#define _DT_BINDINGS_MEDIATEK_MT6358_AUXADC_H
+
+/* ADC Channel Index */
+#define MT6358_AUXADC_BATADC 0
+#define MT6358_AUXADC_VCDT 1
+#define MT6358_AUXADC_BAT_TEMP 2
+#define MT6358_AUXADC_CHIP_TEMP 3
+#define MT6358_AUXADC_ACCDET 4
+#define MT6358_AUXADC_VDCXO 5
+#define MT6358_AUXADC_TSX_TEMP 6
+#define MT6358_AUXADC_HPOFS_CAL 7
+#define MT6358_AUXADC_DCXO_TEMP 8
+#define MT6358_AUXADC_VBIF 9
+#define MT6358_AUXADC_VCORE_TEMP 10
+#define MT6358_AUXADC_VPROC_TEMP 11
+#define MT6358_AUXADC_VGPU_TEMP 12
+#define MT6358_AUXADC_VBAT 13
+
+#endif
diff --git a/include/dt-bindings/iio/adc/mediatek,mt6359-auxadc.h b/include/dt-bindings/iio/adc/mediatek,mt6359-auxadc.h
new file mode 100644
index 000000000000..59826393ee7e
--- /dev/null
+++ b/include/dt-bindings/iio/adc/mediatek,mt6359-auxadc.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+
+#ifndef _DT_BINDINGS_MEDIATEK_MT6359_AUXADC_H
+#define _DT_BINDINGS_MEDIATEK_MT6359_AUXADC_H
+
+/* ADC Channel Index */
+#define MT6359_AUXADC_BATADC 0
+#define MT6359_AUXADC_BAT_TEMP 1
+#define MT6359_AUXADC_CHIP_TEMP 2
+#define MT6359_AUXADC_ACCDET 3
+#define MT6359_AUXADC_VDCXO 4
+#define MT6359_AUXADC_TSX_TEMP 5
+#define MT6359_AUXADC_HPOFS_CAL 6
+#define MT6359_AUXADC_DCXO_TEMP 7
+#define MT6359_AUXADC_VBIF 8
+#define MT6359_AUXADC_VCORE_TEMP 9
+#define MT6359_AUXADC_VPROC_TEMP 10
+#define MT6359_AUXADC_VGPU_TEMP 11
+#define MT6359_AUXADC_VBAT 12
+#define MT6359_AUXADC_IBAT 13
+
+#endif
--
2.45.1


Subject: [PATCH v2 2/5] dt-bindings: mfd: mediatek,mt6357: Describe Auxiliary ADC subdev

Describe the PMIC-integrated Auxiliary Analog to Digital Converter
subdevice node.
Full description is available in the mediatek,mt6359-auxadc.yaml
binding relative to that hardware.

Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
.../devicetree/bindings/mfd/mediatek,mt6357.yaml | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml b/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml
index 37423c2e0fdf..e3513cad25f6 100644
--- a/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml
+++ b/Documentation/devicetree/bindings/mfd/mediatek,mt6357.yaml
@@ -37,6 +37,11 @@ properties:
"#interrupt-cells":
const: 2

+ adc:
+ type: object
+ $ref: /schemas/iio/adc/mediatek,mt6359-auxadc.yaml
+ unevaluatedProperties: false
+
regulators:
type: object
$ref: /schemas/regulator/mediatek,mt6357-regulator.yaml
@@ -83,6 +88,11 @@ examples:
interrupt-controller;
#interrupt-cells = <2>;

+ pmic_adc: adc {
+ compatible = "mediatek,mt6357-auxadc";
+ #io-channel-cells = <1>;
+ };
+
regulators {
mt6357_vproc_reg: buck-vproc {
regulator-name = "vproc";
--
2.45.1


Subject: [PATCH v2 5/5] arm64: dts: mediatek: Add ADC node on MT6357, MT6358, MT6359 PMICs

Add support for the ADC on MT6357/8/9 and keep it default enabled
as this IP is always present on those PMICs.
Users may use different IIO channels depending on board-specific
routing.

Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
arch/arm64/boot/dts/mediatek/mt6357.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt6358.dtsi | 5 +++++
arch/arm64/boot/dts/mediatek/mt6359.dtsi | 5 +++++
3 files changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt6357.dtsi b/arch/arm64/boot/dts/mediatek/mt6357.dtsi
index 3330a03c2f74..5fafa842d312 100644
--- a/arch/arm64/boot/dts/mediatek/mt6357.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6357.dtsi
@@ -10,6 +10,11 @@ &pwrap {
mt6357_pmic: pmic {
compatible = "mediatek,mt6357";

+ pmic_adc: adc {
+ compatible = "mediatek,mt6357-auxadc";
+ #io-channel-cells = <1>;
+ };
+
regulators {
mt6357_vproc_reg: buck-vproc {
regulator-name = "vproc";
diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
index a1b96013f814..641d452fbc08 100644
--- a/arch/arm64/boot/dts/mediatek/mt6358.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
@@ -10,6 +10,11 @@ pmic: pmic {
interrupt-controller;
#interrupt-cells = <2>;

+ pmic_adc: adc {
+ compatible = "mediatek,mt6358-auxadc";
+ #io-channel-cells = <1>;
+ };
+
mt6358codec: mt6358codec {
compatible = "mediatek,mt6358-sound";
mediatek,dmic-mode = <0>; /* two-wires */
diff --git a/arch/arm64/boot/dts/mediatek/mt6359.dtsi b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
index df3e822232d3..8e1b8c85c6ed 100644
--- a/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6359.dtsi
@@ -9,6 +9,11 @@ pmic: pmic {
interrupt-controller;
#interrupt-cells = <2>;

+ pmic_adc: adc {
+ compatible = "mediatek,mt6359-auxadc";
+ #io-channel-cells = <1>;
+ };
+
mt6359codec: mt6359codec {
};

--
2.45.1


Subject: [PATCH v2 4/5] iio: adc: Add support for MediaTek MT6357/8/9 Auxiliary ADC

Add a driver to support reading the Auxiliary ADC IP found in the
MediaTek MT6357, MT6358 and MT6359 Power Management ICs, featuring
a different register layout, configurationm reset and ADC reading
sequence from the other already supported MediaTek SoC or PMIC
(aux)ADC HW.

This driver provides multiple ADC channels for system monitoring,
such as battery voltage, PMIC temperature, PMIC-internal voltage
regulators temperature, and others.

Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
drivers/iio/adc/Kconfig | 12 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/mt6359-auxadc.c | 606 ++++++++++++++++++++++++++++++++
3 files changed, 619 insertions(+)
create mode 100644 drivers/iio/adc/mt6359-auxadc.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 8db68b80b391..1c3df21beaf3 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -870,6 +870,18 @@ config MCP3911
This driver can also be built as a module. If so, the module will be
called mcp3911.

+config MEDIATEK_MT6359_AUXADC
+ tristate "MediaTek MT6359 PMIC AUXADC driver"
+ depends on MFD_MT6397
+ help
+ Say yes here to enable support for MediaTek MT6357, MT6358 and
+ MT6359 PMICs 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 mt6359-auxadc.
+
config MEDIATEK_MT6360_ADC
tristate "Mediatek MT6360 ADC driver"
depends on MFD_MT6360
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index edb32ce2af02..da7d4452b1e0 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -79,6 +79,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
obj-$(CONFIG_MCP3564) += mcp3564.o
obj-$(CONFIG_MCP3911) += mcp3911.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
obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
diff --git a/drivers/iio/adc/mt6359-auxadc.c b/drivers/iio/adc/mt6359-auxadc.c
new file mode 100644
index 000000000000..a4970cfb49a5
--- /dev/null
+++ b/drivers/iio/adc/mt6359-auxadc.c
@@ -0,0 +1,606 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * MediaTek MT6359 PMIC AUXADC IIO driver
+ *
+ * Copyright (c) 2021 MediaTek Inc.
+ * Copyright (c) 2024 Collabora Ltd
+ * Author: AngeloGioacchino Del Regno <[email protected]>
+ */
+
+#include <linux/bits.h>
+#include <linux/cleanup.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+#include <linux/iio/iio.h>
+
+#include <linux/mfd/mt6397/core.h>
+
+#include <dt-bindings/iio/adc/mediatek,mt6357-auxadc.h>
+#include <dt-bindings/iio/adc/mediatek,mt6358-auxadc.h>
+#include <dt-bindings/iio/adc/mediatek,mt6359-auxadc.h>
+
+#define AUXADC_AVG_TIME_US 10
+#define AUXADC_POLL_DELAY_US 100
+#define AUXADC_TIMEOUT_US 32000
+#define AUXADC_VOLT_FULL 1800
+#define IMP_STOP_DELAY_US 150
+#define IMP_POLL_DELAY_US 1000
+
+/* For PMIC_RG_RESET_VAL and MT6358_IMP0_CLEAR, the bits specific purpose is unknown. */
+#define PMIC_RG_RESET_VAL (BIT(0) | BIT(3))
+#define PMIC_AUXADC_RDY_BIT BIT(15)
+#define MT6357_IMP_ADC_NUM 30
+#define MT6358_IMP_ADC_NUM 28
+
+#define MT6358_DCM_CK_SW_EN GENMASK(1, 0)
+#define MT6358_IMP0_CLEAR (BIT(14) | BIT(7))
+#define MT6358_IMP0_IRQ_RDY BIT(8)
+#define MT6358_IMP1_AUTOREPEAT_EN BIT(15)
+
+#define MT6359_IMP0_CONV_EN BIT(0)
+#define MT6359_IMP1_IRQ_RDY BIT(15)
+
+enum mtk_pmic_auxadc_regs {
+ PMIC_AUXADC_ADC0,
+ PMIC_AUXADC_DCM_CON,
+ PMIC_AUXADC_IMP0,
+ PMIC_AUXADC_IMP1,
+ PMIC_AUXADC_IMP3,
+ PMIC_AUXADC_RQST0,
+ PMIC_AUXADC_RQST1,
+ PMIC_HK_TOP_WKEY,
+ PMIC_HK_TOP_RST_CON0,
+ PMIC_FGADC_R_CON0,
+ PMIC_AUXADC_REGS_MAX
+};
+
+enum mtk_pmic_auxadc_channels {
+ PMIC_AUXADC_CHAN_BATADC,
+ PMIC_AUXADC_CHAN_ISENSE,
+ PMIC_AUXADC_CHAN_VCDT,
+ PMIC_AUXADC_CHAN_BAT_TEMP,
+ PMIC_AUXADC_CHAN_BATID,
+ PMIC_AUXADC_CHAN_CHIP_TEMP,
+ PMIC_AUXADC_CHAN_VCORE_TEMP,
+ PMIC_AUXADC_CHAN_VPROC_TEMP,
+ PMIC_AUXADC_CHAN_VGPU_TEMP,
+ PMIC_AUXADC_CHAN_ACCDET,
+ PMIC_AUXADC_CHAN_VDCXO,
+ PMIC_AUXADC_CHAN_TSX_TEMP,
+ PMIC_AUXADC_CHAN_HPOFS_CAL,
+ PMIC_AUXADC_CHAN_DCXO_TEMP,
+ PMIC_AUXADC_CHAN_VBIF,
+ PMIC_AUXADC_CHAN_IBAT,
+ PMIC_AUXADC_CHAN_VBAT,
+ PMIC_AUXADC_CHAN_MAX
+};
+
+/**
+ * struct mt6359_auxadc - Main driver structure
+ * @dev: Device pointer
+ * @regmap: Regmap from SoC PMIC Wrapper
+ * @chip_info: PMIC specific chip info
+ * @lock: Mutex to serialize AUXADC reading vs configuration
+ * @timed_out: Signals whether the last read timed out
+ */
+struct mt6359_auxadc {
+ struct device *dev;
+ struct regmap *regmap;
+ const struct mtk_pmic_auxadc_info *chip_info;
+ struct mutex lock;
+ bool timed_out;
+};
+
+/**
+ * struct mtk_pmic_auxadc_chan - PMIC AUXADC channel data
+ * @req_idx: Request register number
+ * @req_mask: Bitmask to activate a channel
+ * @num_samples: Number of AUXADC samples for averaging
+ * @r_ratio: Resistance ratio fractional
+ */
+struct mtk_pmic_auxadc_chan {
+ u8 req_idx;
+ u16 req_mask;
+ u16 num_samples;
+ struct u8_fract r_ratio;
+};
+
+/**
+ * struct mtk_pmic_auxadc_info - PMIC specific chip info
+ * @model_name: PMIC model name
+ * @channels: IIO specification of ADC channels
+ * @num_channels: Number of ADC channels
+ * @desc: PMIC AUXADC channel data
+ * @regs: List of PMIC specific registers
+ * @sec_unlock_key: Security unlock key for HK_TOP writes
+ * @imp_adc_num: ADC channel for battery impedance readings
+ * @read_imp: Callback to read impedance channels
+ */
+struct mtk_pmic_auxadc_info {
+ const char *model_name;
+ const struct iio_chan_spec *channels;
+ u8 num_channels;
+ const struct mtk_pmic_auxadc_chan *desc;
+ const u16 *regs;
+ u16 sec_unlock_key;
+ u8 imp_adc_num;
+ int (*read_imp)(struct mt6359_auxadc *adc_dev, int *vbat, int *ibat);
+};
+
+#define MTK_PMIC_ADC_CHAN(_ch_idx, _req_idx, _req_bit, _samples, _rnum, _rdiv) \
+ [PMIC_AUXADC_CHAN_##_ch_idx] = { \
+ .req_idx = _req_idx, \
+ .req_mask = BIT(_req_bit), \
+ .num_samples = _samples, \
+ .r_ratio = { _rnum, _rdiv } \
+ }
+
+#define MTK_PMIC_IIO_CHAN(_model, _name, _ch_idx, _adc_idx, _nbits, _ch_type) \
+{ \
+ .type = _ch_type, \
+ .channel = _model##_AUXADC_##_ch_idx, \
+ .address = _adc_idx, \
+ .scan_index = PMIC_AUXADC_CHAN_##_ch_idx, \
+ .datasheet_name = __stringify(_name), \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = _nbits, \
+ .storagebits = 16, \
+ .endianness = IIO_CPU \
+ }, \
+ .indexed = 1, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) \
+}
+
+static const struct iio_chan_spec mt6357_auxadc_channels[] = {
+ MTK_PMIC_IIO_CHAN(MT6357, bat_adc, BATADC, 0, 15, IIO_RESISTANCE),
+ MTK_PMIC_IIO_CHAN(MT6357, isense, ISENSE, 1, 12, IIO_CURRENT),
+ MTK_PMIC_IIO_CHAN(MT6357, cdt_v, VCDT, 2, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6357, batt_temp, BAT_TEMP, 3, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6357, chip_temp, CHIP_TEMP, 4, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6357, acc_det, ACCDET, 5, 12, IIO_RESISTANCE),
+ MTK_PMIC_IIO_CHAN(MT6357, dcxo_v, VDCXO, 6, 12, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(MT6357, tsx_temp, TSX_TEMP, 7, 15, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6357, hp_ofs_cal, HPOFS_CAL, 9, 15, IIO_RESISTANCE),
+ MTK_PMIC_IIO_CHAN(MT6357, dcxo_temp, DCXO_TEMP, 36, 15, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6357, vcore_temp, VCORE_TEMP, 40, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6357, vproc_temp, VPROC_TEMP, 41, 12, IIO_TEMP),
+
+ /* Battery impedance channels */
+ MTK_PMIC_IIO_CHAN(MT6357, batt_v, VBAT, 0, 15, IIO_VOLTAGE),
+};
+
+static const struct mtk_pmic_auxadc_chan mt6357_auxadc_ch_desc[] = {
+ MTK_PMIC_ADC_CHAN(BATADC, PMIC_AUXADC_RQST0, 0, 128, 3, 1),
+ MTK_PMIC_ADC_CHAN(ISENSE, PMIC_AUXADC_RQST0, 0, 128, 3, 1),
+ MTK_PMIC_ADC_CHAN(VCDT, PMIC_AUXADC_RQST0, 0, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(BAT_TEMP, PMIC_AUXADC_RQST0, 3, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(CHIP_TEMP, PMIC_AUXADC_RQST0, 4, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(ACCDET, PMIC_AUXADC_RQST0, 5, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(TSX_TEMP, PMIC_AUXADC_RQST0, 7, 128, 1, 1),
+ MTK_PMIC_ADC_CHAN(HPOFS_CAL, PMIC_AUXADC_RQST0, 9, 256, 1, 1),
+ MTK_PMIC_ADC_CHAN(DCXO_TEMP, PMIC_AUXADC_RQST0, 10, 16, 1, 1),
+ MTK_PMIC_ADC_CHAN(VBIF, PMIC_AUXADC_RQST0, 11, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(VCORE_TEMP, PMIC_AUXADC_RQST1, 5, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(VPROC_TEMP, PMIC_AUXADC_RQST1, 6, 8, 1, 1),
+
+ /* Battery impedance channels */
+ MTK_PMIC_ADC_CHAN(VBAT, 0, 0, 128, 3, 1),
+};
+
+static const u16 mt6357_auxadc_regs[] = {
+ [PMIC_HK_TOP_RST_CON0] = 0x0f90,
+ [PMIC_AUXADC_DCM_CON] = 0x122e,
+ [PMIC_AUXADC_ADC0] = 0x1088,
+ [PMIC_AUXADC_IMP0] = 0x119c,
+ [PMIC_AUXADC_IMP1] = 0x119e,
+ [PMIC_AUXADC_RQST0] = 0x110e,
+ [PMIC_AUXADC_RQST1] = 0x1114,
+};
+
+static const struct iio_chan_spec mt6358_auxadc_channels[] = {
+ MTK_PMIC_IIO_CHAN(MT6358, bat_adc, BATADC, 0, 15, IIO_RESISTANCE),
+ MTK_PMIC_IIO_CHAN(MT6358, cdt_v, VCDT, 2, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6358, batt_temp, BAT_TEMP, 3, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6358, chip_temp, CHIP_TEMP, 4, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6358, acc_det, ACCDET, 5, 12, IIO_RESISTANCE),
+ MTK_PMIC_IIO_CHAN(MT6358, dcxo_v, VDCXO, 6, 12, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(MT6358, tsx_temp, TSX_TEMP, 7, 15, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6358, hp_ofs_cal, HPOFS_CAL, 9, 15, IIO_RESISTANCE),
+ MTK_PMIC_IIO_CHAN(MT6358, dcxo_temp, DCXO_TEMP, 10, 15, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6358, bif_v, VBIF, 11, 12, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(MT6358, vcore_temp, VCORE_TEMP, 38, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6358, vproc_temp, VPROC_TEMP, 39, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6358, vgpu_temp, VGPU_TEMP, 40, 12, IIO_TEMP),
+
+ /* Battery impedance channels */
+ MTK_PMIC_IIO_CHAN(MT6358, batt_v, VBAT, 0, 15, IIO_VOLTAGE),
+};
+
+static const struct mtk_pmic_auxadc_chan mt6358_auxadc_ch_desc[] = {
+ MTK_PMIC_ADC_CHAN(BATADC, PMIC_AUXADC_RQST0, 0, 128, 3, 1),
+ MTK_PMIC_ADC_CHAN(VCDT, PMIC_AUXADC_RQST0, 0, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(BAT_TEMP, PMIC_AUXADC_RQST0, 3, 8, 2, 1),
+ MTK_PMIC_ADC_CHAN(CHIP_TEMP, PMIC_AUXADC_RQST0, 4, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(ACCDET, PMIC_AUXADC_RQST0, 5, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(VDCXO, PMIC_AUXADC_RQST0, 6, 8, 3, 2),
+ MTK_PMIC_ADC_CHAN(TSX_TEMP, PMIC_AUXADC_RQST0, 7, 128, 1, 1),
+ MTK_PMIC_ADC_CHAN(HPOFS_CAL, PMIC_AUXADC_RQST0, 9, 256, 1, 1),
+ MTK_PMIC_ADC_CHAN(DCXO_TEMP, PMIC_AUXADC_RQST0, 10, 16, 1, 1),
+ MTK_PMIC_ADC_CHAN(VBIF, PMIC_AUXADC_RQST0, 11, 8, 2, 1),
+ MTK_PMIC_ADC_CHAN(VCORE_TEMP, PMIC_AUXADC_RQST1, 8, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(VPROC_TEMP, PMIC_AUXADC_RQST1, 9, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(VGPU_TEMP, PMIC_AUXADC_RQST1, 10, 8, 1, 1),
+
+ /* Battery impedance channels */
+ MTK_PMIC_ADC_CHAN(VBAT, 0, 0, 128, 7, 2),
+};
+
+static const u16 mt6358_auxadc_regs[] = {
+ [PMIC_HK_TOP_RST_CON0] = 0x0f90,
+ [PMIC_AUXADC_DCM_CON] = 0x1260,
+ [PMIC_AUXADC_ADC0] = 0x1088,
+ [PMIC_AUXADC_IMP0] = 0x1208,
+ [PMIC_AUXADC_IMP1] = 0x120a,
+ [PMIC_AUXADC_RQST0] = 0x1108,
+ [PMIC_AUXADC_RQST1] = 0x110a,
+};
+
+static const struct iio_chan_spec mt6359_auxadc_channels[] = {
+ MTK_PMIC_IIO_CHAN(MT6359, bat_adc, BATADC, 0, 15, IIO_RESISTANCE),
+ MTK_PMIC_IIO_CHAN(MT6359, batt_temp, BAT_TEMP, 3, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6359, chip_temp, CHIP_TEMP, 4, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6359, acc_det, ACCDET, 5, 12, IIO_RESISTANCE),
+ MTK_PMIC_IIO_CHAN(MT6359, dcxo_v, VDCXO, 6, 12, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(MT6359, tsx_temp, TSX_TEMP, 7, 15, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6359, hp_ofs_cal, HPOFS_CAL, 9, 15, IIO_RESISTANCE),
+ MTK_PMIC_IIO_CHAN(MT6359, dcxo_temp, DCXO_TEMP, 10, 15, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6359, bif_v, VBIF, 11, 12, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(MT6359, vcore_temp, VCORE_TEMP, 30, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6359, vproc_temp, VPROC_TEMP, 31, 12, IIO_TEMP),
+ MTK_PMIC_IIO_CHAN(MT6359, vgpu_temp, VGPU_TEMP, 32, 12, IIO_TEMP),
+
+ /* Battery impedance channels */
+ MTK_PMIC_IIO_CHAN(MT6359, batt_v, VBAT, 0, 15, IIO_VOLTAGE),
+ MTK_PMIC_IIO_CHAN(MT6359, batt_i, IBAT, 0, 15, IIO_CURRENT),
+};
+
+static const struct mtk_pmic_auxadc_chan mt6359_auxadc_ch_desc[] = {
+ MTK_PMIC_ADC_CHAN(BATADC, PMIC_AUXADC_RQST0, 0, 128, 7, 2),
+ MTK_PMIC_ADC_CHAN(BAT_TEMP, PMIC_AUXADC_RQST0, 3, 8, 5, 2),
+ MTK_PMIC_ADC_CHAN(CHIP_TEMP, PMIC_AUXADC_RQST0, 4, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(ACCDET, PMIC_AUXADC_RQST0, 5, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(VDCXO, PMIC_AUXADC_RQST0, 6, 8, 3, 2),
+ MTK_PMIC_ADC_CHAN(TSX_TEMP, PMIC_AUXADC_RQST0, 7, 128, 1, 1),
+ MTK_PMIC_ADC_CHAN(HPOFS_CAL, PMIC_AUXADC_RQST0, 9, 256, 1, 1),
+ MTK_PMIC_ADC_CHAN(DCXO_TEMP, PMIC_AUXADC_RQST0, 10, 16, 1, 1),
+ MTK_PMIC_ADC_CHAN(VBIF, PMIC_AUXADC_RQST0, 11, 8, 5, 2),
+ MTK_PMIC_ADC_CHAN(VCORE_TEMP, PMIC_AUXADC_RQST1, 8, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(VPROC_TEMP, PMIC_AUXADC_RQST1, 9, 8, 1, 1),
+ MTK_PMIC_ADC_CHAN(VGPU_TEMP, PMIC_AUXADC_RQST1, 10, 8, 1, 1),
+
+ /* Battery impedance channels */
+ MTK_PMIC_ADC_CHAN(VBAT, 0, 0, 128, 7, 2),
+ MTK_PMIC_ADC_CHAN(IBAT, 0, 0, 128, 7, 2),
+};
+
+static const u16 mt6359_auxadc_regs[] = {
+ [PMIC_FGADC_R_CON0] = 0x0d88,
+ [PMIC_HK_TOP_WKEY] = 0x0fb4,
+ [PMIC_HK_TOP_RST_CON0] = 0x0f90,
+ [PMIC_AUXADC_RQST0] = 0x1108,
+ [PMIC_AUXADC_RQST1] = 0x110a,
+ [PMIC_AUXADC_ADC0] = 0x1088,
+ [PMIC_AUXADC_IMP0] = 0x1208,
+ [PMIC_AUXADC_IMP1] = 0x120a,
+ [PMIC_AUXADC_IMP3] = 0x120e,
+};
+
+static void mt6358_stop_imp_conv(struct mt6359_auxadc *adc_dev)
+{
+ const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
+ struct regmap *regmap = adc_dev->regmap;
+
+ regmap_set_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP0], MT6358_IMP0_CLEAR);
+ regmap_clear_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP0], MT6358_IMP0_CLEAR);
+ regmap_clear_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP1], MT6358_IMP1_AUTOREPEAT_EN);
+ regmap_clear_bits(regmap, cinfo->regs[PMIC_AUXADC_DCM_CON], MT6358_DCM_CK_SW_EN);
+}
+
+static int mt6358_start_imp_conv(struct mt6359_auxadc *adc_dev)
+{
+ const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
+ struct regmap *regmap = adc_dev->regmap;
+ u32 val;
+ int ret;
+
+ regmap_set_bits(regmap, cinfo->regs[PMIC_AUXADC_DCM_CON], MT6358_DCM_CK_SW_EN);
+ regmap_set_bits(regmap, cinfo->regs[PMIC_AUXADC_IMP1], MT6358_IMP1_AUTOREPEAT_EN);
+
+ ret = regmap_read_poll_timeout(adc_dev->regmap, cinfo->regs[PMIC_AUXADC_IMP0],
+ val, val & MT6358_IMP0_IRQ_RDY,
+ IMP_POLL_DELAY_US, AUXADC_TIMEOUT_US);
+ if (ret) {
+ mt6358_stop_imp_conv(adc_dev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mt6358_read_imp(struct mt6359_auxadc *adc_dev, int *vbat, int *ibat)
+{
+ const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
+ struct regmap *regmap = adc_dev->regmap;
+ u16 reg_adc0 = cinfo->regs[PMIC_AUXADC_ADC0];
+ u32 val_v;
+ int ret;
+
+ ret = mt6358_start_imp_conv(adc_dev);
+ if (ret)
+ return ret;
+
+ /* Read the params before stopping */
+ regmap_read(regmap, reg_adc0 + (cinfo->imp_adc_num << 1), &val_v);
+
+ mt6358_stop_imp_conv(adc_dev);
+
+ if (vbat)
+ *vbat = val_v;
+ if (ibat)
+ *ibat = 0;
+
+ return 0;
+}
+
+static int mt6359_read_imp(struct mt6359_auxadc *adc_dev, int *vbat, int *ibat)
+{
+ const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
+ struct regmap *regmap = adc_dev->regmap;
+ u32 val, val_v, val_i;
+ int ret;
+
+ /* Start conversion */
+ regmap_write(regmap, cinfo->regs[PMIC_AUXADC_IMP0], MT6359_IMP0_CONV_EN);
+ ret = regmap_read_poll_timeout(regmap, cinfo->regs[PMIC_AUXADC_IMP1],
+ val, val & MT6359_IMP1_IRQ_RDY,
+ IMP_POLL_DELAY_US, AUXADC_TIMEOUT_US);
+
+ /* Stop conversion regardless of the result */
+ regmap_write(regmap, cinfo->regs[PMIC_AUXADC_IMP0], 0);
+ if (ret)
+ return ret;
+
+ /* If it succeeded, wait for the registers to be populated */
+ fsleep(IMP_STOP_DELAY_US);
+
+ ret = regmap_read(regmap, cinfo->regs[PMIC_AUXADC_IMP3], &val_v);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(regmap, cinfo->regs[PMIC_FGADC_R_CON0], &val_i);
+ if (ret)
+ return ret;
+
+ if (vbat)
+ *vbat = val_v;
+ if (ibat)
+ *ibat = val_i;
+
+ return 0;
+}
+
+static const struct mtk_pmic_auxadc_info mt6357_chip_info = {
+ .model_name = "MT6357",
+ .channels = mt6357_auxadc_channels,
+ .num_channels = ARRAY_SIZE(mt6357_auxadc_channels),
+ .desc = mt6357_auxadc_ch_desc,
+ .regs = mt6357_auxadc_regs,
+ .imp_adc_num = MT6357_IMP_ADC_NUM,
+ .read_imp = mt6358_read_imp,
+};
+
+static const struct mtk_pmic_auxadc_info mt6358_chip_info = {
+ .model_name = "MT6358",
+ .channels = mt6358_auxadc_channels,
+ .num_channels = ARRAY_SIZE(mt6358_auxadc_channels),
+ .desc = mt6358_auxadc_ch_desc,
+ .regs = mt6358_auxadc_regs,
+ .imp_adc_num = MT6358_IMP_ADC_NUM,
+ .read_imp = mt6358_read_imp,
+};
+
+static const struct mtk_pmic_auxadc_info mt6359_chip_info = {
+ .model_name = "MT6359",
+ .channels = mt6359_auxadc_channels,
+ .num_channels = ARRAY_SIZE(mt6359_auxadc_channels),
+ .desc = mt6359_auxadc_ch_desc,
+ .regs = mt6359_auxadc_regs,
+ .sec_unlock_key = 0x6359,
+ .read_imp = mt6359_read_imp,
+};
+
+static void mt6359_auxadc_reset(struct mt6359_auxadc *adc_dev)
+{
+ const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
+ struct regmap *regmap = adc_dev->regmap;
+
+ /* Unlock HK_TOP writes */
+ if (cinfo->sec_unlock_key)
+ regmap_write(regmap, cinfo->regs[PMIC_HK_TOP_WKEY], cinfo->sec_unlock_key);
+
+ /* Assert ADC reset */
+ regmap_set_bits(regmap, cinfo->regs[PMIC_HK_TOP_RST_CON0], PMIC_RG_RESET_VAL);
+
+ /* De-assert ADC reset. No wait required, as pwrap takes care of that for us. */
+ regmap_clear_bits(regmap, cinfo->regs[PMIC_HK_TOP_RST_CON0], PMIC_RG_RESET_VAL);
+
+ /* Lock HK_TOP writes again */
+ if (cinfo->sec_unlock_key)
+ regmap_write(regmap, cinfo->regs[PMIC_HK_TOP_WKEY], 0);
+}
+
+static int mt6359_auxadc_read_adc(struct mt6359_auxadc *adc_dev,
+ const struct iio_chan_spec *chan, int *out)
+{
+ const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
+ const struct mtk_pmic_auxadc_chan *desc = &cinfo->desc[chan->scan_index];
+ struct regmap *regmap = adc_dev->regmap;
+ u32 val;
+ int ret;
+
+ /* Request to start sampling for ADC channel */
+ ret = regmap_write(regmap, cinfo->regs[desc->req_idx], desc->req_mask);
+ if (ret)
+ return ret;
+
+ /* Wait until all samples are averaged */
+ fsleep(desc->num_samples * AUXADC_AVG_TIME_US);
+
+ ret = regmap_read_poll_timeout(regmap,
+ cinfo->regs[PMIC_AUXADC_ADC0] + (chan->address << 1),
+ val, val & PMIC_AUXADC_RDY_BIT,
+ AUXADC_POLL_DELAY_US, AUXADC_TIMEOUT_US);
+ if (ret)
+ return ret;
+
+ /* Stop sampling */
+ regmap_write(regmap, cinfo->regs[desc->req_idx], 0);
+
+ *out = val & GENMASK(chan->scan_type.realbits - 1, 0);
+ return 0;
+}
+
+static int mt6359_auxadc_read_label(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, char *label)
+{
+ return sysfs_emit(label, "%s\n", chan->datasheet_name);
+}
+
+static int mt6359_auxadc_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long mask)
+{
+ struct mt6359_auxadc *adc_dev = iio_priv(indio_dev);
+ const struct mtk_pmic_auxadc_info *cinfo = adc_dev->chip_info;
+ const struct mtk_pmic_auxadc_chan *desc = &cinfo->desc[chan->scan_index];
+ int ret;
+
+ if (mask == IIO_CHAN_INFO_SCALE) {
+ *val = desc->r_ratio.numerator * AUXADC_VOLT_FULL;
+
+ if (desc->r_ratio.denominator > 1) {
+ *val2 = desc->r_ratio.denominator;
+ return IIO_VAL_FRACTIONAL;
+ }
+
+ return IIO_VAL_INT;
+ }
+
+ scoped_guard(mutex, &adc_dev->lock) {
+ switch (chan->scan_index) {
+ case PMIC_AUXADC_CHAN_IBAT:
+ ret = adc_dev->chip_info->read_imp(adc_dev, NULL, val);
+ break;
+ case PMIC_AUXADC_CHAN_VBAT:
+ ret = adc_dev->chip_info->read_imp(adc_dev, val, NULL);
+ break;
+ default:
+ ret = mt6359_auxadc_read_adc(adc_dev, chan, val);
+ break;
+ }
+ }
+
+ if (ret) {
+ /*
+ * If we get more than one timeout, it's possible that the
+ * AUXADC is stuck: perform a full reset to recover it.
+ */
+ if (ret == -ETIMEDOUT) {
+ if (adc_dev->timed_out) {
+ dev_warn(adc_dev->dev, "Resetting stuck ADC!\r\n");
+ mt6359_auxadc_reset(adc_dev);
+ }
+ adc_dev->timed_out = true;
+ }
+ return ret;
+ }
+ adc_dev->timed_out = false;
+
+ return IIO_VAL_INT;
+}
+
+static const struct iio_info mt6359_auxadc_iio_info = {
+ .read_label = mt6359_auxadc_read_label,
+ .read_raw = mt6359_auxadc_read_raw,
+};
+
+static int mt6359_auxadc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device *mt6397_mfd_dev = dev->parent;
+ struct mt6359_auxadc *adc_dev;
+ struct iio_dev *indio_dev;
+ struct regmap *regmap;
+ int ret;
+
+ /* Regmap is from SoC PMIC Wrapper, parent of the mt6397 MFD */
+ regmap = dev_get_regmap(mt6397_mfd_dev->parent, NULL);
+ if (!regmap)
+ return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n");
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*adc_dev));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ adc_dev = iio_priv(indio_dev);
+ adc_dev->regmap = regmap;
+ adc_dev->dev = dev;
+
+ adc_dev->chip_info = device_get_match_data(dev);
+ if (!adc_dev->chip_info)
+ return -EINVAL;
+
+ mutex_init(&adc_dev->lock);
+
+ mt6359_auxadc_reset(adc_dev);
+
+ indio_dev->name = adc_dev->chip_info->model_name;
+ indio_dev->info = &mt6359_auxadc_iio_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = adc_dev->chip_info->channels;
+ indio_dev->num_channels = adc_dev->chip_info->num_channels;
+
+ ret = devm_iio_device_register(dev, indio_dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register iio device\n");
+
+ return 0;
+}
+
+static const struct of_device_id mt6359_auxadc_of_match[] = {
+ { .compatible = "mediatek,mt6357-auxadc", .data = &mt6357_chip_info },
+ { .compatible = "mediatek,mt6358-auxadc", .data = &mt6358_chip_info },
+ { .compatible = "mediatek,mt6359-auxadc", .data = &mt6359_chip_info },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mt6359_auxadc_of_match);
+
+static struct platform_driver mt6359_auxadc_driver = {
+ .driver = {
+ .name = "mt6359-auxadc",
+ .of_match_table = mt6359_auxadc_of_match,
+ },
+ .probe = mt6359_auxadc_probe,
+};
+module_platform_driver(mt6359_auxadc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("AngeloGioacchino Del Regno <[email protected]>");
+MODULE_DESCRIPTION("MediaTek MT6359 PMIC AUXADC Driver");
--
2.45.1


Subject: [PATCH v2 3/5] math.h: Add unsigned 8 bits fractional numbers type

Some users may be requiring only rather small numbers as both
numerator and denominator: add signed and unsigned 8 bits
structs {s8,u8}_fract.

Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
---
include/linux/math.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/include/linux/math.h b/include/linux/math.h
index dd4152711de7..f5f18dc3616b 100644
--- a/include/linux/math.h
+++ b/include/linux/math.h
@@ -112,6 +112,8 @@ struct type##_fract { \
__##type numerator; \
__##type denominator; \
};
+__STRUCT_FRACT(s8)
+__STRUCT_FRACT(u8)
__STRUCT_FRACT(s16)
__STRUCT_FRACT(u16)
__STRUCT_FRACT(s32)
--
2.45.1


2024-06-04 13:20:25

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v2 3/5] math.h: Add unsigned 8 bits fractional numbers type

On Tue, Jun 4, 2024 at 3:30 PM AngeloGioacchino Del Regno
<[email protected]> wrote:
>
> Some users may be requiring only rather small numbers as both
> numerator and denominator: add signed and unsigned 8 bits
> structs {s8,u8}_fract.

Reviewed-by: Andy Shevchenko <[email protected]>
Thank you!

--
With Best Regards,
Andy Shevchenko

2024-06-04 13:23:32

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v2 4/5] iio: adc: Add support for MediaTek MT6357/8/9 Auxiliary ADC

On Tue, Jun 4, 2024 at 3:30 PM AngeloGioacchino Del Regno
<[email protected]> wrote:
>
> Add a driver to support reading the Auxiliary ADC IP found in the
> MediaTek MT6357, MT6358 and MT6359 Power Management ICs, featuring
> a different register layout, configurationm reset and ADC reading

configuration

> sequence from the other already supported MediaTek SoC or PMIC
> (aux)ADC HW.
>
> This driver provides multiple ADC channels for system monitoring,
> such as battery voltage, PMIC temperature, PMIC-internal voltage
> regulators temperature, and others.

Seems all my concerns were addressed, so
Reviewed-by: Andy Shevchenko <[email protected]>

--
With Best Regards,
Andy Shevchenko

Subject: Re: [PATCH v2 4/5] iio: adc: Add support for MediaTek MT6357/8/9 Auxiliary ADC

Il 04/06/24 15:22, Andy Shevchenko ha scritto:
> On Tue, Jun 4, 2024 at 3:30 PM AngeloGioacchino Del Regno
> <[email protected]> wrote:
>>
>> Add a driver to support reading the Auxiliary ADC IP found in the
>> MediaTek MT6357, MT6358 and MT6359 Power Management ICs, featuring
>> a different register layout, configurationm reset and ADC reading
>
> configuration
>

Oh, oops! If there's no further comment to address, can this be fixed while
applying, please?

Otherwise I can send a v3 :-)

>> sequence from the other already supported MediaTek SoC or PMIC
>> (aux)ADC HW.
>>
>> This driver provides multiple ADC channels for system monitoring,
>> such as battery voltage, PMIC temperature, PMIC-internal voltage
>> regulators temperature, and others.
>
> Seems all my concerns were addressed, so
> Reviewed-by: Andy Shevchenko <[email protected]>
>

Thanks!
Angelo

2024-06-05 23:56:09

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v2 1/5] dt-bindings: iio: adc: Add MediaTek MT6359 PMIC AUXADC

On Tue, Jun 04, 2024 at 02:30:04PM +0200, AngeloGioacchino Del Regno wrote:
> Add a new binding for the MT6350 Series (MT6357/8/9) PMIC AUXADC,
> providing various ADC channels for both internal temperatures and
> voltages, audio accessory detection (hp/mic/hp+mic and buttons,
> usually on a 3.5mm jack) other than some basic battery statistics
> on boards where the battery is managed by this PMIC.
>
> Also add the necessary dt-binding headers for devicetree consumers.
>
> Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
> ---
> .../iio/adc/mediatek,mt6359-auxadc.yaml | 33 +++++++++++++++++++
> .../iio/adc/mediatek,mt6357-auxadc.h | 21 ++++++++++++
> .../iio/adc/mediatek,mt6358-auxadc.h | 22 +++++++++++++
> .../iio/adc/mediatek,mt6359-auxadc.h | 22 +++++++++++++
> 4 files changed, 98 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
> create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6357-auxadc.h
> create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6358-auxadc.h
> create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6359-auxadc.h
>
> diff --git a/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
> new file mode 100644
> index 000000000000..6497c416094d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
> @@ -0,0 +1,33 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iio/adc/mediatek,mt6359-auxadc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek MT6350 series PMIC AUXADC
> +
> +maintainers:
> + - AngeloGioacchino Del Regno <[email protected]>
> +
> +description:
> + The Auxiliary Analog/Digital Converter (AUXADC) is an ADC found
> + in some MediaTek PMICs, 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:
> + enum:
> + - mediatek,mt6357-auxadc
> + - mediatek,mt6358-auxadc
> + - mediatek,mt6359-auxadc
> +
> + "#io-channel-cells":
> + const: 1

Why do you need a node here? Just add #io-channel-cells to the parent
node.

> +
> +required:
> + - compatible
> + - "#io-channel-cells"
> +
> +additionalProperties: false

2024-06-08 17:44:26

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v2 4/5] iio: adc: Add support for MediaTek MT6357/8/9 Auxiliary ADC

On Tue, 4 Jun 2024 15:24:31 +0200
AngeloGioacchino Del Regno <[email protected]> wrote:

> Il 04/06/24 15:22, Andy Shevchenko ha scritto:
> > On Tue, Jun 4, 2024 at 3:30 PM AngeloGioacchino Del Regno
> > <[email protected]> wrote:
> >>
> >> Add a driver to support reading the Auxiliary ADC IP found in the
> >> MediaTek MT6357, MT6358 and MT6359 Power Management ICs, featuring
> >> a different register layout, configurationm reset and ADC reading
> >
> > configuration
> >
>
> Oh, oops! If there's no further comment to address, can this be fixed while
> applying, please?
>
Yes if Rob is happy with your response to his question on the
dt-binding.

LGTM as well btw.

Jonathan

> Otherwise I can send a v3 :-)
>
> >> sequence from the other already supported MediaTek SoC or PMIC
> >> (aux)ADC HW.
> >>
> >> This driver provides multiple ADC channels for system monitoring,
> >> such as battery voltage, PMIC temperature, PMIC-internal voltage
> >> regulators temperature, and others.
> >
> > Seems all my concerns were addressed, so
> > Reviewed-by: Andy Shevchenko <[email protected]>
> >
>
> Thanks!
> Angelo


Subject: Re: [PATCH v2 1/5] dt-bindings: iio: adc: Add MediaTek MT6359 PMIC AUXADC

Il 06/06/24 01:52, Rob Herring ha scritto:
> On Tue, Jun 04, 2024 at 02:30:04PM +0200, AngeloGioacchino Del Regno wrote:
>> Add a new binding for the MT6350 Series (MT6357/8/9) PMIC AUXADC,
>> providing various ADC channels for both internal temperatures and
>> voltages, audio accessory detection (hp/mic/hp+mic and buttons,
>> usually on a 3.5mm jack) other than some basic battery statistics
>> on boards where the battery is managed by this PMIC.
>>
>> Also add the necessary dt-binding headers for devicetree consumers.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <[email protected]>
>> ---
>> .../iio/adc/mediatek,mt6359-auxadc.yaml | 33 +++++++++++++++++++
>> .../iio/adc/mediatek,mt6357-auxadc.h | 21 ++++++++++++
>> .../iio/adc/mediatek,mt6358-auxadc.h | 22 +++++++++++++
>> .../iio/adc/mediatek,mt6359-auxadc.h | 22 +++++++++++++
>> 4 files changed, 98 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
>> create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6357-auxadc.h
>> create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6358-auxadc.h
>> create mode 100644 include/dt-bindings/iio/adc/mediatek,mt6359-auxadc.h
>>
>> diff --git a/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
>> new file mode 100644
>> index 000000000000..6497c416094d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/iio/adc/mediatek,mt6359-auxadc.yaml
>> @@ -0,0 +1,33 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/iio/adc/mediatek,mt6359-auxadc.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: MediaTek MT6350 series PMIC AUXADC
>> +
>> +maintainers:
>> + - AngeloGioacchino Del Regno <[email protected]>
>> +
>> +description:
>> + The Auxiliary Analog/Digital Converter (AUXADC) is an ADC found
>> + in some MediaTek PMICs, 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:
>> + enum:
>> + - mediatek,mt6357-auxadc
>> + - mediatek,mt6358-auxadc
>> + - mediatek,mt6359-auxadc
>> +
>> + "#io-channel-cells":
>> + const: 1
>
> Why do you need a node here? Just add #io-channel-cells to the parent
> node.
>

Because some boards will want to avoid probing the related driver, as that will
trigger a reset and this may not play well with ECs (namely, some Chromebooks),
which are reading the same AUXADC block.

If I avoid using a new node, instead of just using `status`, I'll have to add a
"mediatek,disable-auxadc" property to the parent node, which isn't pretty...

Cheers,
Angelo

>> +
>> +required:
>> + - compatible
>> + - "#io-channel-cells"
>> +
>> +additionalProperties: false