* [v4 00/15] Add support for ast2600 ADC
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
This patch serials make aspeed_adc.c can support ast2600 and backward
compatible.
Change since v3:
dt-bindings:
- Fix properties:aspeed,int_vref_mv type error.
Change since v2:
dt-bindings:
- Create a new dt-bindings for ast2600 adc
aspeed_adc.c:
- Splits the patch for more details
- Remove version enum and use the flags in model data to distinguish
hardware feature
- Support trimming data get and set.
- Use devm_add_action_or_reset to simplify probe error handling.
Changes since v1:
dt-bindings:
- Fix the aspeed,adc.yaml check error.
- Add battery-sensing property.
aspeed_adc.c:
- Change the init flow:
Clock and reference voltage setting should be completed before adc
engine enable.
- Change the default sampling rate to meet most user case.
- Add patch #8 to suppoert battery sensing mode.
Billy Tsai (15):
dt-bindings: iio: adc: Add ast2600-adc bindings
iio: adc: aspeed: completes the bitfield declare.
iio: adc: aspeed: set driver data when adc probe.
iio: adc: aspeed: Keep model data to driver data.
iio: adc: aspeed: Refactory model data structure
iio: adc: aspeed: Add vref config function
iio: adc: aspeed: Set num_channels with model data
iio: adc: aspeed: Use model_data to set clk scaler.
iio: adc: aspeed: Use devm_add_action_or_reset.
iio: adc: aspeed: Support ast2600 adc.
iio: adc: aspeed: Fix the calculate error of clock.
iio: adc: aspeed: Add func to set sampling rate.
iio: adc: aspeed: Add compensation phase.
iio: adc: aspeed: Support battery sensing.
iio: adc: aspeed: Get and set trimming data.
.../bindings/iio/adc/aspeed,ast2600-adc.yaml | 97 +++
drivers/iio/adc/aspeed_adc.c | 562 +++++++++++++++---
2 files changed, 569 insertions(+), 90 deletions(-)
create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
--
2.25.1
^ permalink raw reply [flat|nested] 26+ messages in thread
* [v4 00/15] Add support for ast2600 ADC
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
This patch serials make aspeed_adc.c can support ast2600 and backward
compatible.
Change since v3:
dt-bindings:
- Fix properties:aspeed,int_vref_mv type error.
Change since v2:
dt-bindings:
- Create a new dt-bindings for ast2600 adc
aspeed_adc.c:
- Splits the patch for more details
- Remove version enum and use the flags in model data to distinguish
hardware feature
- Support trimming data get and set.
- Use devm_add_action_or_reset to simplify probe error handling.
Changes since v1:
dt-bindings:
- Fix the aspeed,adc.yaml check error.
- Add battery-sensing property.
aspeed_adc.c:
- Change the init flow:
Clock and reference voltage setting should be completed before adc
engine enable.
- Change the default sampling rate to meet most user case.
- Add patch #8 to suppoert battery sensing mode.
Billy Tsai (15):
dt-bindings: iio: adc: Add ast2600-adc bindings
iio: adc: aspeed: completes the bitfield declare.
iio: adc: aspeed: set driver data when adc probe.
iio: adc: aspeed: Keep model data to driver data.
iio: adc: aspeed: Refactory model data structure
iio: adc: aspeed: Add vref config function
iio: adc: aspeed: Set num_channels with model data
iio: adc: aspeed: Use model_data to set clk scaler.
iio: adc: aspeed: Use devm_add_action_or_reset.
iio: adc: aspeed: Support ast2600 adc.
iio: adc: aspeed: Fix the calculate error of clock.
iio: adc: aspeed: Add func to set sampling rate.
iio: adc: aspeed: Add compensation phase.
iio: adc: aspeed: Support battery sensing.
iio: adc: aspeed: Get and set trimming data.
.../bindings/iio/adc/aspeed,ast2600-adc.yaml | 97 +++
drivers/iio/adc/aspeed_adc.c | 562 +++++++++++++++---
2 files changed, 569 insertions(+), 90 deletions(-)
create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 26+ messages in thread
* [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
2021-08-23 7:02 ` Billy Tsai
@ 2021-08-23 7:02 ` Billy Tsai
-1 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
Add device tree bindings document for the aspeed ast2600 adc device
driver.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
.../bindings/iio/adc/aspeed,ast2600-adc.yaml | 97 +++++++++++++++++++
1 file changed, 97 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
new file mode 100644
index 000000000000..248cda7d91e9
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2600-adc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ADC that forms part of an ASPEED server management processor.
+
+maintainers:
+ - Billy Tsai <billy_tsai@aspeedtech.com>
+
+description: |
+ • 10-bits resolution for 16 voltage channels.
+ • 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 threshold for each channels.
+ • Interrupt when larger or less than threshold for each channels.
+ • Support hysteresis for each channels.
+ • Built-in a compensating method.
+ • Built-in a register to trim internal reference voltage.
+ • 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,ast2600-adc0
+ - aspeed,ast2600-adc1
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ description:
+ Input clock used to derive the sample clock. Expected to be the
+ SoC's APB clock.
+
+ resets:
+ maxItems: 1
+
+ "#io-channel-cells":
+ const: 1
+
+ vref-supply:
+ description:
+ The external regulator supply ADC reference voltage.
+
+ aspeed,int_vref_mv:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [1200, 2500]
+ description:
+ ADC internal reference voltage in millivolts.
+
+ aspeed,battery-sensing:
+ type: boolean
+ description:
+ Inform the driver that last channel will be used to sensor battery.
+
+ aspeed,trim-data-valid:
+ type: boolean
+ description: |
+ The ADC reference voltage can be calibrated to obtain the trimming
+ data which will be stored in otp. This property informs the driver that
+ the data store in the otp is valid.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - resets
+ - "#io-channel-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/ast2600-clock.h>
+ adc0: adc@1e6e9000 {
+ compatible = "aspeed,ast2600-adc0";
+ reg = <0x1e6e9000 0x100>;
+ clocks = <&syscon ASPEED_CLK_APB2>;
+ resets = <&syscon ASPEED_RESET_ADC>;
+ #io-channel-cells = <1>;
+ aspeed,int_vref_mv = <2500>;
+ };
+ adc1: adc@1e6e9100 {
+ compatible = "aspeed,ast2600-adc1";
+ reg = <0x1e6e9100 0x100>;
+ clocks = <&syscon ASPEED_CLK_APB2>;
+ resets = <&syscon ASPEED_RESET_ADC>;
+ #io-channel-cells = <1>;
+ aspeed,int_vref_mv = <2500>;
+ };
+...
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
Add device tree bindings document for the aspeed ast2600 adc device
driver.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
.../bindings/iio/adc/aspeed,ast2600-adc.yaml | 97 +++++++++++++++++++
1 file changed, 97 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
new file mode 100644
index 000000000000..248cda7d91e9
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2600-adc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ADC that forms part of an ASPEED server management processor.
+
+maintainers:
+ - Billy Tsai <billy_tsai@aspeedtech.com>
+
+description: |
+ • 10-bits resolution for 16 voltage channels.
+ • 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 threshold for each channels.
+ • Interrupt when larger or less than threshold for each channels.
+ • Support hysteresis for each channels.
+ • Built-in a compensating method.
+ • Built-in a register to trim internal reference voltage.
+ • 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,ast2600-adc0
+ - aspeed,ast2600-adc1
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ description:
+ Input clock used to derive the sample clock. Expected to be the
+ SoC's APB clock.
+
+ resets:
+ maxItems: 1
+
+ "#io-channel-cells":
+ const: 1
+
+ vref-supply:
+ description:
+ The external regulator supply ADC reference voltage.
+
+ aspeed,int_vref_mv:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ enum: [1200, 2500]
+ description:
+ ADC internal reference voltage in millivolts.
+
+ aspeed,battery-sensing:
+ type: boolean
+ description:
+ Inform the driver that last channel will be used to sensor battery.
+
+ aspeed,trim-data-valid:
+ type: boolean
+ description: |
+ The ADC reference voltage can be calibrated to obtain the trimming
+ data which will be stored in otp. This property informs the driver that
+ the data store in the otp is valid.
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - resets
+ - "#io-channel-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/ast2600-clock.h>
+ adc0: adc@1e6e9000 {
+ compatible = "aspeed,ast2600-adc0";
+ reg = <0x1e6e9000 0x100>;
+ clocks = <&syscon ASPEED_CLK_APB2>;
+ resets = <&syscon ASPEED_RESET_ADC>;
+ #io-channel-cells = <1>;
+ aspeed,int_vref_mv = <2500>;
+ };
+ adc1: adc@1e6e9100 {
+ compatible = "aspeed,ast2600-adc1";
+ reg = <0x1e6e9100 0x100>;
+ clocks = <&syscon ASPEED_CLK_APB2>;
+ resets = <&syscon ASPEED_RESET_ADC>;
+ #io-channel-cells = <1>;
+ aspeed,int_vref_mv = <2500>;
+ };
+...
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 02/15] iio: adc: aspeed: completes the bitfield declare.
2021-08-23 7:02 ` Billy Tsai
@ 2021-08-23 7:02 ` Billy Tsai
-1 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
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 | 56 +++++++++++++++++++++++++-----------
1 file changed, 39 insertions(+), 17 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 19efaa41bc34..7010d56ac3b9 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -3,6 +3,7 @@
* Aspeed AST2400/2500 ADC
*
* Copyright (C) 2017 Google, Inc.
+ * Copyright (C) 2021 Aspeed Technology Inc.
*/
#include <linux/clk.h>
@@ -16,6 +17,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 +30,31 @@
#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_OP_MODE GENMASK(3, 1)
+#define ASPEED_ADC_OP_MODE_PWR_DOWN 0
+#define ASPEED_ADC_OP_MODE_STANDBY 1
+#define ASPEED_ADC_OP_MODE_NORMAL 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 0
+#define ASPEED_ADC_REF_VOLTAGE_1200mV 1
+#define ASPEED_ADC_REF_VOLTAGE_EXT_HIGH 2
+#define ASPEED_ADC_REF_VOLTAGE_EXT_LOW 3
+#define ASPEED_ADC_BAT_SENSING_DIV BIT(6)
+#define ASPEED_ADC_BAT_SENSING_DIV_2_3 0
+#define ASPEED_ADC_BAT_SENSING_DIV_1_3 1
+#define ASPEED_ADC_CTRL_INIT_RDY BIT(8)
+#define ASPEED_ADC_CH7_MODE BIT(12)
+#define ASPEED_ADC_CH7_NORMAL 0
+#define ASPEED_ADC_CH7_BAT 1
+#define ASPEED_ADC_BAT_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 +244,9 @@ 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(FIELD_PREP(ASPEED_ADC_OP_MODE,
+ ASPEED_ADC_OP_MODE_NORMAL) |
+ ASPEED_ADC_ENGINE_ENABLE,
data->base + ASPEED_REG_ENGINE_CONTROL);
/* Wait for initial sequence complete. */
@@ -245,10 +265,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
if (ret)
goto clk_enable_error;
- adc_engine_control_reg_val = GENMASK(31, 16) |
- ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE;
+ adc_engine_control_reg_val =
+ ASPEED_ADC_CTRL_CHANNEL |
+ FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
+ ASPEED_ADC_ENGINE_ENABLE;
writel(adc_engine_control_reg_val,
- data->base + ASPEED_REG_ENGINE_CONTROL);
+ data->base + ASPEED_REG_ENGINE_CONTROL);
model_data = of_device_get_match_data(&pdev->dev);
indio_dev->name = model_data->model_name;
@@ -264,8 +286,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
return 0;
iio_register_error:
- writel(ASPEED_OPERATION_MODE_POWER_DOWN,
- data->base + ASPEED_REG_ENGINE_CONTROL);
+ writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+ data->base + ASPEED_REG_ENGINE_CONTROL);
clk_disable_unprepare(data->clk_scaler->clk);
clk_enable_error:
poll_timeout_error:
@@ -283,8 +305,8 @@ 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,
- data->base + ASPEED_REG_ENGINE_CONTROL);
+ writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_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);
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 02/15] iio: adc: aspeed: completes the bitfield declare.
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
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 | 56 +++++++++++++++++++++++++-----------
1 file changed, 39 insertions(+), 17 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 19efaa41bc34..7010d56ac3b9 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -3,6 +3,7 @@
* Aspeed AST2400/2500 ADC
*
* Copyright (C) 2017 Google, Inc.
+ * Copyright (C) 2021 Aspeed Technology Inc.
*/
#include <linux/clk.h>
@@ -16,6 +17,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 +30,31 @@
#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_OP_MODE GENMASK(3, 1)
+#define ASPEED_ADC_OP_MODE_PWR_DOWN 0
+#define ASPEED_ADC_OP_MODE_STANDBY 1
+#define ASPEED_ADC_OP_MODE_NORMAL 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 0
+#define ASPEED_ADC_REF_VOLTAGE_1200mV 1
+#define ASPEED_ADC_REF_VOLTAGE_EXT_HIGH 2
+#define ASPEED_ADC_REF_VOLTAGE_EXT_LOW 3
+#define ASPEED_ADC_BAT_SENSING_DIV BIT(6)
+#define ASPEED_ADC_BAT_SENSING_DIV_2_3 0
+#define ASPEED_ADC_BAT_SENSING_DIV_1_3 1
+#define ASPEED_ADC_CTRL_INIT_RDY BIT(8)
+#define ASPEED_ADC_CH7_MODE BIT(12)
+#define ASPEED_ADC_CH7_NORMAL 0
+#define ASPEED_ADC_CH7_BAT 1
+#define ASPEED_ADC_BAT_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 +244,9 @@ 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(FIELD_PREP(ASPEED_ADC_OP_MODE,
+ ASPEED_ADC_OP_MODE_NORMAL) |
+ ASPEED_ADC_ENGINE_ENABLE,
data->base + ASPEED_REG_ENGINE_CONTROL);
/* Wait for initial sequence complete. */
@@ -245,10 +265,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
if (ret)
goto clk_enable_error;
- adc_engine_control_reg_val = GENMASK(31, 16) |
- ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE;
+ adc_engine_control_reg_val =
+ ASPEED_ADC_CTRL_CHANNEL |
+ FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_NORMAL) |
+ ASPEED_ADC_ENGINE_ENABLE;
writel(adc_engine_control_reg_val,
- data->base + ASPEED_REG_ENGINE_CONTROL);
+ data->base + ASPEED_REG_ENGINE_CONTROL);
model_data = of_device_get_match_data(&pdev->dev);
indio_dev->name = model_data->model_name;
@@ -264,8 +286,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
return 0;
iio_register_error:
- writel(ASPEED_OPERATION_MODE_POWER_DOWN,
- data->base + ASPEED_REG_ENGINE_CONTROL);
+ writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
+ data->base + ASPEED_REG_ENGINE_CONTROL);
clk_disable_unprepare(data->clk_scaler->clk);
clk_enable_error:
poll_timeout_error:
@@ -283,8 +305,8 @@ 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,
- data->base + ASPEED_REG_ENGINE_CONTROL);
+ writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_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);
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 03/15] iio: adc: aspeed: set driver data when adc probe.
2021-08-23 7:02 ` Billy Tsai
@ 2021-08-23 7:02 ` Billy Tsai
-1 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
Fix the issue when adc remove will get the null driver data.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 7010d56ac3b9..20462cf659e4 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -201,6 +201,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
data = iio_priv(indio_dev);
data->dev = &pdev->dev;
+ platform_set_drvdata(pdev, indio_dev);
data->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->base))
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 03/15] iio: adc: aspeed: set driver data when adc probe.
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
Fix the issue when adc remove will get the null driver data.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 7010d56ac3b9..20462cf659e4 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -201,6 +201,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
data = iio_priv(indio_dev);
data->dev = &pdev->dev;
+ platform_set_drvdata(pdev, indio_dev);
data->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(data->base))
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 04/15] iio: adc: aspeed: Keep model data to driver data.
2021-08-23 7:02 ` Billy Tsai
@ 2021-08-23 7:02 ` Billy Tsai
-1 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
Keep the model data pointer to driver data for reducing the usage of
of_device_get_match_data().
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 20462cf659e4..d85aa31ee3b1 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -69,6 +69,7 @@ struct aspeed_adc_model_data {
struct aspeed_adc_data {
struct device *dev;
+ const struct aspeed_adc_model_data *model_data;
void __iomem *base;
spinlock_t clk_lock;
struct clk_hw *clk_prescaler;
@@ -110,8 +111,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:
@@ -119,7 +118,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->model_data->vref_voltage;
*val2 = ASPEED_RESOLUTION_BITS;
return IIO_VAL_FRACTIONAL_LOG2;
@@ -138,13 +137,11 @@ static int aspeed_adc_write_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_SAMP_FREQ:
- if (val < model_data->min_sampling_rate ||
- val > model_data->max_sampling_rate)
+ if (val < data->model_data->min_sampling_rate ||
+ val > data->model_data->max_sampling_rate)
return -EINVAL;
clk_set_rate(data->clk_scaler->clk,
@@ -190,7 +187,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
struct aspeed_adc_data *data;
- const struct aspeed_adc_model_data *model_data;
const char *clk_parent_name;
int ret;
u32 adc_engine_control_reg_val;
@@ -201,6 +197,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
data = iio_priv(indio_dev);
data->dev = &pdev->dev;
+ data->model_data = of_device_get_match_data(&pdev->dev);
platform_set_drvdata(pdev, indio_dev);
data->base = devm_platform_ioremap_resource(pdev, 0);
@@ -241,9 +238,7 @@ 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) {
+ if (data->model_data->wait_init_sequence) {
/* Enable engine in normal mode. */
writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
ASPEED_ADC_OP_MODE_NORMAL) |
@@ -273,8 +268,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
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 = data->model_data->model_name;
indio_dev->info = &aspeed_adc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = aspeed_adc_iio_channels;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 04/15] iio: adc: aspeed: Keep model data to driver data.
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
Keep the model data pointer to driver data for reducing the usage of
of_device_get_match_data().
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 20462cf659e4..d85aa31ee3b1 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -69,6 +69,7 @@ struct aspeed_adc_model_data {
struct aspeed_adc_data {
struct device *dev;
+ const struct aspeed_adc_model_data *model_data;
void __iomem *base;
spinlock_t clk_lock;
struct clk_hw *clk_prescaler;
@@ -110,8 +111,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:
@@ -119,7 +118,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->model_data->vref_voltage;
*val2 = ASPEED_RESOLUTION_BITS;
return IIO_VAL_FRACTIONAL_LOG2;
@@ -138,13 +137,11 @@ static int aspeed_adc_write_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_SAMP_FREQ:
- if (val < model_data->min_sampling_rate ||
- val > model_data->max_sampling_rate)
+ if (val < data->model_data->min_sampling_rate ||
+ val > data->model_data->max_sampling_rate)
return -EINVAL;
clk_set_rate(data->clk_scaler->clk,
@@ -190,7 +187,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
struct aspeed_adc_data *data;
- const struct aspeed_adc_model_data *model_data;
const char *clk_parent_name;
int ret;
u32 adc_engine_control_reg_val;
@@ -201,6 +197,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
data = iio_priv(indio_dev);
data->dev = &pdev->dev;
+ data->model_data = of_device_get_match_data(&pdev->dev);
platform_set_drvdata(pdev, indio_dev);
data->base = devm_platform_ioremap_resource(pdev, 0);
@@ -241,9 +238,7 @@ 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) {
+ if (data->model_data->wait_init_sequence) {
/* Enable engine in normal mode. */
writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
ASPEED_ADC_OP_MODE_NORMAL) |
@@ -273,8 +268,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
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 = data->model_data->model_name;
indio_dev->info = &aspeed_adc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = aspeed_adc_iio_channels;
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 05/15] iio: adc: aspeed: Refactory model data structure
2021-08-23 7:02 ` Billy Tsai
@ 2021-08-23 7:02 ` Billy Tsai
-1 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
This patch refactory the model data structure to distinguish the
function form differnet version of aspeed adc.
- Rename the vref_voltag to vref_fixed and add vref driver data
When driver probe will check vref_fixed value and store it
to vref which isn't const value.
- Add num_channels
Make num_channles of iio device can be changed by differnet model_data
- Add need_prescaler flag and scaler_bit_width
The need_prescaler flag used to tell the driver the clock divider needs
another prescaler and the scaler_bit_width to set the clock divider
bitfiled width.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index d85aa31ee3b1..f03c7921d534 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -63,8 +63,11 @@ struct aspeed_adc_model_data {
const char *model_name;
unsigned int min_sampling_rate; // Hz
unsigned int max_sampling_rate; // Hz
- unsigned int vref_voltage; // mV
+ unsigned int vref_fixed; // mV
bool wait_init_sequence;
+ bool need_prescaler;
+ u8 scaler_bit_width;
+ unsigned int num_channels;
};
struct aspeed_adc_data {
@@ -75,6 +78,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) { \
@@ -118,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = data->model_data->vref_voltage;
+ *val = data->model_data->vref_fixed;
*val2 = ASPEED_RESOLUTION_BITS;
return IIO_VAL_FRACTIONAL_LOG2;
@@ -312,17 +316,23 @@ static int aspeed_adc_remove(struct platform_device *pdev)
static const struct aspeed_adc_model_data ast2400_model_data = {
.model_name = "ast2400-adc",
- .vref_voltage = 2500, // mV
+ .vref_fixed = 2500, // mV
.min_sampling_rate = 10000,
.max_sampling_rate = 500000,
+ .need_prescaler = true,
+ .scaler_bit_width = 10,
+ .num_channels = 16,
};
static const struct aspeed_adc_model_data ast2500_model_data = {
.model_name = "ast2500-adc",
- .vref_voltage = 1800, // mV
+ .vref_fixed = 1800, // mV
.min_sampling_rate = 1,
.max_sampling_rate = 1000000,
.wait_init_sequence = true,
+ .need_prescaler = true,
+ .scaler_bit_width = 10,
+ .num_channels = 16,
};
static const struct of_device_id aspeed_adc_matches[] = {
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 05/15] iio: adc: aspeed: Refactory model data structure
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
This patch refactory the model data structure to distinguish the
function form differnet version of aspeed adc.
- Rename the vref_voltag to vref_fixed and add vref driver data
When driver probe will check vref_fixed value and store it
to vref which isn't const value.
- Add num_channels
Make num_channles of iio device can be changed by differnet model_data
- Add need_prescaler flag and scaler_bit_width
The need_prescaler flag used to tell the driver the clock divider needs
another prescaler and the scaler_bit_width to set the clock divider
bitfiled width.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index d85aa31ee3b1..f03c7921d534 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -63,8 +63,11 @@ struct aspeed_adc_model_data {
const char *model_name;
unsigned int min_sampling_rate; // Hz
unsigned int max_sampling_rate; // Hz
- unsigned int vref_voltage; // mV
+ unsigned int vref_fixed; // mV
bool wait_init_sequence;
+ bool need_prescaler;
+ u8 scaler_bit_width;
+ unsigned int num_channels;
};
struct aspeed_adc_data {
@@ -75,6 +78,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) { \
@@ -118,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = data->model_data->vref_voltage;
+ *val = data->model_data->vref_fixed;
*val2 = ASPEED_RESOLUTION_BITS;
return IIO_VAL_FRACTIONAL_LOG2;
@@ -312,17 +316,23 @@ static int aspeed_adc_remove(struct platform_device *pdev)
static const struct aspeed_adc_model_data ast2400_model_data = {
.model_name = "ast2400-adc",
- .vref_voltage = 2500, // mV
+ .vref_fixed = 2500, // mV
.min_sampling_rate = 10000,
.max_sampling_rate = 500000,
+ .need_prescaler = true,
+ .scaler_bit_width = 10,
+ .num_channels = 16,
};
static const struct aspeed_adc_model_data ast2500_model_data = {
.model_name = "ast2500-adc",
- .vref_voltage = 1800, // mV
+ .vref_fixed = 1800, // mV
.min_sampling_rate = 1,
.max_sampling_rate = 1000000,
.wait_init_sequence = true,
+ .need_prescaler = true,
+ .scaler_bit_width = 10,
+ .num_channels = 16,
};
static const struct of_device_id aspeed_adc_matches[] = {
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 06/15] iio: adc: aspeed: Add vref config function
2021-08-23 7:02 ` Billy Tsai
@ 2021-08-23 7:02 ` Billy Tsai
-1 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
Add the function to check the vref_fixed and set the value to driver
data.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f03c7921d534..f260e40ab9b2 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -122,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = data->model_data->vref_fixed;
+ *val = data->vref;
*val2 = ASPEED_RESOLUTION_BITS;
return IIO_VAL_FRACTIONAL_LOG2;
@@ -187,6 +187,17 @@ static const struct iio_info aspeed_adc_iio_info = {
.debugfs_reg_access = aspeed_adc_reg_access,
};
+static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
+{
+ struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+ if (data->model_data->vref_fixed) {
+ data->vref = data->model_data->vref_fixed;
+ return 0;
+ }
+ return 0;
+}
+
static int aspeed_adc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
@@ -242,6 +253,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
}
reset_control_deassert(data->rst);
+ ret = aspeed_adc_vref_config(indio_dev);
+ if (ret)
+ goto vref_config_error;
+
if (data->model_data->wait_init_sequence) {
/* Enable engine in normal mode. */
writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
@@ -290,6 +305,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
clk_disable_unprepare(data->clk_scaler->clk);
clk_enable_error:
poll_timeout_error:
+vref_config_error:
reset_control_assert(data->rst);
reset_error:
clk_hw_unregister_divider(data->clk_scaler);
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 06/15] iio: adc: aspeed: Add vref config function
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
Add the function to check the vref_fixed and set the value to driver
data.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f03c7921d534..f260e40ab9b2 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -122,7 +122,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = data->model_data->vref_fixed;
+ *val = data->vref;
*val2 = ASPEED_RESOLUTION_BITS;
return IIO_VAL_FRACTIONAL_LOG2;
@@ -187,6 +187,17 @@ static const struct iio_info aspeed_adc_iio_info = {
.debugfs_reg_access = aspeed_adc_reg_access,
};
+static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
+{
+ struct aspeed_adc_data *data = iio_priv(indio_dev);
+
+ if (data->model_data->vref_fixed) {
+ data->vref = data->model_data->vref_fixed;
+ return 0;
+ }
+ return 0;
+}
+
static int aspeed_adc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
@@ -242,6 +253,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
}
reset_control_deassert(data->rst);
+ ret = aspeed_adc_vref_config(indio_dev);
+ if (ret)
+ goto vref_config_error;
+
if (data->model_data->wait_init_sequence) {
/* Enable engine in normal mode. */
writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
@@ -290,6 +305,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
clk_disable_unprepare(data->clk_scaler->clk);
clk_enable_error:
poll_timeout_error:
+vref_config_error:
reset_control_assert(data->rst);
reset_error:
clk_hw_unregister_divider(data->clk_scaler);
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 07/15] iio: adc: aspeed: Set num_channels with model data
2021-08-23 7:02 ` Billy Tsai
@ 2021-08-23 7:02 ` Billy Tsai
-1 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
Use the model_data member num_channels to set the num_channels of iio
device.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f260e40ab9b2..2d6215a91f99 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -291,7 +291,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
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 = data->model_data->num_channels;
ret = iio_device_register(indio_dev);
if (ret)
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 07/15] iio: adc: aspeed: Set num_channels with model data
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
Use the model_data member num_channels to set the num_channels of iio
device.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index f260e40ab9b2..2d6215a91f99 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -291,7 +291,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)
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 = data->model_data->num_channels;
ret = iio_device_register(indio_dev);
if (ret)
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 08/15] iio: adc: aspeed: Use model_data to set clk scaler.
2021-08-23 7:02 ` Billy Tsai
@ 2021-08-23 7:02 ` Billy Tsai
-1 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
This patch use need_prescaler and scaler_bit_width to set the adc clock
scaler.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 39 +++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 2d6215a91f99..52db38be9699 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -202,9 +202,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
struct aspeed_adc_data *data;
- const char *clk_parent_name;
int ret;
u32 adc_engine_control_reg_val;
+ unsigned long scaler_flags = 0;
+ char clk_name[32], clk_parent_name[32];
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));
if (!indio_dev)
@@ -221,24 +222,28 @@ 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);
-
- 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);
-
+ snprintf(clk_parent_name, 32, of_clk_get_parent_name(pdev->dev.of_node, 0));
+ if (data->model_data->need_prescaler) {
+ snprintf(clk_name, 32, "%s-prescaler",
+ data->model_data->model_name);
+ data->clk_prescaler = clk_hw_register_divider(
+ &pdev->dev, clk_name, 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);
+ snprintf(clk_parent_name, 32, clk_name);
+ scaler_flags = CLK_SET_RATE_PARENT;
+ }
/*
* Register ADC clock scaler downstream from the prescaler. Allow rate
* setting to adjust the prescaler as well.
*/
+ snprintf(clk_name, 32, "%s-scaler", data->model_data->model_name);
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);
+ &pdev->dev, clk_name, clk_parent_name, scaler_flags,
+ data->base + ASPEED_REG_CLOCK_CONTROL, 0,
+ data->model_data->scaler_bit_width, 0, &data->clk_lock);
if (IS_ERR(data->clk_scaler)) {
ret = PTR_ERR(data->clk_scaler);
goto scaler_error;
@@ -310,7 +315,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
reset_error:
clk_hw_unregister_divider(data->clk_scaler);
scaler_error:
- clk_hw_unregister_divider(data->clk_prescaler);
+ if (data->model_data->need_prescaler)
+ clk_hw_unregister_divider(data->clk_prescaler);
return ret;
}
@@ -325,7 +331,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
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 (data->model_data->need_prescaler)
+ clk_hw_unregister_divider(data->clk_prescaler);
return 0;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 08/15] iio: adc: aspeed: Use model_data to set clk scaler.
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
This patch use need_prescaler and scaler_bit_width to set the adc clock
scaler.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 39 +++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 2d6215a91f99..52db38be9699 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -202,9 +202,10 @@ static int aspeed_adc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
struct aspeed_adc_data *data;
- const char *clk_parent_name;
int ret;
u32 adc_engine_control_reg_val;
+ unsigned long scaler_flags = 0;
+ char clk_name[32], clk_parent_name[32];
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data));
if (!indio_dev)
@@ -221,24 +222,28 @@ 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);
-
- 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);
-
+ snprintf(clk_parent_name, 32, of_clk_get_parent_name(pdev->dev.of_node, 0));
+ if (data->model_data->need_prescaler) {
+ snprintf(clk_name, 32, "%s-prescaler",
+ data->model_data->model_name);
+ data->clk_prescaler = clk_hw_register_divider(
+ &pdev->dev, clk_name, 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);
+ snprintf(clk_parent_name, 32, clk_name);
+ scaler_flags = CLK_SET_RATE_PARENT;
+ }
/*
* Register ADC clock scaler downstream from the prescaler. Allow rate
* setting to adjust the prescaler as well.
*/
+ snprintf(clk_name, 32, "%s-scaler", data->model_data->model_name);
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);
+ &pdev->dev, clk_name, clk_parent_name, scaler_flags,
+ data->base + ASPEED_REG_CLOCK_CONTROL, 0,
+ data->model_data->scaler_bit_width, 0, &data->clk_lock);
if (IS_ERR(data->clk_scaler)) {
ret = PTR_ERR(data->clk_scaler);
goto scaler_error;
@@ -310,7 +315,8 @@ static int aspeed_adc_probe(struct platform_device *pdev)
reset_error:
clk_hw_unregister_divider(data->clk_scaler);
scaler_error:
- clk_hw_unregister_divider(data->clk_prescaler);
+ if (data->model_data->need_prescaler)
+ clk_hw_unregister_divider(data->clk_prescaler);
return ret;
}
@@ -325,7 +331,8 @@ static int aspeed_adc_remove(struct platform_device *pdev)
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 (data->model_data->need_prescaler)
+ clk_hw_unregister_divider(data->clk_prescaler);
return 0;
}
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 09/15] iio: adc: aspeed: Use devm_add_action_or_reset.
2021-08-23 7:02 ` Billy Tsai
@ 2021-08-23 7:02 ` Billy Tsai
-1 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
This patch use devm_add_action_or_reset to handle the error in probe
phase.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 92 +++++++++++++++++++++---------------
1 file changed, 55 insertions(+), 37 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 52db38be9699..1c87e12a0cab 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -187,6 +187,27 @@ static const struct iio_info aspeed_adc_iio_info = {
.debugfs_reg_access = aspeed_adc_reg_access,
};
+static void aspeed_adc_unregister_divider(void *data)
+{
+ struct clk_hw *clk = data;
+
+ clk_hw_unregister_divider(clk);
+}
+
+static void aspeed_adc_reset_assert(void *data)
+{
+ struct reset_control *rst = data;
+
+ reset_control_assert(rst);
+}
+
+static void aspeed_adc_clk_disable_unprepare(void *data)
+{
+ struct clk *clk = data;
+
+ clk_disable_unprepare(clk);
+}
+
static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
{
struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -232,6 +253,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
&data->clk_lock);
if (IS_ERR(data->clk_prescaler))
return PTR_ERR(data->clk_prescaler);
+
+ ret = devm_add_action_or_reset(data->dev,
+ aspeed_adc_unregister_divider,
+ data->clk_prescaler);
+ if (ret)
+ return ret;
snprintf(clk_parent_name, 32, clk_name);
scaler_flags = CLK_SET_RATE_PARENT;
}
@@ -244,23 +271,30 @@ static int aspeed_adc_probe(struct platform_device *pdev)
&pdev->dev, clk_name, clk_parent_name, scaler_flags,
data->base + ASPEED_REG_CLOCK_CONTROL, 0,
data->model_data->scaler_bit_width, 0, &data->clk_lock);
- if (IS_ERR(data->clk_scaler)) {
- ret = PTR_ERR(data->clk_scaler);
- goto scaler_error;
- }
+ if (IS_ERR(data->clk_scaler))
+ return PTR_ERR(data->clk_scaler);
+
+ ret = devm_add_action_or_reset(data->dev, aspeed_adc_unregister_divider,
+ data->clk_scaler);
+ if (ret)
+ return ret;
data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(data->rst)) {
dev_err(&pdev->dev,
"invalid or missing reset controller device tree entry");
- ret = PTR_ERR(data->rst);
- goto reset_error;
+ return PTR_ERR(data->rst);
}
reset_control_deassert(data->rst);
+ ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert,
+ data->rst);
+ if (ret)
+ return ret;
+
ret = aspeed_adc_vref_config(indio_dev);
if (ret)
- goto vref_config_error;
+ return ret;
if (data->model_data->wait_init_sequence) {
/* Enable engine in normal mode. */
@@ -277,13 +311,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
ASPEED_ADC_INIT_POLLING_TIME,
ASPEED_ADC_INIT_TIMEOUT);
if (ret)
- goto poll_timeout_error;
+ return ret;
}
/* Start all channels in normal mode. */
ret = clk_prepare_enable(data->clk_scaler->clk);
if (ret)
- goto clk_enable_error;
+ return ret;
+
+ ret = devm_add_action_or_reset(data->dev,
+ aspeed_adc_clk_disable_unprepare,
+ data->clk_scaler->clk);
+ if (ret)
+ return ret;
adc_engine_control_reg_val =
ASPEED_ADC_CTRL_CHANNEL |
@@ -299,41 +339,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
indio_dev->num_channels = data->model_data->num_channels;
ret = iio_device_register(indio_dev);
- if (ret)
- goto iio_register_error;
-
+ if (ret) {
+ writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
+ ASPEED_ADC_OP_MODE_PWR_DOWN),
+ data->base + ASPEED_REG_ENGINE_CONTROL);
+ return ret;
+ }
return 0;
-
-iio_register_error:
- writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
- data->base + ASPEED_REG_ENGINE_CONTROL);
- clk_disable_unprepare(data->clk_scaler->clk);
-clk_enable_error:
-poll_timeout_error:
-vref_config_error:
- reset_control_assert(data->rst);
-reset_error:
- clk_hw_unregister_divider(data->clk_scaler);
-scaler_error:
- if (data->model_data->need_prescaler)
- clk_hw_unregister_divider(data->clk_prescaler);
- return ret;
}
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);
-
iio_device_unregister(indio_dev);
- writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_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);
- if (data->model_data->need_prescaler)
- clk_hw_unregister_divider(data->clk_prescaler);
-
return 0;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [v4 09/15] iio: adc: aspeed: Use devm_add_action_or_reset.
@ 2021-08-23 7:02 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-23 7:02 UTC (permalink / raw)
To: jic23, lars, pmeerw, robh+dt, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel
Cc: BMC-SW
This patch use devm_add_action_or_reset to handle the error in probe
phase.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 92 +++++++++++++++++++++---------------
1 file changed, 55 insertions(+), 37 deletions(-)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 52db38be9699..1c87e12a0cab 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -187,6 +187,27 @@ static const struct iio_info aspeed_adc_iio_info = {
.debugfs_reg_access = aspeed_adc_reg_access,
};
+static void aspeed_adc_unregister_divider(void *data)
+{
+ struct clk_hw *clk = data;
+
+ clk_hw_unregister_divider(clk);
+}
+
+static void aspeed_adc_reset_assert(void *data)
+{
+ struct reset_control *rst = data;
+
+ reset_control_assert(rst);
+}
+
+static void aspeed_adc_clk_disable_unprepare(void *data)
+{
+ struct clk *clk = data;
+
+ clk_disable_unprepare(clk);
+}
+
static int aspeed_adc_vref_config(struct iio_dev *indio_dev)
{
struct aspeed_adc_data *data = iio_priv(indio_dev);
@@ -232,6 +253,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)
&data->clk_lock);
if (IS_ERR(data->clk_prescaler))
return PTR_ERR(data->clk_prescaler);
+
+ ret = devm_add_action_or_reset(data->dev,
+ aspeed_adc_unregister_divider,
+ data->clk_prescaler);
+ if (ret)
+ return ret;
snprintf(clk_parent_name, 32, clk_name);
scaler_flags = CLK_SET_RATE_PARENT;
}
@@ -244,23 +271,30 @@ static int aspeed_adc_probe(struct platform_device *pdev)
&pdev->dev, clk_name, clk_parent_name, scaler_flags,
data->base + ASPEED_REG_CLOCK_CONTROL, 0,
data->model_data->scaler_bit_width, 0, &data->clk_lock);
- if (IS_ERR(data->clk_scaler)) {
- ret = PTR_ERR(data->clk_scaler);
- goto scaler_error;
- }
+ if (IS_ERR(data->clk_scaler))
+ return PTR_ERR(data->clk_scaler);
+
+ ret = devm_add_action_or_reset(data->dev, aspeed_adc_unregister_divider,
+ data->clk_scaler);
+ if (ret)
+ return ret;
data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(data->rst)) {
dev_err(&pdev->dev,
"invalid or missing reset controller device tree entry");
- ret = PTR_ERR(data->rst);
- goto reset_error;
+ return PTR_ERR(data->rst);
}
reset_control_deassert(data->rst);
+ ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert,
+ data->rst);
+ if (ret)
+ return ret;
+
ret = aspeed_adc_vref_config(indio_dev);
if (ret)
- goto vref_config_error;
+ return ret;
if (data->model_data->wait_init_sequence) {
/* Enable engine in normal mode. */
@@ -277,13 +311,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
ASPEED_ADC_INIT_POLLING_TIME,
ASPEED_ADC_INIT_TIMEOUT);
if (ret)
- goto poll_timeout_error;
+ return ret;
}
/* Start all channels in normal mode. */
ret = clk_prepare_enable(data->clk_scaler->clk);
if (ret)
- goto clk_enable_error;
+ return ret;
+
+ ret = devm_add_action_or_reset(data->dev,
+ aspeed_adc_clk_disable_unprepare,
+ data->clk_scaler->clk);
+ if (ret)
+ return ret;
adc_engine_control_reg_val =
ASPEED_ADC_CTRL_CHANNEL |
@@ -299,41 +339,19 @@ static int aspeed_adc_probe(struct platform_device *pdev)
indio_dev->num_channels = data->model_data->num_channels;
ret = iio_device_register(indio_dev);
- if (ret)
- goto iio_register_error;
-
+ if (ret) {
+ writel(FIELD_PREP(ASPEED_ADC_OP_MODE,
+ ASPEED_ADC_OP_MODE_PWR_DOWN),
+ data->base + ASPEED_REG_ENGINE_CONTROL);
+ return ret;
+ }
return 0;
-
-iio_register_error:
- writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_DOWN),
- data->base + ASPEED_REG_ENGINE_CONTROL);
- clk_disable_unprepare(data->clk_scaler->clk);
-clk_enable_error:
-poll_timeout_error:
-vref_config_error:
- reset_control_assert(data->rst);
-reset_error:
- clk_hw_unregister_divider(data->clk_scaler);
-scaler_error:
- if (data->model_data->need_prescaler)
- clk_hw_unregister_divider(data->clk_prescaler);
- return ret;
}
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);
-
iio_device_unregister(indio_dev);
- writel(FIELD_PREP(ASPEED_ADC_OP_MODE, ASPEED_ADC_OP_MODE_PWR_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);
- if (data->model_data->need_prescaler)
- clk_hw_unregister_divider(data->clk_prescaler);
-
return 0;
}
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
2021-08-23 7:02 ` Billy Tsai
@ 2021-08-24 12:13 ` Rob Herring
-1 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2021-08-24 12:13 UTC (permalink / raw)
To: Billy Tsai
Cc: jic23, lars, pmeerw, joel, andrew, p.zabel, lgirdwood, broonie,
linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, BMC-SW
On Mon, Aug 23, 2021 at 03:02:26PM +0800, Billy Tsai wrote:
> Add device tree bindings document for the aspeed ast2600 adc device
> driver.
>
> Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
> ---
> .../bindings/iio/adc/aspeed,ast2600-adc.yaml | 97 +++++++++++++++++++
> 1 file changed, 97 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
>
> diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
> new file mode 100644
> index 000000000000..248cda7d91e9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
> @@ -0,0 +1,97 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2600-adc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ADC that forms part of an ASPEED server management processor.
> +
> +maintainers:
> + - Billy Tsai <billy_tsai@aspeedtech.com>
> +
> +description: |
> + • 10-bits resolution for 16 voltage channels.
> + • 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 threshold for each channels.
> + • Interrupt when larger or less than threshold for each channels.
> + • Support hysteresis for each channels.
> + • Built-in a compensating method.
> + • Built-in a register to trim internal reference voltage.
> + • 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,ast2600-adc0
> + - aspeed,ast2600-adc1
What's the difference between 0 and 1?
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + description:
> + Input clock used to derive the sample clock. Expected to be the
> + SoC's APB clock.
How many clocks?
> +
> + resets:
> + maxItems: 1
> +
> + "#io-channel-cells":
> + const: 1
> +
> + vref-supply:
> + description:
> + The external regulator supply ADC reference voltage.
> +
> + aspeed,int_vref_mv:
Don't use '_' in property names.
Use standard unit suffixes as defined in property-units.yaml.
> + $ref: /schemas/types.yaml#/definitions/uint32
And then you can drop this.
> + enum: [1200, 2500]
> + description:
> + ADC internal reference voltage in millivolts.
> +
> + aspeed,battery-sensing:
> + type: boolean
> + description:
> + Inform the driver that last channel will be used to sensor battery.
> +
> + aspeed,trim-data-valid:
> + type: boolean
> + description: |
> + The ADC reference voltage can be calibrated to obtain the trimming
> + data which will be stored in otp. This property informs the driver that
> + the data store in the otp is valid.
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - resets
> + - "#io-channel-cells"
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/ast2600-clock.h>
> + adc0: adc@1e6e9000 {
> + compatible = "aspeed,ast2600-adc0";
> + reg = <0x1e6e9000 0x100>;
> + clocks = <&syscon ASPEED_CLK_APB2>;
> + resets = <&syscon ASPEED_RESET_ADC>;
> + #io-channel-cells = <1>;
> + aspeed,int_vref_mv = <2500>;
> + };
> + adc1: adc@1e6e9100 {
> + compatible = "aspeed,ast2600-adc1";
> + reg = <0x1e6e9100 0x100>;
> + clocks = <&syscon ASPEED_CLK_APB2>;
> + resets = <&syscon ASPEED_RESET_ADC>;
> + #io-channel-cells = <1>;
> + aspeed,int_vref_mv = <2500>;
> + };
> +...
> --
> 2.25.1
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
@ 2021-08-24 12:13 ` Rob Herring
0 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2021-08-24 12:13 UTC (permalink / raw)
To: Billy Tsai
Cc: jic23, lars, pmeerw, joel, andrew, p.zabel, lgirdwood, broonie,
linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, BMC-SW
On Mon, Aug 23, 2021 at 03:02:26PM +0800, Billy Tsai wrote:
> Add device tree bindings document for the aspeed ast2600 adc device
> driver.
>
> Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
> ---
> .../bindings/iio/adc/aspeed,ast2600-adc.yaml | 97 +++++++++++++++++++
> 1 file changed, 97 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
>
> diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
> new file mode 100644
> index 000000000000..248cda7d91e9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
> @@ -0,0 +1,97 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2600-adc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ADC that forms part of an ASPEED server management processor.
> +
> +maintainers:
> + - Billy Tsai <billy_tsai@aspeedtech.com>
> +
> +description: |
> + • 10-bits resolution for 16 voltage channels.
> + • 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 threshold for each channels.
> + • Interrupt when larger or less than threshold for each channels.
> + • Support hysteresis for each channels.
> + • Built-in a compensating method.
> + • Built-in a register to trim internal reference voltage.
> + • 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,ast2600-adc0
> + - aspeed,ast2600-adc1
What's the difference between 0 and 1?
> +
> + reg:
> + maxItems: 1
> +
> + clocks:
> + description:
> + Input clock used to derive the sample clock. Expected to be the
> + SoC's APB clock.
How many clocks?
> +
> + resets:
> + maxItems: 1
> +
> + "#io-channel-cells":
> + const: 1
> +
> + vref-supply:
> + description:
> + The external regulator supply ADC reference voltage.
> +
> + aspeed,int_vref_mv:
Don't use '_' in property names.
Use standard unit suffixes as defined in property-units.yaml.
> + $ref: /schemas/types.yaml#/definitions/uint32
And then you can drop this.
> + enum: [1200, 2500]
> + description:
> + ADC internal reference voltage in millivolts.
> +
> + aspeed,battery-sensing:
> + type: boolean
> + description:
> + Inform the driver that last channel will be used to sensor battery.
> +
> + aspeed,trim-data-valid:
> + type: boolean
> + description: |
> + The ADC reference voltage can be calibrated to obtain the trimming
> + data which will be stored in otp. This property informs the driver that
> + the data store in the otp is valid.
> +
> +required:
> + - compatible
> + - reg
> + - clocks
> + - resets
> + - "#io-channel-cells"
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/ast2600-clock.h>
> + adc0: adc@1e6e9000 {
> + compatible = "aspeed,ast2600-adc0";
> + reg = <0x1e6e9000 0x100>;
> + clocks = <&syscon ASPEED_CLK_APB2>;
> + resets = <&syscon ASPEED_RESET_ADC>;
> + #io-channel-cells = <1>;
> + aspeed,int_vref_mv = <2500>;
> + };
> + adc1: adc@1e6e9100 {
> + compatible = "aspeed,ast2600-adc1";
> + reg = <0x1e6e9100 0x100>;
> + clocks = <&syscon ASPEED_CLK_APB2>;
> + resets = <&syscon ASPEED_RESET_ADC>;
> + #io-channel-cells = <1>;
> + aspeed,int_vref_mv = <2500>;
> + };
> +...
> --
> 2.25.1
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
2021-08-24 12:13 ` Rob Herring
@ 2021-08-25 0:06 ` Billy Tsai
-1 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-25 0:06 UTC (permalink / raw)
To: Rob Herring
Cc: jic23, lars, pmeerw, joel, andrew, p.zabel, lgirdwood, broonie,
linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, BMC-SW
Hi Rob,
On 2021/8/24, 8:13 PM, "Rob Herring" <robh@kernel.org> wrote:
On Mon, Aug 23, 2021 at 03:02:26PM +0800, Billy Tsai wrote:
> > +properties:
> > + compatible:
> > + enum:
> > + - aspeed,ast2600-adc0
> > + - aspeed,ast2600-adc1
> What's the difference between 0 and 1?
Their trimming data, which is used to calibrate internal reference volage,
locates in different address of OTP.
Best Regards,
Billy Tsai
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
@ 2021-08-25 0:06 ` Billy Tsai
0 siblings, 0 replies; 26+ messages in thread
From: Billy Tsai @ 2021-08-25 0:06 UTC (permalink / raw)
To: Rob Herring
Cc: jic23, lars, pmeerw, joel, andrew, p.zabel, lgirdwood, broonie,
linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, BMC-SW
Hi Rob,
On 2021/8/24, 8:13 PM, "Rob Herring" <robh@kernel.org> wrote:
On Mon, Aug 23, 2021 at 03:02:26PM +0800, Billy Tsai wrote:
> > +properties:
> > + compatible:
> > + enum:
> > + - aspeed,ast2600-adc0
> > + - aspeed,ast2600-adc1
> What's the difference between 0 and 1?
Their trimming data, which is used to calibrate internal reference volage,
locates in different address of OTP.
Best Regards,
Billy Tsai
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
2021-08-25 0:06 ` Billy Tsai
@ 2021-08-29 14:53 ` Jonathan Cameron
-1 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2021-08-29 14:53 UTC (permalink / raw)
To: Billy Tsai
Cc: Rob Herring, lars, pmeerw, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, BMC-SW
On Wed, 25 Aug 2021 00:06:47 +0000
Billy Tsai <billy_tsai@aspeedtech.com> wrote:
> Hi Rob,
>
> On 2021/8/24, 8:13 PM, "Rob Herring" <robh@kernel.org> wrote:
>
> On Mon, Aug 23, 2021 at 03:02:26PM +0800, Billy Tsai wrote:
> > > +properties:
> > > + compatible:
> > > + enum:
> > > + - aspeed,ast2600-adc0
> > > + - aspeed,ast2600-adc1
>
> > What's the difference between 0 and 1?
>
> Their trimming data, which is used to calibrate internal reference volage,
> locates in different address of OTP.
At very least document that with a description: here to avoid anyone looking
at this later asking the same question!
Jonathan
>
> Best Regards,
> Billy Tsai
>
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
@ 2021-08-29 14:53 ` Jonathan Cameron
0 siblings, 0 replies; 26+ messages in thread
From: Jonathan Cameron @ 2021-08-29 14:53 UTC (permalink / raw)
To: Billy Tsai
Cc: Rob Herring, lars, pmeerw, joel, andrew, p.zabel, lgirdwood,
broonie, linux-iio, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, BMC-SW
On Wed, 25 Aug 2021 00:06:47 +0000
Billy Tsai <billy_tsai@aspeedtech.com> wrote:
> Hi Rob,
>
> On 2021/8/24, 8:13 PM, "Rob Herring" <robh@kernel.org> wrote:
>
> On Mon, Aug 23, 2021 at 03:02:26PM +0800, Billy Tsai wrote:
> > > +properties:
> > > + compatible:
> > > + enum:
> > > + - aspeed,ast2600-adc0
> > > + - aspeed,ast2600-adc1
>
> > What's the difference between 0 and 1?
>
> Their trimming data, which is used to calibrate internal reference volage,
> locates in different address of OTP.
At very least document that with a description: here to avoid anyone looking
at this later asking the same question!
Jonathan
>
> Best Regards,
> Billy Tsai
>
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2021-08-29 14:52 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-23 7:02 [v4 00/15] Add support for ast2600 ADC Billy Tsai
2021-08-23 7:02 ` Billy Tsai
2021-08-23 7:02 ` [v4 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings Billy Tsai
2021-08-23 7:02 ` Billy Tsai
2021-08-24 12:13 ` Rob Herring
2021-08-24 12:13 ` Rob Herring
2021-08-25 0:06 ` Billy Tsai
2021-08-25 0:06 ` Billy Tsai
2021-08-29 14:53 ` Jonathan Cameron
2021-08-29 14:53 ` Jonathan Cameron
2021-08-23 7:02 ` [v4 02/15] iio: adc: aspeed: completes the bitfield declare Billy Tsai
2021-08-23 7:02 ` Billy Tsai
2021-08-23 7:02 ` [v4 03/15] iio: adc: aspeed: set driver data when adc probe Billy Tsai
2021-08-23 7:02 ` Billy Tsai
2021-08-23 7:02 ` [v4 04/15] iio: adc: aspeed: Keep model data to driver data Billy Tsai
2021-08-23 7:02 ` Billy Tsai
2021-08-23 7:02 ` [v4 05/15] iio: adc: aspeed: Refactory model data structure Billy Tsai
2021-08-23 7:02 ` Billy Tsai
2021-08-23 7:02 ` [v4 06/15] iio: adc: aspeed: Add vref config function Billy Tsai
2021-08-23 7:02 ` Billy Tsai
2021-08-23 7:02 ` [v4 07/15] iio: adc: aspeed: Set num_channels with model data Billy Tsai
2021-08-23 7:02 ` Billy Tsai
2021-08-23 7:02 ` [v4 08/15] iio: adc: aspeed: Use model_data to set clk scaler Billy Tsai
2021-08-23 7:02 ` Billy Tsai
2021-08-23 7:02 ` [v4 09/15] iio: adc: aspeed: Use devm_add_action_or_reset Billy Tsai
2021-08-23 7:02 ` Billy Tsai
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.