* [PATCH 1/4] dt-bindings: iio: adc: samsung,exynos: Add Exynos850 compatible
2026-10-01 3:09 [PATCH 0/4] Exynos850 ADC support and soc thermistor Alexey Klimov
@ 2026-10-01 3:09 ` Alexey Klimov
2026-10-01 19:20 ` Conor Dooley
2026-10-01 3:09 ` [PATCH 2/4] iio: adc: exynos_adc: add Exynos850 support Alexey Klimov
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Alexey Klimov @ 2026-10-01 3:09 UTC (permalink / raw)
To: Sam Protsenko, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Peter Griffin, Alim Akhtar, Krzysztof Kozlowski
Cc: linux-iio, devicetree, linux-arm-kernel, linux-samsung-soc, linux-kernel
The Exynos850 SoC contains an ADC block within the CMGP block.
While similar to existing Exynos ADC v2 blocks, its data register is
located at a different base offset (0x08) hence a new compatible.
Add "samsung,exynos850-adc" to the devicetree bindings to differentiate
it from existing Exynos ADC variants.
Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
---
Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
index def879f6ed20..90a220e3b78d 100644
--- a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
@@ -18,6 +18,7 @@ properties:
- samsung,exynos3250-adc
- samsung,exynos4212-adc # Exynos4212 and Exynos4412
- samsung,exynos7-adc
+ - samsung,exynos850-adc
- samsung,s3c6410-adc
- samsung,s5pv210-adc
- items:
--
2.51.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 2/4] iio: adc: exynos_adc: add Exynos850 support
2026-10-01 3:09 [PATCH 0/4] Exynos850 ADC support and soc thermistor Alexey Klimov
2026-10-01 3:09 ` [PATCH 1/4] dt-bindings: iio: adc: samsung,exynos: Add Exynos850 compatible Alexey Klimov
@ 2026-10-01 3:09 ` Alexey Klimov
2026-10-02 7:34 ` Andy Shevchenko
2026-10-01 3:09 ` [PATCH 3/4] arm64: dts: exynos850: add ADC node Alexey Klimov
2026-10-01 3:09 ` [PATCH 4/4] arm64: dts: exynos850-e850-96: add soc thermistor node Alexey Klimov
3 siblings, 1 reply; 7+ messages in thread
From: Alexey Klimov @ 2026-10-01 3:09 UTC (permalink / raw)
To: Sam Protsenko, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Peter Griffin, Alim Akhtar, Krzysztof Kozlowski
Cc: linux-iio, devicetree, linux-arm-kernel, linux-samsung-soc, linux-kernel
The Exynos850 ADC controller located inside the CMGP block differs from
other Exynos ADC controllers, mainly in its register layout.
Specifically, the data register sits at offset 0x08.
Abstract the read_value() operation in driver data exynos_adc_data to
support SoC-dependent data register read callbacks.
Add the exynos850_adc_data struct that describes Exynos850 ADC ops.
It also requires its own hardware initialization and exit routines.
Add them as well.
Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
---
drivers/iio/adc/exynos_adc.c | 66 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 64 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index c1a0061b16ca..3e9b5d28b922 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -46,6 +46,8 @@
#define ADC_V2_INT_ST(x) ((x) + 0x14)
#define ADC_V2_VER(x) ((x) + 0x20)
+#define ADC_EXYNOS850_DAT(x) ((x) + 0x08)
+
/* Bit definitions for ADC_V1 */
#define ADC_V1_CON_RES (1u << 16)
#define ADC_V1_CON_PRSCEN (1u << 14)
@@ -133,6 +135,7 @@ struct exynos_adc_data {
void (*exit_hw)(struct exynos_adc *info);
void (*clear_irq)(struct exynos_adc *info);
void (*start_conv)(struct exynos_adc *info, unsigned long addr);
+ u32 (*read_value)(struct exynos_adc *info);
};
static void exynos_adc_unprepare_clk(struct exynos_adc *info)
@@ -195,6 +198,11 @@ static int exynos_adc_enable_clk(struct exynos_adc *info)
return 0;
}
+static u32 exynos_adc_v1_read_value(struct exynos_adc *info)
+{
+ return readl(ADC_V1_DATX(info->regs)) & info->data->mask;
+}
+
static void exynos_adc_v1_init_hw(struct exynos_adc *info)
{
u32 con1;
@@ -252,6 +260,7 @@ static const struct exynos_adc_data exynos4212_adc_data = {
.exit_hw = exynos_adc_v1_exit_hw,
.clear_irq = exynos_adc_v1_clear_irq,
.start_conv = exynos_adc_v1_start_conv,
+ .read_value = exynos_adc_v1_read_value,
};
static const struct exynos_adc_data exynos_adc_v1_data = {
@@ -264,6 +273,7 @@ static const struct exynos_adc_data exynos_adc_v1_data = {
.exit_hw = exynos_adc_v1_exit_hw,
.clear_irq = exynos_adc_v1_clear_irq,
.start_conv = exynos_adc_v1_start_conv,
+ .read_value = exynos_adc_v1_read_value,
};
static const struct exynos_adc_data exynos_adc_s5pv210_data = {
@@ -274,6 +284,7 @@ static const struct exynos_adc_data exynos_adc_s5pv210_data = {
.exit_hw = exynos_adc_v1_exit_hw,
.clear_irq = exynos_adc_v1_clear_irq,
.start_conv = exynos_adc_v1_start_conv,
+ .read_value = exynos_adc_v1_read_value,
};
static void exynos_adc_s3c64xx_start_conv(struct exynos_adc *info,
@@ -295,6 +306,7 @@ static struct exynos_adc_data const exynos_adc_s3c64xx_data = {
.exit_hw = exynos_adc_v1_exit_hw,
.clear_irq = exynos_adc_v1_clear_irq,
.start_conv = exynos_adc_s3c64xx_start_conv,
+ .read_value = exynos_adc_v1_read_value,
};
static void exynos_adc_v2_init_hw(struct exynos_adc *info)
@@ -356,6 +368,7 @@ static const struct exynos_adc_data exynos_adc_v2_data = {
.exit_hw = exynos_adc_v2_exit_hw,
.clear_irq = exynos_adc_v2_clear_irq,
.start_conv = exynos_adc_v2_start_conv,
+ .read_value = exynos_adc_v1_read_value,
};
static const struct exynos_adc_data exynos3250_adc_data = {
@@ -369,6 +382,7 @@ static const struct exynos_adc_data exynos3250_adc_data = {
.exit_hw = exynos_adc_v2_exit_hw,
.clear_irq = exynos_adc_v2_clear_irq,
.start_conv = exynos_adc_v2_start_conv,
+ .read_value = exynos_adc_v1_read_value,
};
static void exynos_adc_exynos7_init_hw(struct exynos_adc *info)
@@ -395,6 +409,52 @@ static const struct exynos_adc_data exynos7_adc_data = {
.exit_hw = exynos_adc_v2_exit_hw,
.clear_irq = exynos_adc_v2_clear_irq,
.start_conv = exynos_adc_v2_start_conv,
+ .read_value = exynos_adc_v1_read_value,
+};
+
+static void exynos850_adc_init_hw(struct exynos_adc *info)
+{
+ u32 con1, con2;
+
+ con1 = ADC_V2_CON1_SOFT_RESET;
+ writel(con1, ADC_V2_CON1(info->regs));
+
+ /* Bring out of reset */
+ writel(0, ADC_V2_CON1(info->regs));
+
+ /* 64 times conversion */
+ con2 = ADC_V2_CON2_C_TIME(6);
+ writel(con2, ADC_V2_CON2(info->regs));
+
+ writel(1, ADC_V2_INT_EN(info->regs));
+}
+
+static void exynos850_adc_exit_hw(struct exynos_adc *info)
+{
+ u32 con2;
+
+ con2 = readl(ADC_V2_CON2(info->regs));
+ con2 &= ~ADC_V2_CON2_C_TIME(7);
+ writel(con2, ADC_V2_CON2(info->regs));
+
+ writel(0, ADC_V2_INT_EN(info->regs));
+}
+
+static u32 exynos850_adc_read_value(struct exynos_adc *info)
+{
+ return readl(ADC_EXYNOS850_DAT(info->regs)) & info->data->mask;
+}
+
+static const struct exynos_adc_data exynos850_adc_data = {
+ .num_channels = MAX_ADC_V2_CHANNELS,
+ .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */
+ .needs_adc_phy = false,
+
+ .init_hw = exynos850_adc_init_hw,
+ .exit_hw = exynos850_adc_exit_hw,
+ .clear_irq = exynos_adc_v2_clear_irq,
+ .start_conv = exynos_adc_v2_start_conv,
+ .read_value = exynos850_adc_read_value,
};
static const struct of_device_id exynos_adc_match[] = {
@@ -419,6 +479,9 @@ static const struct of_device_id exynos_adc_match[] = {
}, {
.compatible = "samsung,exynos7-adc",
.data = &exynos7_adc_data,
+ }, {
+ .compatible = "samsung,exynos850-adc",
+ .data = &exynos850_adc_data,
},
{ }
};
@@ -484,10 +547,9 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
static irqreturn_t exynos_adc_isr(int irq, void *dev_id)
{
struct exynos_adc *info = dev_id;
- u32 mask = info->data->mask;
/* Read value */
- info->value = readl(ADC_V1_DATX(info->regs)) & mask;
+ info->value = info->data->read_value(info);
/* clear irq */
if (info->data->clear_irq)
--
2.51.0
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 4/4] arm64: dts: exynos850-e850-96: add soc thermistor node
2026-10-01 3:09 [PATCH 0/4] Exynos850 ADC support and soc thermistor Alexey Klimov
` (2 preceding siblings ...)
2026-10-01 3:09 ` [PATCH 3/4] arm64: dts: exynos850: add ADC node Alexey Klimov
@ 2026-10-01 3:09 ` Alexey Klimov
3 siblings, 0 replies; 7+ messages in thread
From: Alexey Klimov @ 2026-10-01 3:09 UTC (permalink / raw)
To: Sam Protsenko, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Peter Griffin, Alim Akhtar, Krzysztof Kozlowski
Cc: linux-iio, devicetree, linux-arm-kernel, linux-samsung-soc, linux-kernel
The WinLink E850-96 board has a Murata NCP03WF104 NTC thermistor placed
near the SoC package die and connected to channel 0 of the CMGP ADC.
Enable the ADC node, define a dummy 1.8V regulator supply for ADC, and
add the board-level thermistor node linked to channel 0 of exynos_adc.
Regulator is represented as a dummy one because we lack PMIC support and
should be replaced with a real one when PMIC support will be implemented.
Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
---
arch/arm64/boot/dts/exynos/exynos850-e850-96.dts | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts b/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
index afef32ad4ee2..1abae8b9fa49 100644
--- a/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
+++ b/arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
@@ -126,6 +126,14 @@ reg_dummy: regulator-0 {
regulator-name = "dummy_reg";
};
+ /* TODO: Remove this once PMIC is implemented */
+ vdd_1v8_dummy: regulator-1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_1v8_dummy";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
reg_usb_host_vbus: regulator-1 {
compatible = "regulator-fixed";
regulator-name = "usb_host_vbus";
@@ -166,6 +174,20 @@ rtcclk: clock-rtcclk {
#clock-cells = <0>;
clock-frequency = <32768>;
};
+
+ thermistor-soc {
+ compatible = "murata,ncp03wf104";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <0>;
+ io-channels = <&exynos_adc 0>;
+ #thermal-sensor-cells = <0>;
+ };
+};
+
+&exynos_adc {
+ status = "okay";
+ vdd-supply = <&vdd_1v8_dummy>;
};
&cmu_hsi {
--
2.51.0
^ permalink raw reply [flat|nested] 7+ messages in thread