From patchwork Fri Jul 23 08:16:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12395497 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,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham 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 10E8FC4338F for ; Fri, 23 Jul 2021 08:15:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ED21460F02 for ; Fri, 23 Jul 2021 08:15:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234351AbhGWHfO (ORCPT ); Fri, 23 Jul 2021 03:35:14 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:29928 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234348AbhGWHfO (ORCPT ); Fri, 23 Jul 2021 03:35:14 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16N7x5V1041949; Fri, 23 Jul 2021 15:59:05 +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; Fri, 23 Jul 2021 16:15:39 +0800 From: Billy Tsai To: , , , , , , , , , , , CC: Subject: [v2 1/8] dt-bindings: iio: adc: rename the aspeed adc yaml Date: Fri, 23 Jul 2021 16:16:14 +0800 Message-ID: <20210723081621.29477-2-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210723081621.29477-1-billy_tsai@aspeedtech.com> References: <20210723081621.29477-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 16N7x5V1041949 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 --- .../iio/adc/{aspeed,ast2400-adc.yaml => aspeed,adc.yaml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Documentation/devicetree/bindings/iio/adc/{aspeed,ast2400-adc.yaml => aspeed,adc.yaml} (93%) diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml similarity index 93% rename from Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml rename to Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml index 7f534a933e92..23f3da1ffca3 100644 --- a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) %YAML 1.2 --- -$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2400-adc.yaml# +$id: http://devicetree.org/schemas/iio/adc/aspeed,adc.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# title: ADC that forms part of an ASPEED server management processor. From patchwork Fri Jul 23 08:16:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12395499 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,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham 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 09926C4338F for ; Fri, 23 Jul 2021 08:15:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E292460F12 for ; Fri, 23 Jul 2021 08:15:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234311AbhGWHfS (ORCPT ); Fri, 23 Jul 2021 03:35:18 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:29933 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234348AbhGWHfS (ORCPT ); Fri, 23 Jul 2021 03:35:18 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16N7x5V2041949; Fri, 23 Jul 2021 15:59:05 +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; Fri, 23 Jul 2021 16:15:39 +0800 From: Billy Tsai To: , , , , , , , , , , , CC: Subject: [v2 2/8] dt-bindings: iio: adc: Binding ast2600 adc. Date: Fri, 23 Jul 2021 16:16:15 +0800 Message-ID: <20210723081621.29477-3-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210723081621.29477-1-billy_tsai@aspeedtech.com> References: <20210723081621.29477-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 16N7x5V2041949 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org This patch add more description about aspeed adc and add two property for ast2600: - vref: used to configure reference voltage. - battery-sensing: used to enable battery sensing mode for last channel. Signed-off-by: Billy Tsai --- .../bindings/iio/adc/aspeed,adc.yaml | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,adc.yaml index 23f3da1ffca3..a562a7fbc30c 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,18 @@ properties: "#io-channel-cells": const: 1 + vref: + minItems: 900 + maxItems: 2700 + default: 2500 + description: + ADC Reference voltage in millivolts. + + battery-sensing: + type: boolean + description: + Inform the driver that last channel will be used to sensor battery. + required: - compatible - reg From patchwork Fri Jul 23 08:16:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12395509 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,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham 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 3B7CBC4338F for ; Fri, 23 Jul 2021 08:16:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 26F8860E8E for ; Fri, 23 Jul 2021 08:16:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234361AbhGWHfp (ORCPT ); Fri, 23 Jul 2021 03:35:45 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:29983 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234328AbhGWHfn (ORCPT ); Fri, 23 Jul 2021 03:35:43 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16N7x6Rc041950; Fri, 23 Jul 2021 15:59:06 +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; Fri, 23 Jul 2021 16:15:40 +0800 From: Billy Tsai To: , , , , , , , , , , , CC: Subject: [v2 3/8] iio: adc: aspeed: completes the bitfield declare. Date: Fri, 23 Jul 2021 16:16:16 +0800 Message-ID: <20210723081621.29477-4-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210723081621.29477-1-billy_tsai@aspeedtech.com> References: <20210723081621.29477-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 16N7x6Rc041950 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 Fri Jul 23 08:16:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12395507 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, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham 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 A95DBC4338F for ; Fri, 23 Jul 2021 08:16:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 91BFF60EBD for ; Fri, 23 Jul 2021 08:16:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234263AbhGWHfi (ORCPT ); Fri, 23 Jul 2021 03:35:38 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:29972 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234361AbhGWHfi (ORCPT ); Fri, 23 Jul 2021 03:35:38 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16N7x6St041951; Fri, 23 Jul 2021 15:59:06 +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; Fri, 23 Jul 2021 16:15:40 +0800 From: Billy Tsai To: , , , , , , , , , , , CC: Subject: [v2 4/8] iio: adc: aspeed: Allow driver to support ast2600 Date: Fri, 23 Jul 2021 16:16:17 +0800 Message-ID: <20210723081621.29477-5-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210723081621.29477-1-billy_tsai@aspeedtech.com> References: <20210723081621.29477-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 16N7x6St041951 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 | 176 ++++++++++++++++++++++++++--------- 1 file changed, 132 insertions(+), 44 deletions(-) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index 99466a5924c7..84f079195375 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,11 +303,17 @@ static int aspeed_adc_probe(struct platform_device *pdev) } reset_control_deassert(data->rst); - model_data = of_device_get_match_data(&pdev->dev); + ret = aspeed_adc_vref_config(pdev); + if (ret) + goto vref_config_error; if (model_data->wait_init_sequence) { + adc_engine_control_reg_val = + readl(data->base + ASPEED_REG_ENGINE_CONTROL); /* Enable engine in normal mode. */ - writel(ASPEED_ADC_OPERATION_MODE_NORMAL | ASPEED_ADC_ENGINE_ENABLE, + writel(adc_engine_control_reg_val | + ASPEED_ADC_OPERATION_MODE_NORMAL | + ASPEED_ADC_ENGINE_ENABLE, data->base + ASPEED_REG_ENGINE_CONTROL); /* Wait for initial sequence complete. */ @@ -254,22 +327,23 @@ static int aspeed_adc_probe(struct platform_device *pdev) goto poll_timeout_error; } - /* Start all channels in normal mode. */ 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 +355,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 +371,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 +429,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 Fri Jul 23 08:16:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12395503 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,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham 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 4A136C4338F for ; Fri, 23 Jul 2021 08:16:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2DA4260E8E for ; Fri, 23 Jul 2021 08:16:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234030AbhGWHf2 (ORCPT ); Fri, 23 Jul 2021 03:35:28 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:29947 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234348AbhGWHf2 (ORCPT ); Fri, 23 Jul 2021 03:35:28 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16N7x6Su041951; Fri, 23 Jul 2021 15:59:06 +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; Fri, 23 Jul 2021 16:15:40 +0800 From: Billy Tsai To: , , , , , , , , , , , CC: Subject: [v2 5/8] iio: adc: aspeed: Add func to set sampling rate. Date: Fri, 23 Jul 2021 16:16:18 +0800 Message-ID: <20210723081621.29477-6-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210723081621.29477-1-billy_tsai@aspeedtech.com> References: <20210723081621.29477-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 16N7x6Su041951 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 | 48 +++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index 84f079195375..bb6100228cae 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -55,6 +55,12 @@ #define ASPEED_ADC_INIT_POLLING_TIME 500 #define ASPEED_ADC_INIT_TIMEOUT 500000 +/* + * When the sampling rate is too high, the ADC may not have enough charging + * time, resulting in a low voltage value. Thus, default use slow sampling + * rate for most user case. + */ +#define ASPEED_ADC_DEF_SAMPLING_RATE 65000 enum aspeed_adc_version { aspeed_adc_ast2400, @@ -77,6 +83,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 +115,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 +165,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: @@ -302,6 +319,10 @@ static int aspeed_adc_probe(struct platform_device *pdev) goto reset_error; } reset_control_deassert(data->rst); + 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); ret = aspeed_adc_vref_config(pdev); if (ret) @@ -327,9 +348,6 @@ static int aspeed_adc_probe(struct platform_device *pdev) goto poll_timeout_error; } - ret = clk_prepare_enable(data->clk_scaler->clk); - if (ret) - goto clk_enable_error; adc_engine_control_reg_val = readl(data->base + ASPEED_REG_ENGINE_CONTROL); /* Start all channels in normal mode. */ @@ -354,8 +372,8 @@ static int aspeed_adc_probe(struct platform_device *pdev) iio_register_error: writel(ASPEED_ADC_OPERATION_MODE_POWER_DOWN, data->base + ASPEED_REG_ENGINE_CONTROL); - clk_disable_unprepare(data->clk_scaler->clk); vref_config_error: + clk_disable_unprepare(data->clk_scaler->clk); clk_enable_error: poll_timeout_error: reset_control_assert(data->rst); From patchwork Fri Jul 23 08:16:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12395505 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,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham 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 3E077C4338F for ; Fri, 23 Jul 2021 08:16:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 269FA60E8E for ; Fri, 23 Jul 2021 08:16:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234348AbhGWHfd (ORCPT ); Fri, 23 Jul 2021 03:35:33 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:29960 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234354AbhGWHfd (ORCPT ); Fri, 23 Jul 2021 03:35:33 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16N7x6Sv041951; Fri, 23 Jul 2021 15:59:06 +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; Fri, 23 Jul 2021 16:15:40 +0800 From: Billy Tsai To: , , , , , , , , , , , CC: Subject: [v2 6/8] iio: adc: aspeed: Add compensation phase. Date: Fri, 23 Jul 2021 16:16:19 +0800 Message-ID: <20210723081621.29477-7-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210723081621.29477-1-billy_tsai@aspeedtech.com> References: <20210723081621.29477-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 16N7x6Sv041951 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 | 52 ++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index bb6100228cae..0153b28b83b7 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -61,6 +61,7 @@ * rate for most user case. */ #define ASPEED_ADC_DEF_SAMPLING_RATE 65000 +#define ASPEED_ADC_MAX_RAW_DATA GENMASK(9, 0) enum aspeed_adc_version { aspeed_adc_ast2400, @@ -84,6 +85,7 @@ struct aspeed_adc_data { struct reset_control *rst; int vref; u32 sample_period_ns; + int cv; }; #define ASPEED_CHAN(_idx, _data_reg_addr) { \ @@ -115,6 +117,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); @@ -143,7 +187,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: @@ -347,7 +395,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) if (ret) goto poll_timeout_error; } - + aspeed_adc_compensation(pdev); adc_engine_control_reg_val = readl(data->base + ASPEED_REG_ENGINE_CONTROL); /* Start all channels in normal mode. */ From patchwork Fri Jul 23 08:16:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12395511 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, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham 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 2D512C4338F for ; Fri, 23 Jul 2021 08:16:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 125C560EBD for ; Fri, 23 Jul 2021 08:16:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234300AbhGWHft (ORCPT ); Fri, 23 Jul 2021 03:35:49 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:29994 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234313AbhGWHfs (ORCPT ); Fri, 23 Jul 2021 03:35:48 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16N7x6Wf041952; Fri, 23 Jul 2021 15:59:06 +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; Fri, 23 Jul 2021 16:15:41 +0800 From: Billy Tsai To: , , , , , , , , , , , CC: Subject: [v2 7/8] iio: adc: aspeed: Fix the calculate error of clock. Date: Fri, 23 Jul 2021 16:16:20 +0800 Message-ID: <20210723081621.29477-8-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210723081621.29477-1-billy_tsai@aspeedtech.com> References: <20210723081621.29477-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 16N7x6Wf041952 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 0153b28b83b7..7e674b607e36 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -80,6 +80,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; @@ -310,6 +311,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)); @@ -328,10 +330,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); @@ -349,14 +356,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); @@ -430,6 +446,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; } @@ -448,6 +465,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; } From patchwork Fri Jul 23 08:16:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Billy Tsai X-Patchwork-Id: 12395513 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, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham 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 BE05FC4338F for ; Fri, 23 Jul 2021 08:16:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A92F260F02 for ; Fri, 23 Jul 2021 08:16:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234313AbhGWHfy (ORCPT ); Fri, 23 Jul 2021 03:35:54 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:30010 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234307AbhGWHfx (ORCPT ); Fri, 23 Jul 2021 03:35:53 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 16N7x7uR041953; Fri, 23 Jul 2021 15:59:07 +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; Fri, 23 Jul 2021 16:15:41 +0800 From: Billy Tsai To: , , , , , , , , , , , CC: Subject: [v2 8/8] iio: adc: aspeed: Support battery sensing. Date: Fri, 23 Jul 2021 16:16:21 +0800 Message-ID: <20210723081621.29477-9-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210723081621.29477-1-billy_tsai@aspeedtech.com> References: <20210723081621.29477-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 16N7x7uR041953 Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org 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 --- drivers/iio/adc/aspeed_adc.c | 60 +++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index 7e674b607e36..6c7e2bb7b1ac 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -45,6 +45,9 @@ #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_BATTERY_SENSING_DIV BIT(6) +#define ASPEED_ADC_BATTERY_SENSING_DIV_2_3 FIELD_PREP(ASPEED_ADC_BATTERY_SENSING_DIV, 0) +#define ASPEED_ADC_BATTERY_SENSING_DIV_1_3 FIELD_PREP(ASPEED_ADC_BATTERY_SENSING_DIV, 1) #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) @@ -76,6 +79,11 @@ struct aspeed_adc_model_data { unsigned int num_channels; }; +struct adc_gain { + u8 mult; + u8 div; +}; + struct aspeed_adc_data { struct device *dev; void __iomem *base; @@ -87,6 +95,8 @@ struct aspeed_adc_data { int vref; u32 sample_period_ns; int cv; + bool battery_sensing; + struct adc_gain battery_mode_gain; }; #define ASPEED_CHAN(_idx, _data_reg_addr) { \ @@ -185,14 +195,38 @@ 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); + u32 adc_engine_control_reg_val; switch (mask) { case IIO_CHAN_INFO_RAW: - *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; + 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 | + ASPEED_ADC_CH7_BATTERY | + ASPEED_ADC_BATTERY_SENSING_ENABLE, + data->base + ASPEED_REG_ENGINE_CONTROL); + /* + * After enable battery sensing mode need to wait some time for adc stable + * Experiment result is 1ms. + */ + mdelay(1); + *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; + *val = (*val * data->battery_mode_gain.mult) / + data->battery_mode_gain.div; + writel(adc_engine_control_reg_val, + data->base + ASPEED_REG_ENGINE_CONTROL); + } else { + *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: @@ -392,6 +426,22 @@ static int aspeed_adc_probe(struct platform_device *pdev) if (ret) goto vref_config_error; + if (of_find_property(data->dev->of_node, "battery-sensing", NULL)) { + if (model_data->version >= aspeed_adc_ast2600) { + data->battery_sensing = 1; + if (readl(data->base + ASPEED_REG_ENGINE_CONTROL) & + ASPEED_ADC_BATTERY_SENSING_DIV_1_3) { + 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 (model_data->wait_init_sequence) { adc_engine_control_reg_val = readl(data->base + ASPEED_REG_ENGINE_CONTROL);