linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [v1 0/7] Add support for ast2600 ADC
@ 2021-07-19  8:06 Billy Tsai
  2021-07-19  8:06 ` [v1 1/7] dt-bindings: iio: adc: rename the aspeed adc yaml Billy Tsai
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Billy Tsai @ 2021-07-19  8:06 UTC (permalink / raw)
  To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, billy_tsai,
	linux-iio, devicetree, linux-arm-kernel, linux-aspeed, raltherr
  Cc: BMC-SW

This patch serials make aspeed_adc.c can support ast2600.
In additional,
patch #6 is used to improve the adc accurate and 
patch #7 is used to fix the clock issue in the original code.

Billy Tsai (7):
  dt-bindings: iio: adc: rename the aspeed adc yaml
  dt-bindings: iio: adc: Binding ast2600 adc.
  iio: adc: aspeed: completes the bitfield declare.
  iio: adc: aspeed: Allow driver to support ast2600
  iio: adc: aspeed: Add func to set sampling rate.
  iio: adc: aspeed: Add compensation phase.
  iio: adc: aspeed: Fix the calculate error of clock.

 ...speed,ast2400-adc.yaml => aspeed,adc.yaml} |  23 +-
 drivers/iio/adc/aspeed_adc.c                  | 313 ++++++++++++++----
 2 files changed, 266 insertions(+), 70 deletions(-)
 rename Documentation/devicetree/bindings/iio/adc/{aspeed,ast2400-adc.yaml => aspeed,adc.yaml} (53%)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [v1 1/7] dt-bindings: iio: adc: rename the aspeed adc yaml
  2021-07-19  8:06 [v1 0/7] Add support for ast2600 ADC Billy Tsai
@ 2021-07-19  8:06 ` Billy Tsai
  2021-07-19  8:06 ` [v1 2/7] dt-bindings: iio: adc: Binding ast2600 adc Billy Tsai
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Billy Tsai @ 2021-07-19  8:06 UTC (permalink / raw)
  To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, billy_tsai,
	linux-iio, devicetree, linux-arm-kernel, linux-aspeed, raltherr
  Cc: BMC-SW

The aspeed,ast2400-adc.yaml not only descriptor the bindings of ast2400.
Rename it to aspeed,adc.yaml for all of the aspeed adc bindings.

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
 .../bindings/iio/adc/{aspeed,ast2400-adc.yaml => aspeed,adc.yaml} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Documentation/devicetree/bindings/iio/adc/{aspeed,ast2400-adc.yaml => aspeed,adc.yaml} (100%)

diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml
similarity index 100%
rename from Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml
rename to Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml
-- 
2.25.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [v1 2/7] dt-bindings: iio: adc: Binding ast2600 adc.
  2021-07-19  8:06 [v1 0/7] Add support for ast2600 ADC Billy Tsai
  2021-07-19  8:06 ` [v1 1/7] dt-bindings: iio: adc: rename the aspeed adc yaml Billy Tsai
@ 2021-07-19  8:06 ` Billy Tsai
  2021-07-19  8:06 ` [v1 3/7] iio: adc: aspeed: completes the bitfield declare Billy Tsai
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Billy Tsai @ 2021-07-19  8:06 UTC (permalink / raw)
  To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, billy_tsai,
	linux-iio, devicetree, linux-arm-kernel, linux-aspeed, raltherr
  Cc: BMC-SW

This patch add more description about aspeed adc and add vref property
for ast2600 to configure it reference voltage.

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
 .../bindings/iio/adc/aspeed,adc.yaml          | 23 +++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml
index 7f534a933e92..67ff0b5c7ef2 100644
--- a/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml
@@ -10,14 +10,26 @@ maintainers:
   - Joel Stanley <joel@jms.id.au>
 
 description:
-  This device is a 10-bit converter for 16 voltage channels.  All inputs are
-  single ended.
+  • 10-bits resolution for 16 voltage channels.
+  At ast2400/ast2500 the device has only one engine with 16 voltage channels.
+  At ast2600 the device split into two individual engine and each contains 8 voltage channels.
+  • Channel scanning can be non-continuous.
+  • Programmable ADC clock frequency.
+  • Programmable upper and lower bound for each channels.
+  • Interrupt when larger or less than bounds for each channels.
+  • Support hysteresis for each channels.
+  • Buildin a compensating method.
+  Additional feature at ast2600
+  • Internal or External reference voltage.
+  • Support 2 Internal reference voltage 1.2v or 2.5v.
+  • Integrate dividing circuit for battery sensing.
 
 properties:
   compatible:
     enum:
       - aspeed,ast2400-adc
       - aspeed,ast2500-adc
+      - aspeed,ast2600-adc
 
   reg:
     maxItems: 1
@@ -33,6 +45,13 @@ properties:
   "#io-channel-cells":
     const: 1
 
