From patchwork Mon Jul 19 08:06:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12385059 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29B2AC636C9 for ; Mon, 19 Jul 2021 09:02:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0A49C611C2 for ; Mon, 19 Jul 2021 09:02:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235317AbhGSIVm (ORCPT ); Mon, 19 Jul 2021 04:21:42 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:22444 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234973AbhGSIVl (ORCPT ); Mon, 19 Jul 2021 04:21:41 -0400 Received: from twspam01.aspeedtech.com (localhost [127.0.0.2] (may be forged)) by twspam01.aspeedtech.com with ESMTP id 16J7oY9O015581 for ; Mon, 19 Jul 2021 15:50:34 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16J7nQi0015320; Mon, 19 Jul 2021 15:49:26 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from BillyTsai-pc.aspeed.com (192.168.2.149) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 19 Jul 2021 16:05:47 +0800 From: Billy Tsai To: , , , , , , , , , , , , CC: Subject: [v1 1/7] dt-bindings: iio: adc: rename the aspeed adc yaml Date: Mon, 19 Jul 2021 16:06:01 +0800 Message-ID: <20210719080607.28712-2-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210719080607.28712-1-billy_tsai@aspeedtech.com> References: <20210719080607.28712-1-billy_tsai@aspeedtech.com> MIME-Version: 1.0 X-Originating-IP: [192.168.2.149] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 16J7nQi0015320 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org The aspeed,ast2400-adc.yaml not only descriptor the bindings of ast2400. Rename it to aspeed,adc.yaml for all of the aspeed adc bindings. Signed-off-by: Billy Tsai --- .../bindings/iio/adc/{aspeed,ast2400-adc.yaml => aspeed,adc.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Documentation/devicetree/bindings/iio/adc/{aspeed,ast2400-adc.yaml => aspeed,adc.yaml} (100%) diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml similarity index 100% rename from Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml rename to Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml From patchwork Mon Jul 19 08:06:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12385055 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2C511C12002 for ; Mon, 19 Jul 2021 09:02:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0AFD6611EF for ; Mon, 19 Jul 2021 09:02:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235347AbhGSIVj (ORCPT ); Mon, 19 Jul 2021 04:21:39 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:51414 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235317AbhGSIVi (ORCPT ); Mon, 19 Jul 2021 04:21:38 -0400 X-Greylist: delayed 709 seconds by postgrey-1.27 at vger.kernel.org; Mon, 19 Jul 2021 04:21:37 EDT Received: from twspam01.aspeedtech.com (localhost [127.0.0.2] (may be forged)) by twspam01.aspeedtech.com with ESMTP id 16J7oVkX015578 for ; Mon, 19 Jul 2021 15:50:31 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16J7nQKL015321; Mon, 19 Jul 2021 15:49:26 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from BillyTsai-pc.aspeed.com (192.168.2.149) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 19 Jul 2021 16:05:48 +0800 From: Billy Tsai To: , , , , , , , , , , , , CC: Subject: [v1 2/7] dt-bindings: iio: adc: Binding ast2600 adc. Date: Mon, 19 Jul 2021 16:06:02 +0800 Message-ID: <20210719080607.28712-3-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210719080607.28712-1-billy_tsai@aspeedtech.com> References: <20210719080607.28712-1-billy_tsai@aspeedtech.com> MIME-Version: 1.0 X-Originating-IP: [192.168.2.149] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 16J7nQKL015321 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch add more description about aspeed adc and add vref property for ast2600 to configure it reference voltage. Signed-off-by: Billy Tsai --- .../bindings/iio/adc/aspeed,adc.yaml | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml index 7f534a933e92..67ff0b5c7ef2 100644 --- a/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml @@ -10,14 +10,26 @@ maintainers: - Joel Stanley description: - This device is a 10-bit converter for 16 voltage channels. All inputs are - single ended. + • 10-bits resolution for 16 voltage channels. + At ast2400/ast2500 the device has only one engine with 16 voltage channels. + At ast2600 the device split into two individual engine and each contains 8 voltage channels. + • Channel scanning can be non-continuous. + • Programmable ADC clock frequency. + • Programmable upper and lower bound for each channels. + • Interrupt when larger or less than bounds for each channels. + • Support hysteresis for each channels. + • Buildin a compensating method. + Additional feature at ast2600 + • Internal or External reference voltage. + • Support 2 Internal reference voltage 1.2v or 2.5v. + • Integrate dividing circuit for battery sensing. properties: compatible: enum: - aspeed,ast2400-adc - aspeed,ast2500-adc + - aspeed,ast2600-adc reg: maxItems: 1 @@ -33,6 +45,13 @@ properties: "#io-channel-cells": const: 1 + vref: + minItems: 900 + maxItems: 2700 + default: 2500 + description: + ADC Reference voltage in millivolts (only work at ast2600) + required: - compatible - reg From patchwork Mon Jul 19 08:06:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12385057 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UPPERCASE_50_75,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B45D5C636CB for ; Mon, 19 Jul 2021 09:02:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 906A7611C2 for ; Mon, 19 Jul 2021 09:02:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235301AbhGSIVk (ORCPT ); Mon, 19 Jul 2021 04:21:40 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:48638 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234973AbhGSIVk (ORCPT ); Mon, 19 Jul 2021 04:21:40 -0400 Received: from twspam01.aspeedtech.com (localhost [127.0.0.2] (may be forged)) by twspam01.aspeedtech.com with ESMTP id 16J7oVqO015579 for ; Mon, 19 Jul 2021 15:50:31 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16J7nQMB015322; Mon, 19 Jul 2021 15:49:26 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from BillyTsai-pc.aspeed.com (192.168.2.149) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 19 Jul 2021 16:05:48 +0800 From: Billy Tsai To: , , , , , , , , , , , , CC: Subject: [v1 3/7] iio: adc: aspeed: completes the bitfield declare. Date: Mon, 19 Jul 2021 16:06:03 +0800 Message-ID: <20210719080607.28712-4-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210719080607.28712-1-billy_tsai@aspeedtech.com> References: <20210719080607.28712-1-billy_tsai@aspeedtech.com> MIME-Version: 1.0 X-Originating-IP: [192.168.2.149] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 16J7nQMB015322 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch completes the declare of adc register bitfields and uses the same prefix ASPEED_ADC_* for these bitfields. Signed-off-by: Billy Tsai --- drivers/iio/adc/aspeed_adc.c | 40 ++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index 19efaa41bc34..99466a5924c7 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -28,15 +29,28 @@ #define ASPEED_REG_INTERRUPT_CONTROL 0x04 #define ASPEED_REG_VGA_DETECT_CONTROL 0x08 #define ASPEED_REG_CLOCK_CONTROL 0x0C -#define ASPEED_REG_MAX 0xC0 - -#define ASPEED_OPERATION_MODE_POWER_DOWN (0x0 << 1) -#define ASPEED_OPERATION_MODE_STANDBY (0x1 << 1) -#define ASPEED_OPERATION_MODE_NORMAL (0x7 << 1) - -#define ASPEED_ENGINE_ENABLE BIT(0) - -#define ASPEED_ADC_CTRL_INIT_RDY BIT(8) +#define ASPEED_REG_COMPENSATION_TRIM 0xC4 +#define ASPEED_REG_MAX 0xCC + +#define ASPEED_ADC_ENGINE_ENABLE BIT(0) +#define ASPEED_ADC_OPERATION_MODE GENMASK(3, 1) +#define ASPEED_ADC_OPERATION_MODE_POWER_DOWN FIELD_PREP(ASPEED_ADC_OPERATION_MODE, 0) +#define ASPEED_ADC_OPERATION_MODE_STANDBY FIELD_PREP(ASPEED_ADC_OPERATION_MODE, 1) +#define ASPEED_ADC_OPERATION_MODE_NORMAL FIELD_PREP(ASPEED_ADC_OPERATION_MODE, 7) +#define ASPEED_ADC_CTRL_COMPENSATION BIT(4) +#define ASPEED_ADC_AUTO_COMPENSATION BIT(5) +#define ASPEED_ADC_REF_VOLTAGE GENMASK(7, 6) +#define ASPEED_ADC_REF_VOLTAGE_2500mV FIELD_PREP(ASPEED_ADC_REF_VOLTAGE, 0) +#define ASPEED_ADC_REF_VOLTAGE_1200mV FIELD_PREP(ASPEED_ADC_REF_VOLTAGE, 1) +#define ASPEED_ADC_REF_VOLTAGE_EXT_HIGH FIELD_PREP(ASPEED_ADC_REF_VOLTAGE, 2) +#define ASPEED_ADC_REF_VOLTAGE_EXT_LOW FIELD_PREP(ASPEED_ADC_REF_VOLTAGE, 3) +#define ASPEED_ADC_CTRL_INIT_RDY BIT(8) +#define ASPEED_ADC_CH7_MODE BIT(12) +#define ASPEED_ADC_CH7_NORMAL FIELD_PREP(ASPEED_ADC_CH7_MODE, 0) +#define ASPEED_ADC_CH7_BATTERY FIELD_PREP(ASPEED_ADC_CH7_MODE, 1) +#define ASPEED_ADC_BATTERY_SENSING_ENABLE BIT(13) +#define ASPEED_ADC_CTRL_CHANNEL GENMASK(31, 16) +#define ASPEED_ADC_CTRL_CHANNEL_ENABLE(ch) FIELD_PREP(ASPEED_ADC_CTRL_CHANNEL, BIT(ch)) #define ASPEED_ADC_INIT_POLLING_TIME 500 #define ASPEED_ADC_INIT_TIMEOUT 500000 @@ -226,7 +240,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) if (model_data->wait_init_sequence) { /* Enable engine in normal mode. */ - writel(ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE, + writel(ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE, data->base + ASPEED_REG_ENGINE_CONTROL); /* Wait for initial sequence complete. */ @@ -246,7 +260,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) goto clk_enable_error; adc_engine_control_reg_val = GENMASK(31, 16) | - ASPEED_OPERATION_MODE_NORMAL | ASPEED_ENGINE_ENABLE; + ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE; writel(adc_engine_control_reg_val, data->base + ASPEED_REG_ENGINE_CONTROL); @@ -264,7 +278,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) return 0; iio_register_error: - writel(ASPEED_OPERATION_MODE_POWER_DOWN, + writel(ASPEED_ADC_OPERATION_MODE_POWER_DOWN, data->base + ASPEED_REG_ENGINE_CONTROL); clk_disable_unprepare(data->clk_scaler->clk); clk_enable_error: @@ -283,7 +297,7 @@ static int aspeed_adc_remove(struct platform_device *pdev) struct aspeed_adc_data *data = iio_priv(indio_dev); iio_device_unregister(indio_dev); - writel(ASPEED_OPERATION_MODE_POWER_DOWN, + writel(ASPEED_ADC_OPERATION_MODE_POWER_DOWN, data->base + ASPEED_REG_ENGINE_CONTROL); clk_disable_unprepare(data->clk_scaler->clk); reset_control_assert(data->rst); From patchwork Mon Jul 19 08:06:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12385065 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 64D3FC636C9 for ; Mon, 19 Jul 2021 09:02:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 47321611AF for ; Mon, 19 Jul 2021 09:02:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235436AbhGSIVq (ORCPT ); Mon, 19 Jul 2021 04:21:46 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:49895 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234973AbhGSIVq (ORCPT ); Mon, 19 Jul 2021 04:21:46 -0400 Received: from twspam01.aspeedtech.com (localhost [127.0.0.2] (may be forged)) by twspam01.aspeedtech.com with ESMTP id 16J7ol4x015586 for ; Mon, 19 Jul 2021 15:50:47 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16J7nRfm015323; Mon, 19 Jul 2021 15:49:27 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from BillyTsai-pc.aspeed.com (192.168.2.149) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 19 Jul 2021 16:05:48 +0800 From: Billy Tsai To: , , , , , , , , , , , , CC: Subject: [v1 4/7] iio: adc: aspeed: Allow driver to support ast2600 Date: Mon, 19 Jul 2021 16:06:04 +0800 Message-ID: <20210719080607.28712-5-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210719080607.28712-1-billy_tsai@aspeedtech.com> References: <20210719080607.28712-1-billy_tsai@aspeedtech.com> MIME-Version: 1.0 X-Originating-IP: [192.168.2.149] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 16J7nRfm015323 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org The adc controller have some differents at ast2600: 1. Combine control register of clock divider to continuous bitfields. 2. Reference voltage becomes optional which are internal 2500mv/1200mv and external range from 900mv to 2700mv 3. Divided into two engine, each one has 8 voltage sensing channels. This patch handled these changes and compatible with old version. Signed-off-by: Billy Tsai --- drivers/iio/adc/aspeed_adc.c | 171 ++++++++++++++++++++++++++--------- 1 file changed, 127 insertions(+), 44 deletions(-) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index 99466a5924c7..6a77ac4e7dcb 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Aspeed AST2400/2500 ADC + * Aspeed AST2400/2500/2600 ADC * * Copyright (C) 2017 Google, Inc. + * Copyright (C) 2021 Aspeed Technology Inc. */ #include @@ -55,12 +56,17 @@ #define ASPEED_ADC_INIT_POLLING_TIME 500 #define ASPEED_ADC_INIT_TIMEOUT 500000 +enum aspeed_adc_version { + aspeed_adc_ast2400, + aspeed_adc_ast2500, + aspeed_adc_ast2600, +}; struct aspeed_adc_model_data { - const char *model_name; + enum aspeed_adc_version version; unsigned int min_sampling_rate; // Hz unsigned int max_sampling_rate; // Hz - unsigned int vref_voltage; // mV bool wait_init_sequence; + unsigned int num_channels; }; struct aspeed_adc_data { @@ -70,6 +76,7 @@ struct aspeed_adc_data { struct clk_hw *clk_prescaler; struct clk_hw *clk_scaler; struct reset_control *rst; + int vref; }; #define ASPEED_CHAN(_idx, _data_reg_addr) { \ @@ -106,8 +113,6 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { struct aspeed_adc_data *data = iio_priv(indio_dev); - const struct aspeed_adc_model_data *model_data = - of_device_get_match_data(data->dev); switch (mask) { case IIO_CHAN_INFO_RAW: @@ -115,7 +120,7 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - *val = model_data->vref_voltage; + *val = data->vref; *val2 = ASPEED_RESOLUTION_BITS; return IIO_VAL_FRACTIONAL_LOG2; @@ -182,6 +187,55 @@ static const struct iio_info aspeed_adc_iio_info = { .debugfs_reg_access = aspeed_adc_reg_access, }; +static int aspeed_adc_vref_config(struct platform_device *pdev) +{ + const struct aspeed_adc_model_data *model_data; + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct aspeed_adc_data *data = iio_priv(indio_dev); + int vref; + u32 adc_engine_control_reg_val = + readl(data->base + ASPEED_REG_ENGINE_CONTROL); + + model_data = of_device_get_match_data(&pdev->dev); + switch (model_data->version) { + case aspeed_adc_ast2400: + vref = 2500; + break; + case aspeed_adc_ast2500: + vref = 1800; + break; + case aspeed_adc_ast2600: + if (of_property_read_u32(pdev->dev.of_node, "vref", &vref)) + vref = 2500; + if (vref == 2500) + writel(adc_engine_control_reg_val | + ASPEED_ADC_REF_VOLTAGE_2500mV, + data->base + ASPEED_REG_ENGINE_CONTROL); + else if (vref == 1200) + writel(adc_engine_control_reg_val | + ASPEED_ADC_REF_VOLTAGE_1200mV, + data->base + ASPEED_REG_ENGINE_CONTROL); + else if ((vref >= 1550) && (vref <= 2700)) + writel(adc_engine_control_reg_val | + ASPEED_ADC_REF_VOLTAGE_EXT_HIGH, + data->base + ASPEED_REG_ENGINE_CONTROL); + else if ((vref >= 900) && (vref <= 1650)) + writel(adc_engine_control_reg_val | + ASPEED_ADC_REF_VOLTAGE_EXT_LOW, + data->base + ASPEED_REG_ENGINE_CONTROL); + else { + dev_err(&pdev->dev, "Vref not support"); + return -EOPNOTSUPP; + } + break; + default: + dev_err(&pdev->dev, "ADC version not recognized"); + return -EOPNOTSUPP; + } + data->vref = vref; + return 0; +} + static int aspeed_adc_probe(struct platform_device *pdev) { struct iio_dev *indio_dev; @@ -190,13 +244,16 @@ static int aspeed_adc_probe(struct platform_device *pdev) const char *clk_parent_name; int ret; u32 adc_engine_control_reg_val; + char scaler_clk_name[32]; + model_data = of_device_get_match_data(&pdev->dev); indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; data = iio_priv(indio_dev); data->dev = &pdev->dev; + dev_set_drvdata(data->dev, indio_dev); data->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(data->base)) @@ -205,29 +262,39 @@ static int aspeed_adc_probe(struct platform_device *pdev) /* Register ADC clock prescaler with source specified by device tree. */ spin_lock_init(&data->clk_lock); clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0); + if (model_data->version <= aspeed_adc_ast2500) { + data->clk_prescaler = clk_hw_register_divider( + &pdev->dev, "prescaler", clk_parent_name, 0, + data->base + ASPEED_REG_CLOCK_CONTROL, + 17, 15, 0, &data->clk_lock); + if (IS_ERR(data->clk_prescaler)) + return PTR_ERR(data->clk_prescaler); - data->clk_prescaler = clk_hw_register_divider( - &pdev->dev, "prescaler", clk_parent_name, 0, - data->base + ASPEED_REG_CLOCK_CONTROL, - 17, 15, 0, &data->clk_lock); - if (IS_ERR(data->clk_prescaler)) - return PTR_ERR(data->clk_prescaler); - - /* - * Register ADC clock scaler downstream from the prescaler. Allow rate - * setting to adjust the prescaler as well. - */ - data->clk_scaler = clk_hw_register_divider( - &pdev->dev, "scaler", "prescaler", - CLK_SET_RATE_PARENT, - data->base + ASPEED_REG_CLOCK_CONTROL, - 0, 10, 0, &data->clk_lock); - if (IS_ERR(data->clk_scaler)) { - ret = PTR_ERR(data->clk_scaler); - goto scaler_error; + /* + * Register ADC clock scaler downstream from the prescaler. Allow rate + * setting to adjust the prescaler as well. + */ + data->clk_scaler = clk_hw_register_divider( + &pdev->dev, "scaler", "prescaler", + CLK_SET_RATE_PARENT, + data->base + ASPEED_REG_CLOCK_CONTROL, + 0, 10, 0, &data->clk_lock); + if (IS_ERR(data->clk_scaler)) { + ret = PTR_ERR(data->clk_scaler); + goto scaler_error; + } + } else { + snprintf(scaler_clk_name, sizeof(scaler_clk_name), "scaler-%s", + pdev->name); + data->clk_scaler = clk_hw_register_divider( + &pdev->dev, scaler_clk_name, clk_parent_name, 0, + data->base + ASPEED_REG_CLOCK_CONTROL, 0, 16, 0, + &data->clk_lock); + if (IS_ERR(data->clk_scaler)) + return PTR_ERR(data->clk_scaler); } - data->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); + data->rst = devm_reset_control_get_shared(&pdev->dev, NULL); if (IS_ERR(data->rst)) { dev_err(&pdev->dev, "invalid or missing reset controller device tree entry"); @@ -236,8 +303,6 @@ static int aspeed_adc_probe(struct platform_device *pdev) } reset_control_deassert(data->rst); - model_data = of_device_get_match_data(&pdev->dev); - if (model_data->wait_init_sequence) { /* Enable engine in normal mode. */ writel(ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE, @@ -254,22 +319,26 @@ static int aspeed_adc_probe(struct platform_device *pdev) goto poll_timeout_error; } - /* Start all channels in normal mode. */ + ret = aspeed_adc_vref_config(pdev); + if (ret) + goto vref_config_error; ret = clk_prepare_enable(data->clk_scaler->clk); if (ret) goto clk_enable_error; - - adc_engine_control_reg_val = GENMASK(31, 16) | - ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE; + adc_engine_control_reg_val = + readl(data->base + ASPEED_REG_ENGINE_CONTROL); + /* Start all channels in normal mode. */ + adc_engine_control_reg_val |= ASPEED_ADC_CTRL_CHANNEL | + ASPEED_ADC_OPERATION_MODE_NORMAL | + ASPEED_ADC_ENGINE_ENABLE; writel(adc_engine_control_reg_val, data->base + ASPEED_REG_ENGINE_CONTROL); - model_data = of_device_get_match_data(&pdev->dev); - indio_dev->name = model_data->model_name; + indio_dev->name = dev_name(&pdev->dev); indio_dev->info = &aspeed_adc_iio_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = aspeed_adc_iio_channels; - indio_dev->num_channels = ARRAY_SIZE(aspeed_adc_iio_channels); + indio_dev->num_channels = model_data->num_channels; ret = iio_device_register(indio_dev); if (ret) @@ -281,13 +350,15 @@ static int aspeed_adc_probe(struct platform_device *pdev) writel(ASPEED_ADC_OPERATION_MODE_POWER_DOWN, data->base + ASPEED_REG_ENGINE_CONTROL); clk_disable_unprepare(data->clk_scaler->clk); +vref_config_error: clk_enable_error: poll_timeout_error: reset_control_assert(data->rst); reset_error: clk_hw_unregister_divider(data->clk_scaler); scaler_error: - clk_hw_unregister_divider(data->clk_prescaler); + if (model_data->version <= aspeed_adc_ast2500) + clk_hw_unregister_divider(data->clk_prescaler); return ret; } @@ -295,36 +366,48 @@ static int aspeed_adc_remove(struct platform_device *pdev) { struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct aspeed_adc_data *data = iio_priv(indio_dev); + const struct aspeed_adc_model_data *model_data; + model_data = of_device_get_match_data(&pdev->dev); iio_device_unregister(indio_dev); writel(ASPEED_ADC_OPERATION_MODE_POWER_DOWN, data->base + ASPEED_REG_ENGINE_CONTROL); clk_disable_unprepare(data->clk_scaler->clk); reset_control_assert(data->rst); clk_hw_unregister_divider(data->clk_scaler); - clk_hw_unregister_divider(data->clk_prescaler); + if (model_data->version <= aspeed_adc_ast2500) + clk_hw_unregister_divider(data->clk_prescaler); return 0; } static const struct aspeed_adc_model_data ast2400_model_data = { - .model_name = "ast2400-adc", - .vref_voltage = 2500, // mV + .version = aspeed_adc_ast2400, .min_sampling_rate = 10000, .max_sampling_rate = 500000, + .num_channels = 16, }; static const struct aspeed_adc_model_data ast2500_model_data = { - .model_name = "ast2500-adc", - .vref_voltage = 1800, // mV - .min_sampling_rate = 1, - .max_sampling_rate = 1000000, + .version = aspeed_adc_ast2500, + .min_sampling_rate = 10000, + .max_sampling_rate = 500000, + .wait_init_sequence = true, + .num_channels = 16, +}; + +static const struct aspeed_adc_model_data ast2600_model_data = { + .version = aspeed_adc_ast2600, + .min_sampling_rate = 10000, + .max_sampling_rate = 500000, .wait_init_sequence = true, + .num_channels = 8, }; static const struct of_device_id aspeed_adc_matches[] = { { .compatible = "aspeed,ast2400-adc", .data = &ast2400_model_data }, { .compatible = "aspeed,ast2500-adc", .data = &ast2500_model_data }, + { .compatible = "aspeed,ast2600-adc", .data = &ast2600_model_data }, {}, }; MODULE_DEVICE_TABLE(of, aspeed_adc_matches); @@ -341,5 +424,5 @@ static struct platform_driver aspeed_adc_driver = { module_platform_driver(aspeed_adc_driver); MODULE_AUTHOR("Rick Altherr "); -MODULE_DESCRIPTION("Aspeed AST2400/2500 ADC Driver"); +MODULE_DESCRIPTION("Aspeed AST2400/2500/2600 ADC Driver"); MODULE_LICENSE("GPL"); From patchwork Mon Jul 19 08:06:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12385063 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B792DC12002 for ; Mon, 19 Jul 2021 09:02:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9622F611C2 for ; Mon, 19 Jul 2021 09:02:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235471AbhGSIVo (ORCPT ); Mon, 19 Jul 2021 04:21:44 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:19043 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234973AbhGSIVo (ORCPT ); Mon, 19 Jul 2021 04:21:44 -0400 Received: from twspam01.aspeedtech.com (localhost [127.0.0.2] (may be forged)) by twspam01.aspeedtech.com with ESMTP id 16J7ojeR015585 for ; Mon, 19 Jul 2021 15:50:45 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16J7nREM015324; Mon, 19 Jul 2021 15:49:27 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from BillyTsai-pc.aspeed.com (192.168.2.149) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 19 Jul 2021 16:05:48 +0800 From: Billy Tsai To: , , , , , , , , , , , , CC: Subject: [v1 5/7] iio: adc: aspeed: Add func to set sampling rate. Date: Mon, 19 Jul 2021 16:06:05 +0800 Message-ID: <20210719080607.28712-6-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210719080607.28712-1-billy_tsai@aspeedtech.com> References: <20210719080607.28712-1-billy_tsai@aspeedtech.com> MIME-Version: 1.0 X-Originating-IP: [192.168.2.149] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 16J7nREM015324 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org 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 --- drivers/iio/adc/aspeed_adc.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index 6a77ac4e7dcb..b33ff9f0a3af 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -55,6 +55,7 @@ #define ASPEED_ADC_INIT_POLLING_TIME 500 #define ASPEED_ADC_INIT_TIMEOUT 500000 +#define ASPEED_ADC_DEF_SAMPLING_RATE 250000 enum aspeed_adc_version { aspeed_adc_ast2400, @@ -77,6 +78,7 @@ struct aspeed_adc_data { struct clk_hw *clk_scaler; struct reset_control *rst; int vref; + u32 sample_period_ns; }; #define ASPEED_CHAN(_idx, _data_reg_addr) { \ @@ -108,6 +110,26 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = { ASPEED_CHAN(15, 0x2E), }; +static int aspeed_adc_set_sampling_rate(struct iio_dev *indio_dev, u32 rate) +{ + struct aspeed_adc_data *data = iio_priv(indio_dev); + const struct aspeed_adc_model_data *model_data = + of_device_get_match_data(data->dev); + + if (rate < model_data->min_sampling_rate || + rate > model_data->max_sampling_rate) + return -EINVAL; + /* Each sampling needs 12 clocks to covert.*/ + clk_set_rate(data->clk_scaler->clk, rate * ASPEED_CLOCKS_PER_SAMPLE); + + rate = clk_get_rate(data->clk_scaler->clk); + data->sample_period_ns = DIV_ROUND_UP_ULL( + (u64)NSEC_PER_SEC * ASPEED_CLOCKS_PER_SAMPLE, rate); + dev_dbg(data->dev, "Adc clock = %d sample period = %d ns", rate, + data->sample_period_ns); + return 0; +} + static int aspeed_adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -138,19 +160,9 @@ static int aspeed_adc_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { - struct aspeed_adc_data *data = iio_priv(indio_dev); - const struct aspeed_adc_model_data *model_data = - of_device_get_match_data(data->dev); - switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: - if (val < model_data->min_sampling_rate || - val > model_data->max_sampling_rate) - return -EINVAL; - - clk_set_rate(data->clk_scaler->clk, - val * ASPEED_CLOCKS_PER_SAMPLE); - return 0; + return aspeed_adc_set_sampling_rate(indio_dev, val); case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_RAW: @@ -325,6 +337,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) ret = clk_prepare_enable(data->clk_scaler->clk); if (ret) goto clk_enable_error; + aspeed_adc_set_sampling_rate(indio_dev, ASPEED_ADC_DEF_SAMPLING_RATE); adc_engine_control_reg_val = readl(data->base + ASPEED_REG_ENGINE_CONTROL); /* Start all channels in normal mode. */ From patchwork Mon Jul 19 08:06:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12385069 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B8CEFC636C9 for ; Mon, 19 Jul 2021 09:02:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9AE826100C for ; Mon, 19 Jul 2021 09:02:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235382AbhGSIVt (ORCPT ); Mon, 19 Jul 2021 04:21:49 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:19376 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235374AbhGSIVt (ORCPT ); Mon, 19 Jul 2021 04:21:49 -0400 Received: from twspam01.aspeedtech.com (localhost [127.0.0.2] (may be forged)) by twspam01.aspeedtech.com with ESMTP id 16J7otGD015590 for ; Mon, 19 Jul 2021 15:50:55 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16J7nRHu015325; Mon, 19 Jul 2021 15:49:27 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from BillyTsai-pc.aspeed.com (192.168.2.149) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 19 Jul 2021 16:05:49 +0800 From: Billy Tsai To: , , , , , , , , , , , , CC: Subject: [v1 6/7] iio: adc: aspeed: Add compensation phase. Date: Mon, 19 Jul 2021 16:06:06 +0800 Message-ID: <20210719080607.28712-7-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210719080607.28712-1-billy_tsai@aspeedtech.com> References: <20210719080607.28712-1-billy_tsai@aspeedtech.com> MIME-Version: 1.0 X-Originating-IP: [192.168.2.149] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 16J7nRHu015325 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch adds a compensation phase to improve the accurate of adc measurement. This is the builtin function though input half of the reference voltage to get the adc offset. Signed-off-by: Billy Tsai --- drivers/iio/adc/aspeed_adc.c | 51 +++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index b33ff9f0a3af..b0d7a58cb7f5 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -56,6 +56,7 @@ #define ASPEED_ADC_INIT_POLLING_TIME 500 #define ASPEED_ADC_INIT_TIMEOUT 500000 #define ASPEED_ADC_DEF_SAMPLING_RATE 250000 +#define ASPEED_ADC_MAX_RAW_DATA GENMASK(9, 0) enum aspeed_adc_version { aspeed_adc_ast2400, @@ -79,6 +80,7 @@ struct aspeed_adc_data { struct reset_control *rst; int vref; u32 sample_period_ns; + int cv; }; #define ASPEED_CHAN(_idx, _data_reg_addr) { \ @@ -110,6 +112,48 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = { ASPEED_CHAN(15, 0x2E), }; +static int aspeed_adc_compensation(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct aspeed_adc_data *data = iio_priv(indio_dev); + u32 index, adc_raw = 0; + u32 adc_engine_control_reg_val = + readl(data->base + ASPEED_REG_ENGINE_CONTROL); + adc_engine_control_reg_val |= + (ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE); + + /* + * Enable compensating sensing: + * After that, the input voltage of adc will force to half of the reference + * voltage. So the expected reading raw data will become half of the max + * value. We can get compensating value = 0x200 - adc read raw value. + * It is recommended to average at least 10 samples to get a final CV. + */ + writel(adc_engine_control_reg_val | ASPEED_ADC_CTRL_COMPENSATION | + ASPEED_ADC_CTRL_CHANNEL_ENABLE(0), + data->base + ASPEED_REG_ENGINE_CONTROL); + /* + * After enable compensating sensing mode need to wait some time for adc stable + * Experiment result is 1ms. + */ + mdelay(1); + + for (index = 0; index < 16; index++) { + /* + * Waiting for the sampling period ensures that the value acquired + * is fresh each time. + */ + ndelay(data->sample_period_ns); + adc_raw += readw(data->base + aspeed_adc_iio_channels[0].address); + } + adc_raw >>= 4; + data->cv = BIT(ASPEED_RESOLUTION_BITS - 1) - adc_raw; + writel(adc_engine_control_reg_val, + data->base + ASPEED_REG_ENGINE_CONTROL); + dev_dbg(data->dev, "compensating value = %d\n", data->cv); + return 0; +} + static int aspeed_adc_set_sampling_rate(struct iio_dev *indio_dev, u32 rate) { struct aspeed_adc_data *data = iio_priv(indio_dev); @@ -138,7 +182,11 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - *val = readw(data->base + chan->address); + *val = readw(data->base + chan->address) + data->cv; + if (*val < 0) + *val = 0; + else if (*val >= ASPEED_ADC_MAX_RAW_DATA) + *val = ASPEED_ADC_MAX_RAW_DATA; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -338,6 +386,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) if (ret) goto clk_enable_error; aspeed_adc_set_sampling_rate(indio_dev, ASPEED_ADC_DEF_SAMPLING_RATE); + aspeed_adc_compensation(pdev); adc_engine_control_reg_val = readl(data->base + ASPEED_REG_ENGINE_CONTROL); /* Start all channels in normal mode. */ From patchwork Mon Jul 19 08:06:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12385067 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4498EC636CB for ; Mon, 19 Jul 2021 09:02:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2C1F5611AF for ; Mon, 19 Jul 2021 09:02:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235459AbhGSIVs (ORCPT ); Mon, 19 Jul 2021 04:21:48 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:51736 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235374AbhGSIVr (ORCPT ); Mon, 19 Jul 2021 04:21:47 -0400 Received: from twspam01.aspeedtech.com (localhost [127.0.0.2] (may be forged)) by twspam01.aspeedtech.com with ESMTP id 16J7otUq015589 for ; Mon, 19 Jul 2021 15:50:55 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16J7nROo015326; Mon, 19 Jul 2021 15:49:27 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from BillyTsai-pc.aspeed.com (192.168.2.149) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 19 Jul 2021 16:05:49 +0800 From: Billy Tsai To: , , , , , , , , , , , , CC: Subject: [v1 7/7] iio: adc: aspeed: Fix the calculate error of clock. Date: Mon, 19 Jul 2021 16:06:07 +0800 Message-ID: <20210719080607.28712-8-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210719080607.28712-1-billy_tsai@aspeedtech.com> References: <20210719080607.28712-1-billy_tsai@aspeedtech.com> MIME-Version: 1.0 X-Originating-IP: [192.168.2.149] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 16J7nROo015326 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org 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 --- drivers/iio/adc/aspeed_adc.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index b0d7a58cb7f5..2b96b57b5a80 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -75,6 +75,7 @@ struct aspeed_adc_data { struct device *dev; void __iomem *base; spinlock_t clk_lock; + struct clk_hw *fixed_div_clk; struct clk_hw *clk_prescaler; struct clk_hw *clk_scaler; struct reset_control *rst; @@ -305,6 +306,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) int ret; u32 adc_engine_control_reg_val; char scaler_clk_name[32]; + char fixed_div_clk_name[32]; model_data = of_device_get_match_data(&pdev->dev); indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data)); @@ -323,10 +325,15 @@ static int aspeed_adc_probe(struct platform_device *pdev) spin_lock_init(&data->clk_lock); clk_parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0); if (model_data->version <= aspeed_adc_ast2500) { + /* ADC clock period = PCLK * 2 * (ADC0C[31:17] + 1) * (ADC0C[9:0] + 1) */ + data->fixed_div_clk = clk_hw_register_fixed_factor( + &pdev->dev, "fixed-div", clk_parent_name, 0, 1, 2); + if (IS_ERR(data->fixed_div_clk)) + return PTR_ERR(data->fixed_div_clk); data->clk_prescaler = clk_hw_register_divider( - &pdev->dev, "prescaler", clk_parent_name, 0, - data->base + ASPEED_REG_CLOCK_CONTROL, - 17, 15, 0, &data->clk_lock); + &pdev->dev, "prescaler", "fixed-div", 0, + data->base + ASPEED_REG_CLOCK_CONTROL, 17, 15, 0, + &data->clk_lock); if (IS_ERR(data->clk_prescaler)) return PTR_ERR(data->clk_prescaler); @@ -344,14 +351,23 @@ static int aspeed_adc_probe(struct platform_device *pdev) goto scaler_error; } } else { + /* ADC clock period = period of PCLK * 2 * (ADC0C[15:0] + 1) */ + snprintf(fixed_div_clk_name, sizeof(fixed_div_clk_name), "fixed-div-%s", + pdev->name); + data->fixed_div_clk = clk_hw_register_fixed_factor( + &pdev->dev, fixed_div_clk_name, clk_parent_name, 0, 1, 2); + if (IS_ERR(data->fixed_div_clk)) + return PTR_ERR(data->fixed_div_clk); snprintf(scaler_clk_name, sizeof(scaler_clk_name), "scaler-%s", pdev->name); data->clk_scaler = clk_hw_register_divider( &pdev->dev, scaler_clk_name, clk_parent_name, 0, data->base + ASPEED_REG_CLOCK_CONTROL, 0, 16, 0, &data->clk_lock); - if (IS_ERR(data->clk_scaler)) - return PTR_ERR(data->clk_scaler); + if (IS_ERR(data->clk_scaler)) { + ret = PTR_ERR(data->clk_scaler); + goto scaler_error; + } } data->rst = devm_reset_control_get_shared(&pdev->dev, NULL); @@ -421,6 +437,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) scaler_error: if (model_data->version <= aspeed_adc_ast2500) clk_hw_unregister_divider(data->clk_prescaler); + clk_hw_unregister_fixed_factor(data->fixed_div_clk); return ret; } @@ -439,6 +456,7 @@ static int aspeed_adc_remove(struct platform_device *pdev) clk_hw_unregister_divider(data->clk_scaler); if (model_data->version <= aspeed_adc_ast2500) clk_hw_unregister_divider(data->clk_prescaler); + clk_hw_unregister_fixed_factor(data->fixed_div_clk); return 0; }