From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-24 09:13:59
This patch serials make aspeed_adc.c can support ast2600 and backward
compatible.
RESEND due to miss some patches when sent patch v4.
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
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-24 09:13:56
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(-)
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-24 09:13:58
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(-)
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-24 09:14:21
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(+)
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-24 09:14:36
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(-)
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-24 09:14:50
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(-)
@@ -110,8 +111,6 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,int*val,int*val2,longmask){structaspeed_adc_data*data=iio_priv(indio_dev);-conststructaspeed_adc_model_data*model_data=-of_device_get_match_data(data->dev);switch(mask){caseIIO_CHAN_INFO_RAW:
@@ -119,7 +118,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,returnIIO_VAL_INT;caseIIO_CHAN_INFO_SCALE:-*val=model_data->vref_voltage;+*val=data->model_data->vref_voltage;*val2=ASPEED_RESOLUTION_BITS;returnIIO_VAL_FRACTIONAL_LOG2;
@@ -138,13 +137,11 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev,intval,intval2,longmask){structaspeed_adc_data*data=iio_priv(indio_dev);-conststructaspeed_adc_model_data*model_data=-of_device_get_match_data(data->dev);switch(mask){caseIIO_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){structiio_dev*indio_dev;structaspeed_adc_data*data;-conststructaspeed_adc_model_data*model_data;constchar*clk_parent_name;intret;u32adc_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
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-24 09:15:05
Make driver to support ast2600 adc device.
- Use shared reset controller
- Complete the vref configure function
- Add the model data for ast2600 adc
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 106 +++++++++++++++++++++++++++++++++--
1 file changed, 100 insertions(+), 6 deletions(-)
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-24 09:15:15
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(+)
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-24 09:15:24
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(-)
@@ -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)+gotovref_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
@@ -0,0 +1,97 @@+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)+%YAML1.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
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-25 00:57:58
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(-)
@@ -232,6 +253,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)&data->clk_lock);if(IS_ERR(data->clk_prescaler))returnPTR_ERR(data->clk_prescaler);++ret=devm_add_action_or_reset(data->dev,+aspeed_adc_unregister_divider,+data->clk_prescaler);+if(ret)+returnret;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);-gotoscaler_error;-}+if(IS_ERR(data->clk_scaler))+returnPTR_ERR(data->clk_scaler);++ret=devm_add_action_or_reset(data->dev,aspeed_adc_unregister_divider,+data->clk_scaler);+if(ret)+returnret;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);-gotoreset_error;+returnPTR_ERR(data->rst);}reset_control_deassert(data->rst);+ret=devm_add_action_or_reset(data->dev,aspeed_adc_reset_assert,+data->rst);+if(ret)+returnret;+ret=aspeed_adc_vref_config(indio_dev);if(ret)-gotovref_config_error;+returnret;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)-gotopoll_timeout_error;+returnret;}/* Start all channels in normal mode. */ret=clk_prepare_enable(data->clk_scaler->clk);if(ret)-gotoclk_enable_error;+returnret;++ret=devm_add_action_or_reset(data->dev,+aspeed_adc_clk_disable_unprepare,+data->clk_scaler->clk);+if(ret)+returnret;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)-gotoiio_register_error;-+if(ret){+writel(FIELD_PREP(ASPEED_ADC_OP_MODE,+ASPEED_ADC_OP_MODE_PWR_DOWN),+data->base+ASPEED_REG_ENGINE_CONTROL);+returnret;+}return0;--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);-returnret;}staticintaspeed_adc_remove(structplatform_device*pdev){structiio_dev*indio_dev=platform_get_drvdata(pdev);-structaspeed_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);-return0;}
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-25 01:57:24
Add the function to set the sampling rate and keep the sampling period
for a driver used to wait the lastest value.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 58 +++++++++++++++++++++++++-----------
1 file changed, 40 insertions(+), 18 deletions(-)
@@ -119,6 +126,24 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = {ASPEED_CHAN(15,0x2E),};+staticintaspeed_adc_set_sampling_rate(structiio_dev*indio_dev,u32rate)+{+structaspeed_adc_data*data=iio_priv(indio_dev);++if(rate<data->model_data->min_sampling_rate||+rate>data->model_data->max_sampling_rate)+return-EINVAL;+/* Each sampling needs 12 clocks to covert.*/+clk_set_rate(data->clk_scaler->clk,rate*ASPEED_CLOCKS_PER_SAMPLE);+rate=clk_get_rate(data->clk_scaler->clk);+data->sample_period_ns=DIV_ROUND_UP_ULL(+(u64)NSEC_PER_SEC*ASPEED_CLOCKS_PER_SAMPLE,rate);+dev_dbg(data->dev,"Adc clock = %d sample period = %d ns",rate,+data->sample_period_ns);++return0;+}+staticintaspeed_adc_read_raw(structiio_dev*indio_dev,structiio_chan_specconst*chan,int*val,int*val2,longmask)
@@ -149,17 +174,10 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev,structiio_chan_specconst*chan,intval,intval2,longmask){-structaspeed_adc_data*data=iio_priv(indio_dev);switch(mask){caseIIO_CHAN_INFO_SAMP_FREQ:-if(val<data->model_data->min_sampling_rate||-val>data->model_data->max_sampling_rate)-return-EINVAL;--clk_set_rate(data->clk_scaler->clk,-val*ASPEED_CLOCKS_PER_SAMPLE);-return0;+returnaspeed_adc_set_sampling_rate(indio_dev,val);caseIIO_CHAN_INFO_SCALE:caseIIO_CHAN_INFO_RAW:
@@ -386,6 +404,20 @@ static int aspeed_adc_probe(struct platform_device *pdev)if(ret)returnret;+ret=clk_prepare_enable(data->clk_scaler->clk);+if(ret)+returnret;++ret=devm_add_action_or_reset(data->dev,+aspeed_adc_clk_disable_unprepare,+data->clk_scaler->clk);+if(ret)+returnret;++ret=aspeed_adc_set_sampling_rate(indio_dev,ASPEED_ADC_DEF_SAMPLING_RATE);+if(ret)+returnret;+ret=aspeed_adc_vref_config(indio_dev);if(ret)returnret;
@@ -413,16 +445,6 @@ static int aspeed_adc_probe(struct platform_device *pdev)}/* Start all channels in normal mode. */-ret=clk_prepare_enable(data->clk_scaler->clk);-if(ret)-returnret;--ret=devm_add_action_or_reset(data->dev,-aspeed_adc_clk_disable_unprepare,-data->clk_scaler->clk);-if(ret)-returnret;-adc_engine_control_reg_val=readl(data->base+ASPEED_REG_ENGINE_CONTROL);adc_engine_control_reg_val|=
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-25 01:57:29
In ast2600, ADC integrate dividing circuit at last input channel for
battery sensing. This patch use the dts property "battery-sensing" to
enable this feature makes the last channel of each adc can tolerance
higher voltage than reference voltage.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 62 +++++++++++++++++++++++++++++++++---
1 file changed, 57 insertions(+), 5 deletions(-)
@@ -196,14 +204,39 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,int*val,int*val2,longmask){structaspeed_adc_data*data=iio_priv(indio_dev);+u32adc_engine_control_reg_val;switch(mask){caseIIO_CHAN_INFO_RAW:-*val=readw(data->base+chan->address);+if(data->battery_sensing&&chan->channel==7){+adc_engine_control_reg_val=+readl(data->base+ASPEED_REG_ENGINE_CONTROL);+writel(adc_engine_control_reg_val|+FIELD_PREP(ASPEED_ADC_CH7_MODE,+ASPEED_ADC_CH7_BAT)|+ASPEED_ADC_BAT_SENSING_ENABLE,+data->base+ASPEED_REG_ENGINE_CONTROL);+/*+*Afterenablebatterysensingmodeneedtowaitsometimeforadcstable+*Experimentresultis1ms.+*/+mdelay(1);+*val=readw(data->base+chan->address);+*val=(*val*data->battery_mode_gain.mult)/+data->battery_mode_gain.div;+/* Restore control register value */+writel(adc_engine_control_reg_val,+data->base+ASPEED_REG_ENGINE_CONTROL);+}else+*val=readw(data->base+chan->address);returnIIO_VAL_INT;caseIIO_CHAN_INFO_OFFSET:-*val=data->cv;+if(data->battery_sensing&&chan->channel==7)+*val=(data->cv*data->battery_mode_gain.mult)/+data->battery_mode_gain.div;+else+*val=data->cv;returnIIO_VAL_INT;caseIIO_CHAN_INFO_SCALE:
@@ -473,6 +506,23 @@ static int aspeed_adc_probe(struct platform_device *pdev)if(ret)returnret;+if(of_find_property(data->dev->of_node,"aspeed,battery-sensing",+NULL)){+if(data->model_data->bat_sense_sup){+data->battery_sensing=1;+if(readl(data->base+ASPEED_REG_ENGINE_CONTROL)&+ASPEED_ADC_BAT_SENSING_DIV){+data->battery_mode_gain.mult=3;+data->battery_mode_gain.div=1;+}else{+data->battery_mode_gain.mult=3;+data->battery_mode_gain.div=2;+}+}else+dev_warn(&pdev->dev,+"Failed to enable battey-sensing mode\n");+}+if(data->model_data->wait_init_sequence){adc_engine_control_reg_val=readl(data->base+ASPEED_REG_ENGINE_CONTROL);
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-25 02:57:49
This patch adds a compensation phase to improve the accurate of ADC
measurement. This is the built-in function though input half of the
reference voltage to get the ADC offset.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 54 +++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
@@ -155,6 +202,10 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,*val=readw(data->base+chan->address);returnIIO_VAL_INT;+caseIIO_CHAN_INFO_OFFSET:+*val=data->cv;+returnIIO_VAL_INT;+caseIIO_CHAN_INFO_SCALE:*val=data->vref;*val2=ASPEED_RESOLUTION_BITS;
@@ -444,6 +495,7 @@ static int aspeed_adc_probe(struct platform_device *pdev)returnret;}+aspeed_adc_compensation(indio_dev);/* Start all channels in normal mode. */adc_engine_control_reg_val=readl(data->base+ASPEED_REG_ENGINE_CONTROL);
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-25 02:58:00
The adc controller have trimming register for fine-tune the reference
voltage. The trimming value come from the otp register which will be
written before chip product. This patch will read this otp value and
configure it to the adc register when adc controller probe and using dts
property "aspeed,trim-data-valid" to determine whether to execute this
flow.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 68 ++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-25 02:58:05
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(-)
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-25 02:58:09
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(-)
@@ -232,6 +253,12 @@ static int aspeed_adc_probe(struct platform_device *pdev)&data->clk_lock);if(IS_ERR(data->clk_prescaler))returnPTR_ERR(data->clk_prescaler);++ret=devm_add_action_or_reset(data->dev,+aspeed_adc_unregister_divider,+data->clk_prescaler);+if(ret)+returnret;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);-gotoscaler_error;-}+if(IS_ERR(data->clk_scaler))+returnPTR_ERR(data->clk_scaler);++ret=devm_add_action_or_reset(data->dev,aspeed_adc_unregister_divider,+data->clk_scaler);+if(ret)+returnret;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);-gotoreset_error;+returnPTR_ERR(data->rst);}reset_control_deassert(data->rst);+ret=devm_add_action_or_reset(data->dev,aspeed_adc_reset_assert,+data->rst);+if(ret)+returnret;+ret=aspeed_adc_vref_config(indio_dev);if(ret)-gotovref_config_error;+returnret;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)-gotopoll_timeout_error;+returnret;}/* Start all channels in normal mode. */ret=clk_prepare_enable(data->clk_scaler->clk);if(ret)-gotoclk_enable_error;+returnret;++ret=devm_add_action_or_reset(data->dev,+aspeed_adc_clk_disable_unprepare,+data->clk_scaler->clk);+if(ret)+returnret;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)-gotoiio_register_error;-+if(ret){+writel(FIELD_PREP(ASPEED_ADC_OP_MODE,+ASPEED_ADC_OP_MODE_PWR_DOWN),+data->base+ASPEED_REG_ENGINE_CONTROL);+returnret;+}return0;--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);-returnret;}staticintaspeed_adc_remove(structplatform_device*pdev){structiio_dev*indio_dev=platform_get_drvdata(pdev);-structaspeed_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);-return0;}
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Billy Tsai <billy_tsai@aspeedtech.com> Date: 2021-08-25 02:58:45
The adc controller have trimming register for fine-tune the reference
voltage. The trimming value come from the otp register which will be
written before chip product. This patch will read this otp value and
configure it to the adc register when adc controller probe and using dts
property "aspeed,trim-data-valid" to determine whether to execute this
flow.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/iio/adc/aspeed_adc.c | 68 ++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
From: Jonathan Cameron <jic23@kernel.org> Date: 2021-08-29 15:04:01
On Tue, 24 Aug 2021 17:12:30 +0800
Billy Tsai [off-list ref] wrote:
quoted hunk
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(-)
This REG_MAX value is used as a sanity check for debugfs based access.
As this raises the limit for all devices supported by the driver, not just the
new ast2600, are we fine to read these non existent registers on the other
parts? If so, perhaps a comment to say that here somewhere?
+
+#define ASPEED_ADC_ENGINE_ENABLE BIT(0)
Are all the following in the same register? Bit usual to have
overlapping fields, so if they are, perhaps a few comments to
explain what is going on would be good.
Ideally these white space changes would be in a precursor patch.
At the very least mention them in the patch description. They are good
thing to tidy up, but they do add noise to this patch.
From: Jonathan Cameron <jic23@kernel.org> Date: 2021-08-29 15:05:55
On Tue, 24 Aug 2021 17:12:31 +0800
Billy Tsai [off-list ref] wrote:
Fix the issue when adc remove will get the null driver data.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
This is a fix that we should probably backport. Please add a fixes tag and move
it to the start of the series so I can pick it during this kernel
cycle rather than waiting for the next one.
Thanks,
Jonathan
From: Jonathan Cameron <jic23@kernel.org> Date: 2021-08-29 15:10:12
On Tue, 24 Aug 2021 17:12:33 +0800
Billy Tsai [off-list ref] wrote:
This patch refactory the model data structure to distinguish the
function form differnet version of aspeed adc.
from different versions
- Rename the vref_voltag to vref_fixed and add vref driver data
vref_voltage
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
different
- 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.
Whilst here, you could make the name carry the information of the units.
e.g. vref_fixed_mv; That way we always know what the units are without having
to spot this comment.
From: Jonathan Cameron <jic23@kernel.org> Date: 2021-08-29 15:28:35
On Tue, 24 Aug 2021 17:12:38 +0800
Billy Tsai [off-list ref] wrote:
Make driver to support ast2600 adc device.
- Use shared reset controller
- Complete the vref configure function
- Add the model data for ast2600 adc
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
Perhaps document that as default in the dt-binding, then you can remove this warning and
handle this as:
data->vref = 2500;
of_property_read_u32(data->dev->of_node,
"aspeed,int-vref-mvolts", &data->vref);
etc
From: Jonathan Cameron <jic23@kernel.org> Date: 2021-08-29 15:30:40
On Tue, 24 Aug 2021 17:12:39 +0800
Billy Tsai [off-list ref] wrote:
The adc clcok formula is
clock
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.
What are the impacts of this being wrong before? Is this something we
should look to backport?
Comment inline.