LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [v3 00/15] Add support for ast2600 ADC
@ 2021-08-16 10:48 Billy Tsai
2021-08-16 10:48 ` [v3 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings Billy Tsai
` (8 more replies)
0 siblings, 9 replies; 11+ messages in thread
From: Billy Tsai @ 2021-08-16 10:48 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 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 | 98 +++
drivers/iio/adc/aspeed_adc.c | 562 +++++++++++++++---
2 files changed, 570 insertions(+), 90 deletions(-)
create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
--
2.25.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [v3 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
2021-08-16 10:48 [v3 00/15] Add support for ast2600 ADC Billy Tsai
@ 2021-08-16 10:48 ` Billy Tsai
2021-08-16 20:07 ` Rob Herring
2021-08-16 10:48 ` [v3 02/15] iio: adc: aspeed: completes the bitfield declare Billy Tsai
` (7 subsequent siblings)
8 siblings, 1 reply; 11+ messages in thread
From: Billy Tsai @ 2021-08-16 10:48 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 | 98 +++++++++++++++++++
1 file changed, 98 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..28bff89e0d75
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
@@ -0,0 +1,98 @@
+# 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:
+ 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] 11+ messages in thread
* [v3 02/15] iio: adc: aspeed: completes the bitfield declare.
2021-08-16 10:48 [v3 00/15] Add support for ast2600 ADC Billy Tsai
2021-08-16 10:48 ` [v3 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings Billy Tsai
@ 2021-08-16 10:48 ` Billy Tsai
2021-08-16 10:48 ` [v3 03/15] iio: adc: aspeed: set driver data when adc probe Billy Tsai
` (6 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Billy Tsai @ 2021-08-16 10:48 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] 11+ messages in thread
* [v3 03/15] iio: adc: aspeed: set driver data when adc probe.
2021-08-16 10:48 [v3 00/15] Add support for ast2600 ADC Billy Tsai
2021-08-16 10:48 ` [v3 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings Billy Tsai
2021-08-16 10:48 ` [v3 02/15] iio: adc: aspeed: completes the bitfield declare Billy Tsai
@ 2021-08-16 10:48 ` Billy Tsai
2021-08-16 10:48 ` [v3 04/15] iio: adc: aspeed: Keep model data to driver data Billy Tsai
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Billy Tsai @ 2021-08-16 10:48 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] 11+ messages in thread
* [v3 04/15] iio: adc: aspeed: Keep model data to driver data.
2021-08-16 10:48 [v3 00/15] Add support for ast2600 ADC Billy Tsai
` (2 preceding siblings ...)
2021-08-16 10:48 ` [v3 03/15] iio: adc: aspeed: set driver data when adc probe Billy Tsai
@ 2021-08-16 10:48 ` Billy Tsai
2021-08-16 10:48 ` [v3 05/15] iio: adc: aspeed: Refactory model data structure Billy Tsai
` (4 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Billy Tsai @ 2021-08-16 10:48 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] 11+ messages in thread
* [v3 05/15] iio: adc: aspeed: Refactory model data structure
2021-08-16 10:48 [v3 00/15] Add support for ast2600 ADC Billy Tsai
` (3 preceding siblings ...)
2021-08-16 10:48 ` [v3 04/15] iio: adc: aspeed: Keep model data to driver data Billy Tsai
@ 2021-08-16 10:48 ` Billy Tsai
2021-08-16 10:48 ` [v3 06/15] iio: adc: aspeed: Add vref config function Billy Tsai
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Billy Tsai @ 2021-08-16 10:48 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] 11+ messages in thread
* [v3 06/15] iio: adc: aspeed: Add vref config function
2021-08-16 10:48 [v3 00/15] Add support for ast2600 ADC Billy Tsai
` (4 preceding siblings ...)
2021-08-16 10:48 ` [v3 05/15] iio: adc: aspeed: Refactory model data structure Billy Tsai
@ 2021-08-16 10:48 ` Billy Tsai
2021-08-16 10:48 ` [v3 07/15] iio: adc: aspeed: Set num_channels with model data Billy Tsai
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Billy Tsai @ 2021-08-16 10:48 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] 11+ messages in thread
* [v3 07/15] iio: adc: aspeed: Set num_channels with model data
2021-08-16 10:48 [v3 00/15] Add support for ast2600 ADC Billy Tsai
` (5 preceding siblings ...)
2021-08-16 10:48 ` [v3 06/15] iio: adc: aspeed: Add vref config function Billy Tsai
@ 2021-08-16 10:48 ` Billy Tsai
2021-08-16 10:48 ` [v3 09/15] iio: adc: aspeed: Use devm_add_action_or_reset Billy Tsai
2021-08-16 10:48 ` [v3 11/15] iio: adc: aspeed: Fix the calculate error of clock Billy Tsai
8 siblings, 0 replies; 11+ messages in thread
From: Billy Tsai @ 2021-08-16 10:48 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] 11+ messages in thread
* [v3 09/15] iio: adc: aspeed: Use devm_add_action_or_reset.
2021-08-16 10:48 [v3 00/15] Add support for ast2600 ADC Billy Tsai
` (6 preceding siblings ...)
2021-08-16 10:48 ` [v3 07/15] iio: adc: aspeed: Set num_channels with model data Billy Tsai
@ 2021-08-16 10:48 ` Billy Tsai
2021-08-16 10:48 ` [v3 11/15] iio: adc: aspeed: Fix the calculate error of clock Billy Tsai
8 siblings, 0 replies; 11+ messages in thread
From: Billy Tsai @ 2021-08-16 10:48 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] 11+ messages in thread
* [v3 11/15] iio: adc: aspeed: Fix the calculate error of clock.
2021-08-16 10:48 [v3 00/15] Add support for ast2600 ADC Billy Tsai
` (7 preceding siblings ...)
2021-08-16 10:48 ` [v3 09/15] iio: adc: aspeed: Use devm_add_action_or_reset Billy Tsai
@ 2021-08-16 10:48 ` Billy Tsai
8 siblings, 0 replies; 11+ messages in thread
From: Billy Tsai @ 2021-08-16 10:48 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
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 | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index ea3e9a52fcc9..8fe7da1a651f 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -4,6 +4,12 @@
*
* Copyright (C) 2017 Google, Inc.
* Copyright (C) 2021 Aspeed Technology Inc.
+ *
+ * ADC clock formula:
+ * Ast2400/Ast2500:
+ * clock period = period of PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1)
+ * Ast2600:
+ * clock period = period of PCLK * 2 * (ADC0C[15:0] + 1)
*/
#include <linux/clk.h>
@@ -77,6 +83,7 @@ struct aspeed_adc_data {
struct regulator *regulator;
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;
@@ -196,6 +203,13 @@ static void aspeed_adc_unregister_divider(void *data)
clk_hw_unregister_divider(clk);
}
+static void aspeed_adc_unregister_fixed_divider(void *data)
+{
+ struct clk_hw *clk = data;
+
+ clk_hw_unregister_fixed_factor(clk);
+}
+
static void aspeed_adc_reset_assert(void *data)
{
struct reset_control *rst = data;
@@ -312,6 +326,18 @@ 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);
snprintf(clk_parent_name, 32, of_clk_get_parent_name(pdev->dev.of_node, 0));
+ snprintf(clk_name, 32, "%s-fixed-div", data->model_data->model_name);
+ data->fixed_div_clk = clk_hw_register_fixed_factor(
+ &pdev->dev, clk_name, clk_parent_name, 0, 1, 2);
+ if (IS_ERR(data->fixed_div_clk))
+ return PTR_ERR(data->fixed_div_clk);
+
+ ret = devm_add_action_or_reset(data->dev,
+ aspeed_adc_unregister_fixed_divider,
+ data->clk_prescaler);
+ if (ret)
+ return ret;
+ snprintf(clk_parent_name, 32, clk_name);
if (data->model_data->need_prescaler) {
snprintf(clk_name, 32, "%s-prescaler",
data->model_data->model_name);
--
2.25.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [v3 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings
2021-08-16 10:48 ` [v3 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings Billy Tsai
@ 2021-08-16 20:07 ` Rob Herring
0 siblings, 0 replies; 11+ messages in thread
From: Rob Herring @ 2021-08-16 20:07 UTC (permalink / raw)
To: Billy Tsai
Cc: linux-kernel, lars, andrew, BMC-SW, joel, robh+dt, p.zabel,
linux-iio, devicetree, linux-arm-kernel, lgirdwood, broonie,
linux-aspeed, pmeerw, jic23
On Mon, 16 Aug 2021 18:48:32 +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 | 98 +++++++++++++++++++
> 1 file changed, 98 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
>
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml: properties:aspeed,int_vref_mv: 'oneOf' conditional failed, one must be fixed:
'type' is a required property
hint: A vendor boolean property can use "type: boolean"
Additional properties are not allowed ('enum' was unexpected)
hint: A vendor boolean property can use "type: boolean"
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml: properties:aspeed,int_vref_mv: 'oneOf' conditional failed, one must be fixed:
'$ref' is a required property
'allOf' is a required property
hint: A vendor property needs a $ref to types.yaml
from schema $id: http://devicetree.org/meta-schemas/vendor-props.yaml#
1200 is not of type 'string'
hint: A vendor string property with exact values has an implicit type
2500 is not of type 'string'
hint: A vendor string property with exact values has an implicit type
hint: Vendor specific properties must have a type and description unless they have a defined, common suffix.
from schema $id: http://devicetree.org/meta-schemas/vendor-props.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml: ignoring, error in schema: properties: aspeed,int_vref_mv
warning: no schema found in file: ./Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.example.dt.yaml:0:0: /example-0/adc@1e6e9000: failed to match any schema with compatible: ['aspeed,ast2600-adc0']
Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.example.dt.yaml:0:0: /example-0/adc@1e6e9100: failed to match any schema with compatible: ['aspeed,ast2600-adc1']
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/patch/1517123
This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2021-08-16 20:07 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-16 10:48 [v3 00/15] Add support for ast2600 ADC Billy Tsai
2021-08-16 10:48 ` [v3 01/15] dt-bindings: iio: adc: Add ast2600-adc bindings Billy Tsai
2021-08-16 20:07 ` Rob Herring
2021-08-16 10:48 ` [v3 02/15] iio: adc: aspeed: completes the bitfield declare Billy Tsai
2021-08-16 10:48 ` [v3 03/15] iio: adc: aspeed: set driver data when adc probe Billy Tsai
2021-08-16 10:48 ` [v3 04/15] iio: adc: aspeed: Keep model data to driver data Billy Tsai
2021-08-16 10:48 ` [v3 05/15] iio: adc: aspeed: Refactory model data structure Billy Tsai
2021-08-16 10:48 ` [v3 06/15] iio: adc: aspeed: Add vref config function Billy Tsai
2021-08-16 10:48 ` [v3 07/15] iio: adc: aspeed: Set num_channels with model data Billy Tsai
2021-08-16 10:48 ` [v3 09/15] iio: adc: aspeed: Use devm_add_action_or_reset Billy Tsai
2021-08-16 10:48 ` [v3 11/15] iio: adc: aspeed: Fix the calculate error of clock Billy Tsai
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).