+  vref:
+    minItems: 900
+    maxItems: 2700
+    default: 2500
+    description:
+      ADC Reference voltage in millivolts (only work at ast2600)
+
 required:
   - compatible
   - reg
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [v1 3/7] iio: adc: aspeed: completes the bitfield declare.
  2021-07-19  8:06 [v1 0/7] Add support for ast2600 ADC Billy Tsai
  2021-07-19  8:06 ` [v1 1/7] dt-bindings: iio: adc: rename the aspeed adc yaml Billy Tsai
  2021-07-19  8:06 ` [v1 2/7] dt-bindings: iio: adc: Binding ast2600 adc Billy Tsai
@ 2021-07-19  8:06 ` Billy Tsai
  2021-07-19  8:06 ` [v1 4/7] iio: adc: aspeed: Allow driver to support ast2600 Billy Tsai
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Billy Tsai @ 2021-07-19  8:06 UTC (permalink / raw)
  To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, billy_tsai,
	linux-iio, devicetree, linux-arm-kernel, linux-aspeed, raltherr
  Cc: BMC-SW

This patch completes the declare of adc register bitfields and uses the
same prefix ASPEED_ADC_* for these bitfields.

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 40 ++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 19efaa41bc34..99466a5924c7 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -16,6 +16,7 @@
 #include <linux/reset.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
+#include <linux/bitfield.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/driver.h>
@@ -28,15 +29,28 @@
 #define ASPEED_REG_INTERRUPT_CONTROL	0x04
 #define ASPEED_REG_VGA_DETECT_CONTROL	0x08
 #define ASPEED_REG_CLOCK_CONTROL	0x0C
-#define ASPEED_REG_MAX			0xC0
-
-#define ASPEED_OPERATION_MODE_POWER_DOWN	(0x0 << 1)
-#define ASPEED_OPERATION_MODE_STANDBY		(0x1 << 1)
-#define ASPEED_OPERATION_MODE_NORMAL		(0x7 << 1)
-
-#define ASPEED_ENGINE_ENABLE		BIT(0)
-
-#define ASPEED_ADC_CTRL_INIT_RDY	BIT(8)
+#define ASPEED_REG_COMPENSATION_TRIM	0xC4
+#define ASPEED_REG_MAX			0xCC
+
+#define ASPEED_ADC_ENGINE_ENABLE		BIT(0)
+#define ASPEED_ADC_OPERATION_MODE		GENMASK(3, 1)
+#define ASPEED_ADC_OPERATION_MODE_POWER_DOWN	FIELD_PREP(ASPEED_ADC_OPERATION_MODE, 0)
+#define ASPEED_ADC_OPERATION_MODE_STANDBY	FIELD_PREP(ASPEED_ADC_OPERATION_MODE, 1)
+#define ASPEED_ADC_OPERATION_MODE_NORMAL	FIELD_PREP(ASPEED_ADC_OPERATION_MODE, 7)
+#define ASPEED_ADC_CTRL_COMPENSATION		BIT(4)
+#define ASPEED_ADC_AUTO_COMPENSATION		BIT(5)
+#define ASPEED_ADC_REF_VOLTAGE			GENMASK(7, 6)
+#define ASPEED_ADC_REF_VOLTAGE_2500mV		FIELD_PREP(ASPEED_ADC_REF_VOLTAGE, 0)
+#define ASPEED_ADC_REF_VOLTAGE_1200mV		FIELD_PREP(ASPEED_ADC_REF_VOLTAGE, 1)
+#define ASPEED_ADC_REF_VOLTAGE_EXT_HIGH		FIELD_PREP(ASPEED_ADC_REF_VOLTAGE, 2)
+#define ASPEED_ADC_REF_VOLTAGE_EXT_LOW		FIELD_PREP(ASPEED_ADC_REF_VOLTAGE, 3)
+#define ASPEED_ADC_CTRL_INIT_RDY		BIT(8)
+#define ASPEED_ADC_CH7_MODE			BIT(12)
+#define ASPEED_ADC_CH7_NORMAL			FIELD_PREP(ASPEED_ADC_CH7_MODE, 0)
+#define ASPEED_ADC_CH7_BATTERY			FIELD_PREP(ASPEED_ADC_CH7_MODE, 1)
+#define ASPEED_ADC_BATTERY_SENSING_ENABLE	BIT(13)
+#define ASPEED_ADC_CTRL_CHANNEL			GENMASK(31, 16)
+#define ASPEED_ADC_CTRL_CHANNEL_ENABLE(ch)	FIELD_PREP(ASPEED_ADC_CTRL_CHANNEL, BIT(ch))
 
 #define ASPEED_ADC_INIT_POLLING_TIME	500
 #define ASPEED_ADC_INIT_TIMEOUT		500000
