Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp262773pxb; Wed, 22 Sep 2021 01:21:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyMEEYDC9oYJiTCjvx6rqIoa134JzXETF6MsQfo3HQUa10h7Y63EHDI+aYXeyvYS8RZI1fV X-Received: by 2002:a50:cd06:: with SMTP id z6mr40741099edi.12.1632298890440; Wed, 22 Sep 2021 01:21:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632298890; cv=none; d=google.com; s=arc-20160816; b=h15zgoGbHpBRtd3uT5FdqI8qfVGg+m0HJmM4WEbSQEEXxcFIqCnZ65rLV4h3/nDbVg MFmU7jgHTpk0JQB8k2OoTpA1zKwOEV5l/AXCQ+M4pFB9E6CAHzMmNPUjuxWQn0sJT6eQ M1VRs+bSNiN1zAznVxotVKVmgvpt9BnG4vPI3pVjMxPEYHZTJZBRfY4dYgqZuJ42X/B/ 0Kw7o5FqDqzCvnip84dTC5L6O9cRKuF+OSPWinXAUskzMsLIpPNson1GdpHTmHxb7GRN MifhWpg/rhZnqOjAN2DBjlkD9uYN68Wnewq8yqvel7wcsvu9l+xK1duXH/iut4IIRNLP WtAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=N+O3buaUMnLAZw3MqWLwkSkMZgUAL4BwKw3yiiMc+Po=; b=OXFbHEBIYo4LFQgDwmkQ+ofFqMut8UsO7LJKU6jy3uYB0Abje+wRyPh+D8VrulBwcn DhR0Kew3vRl+o1EWPEnRf0NY2tsWcH7jcKrbXfblGjaK18Oxqe82jRcxH87aFr8BqVs9 7tnlxnvkD+rzTgSADgYtmrF1/TmVYsT8Ke5p7mdrDyu9QKg6tsYu6BOP1gc5Bwg6zO7a wyLEEnt2NeeV6UinL5wqTom1KORNu2Dg6QTIpwpeX6H32CrZpJaHZ+VUqF7eBjsw/VJ0 Zj1St+btSWM1yLTh55rsqxpqyUOPX30RZQsKjIA19Ydj92tleQDl9qDuwhYCXzZ7T8bR Xa5Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id x15si1989243ede.404.2021.09.22.01.21.04; Wed, 22 Sep 2021 01:21:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233866AbhIVITA (ORCPT + 99 others); Wed, 22 Sep 2021 04:19:00 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:14784 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233470AbhIVISx (ORCPT ); Wed, 22 Sep 2021 04:18:53 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 18M7sdQ0099805; Wed, 22 Sep 2021 15:54:39 +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; Wed, 22 Sep 2021 16:14:57 +0800 From: Billy Tsai To: , , , , , , , , , , , , , CC: Subject: [v7 11/11] iio: adc: aspeed: Get and set trimming data. Date: Wed, 22 Sep 2021 16:15:20 +0800 Message-ID: <20210922081520.30580-12-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210922081520.30580-1-billy_tsai@aspeedtech.com> References: <20210922081520.30580-1-billy_tsai@aspeedtech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII 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 18M7sdQ0099805 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The ADC controller has a trimming register for fine-tune the reference voltage. The trimming value comes from the OTP register which will be written during chip production. This patch will read this OTP value and configure it to the ADC register when the ADC controller probes and using dts property "aspeed,trim-data-valid" to determine whether to execute this flow. Signed-off-by: Billy Tsai --- drivers/iio/adc/aspeed_adc.c | 71 ++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index e22c59f6c3d0..c7e15c0c1951 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include @@ -80,6 +82,11 @@ */ #define ASPEED_ADC_DEF_SAMPLING_RATE 65000 +struct aspeed_adc_trim_locate { + const unsigned int offset; + const unsigned int field; +}; + struct aspeed_adc_model_data { const char *model_name; unsigned int min_sampling_rate; // Hz @@ -90,6 +97,7 @@ struct aspeed_adc_model_data { bool bat_sense_sup; u8 scaler_bit_width; unsigned int num_channels; + const struct aspeed_adc_trim_locate *trim_locate; }; struct adc_gain { @@ -165,6 +173,44 @@ static const struct iio_chan_spec aspeed_adc_iio_bat_channels[] = { ASPEED_BAT_CHAN(7, 0x1E), }; +static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev) +{ + struct device_node *syscon; + struct regmap *scu; + u32 scu_otp, trimming_val; + struct aspeed_adc_data *data = iio_priv(indio_dev); + + syscon = of_find_node_by_name(NULL, "syscon"); + if (syscon == NULL) { + dev_warn(data->dev, "Couldn't find syscon node\n"); + return -EOPNOTSUPP; + } + scu = syscon_node_to_regmap(syscon); + if (IS_ERR(scu)) { + dev_warn(data->dev, "Failed to get syscon regmap\n"); + return -EOPNOTSUPP; + } + if (data->model_data->trim_locate) { + if (regmap_read(scu, data->model_data->trim_locate->offset, + &scu_otp)) { + dev_warn(data->dev, + "Failed to get adc trimming data\n"); + trimming_val = 0x8; + } else { + trimming_val = + ((scu_otp) & + (data->model_data->trim_locate->field)) >> + __ffs(data->model_data->trim_locate->field); + } + dev_dbg(data->dev, + "trimming val = %d, offset = %08x, fields = %08x\n", + trimming_val, data->model_data->trim_locate->offset, + data->model_data->trim_locate->field); + writel(trimming_val, data->base + ASPEED_REG_COMPENSATION_TRIM); + } + return 0; +} + static int aspeed_adc_compensation(struct iio_dev *indio_dev) { struct aspeed_adc_data *data = iio_priv(indio_dev); @@ -514,6 +560,13 @@ static int aspeed_adc_probe(struct platform_device *pdev) if (ret) return ret; + if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid", + NULL)) { + ret = aspeed_adc_set_trim_data(indio_dev); + if (ret) + return ret; + } + if (of_find_property(data->dev->of_node, "aspeed,battery-sensing", NULL)) { if (data->model_data->bat_sense_sup) { @@ -590,6 +643,21 @@ static int aspeed_adc_probe(struct platform_device *pdev) return ret; } +static const struct aspeed_adc_trim_locate ast2500_adc_trim = { + .offset = 0x154, + .field = GENMASK(31, 28), +}; + +static const struct aspeed_adc_trim_locate ast2600_adc0_trim = { + .offset = 0x5d0, + .field = GENMASK(3, 0), +}; + +static const struct aspeed_adc_trim_locate ast2600_adc1_trim = { + .offset = 0x5d0, + .field = GENMASK(7, 4), +}; + static const struct aspeed_adc_model_data ast2400_model_data = { .model_name = "ast2400-adc", .vref_fixed_mv = 2500, @@ -609,6 +677,7 @@ static const struct aspeed_adc_model_data ast2500_model_data = { .need_prescaler = true, .scaler_bit_width = 10, .num_channels = 16, + .trim_locate = &ast2500_adc_trim, }; static const struct aspeed_adc_model_data ast2600_adc0_model_data = { @@ -619,6 +688,7 @@ static const struct aspeed_adc_model_data ast2600_adc0_model_data = { .bat_sense_sup = true, .scaler_bit_width = 16, .num_channels = 8, + .trim_locate = &ast2600_adc0_trim, }; static const struct aspeed_adc_model_data ast2600_adc1_model_data = { @@ -629,6 +699,7 @@ static const struct aspeed_adc_model_data ast2600_adc1_model_data = { .bat_sense_sup = true, .scaler_bit_width = 16, .num_channels = 8, + .trim_locate = &ast2600_adc1_trim, }; static const struct of_device_id aspeed_adc_matches[] = { -- 2.25.1