@@ -226,7 +240,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 
 	if (model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
-		writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE,
+		writel(ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE,
 		       data->base + ASPEED_REG_ENGINE_CONTROL);
 
 		/* Wait for initial sequence complete. */
@@ -246,7 +260,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 		goto clk_enable_error;
 
 	adc_engine_control_reg_val = GENMASK(31, 16) |
-		ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE;
+		ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE;
 	writel(adc_engine_control_reg_val,
 		data->base + ASPEED_REG_ENGINE_CONTROL);
 
@@ -264,7 +278,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	return 0;
 
 iio_register_error:
-	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
+	writel(ASPEED_ADC_OPERATION_MODE_POWER_DOWN,
 		data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 clk_enable_error:
@@ -283,7 +297,7 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
-	writel(ASPEED_OPERATION_MODE_POWER_DOWN,
+	writel(ASPEED_ADC_OPERATION_MODE_POWER_DOWN,
 		data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 	reset_control_assert(data->rst);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [v1 4/7] iio: adc: aspeed: Allow driver to support ast2600
  2021-07-19  8:06 [v1 0/7] Add support for ast2600 ADC Billy Tsai
                   ` (2 preceding siblings ...)
  2021-07-19  8:06 ` [v1 3/7] iio: adc: aspeed: completes the bitfield declare Billy Tsai
@ 2021-07-19  8:06 ` Billy Tsai
  2021-07-19  8:06 ` [v1 5/7] iio: adc: aspeed: Add func to set sampling rate Billy Tsai
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Billy Tsai @ 2021-07-19  8:06 UTC (permalink / raw)
  To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, billy_tsai,
	linux-iio, devicetree, linux-arm-kernel, linux-aspeed, raltherr
  Cc: BMC-SW

The adc controller have some differents at ast2600:
1. Combine control register of clock divider to continuous bitfields.
2. Reference voltage becomes optional which are internal 2500mv/1200mv
and external range from 900mv to 2700mv
3. Divided into two engine, each one has 8 voltage sensing channels.

This patch handled these changes and compatible with old version.

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 171 ++++++++++++++++++++++++++---------
 1 file changed, 127 insertions(+), 44 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 99466a5924c7..6a77ac4e7dcb 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -1,8 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Aspeed AST2400/2500 ADC
+ * Aspeed AST2400/2500/2600 ADC
  *
  * Copyright (C) 2017 Google, Inc.
+ * Copyright (C) 2021 Aspeed Technology Inc.
  */
 
 #include <linux/clk.h>
@@ -55,12 +56,17 @@
 #define ASPEED_ADC_INIT_POLLING_TIME	500
 #define ASPEED_ADC_INIT_TIMEOUT		500000
 
+enum aspeed_adc_version {
+	aspeed_adc_ast2400,
+	aspeed_adc_ast2500,
+	aspeed_adc_ast2600,
+};
 struct aspeed_adc_model_data {
-	const char *model_name;
+	enum aspeed_adc_version version;
 	unsigned int min_sampling_rate;	// Hz
 	unsigned int max_sampling_rate;	// Hz
-	unsigned int vref_voltage;	// mV
 	bool wait_init_sequence;
+	unsigned int num_channels;
 };
 
 struct aspeed_adc_data {
@@ -70,6 +76,7 @@ struct aspeed_adc_data {
 	struct clk_hw		*clk_prescaler;
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
+	int			vref;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -106,8 +113,6 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 			       int *val, int *val2, long mask)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
-	const struct aspeed_adc_model_data *model_data =
-			of_device_get_match_data(data->dev);
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
@@ -115,7 +120,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
-		*val = model_data->vref_voltage;
+		*val = data->vref;
 		*val2 = ASPEED_RESOLUTION_BITS;
 		return IIO_VAL_FRACTIONAL_LOG2;
 
@@ -182,6 +187,55 @@ static const struct iio_info aspeed_adc_iio_info = {
 	.debugfs_reg_access = aspeed_adc_reg_access,
 };
 
+static int aspeed_adc_vref_config(struct platform_device *pdev)
+{
+	const struct aspeed_adc_model_data *model_data;
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+	int vref;
+	u32 adc_engine_control_reg_val =
+		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+
+	model_data = of_device_get_match_data(&pdev->dev);
+	switch (model_data->version) {
+	case aspeed_adc_ast2400:
+		vref = 2500;
+		break;
+	case aspeed_adc_ast2500:
+		vref = 1800;
+		break;
+	case aspeed_adc_ast2600:
+		if (of_property_read_u32(pdev->dev.of_node, "vref", &vref))
+			vref = 2500;
+		if (vref == 2500)
+			writel(adc_engine_control_reg_val |
+				       ASPEED_ADC_REF_VOLTAGE_2500mV,
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+		else if (vref == 1200)
+			writel(adc_engine_control_reg_val |
+				       ASPEED_ADC_REF_VOLTAGE_1200mV,
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+		else if ((vref >= 1550) && (vref <= 2700))
+			writel(adc_engine_control_reg_val |
+				       ASPEED_ADC_REF_VOLTAGE_EXT_HIGH,
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+		else if ((vref >= 900) && (vref <= 1650))
+			writel(adc_engine_control_reg_val |
+				       ASPEED_ADC_REF_VOLTAGE_EXT_LOW,
+			       data->base + ASPEED_REG_ENGINE_CONTROL);
+		else {
+			dev_err(&pdev->dev, "Vref not support");
+			return -EOPNOTSUPP;
+		}
+		break;
+	default:
+		dev_err(&pdev->dev, "ADC version not recognized");
+		return -EOPNOTSUPP;
+	}
+	data->vref = vref;
+	return 0;
+}
+
 static int aspeed_adc_probe(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev;
@@ -190,13 +244,16 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	const char *clk_parent_name;
 	int ret;
 	u32 adc_engine_control_reg_val;
+	char scaler_clk_name[32];
 
+	model_data = of_device_get_match_data(&pdev->dev);
 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));
 	if (!indio_dev)
 		return -ENOMEM;
 
 	data = iio_priv(indio_dev);
 	data->dev = &pdev->dev;
+	dev_set_drvdata(data->dev, indio_dev);
 
 	data->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->base))
@@ -205,29 +262,39 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	/* Register ADC clock prescaler with source specified by device tree. */
 	spin_lock_init(&data->clk_lock);
 	clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
+	if (model_data->version <= aspeed_adc_ast2500) {
+		data->clk_prescaler = clk_hw_register_divider(
+					&pdev->dev, "prescaler", clk_parent_name, 0,
+					data->base + ASPEED_REG_CLOCK_CONTROL,
+					17, 15, 0, &data->clk_lock);
+		if (IS_ERR(data->clk_prescaler))
+			return PTR_ERR(data->clk_prescaler);
 
-	data->clk_prescaler = clk_hw_register_divider(
-				&pdev->dev, "prescaler", clk_parent_name, 0,
-				data->base + ASPEED_REG_CLOCK_CONTROL,
-				17, 15, 0, &data->clk_lock);
-	if (IS_ERR(data->clk_prescaler))
-		return PTR_ERR(data->clk_prescaler);
-
-	/*
-	 * Register ADC clock scaler downstream from the prescaler. Allow rate
-	 * setting to adjust the prescaler as well.
-	 */
-	data->clk_scaler = clk_hw_register_divider(
-				&pdev->dev, "scaler", "prescaler",
-				CLK_SET_RATE_PARENT,
-				data->base + ASPEED_REG_CLOCK_CONTROL,
-				0, 10, 0, &data->clk_lock);
-	if (IS_ERR(data->clk_scaler)) {
-		ret = PTR_ERR(data->clk_scaler);
-		goto scaler_error;
+		/*
+		 * Register ADC clock scaler downstream from the prescaler. Allow rate
+		 * setting to adjust the prescaler as well.
+		 */
+		data->clk_scaler = clk_hw_register_divider(
+					&pdev->dev, "scaler", "prescaler",
+					CLK_SET_RATE_PARENT,
+					data->base + ASPEED_REG_CLOCK_CONTROL,
+					0, 10, 0, &data->clk_lock);
+		if (IS_ERR(data->clk_scaler)) {
+			ret = PTR_ERR(data->clk_scaler);
+			goto scaler_error;
+		}
+	} else {
+		snprintf(scaler_clk_name, sizeof(scaler_clk_name), "scaler-%s",
+			 pdev->name);
+		data->clk_scaler = clk_hw_register_divider(
+			&pdev->dev, scaler_clk_name, clk_parent_name, 0,
+			data->base + ASPEED_REG_CLOCK_CONTROL, 0, 16, 0,
+			&data->clk_lock);
+		if (IS_ERR(data->clk_scaler))
+			return PTR_ERR(data->clk_scaler);
 	}
 
-	data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	data->rst = devm_reset_control_get_shared(&pdev->dev, NULL);
 	if (IS_ERR(data->rst)) {
 		dev_err(&pdev->dev,
 			"invalid or missing reset controller device tree entry");
@@ -236,8 +303,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	}
 	reset_control_deassert(data->rst);
 
-	model_data = of_device_get_match_data(&pdev->dev);
-
 	if (model_data->wait_init_sequence) {
 		/* Enable engine in normal mode. */
 		writel(ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE,
@@ -254,22 +319,26 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 			goto poll_timeout_error;
 	}
 
-	/* Start all channels in normal mode. */
+	ret = aspeed_adc_vref_config(pdev);
+	if (ret)
+		goto vref_config_error;
 	ret = clk_prepare_enable(data->clk_scaler->clk);
 	if (ret)
 		goto clk_enable_error;
-
-	adc_engine_control_reg_val = GENMASK(31, 16) |
-		ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE;
+	adc_engine_control_reg_val =
+		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+	/* Start all channels in normal mode. */
+	adc_engine_control_reg_val |= ASPEED_ADC_CTRL_CHANNEL |
+				     ASPEED_ADC_OPERATION_MODE_NORMAL |
+				     ASPEED_ADC_ENGINE_ENABLE;
 	writel(adc_engine_control_reg_val,
 		data->base + ASPEED_REG_ENGINE_CONTROL);
 
-	model_data = of_device_get_match_data(&pdev->dev);
-	indio_dev->name = model_data->model_name;
+	indio_dev->name = dev_name(&pdev->dev);
 	indio_dev->info = &aspeed_adc_iio_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = aspeed_adc_iio_channels;
-	indio_dev->num_channels = ARRAY_SIZE(aspeed_adc_iio_channels);
+	indio_dev->num_channels = model_data->num_channels;
 
 	ret = iio_device_register(indio_dev);
 	if (ret)
@@ -281,13 +350,15 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	writel(ASPEED_ADC_OPERATION_MODE_POWER_DOWN,
 		data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
+vref_config_error:
 clk_enable_error:
 poll_timeout_error:
 	reset_control_assert(data->rst);
 reset_error:
 	clk_hw_unregister_divider(data->clk_scaler);
 scaler_error:
-	clk_hw_unregister_divider(data->clk_prescaler);
+	if (model_data->version <= aspeed_adc_ast2500)
+		clk_hw_unregister_divider(data->clk_prescaler);
 	return ret;
 }
 
@@ -295,36 +366,48 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 {
 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
+	const struct aspeed_adc_model_data *model_data;
 
+	model_data = of_device_get_match_data(&pdev->dev);
 	iio_device_unregister(indio_dev);
 	writel(ASPEED_ADC_OPERATION_MODE_POWER_DOWN,
 		data->base + ASPEED_REG_ENGINE_CONTROL);
 	clk_disable_unprepare(data->clk_scaler->clk);
 	reset_control_assert(data->rst);
 	clk_hw_unregister_divider(data->clk_scaler);
-	clk_hw_unregister_divider(data->clk_prescaler);
+	if (model_data->version <= aspeed_adc_ast2500)
+		clk_hw_unregister_divider(data->clk_prescaler);
 
 	return 0;
 }
 
 static const struct aspeed_adc_model_data ast2400_model_data = {
-	.model_name = "ast2400-adc",
-	.vref_voltage = 2500, // mV
+	.version = aspeed_adc_ast2400,
 	.min_sampling_rate = 10000,
 	.max_sampling_rate = 500000,
+	.num_channels = 16,
 };
 
 static const struct aspeed_adc_model_data ast2500_model_data = {
-	.model_name = "ast2500-adc",
-	.vref_voltage = 1800, // mV
-	.min_sampling_rate = 1,
-	.max_sampling_rate = 1000000,
+	.version = aspeed_adc_ast2500,
+	.min_sampling_rate = 10000,
+	.max_sampling_rate = 500000,
+	.wait_init_sequence = true,
+	.num_channels = 16,
+};
+
+static const struct aspeed_adc_model_data ast2600_model_data = {
+	.version = aspeed_adc_ast2600,
+	.min_sampling_rate = 10000,
+	.max_sampling_rate = 500000,
 	.wait_init_sequence = true,
+	.num_channels = 8,
 };
 
 static const struct of_device_id aspeed_adc_matches[] = {
 	{ .compatible = "aspeed,ast2400-adc", .data = &ast2400_model_data },
 	{ .compatible = "aspeed,ast2500-adc", .data = &ast2500_model_data },
+	{ .compatible = "aspeed,ast2600-adc", .data = &ast2600_model_data },
 	{},
 };
 MODULE_DEVICE_TABLE(of, aspeed_adc_matches);
@@ -341,5 +424,5 @@ static struct platform_driver aspeed_adc_driver = {
 module_platform_driver(aspeed_adc_driver);
 
 MODULE_AUTHOR("Rick Altherr <raltherr@google.com>");
-MODULE_DESCRIPTION("Aspeed AST2400/2500 ADC Driver");
+MODULE_DESCRIPTION("Aspeed AST2400/2500/2600 ADC Driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [v1 5/7] iio: adc: aspeed: Add func to set sampling rate.
  2021-07-19  8:06 [v1 0/7] Add support for ast2600 ADC Billy Tsai
                   ` (3 preceding siblings ...)
  2021-07-19  8:06 ` [v1 4/7] iio: adc: aspeed: Allow driver to support ast2600 Billy Tsai
@ 2021-07-19  8:06 ` Billy Tsai
  2021-07-19  8:06 ` [v1 6/7] iio: adc: aspeed: Add compensation phase Billy Tsai
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Billy Tsai @ 2021-07-19  8:06 UTC (permalink / raw)
  To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, billy_tsai,
	linux-iio, devicetree, linux-arm-kernel, linux-aspeed, raltherr
  Cc: BMC-SW

Add the function to set the sampling rate and keep the sampling period
for a driver used to wait the lastest value.

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 6a77ac4e7dcb..b33ff9f0a3af 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -55,6 +55,7 @@
 
 #define ASPEED_ADC_INIT_POLLING_TIME	500
 #define ASPEED_ADC_INIT_TIMEOUT		500000
+#define ASPEED_ADC_DEF_SAMPLING_RATE	250000
 
 enum aspeed_adc_version {
 	aspeed_adc_ast2400,
@@ -77,6 +78,7 @@ struct aspeed_adc_data {
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
 	int			vref;
+	u32			sample_period_ns;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -108,6 +110,26 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
 	ASPEED_CHAN(15, 0x2E),
 };
 
+static int aspeed_adc_set_sampling_rate(struct iio_dev *indio_dev, u32 rate)
+{
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+	const struct aspeed_adc_model_data *model_data =
+		of_device_get_match_data(data->dev);
+
+	if (rate < model_data->min_sampling_rate ||
+	    rate > model_data->max_sampling_rate)
+		return -EINVAL;
+	/* Each sampling needs 12 clocks to covert.*/
+	clk_set_rate(data->clk_scaler->clk, rate * ASPEED_CLOCKS_PER_SAMPLE);
+
+	rate = clk_get_rate(data->clk_scaler->clk);
+	data->sample_period_ns = DIV_ROUND_UP_ULL(
+		(u64)NSEC_PER_SEC * ASPEED_CLOCKS_PER_SAMPLE, rate);
+	dev_dbg(data->dev, "Adc clock = %d sample period = %d ns", rate,
+		data->sample_period_ns);
+	return 0;
+}
+
 static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 			       struct iio_chan_spec const *chan,
 			       int *val, int *val2, long mask)
@@ -138,19 +160,9 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev,
 				struct iio_chan_spec const *chan,
 				int val, int val2, long mask)
 {
-	struct aspeed_adc_data *data = iio_priv(indio_dev);
-	const struct aspeed_adc_model_data *model_data =
-			of_device_get_match_data(data->dev);
-
 	switch (mask) {
 	case IIO_CHAN_INFO_SAMP_FREQ:
-		if (val < model_data->min_sampling_rate ||
-			val > model_data->max_sampling_rate)
-			return -EINVAL;
-
-		clk_set_rate(data->clk_scaler->clk,
-				val * ASPEED_CLOCKS_PER_SAMPLE);
-		return 0;
+		return aspeed_adc_set_sampling_rate(indio_dev, val);
 
 	case IIO_CHAN_INFO_SCALE:
 	case IIO_CHAN_INFO_RAW:
@@ -325,6 +337,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	ret = clk_prepare_enable(data->clk_scaler->clk);
 	if (ret)
 		goto clk_enable_error;
+	aspeed_adc_set_sampling_rate(indio_dev, ASPEED_ADC_DEF_SAMPLING_RATE);
 	adc_engine_control_reg_val =
 		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
 	/* Start all channels in normal mode. */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [v1 6/7] iio: adc: aspeed: Add compensation phase.
  2021-07-19  8:06 [v1 0/7] Add support for ast2600 ADC Billy Tsai
                   ` (4 preceding siblings ...)
  2021-07-19  8:06 ` [v1 5/7] iio: adc: aspeed: Add func to set sampling rate Billy Tsai
@ 2021-07-19  8:06 ` Billy Tsai
  2021-07-19  8:06 ` [v1 7/7] iio: adc: aspeed: Fix the calculate error of clock Billy Tsai
  2021-07-24 16:24 ` [v1 0/7] Add support for ast2600 ADC Jonathan Cameron
  7 siblings, 0 replies; 9+ messages in thread
From: Billy Tsai @ 2021-07-19  8:06 UTC (permalink / raw)
  To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, billy_tsai,
	linux-iio, devicetree, linux-arm-kernel, linux-aspeed, raltherr
  Cc: BMC-SW

This patch adds a compensation phase to improve the accurate of adc
measurement. This is the builtin function though input half of the
reference voltage to get the adc offset.

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 51 +++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index b33ff9f0a3af..b0d7a58cb7f5 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -56,6 +56,7 @@
 #define ASPEED_ADC_INIT_POLLING_TIME	500
 #define ASPEED_ADC_INIT_TIMEOUT		500000
 #define ASPEED_ADC_DEF_SAMPLING_RATE	250000
+#define ASPEED_ADC_MAX_RAW_DATA		GENMASK(9, 0)
 
 enum aspeed_adc_version {
 	aspeed_adc_ast2400,
@@ -79,6 +80,7 @@ struct aspeed_adc_data {
 	struct reset_control	*rst;
 	int			vref;
 	u32			sample_period_ns;
+	int			cv;
 };
 
 #define ASPEED_CHAN(_idx, _data_reg_addr) {			\
@@ -110,6 +112,48 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
 	ASPEED_CHAN(15, 0x2E),
 };
 
+static int aspeed_adc_compensation(struct platform_device *pdev)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct aspeed_adc_data *data = iio_priv(indio_dev);
+	u32 index, adc_raw = 0;
+	u32 adc_engine_control_reg_val =
+		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+	adc_engine_control_reg_val |=
+		(ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE);
+
+	/*
+	 * Enable compensating sensing:
+	 * After that, the input voltage of adc will force to half of the reference
+	 * voltage. So the expected reading raw data will become half of the max
+	 * value. We can get compensating value = 0x200 - adc read raw value.
+	 * It is recommended to average at least 10 samples to get a final CV.
+	 */
+	writel(adc_engine_control_reg_val | ASPEED_ADC_CTRL_COMPENSATION |
+		       ASPEED_ADC_CTRL_CHANNEL_ENABLE(0),
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
+	/*
+	 * After enable compensating sensing mode need to wait some time for adc stable
+	 * Experiment result is 1ms.
+	 */
+	mdelay(1);
+
+	for (index = 0; index < 16; index++) {
+		/*
+		 * Waiting for the sampling period ensures that the value acquired
+		 * is fresh each time.
+		 */
+		ndelay(data->sample_period_ns);
+		adc_raw += readw(data->base + aspeed_adc_iio_channels[0].address);
+	}
+	adc_raw >>= 4;
+	data->cv = BIT(ASPEED_RESOLUTION_BITS - 1) - adc_raw;
+	writel(adc_engine_control_reg_val,
+	       data->base + ASPEED_REG_ENGINE_CONTROL);
+	dev_dbg(data->dev, "compensating value = %d\n", data->cv);
+	return 0;
+}
+
 static int aspeed_adc_set_sampling_rate(struct iio_dev *indio_dev, u32 rate)
 {
 	struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -138,7 +182,11 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
-		*val = readw(data->base + chan->address);
+		*val = readw(data->base + chan->address) + data->cv;
+		if (*val < 0)
+			*val = 0;
+		else if (*val >= ASPEED_ADC_MAX_RAW_DATA)
+			*val = ASPEED_ADC_MAX_RAW_DATA;
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_SCALE:
@@ -338,6 +386,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	if (ret)
 		goto clk_enable_error;
 	aspeed_adc_set_sampling_rate(indio_dev, ASPEED_ADC_DEF_SAMPLING_RATE);
+	aspeed_adc_compensation(pdev);
 	adc_engine_control_reg_val =
 		readl(data->base + ASPEED_REG_ENGINE_CONTROL);
 	/* Start all channels in normal mode. */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [v1 7/7] iio: adc: aspeed: Fix the calculate error of clock.
  2021-07-19  8:06 [v1 0/7] Add support for ast2600 ADC Billy Tsai
                   ` (5 preceding siblings ...)
  2021-07-19  8:06 ` [v1 6/7] iio: adc: aspeed: Add compensation phase Billy Tsai
@ 2021-07-19  8:06 ` Billy Tsai
  2021-07-24 16:24 ` [v1 0/7] Add support for ast2600 ADC Jonathan Cameron
  7 siblings, 0 replies; 9+ messages in thread
From: Billy Tsai @ 2021-07-19  8:06 UTC (permalink / raw)
  To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, billy_tsai,
	linux-iio, devicetree, linux-arm-kernel, linux-aspeed, raltherr
  Cc: BMC-SW

The adc clcok formula is
ast2400/2500:
ADC clock period = PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1)
ast2600:
ADC clock period = PCLK * 2 * (ADC0C[15:0] + 1)
They all have one fixed divided 2 and the legacy driver didn't handle it.
This patch register the fixed factory clock device as the parent of adc
clock scaler to fix this issue.

Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
 drivers/iio/adc/aspeed_adc.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index b0d7a58cb7f5..2b96b57b5a80 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -75,6 +75,7 @@ struct aspeed_adc_data {
 	struct device		*dev;
 	void __iomem		*base;
 	spinlock_t		clk_lock;
+	struct clk_hw		*fixed_div_clk;
 	struct clk_hw		*clk_prescaler;
 	struct clk_hw		*clk_scaler;
 	struct reset_control	*rst;
@@ -305,6 +306,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	int ret;
 	u32 adc_engine_control_reg_val;
 	char scaler_clk_name[32];
+	char fixed_div_clk_name[32];
 
 	model_data = of_device_get_match_data(&pdev->dev);
 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));
@@ -323,10 +325,15 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 	spin_lock_init(&data->clk_lock);
 	clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
 	if (model_data->version <= aspeed_adc_ast2500) {
+		/* ADC clock period = PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1) */
+		data->fixed_div_clk = clk_hw_register_fixed_factor(
+			&pdev->dev, "fixed-div", clk_parent_name, 0, 1, 2);
+		if (IS_ERR(data->fixed_div_clk))
+			return PTR_ERR(data->fixed_div_clk);
 		data->clk_prescaler = clk_hw_register_divider(
-					&pdev->dev, "prescaler", clk_parent_name, 0,
-					data->base + ASPEED_REG_CLOCK_CONTROL,
-					17, 15, 0, &data->clk_lock);
+			&pdev->dev, "prescaler", "fixed-div", 0,
+			data->base + ASPEED_REG_CLOCK_CONTROL, 17, 15, 0,
+			&data->clk_lock);
 		if (IS_ERR(data->clk_prescaler))
 			return PTR_ERR(data->clk_prescaler);
 
@@ -344,14 +351,23 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 			goto scaler_error;
 		}
 	} else {
+		/* ADC clock period = period of PCLK * 2 * (ADC0C[15:0] + 1) */
+		snprintf(fixed_div_clk_name, sizeof(fixed_div_clk_name), "fixed-div-%s",
+			 pdev->name);
+		data->fixed_div_clk = clk_hw_register_fixed_factor(
+			&pdev->dev, fixed_div_clk_name, clk_parent_name, 0, 1, 2);
+		if (IS_ERR(data->fixed_div_clk))
+			return PTR_ERR(data->fixed_div_clk);
 		snprintf(scaler_clk_name, sizeof(scaler_clk_name), "scaler-%s",
 			 pdev->name);
 		data->clk_scaler = clk_hw_register_divider(
 			&pdev->dev, scaler_clk_name, clk_parent_name, 0,
 			data->base + ASPEED_REG_CLOCK_CONTROL, 0, 16, 0,
 			&data->clk_lock);
-		if (IS_ERR(data->clk_scaler))
-			return PTR_ERR(data->clk_scaler);
+		if (IS_ERR(data->clk_scaler)) {
+			ret = PTR_ERR(data->clk_scaler);
+			goto scaler_error;
+		}
 	}
 
 	data->rst = devm_reset_control_get_shared(&pdev->dev, NULL);
@@ -421,6 +437,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
 scaler_error:
 	if (model_data->version <= aspeed_adc_ast2500)
 		clk_hw_unregister_divider(data->clk_prescaler);
+	clk_hw_unregister_fixed_factor(data->fixed_div_clk);
 	return ret;
 }
 
@@ -439,6 +456,7 @@ static int aspeed_adc_remove(struct platform_device *pdev)
 	clk_hw_unregister_divider(data->clk_scaler);
 	if (model_data->version <= aspeed_adc_ast2500)
 		clk_hw_unregister_divider(data->clk_prescaler);
+	clk_hw_unregister_fixed_factor(data->fixed_div_clk);
 
 	return 0;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [v1 0/7] Add support for ast2600 ADC
  2021-07-19  8:06 [v1 0/7] Add support for ast2600 ADC Billy Tsai
                   ` (6 preceding siblings ...)
  2021-07-19  8:06 ` [v1 7/7] iio: adc: aspeed: Fix the calculate error of clock Billy Tsai
@ 2021-07-24 16:24 ` Jonathan Cameron
  7 siblings, 0 replies; 9+ messages in thread
From: Jonathan Cameron @ 2021-07-24 16:24 UTC (permalink / raw)
  To: Billy Tsai
  Cc: lars, pmeerw, robh+dt, joel, andrew, p.zabel, linux-iio,
	devicetree, linux-arm-kernel, linux-aspeed, raltherr, BMC-SW

On Mon, 19 Jul 2021 16:06:00 +0800
Billy Tsai <billy_tsai@aspeedtech.com> wrote:

> This patch serials make aspeed_adc.c can support ast2600.
> In additional,
> patch #6 is used to improve the adc accurate and 
> patch #7 is used to fix the clock issue in the original code.
> 
> Billy Tsai (7):
>   dt-bindings: iio: adc: rename the aspeed adc yaml
>   dt-bindings: iio: adc: Binding ast2600 adc.
>   iio: adc: aspeed: completes the bitfield declare.
>   iio: adc: aspeed: Allow driver to support ast2600
>   iio: adc: aspeed: Add func to set sampling rate.
>   iio: adc: aspeed: Add compensation phase.
>   iio: adc: aspeed: Fix the calculate error of clock.

Hi Billy,

Small process note.  If you resend for some reason and the original series
has no reply, it is helpful to people if you just send a reply yourself
to say there is a v2. In the past I've occasionally applied wrong versions
when someone does this!

Thanks,

Jonathan

> 
>  ...speed,ast2400-adc.yaml => aspeed,adc.yaml} |  23 +-
>  drivers/iio/adc/aspeed_adc.c                  | 313 ++++++++++++++----
>  2 files changed, 266 insertions(+), 70 deletions(-)
>  rename Documentation/devicetree/bindings/iio/adc/{aspeed,ast2400-adc.yaml => aspeed,adc.yaml} (53%)
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-07-24 16:22 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-19  8:06 [v1 0/7] Add support for ast2600 ADC Billy Tsai
2021-07-19  8:06 ` [v1 1/7] dt-bindings: iio: adc: rename the aspeed adc yaml Billy Tsai
2021-07-19  8:06 ` [v1 2/7] dt-bindings: iio: adc: Binding ast2600 adc Billy Tsai
2021-07-19  8:06 ` [v1 3/7] iio: adc: aspeed: completes the bitfield declare Billy Tsai
2021-07-19  8:06 ` [v1 4/7] iio: adc: aspeed: Allow driver to support ast2600 Billy Tsai
2021-07-19  8:06 ` [v1 5/7] iio: adc: aspeed: Add func to set sampling rate Billy Tsai
2021-07-19  8:06 ` [v1 6/7] iio: adc: aspeed: Add compensation phase Billy Tsai
2021-07-19  8:06 ` [v1 7/7] iio: adc: aspeed: Fix the calculate error of clock Billy Tsai
2021-07-24 16:24 ` [v1 0/7] Add support for ast2600 ADC Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).