Received: by 2002:a05:6a10:6d25:0:0:0:0 with SMTP id gq37csp1596459pxb; Mon, 13 Sep 2021 00:56:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwhOyXcHDizskYRCeWgbwB6T1RSuhaIQP3Cb5+PLmqTGUW6H482pmfPH/Q5HphyC/huRRo1 X-Received: by 2002:a92:2c0d:: with SMTP id t13mr6962858ile.99.1631519781825; Mon, 13 Sep 2021 00:56:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631519781; cv=none; d=google.com; s=arc-20160816; b=haG9sUyz4j3WYW6j02qe8vDmQODyC7xq5xv7eh8NqMA6DES8REvUnl3yMoGzaOtcWj WJDAdJv3IlUyDzDNdT8XKYjNHGWfrrhv46MPzpcs6Hnm+4aC6Vj26d9kHJcC//VJY9RE l/K/UugojUIp57dV4jPkeXDPHIjFR71ImvXMLtMj2fNBqsKl06pAPGCQDE+vLhnDw0H9 56DSGUFLlJfSIxqNBFC0c7KiNVtmvwXjmJpS3VjViGBl7YVhrGFiw1IcNjSBAzz5boJV Gl/r2dvyuWQLwWfijcrzz1GicTBno6kQHIM/GpDWCiEAG8NtHMKMrkEs9KdKUSjFsCXF 6rlg== 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=uuSzpLLDhhSBwwB3Wh3nGeptnhZ1GakkJeTgYEv76/M=; b=hb+YY0Q/mGrZZjPkb1yK8DQB7m84s0PCMCLdoBE/pkuB3n0GAK0+HtP5HK9zJevwGA ogGd9is4c99h60+r11smdWZ7CIyHdwf81awBYabybD3739UDZaugqW94nzGQvJYduJqV BdRccR8vCPQUqJ0D8/Npk2Njx8HkuDsaD/cOk9LXxk0y7Ip6P4atAaILEZuaRCV4vIy4 VHRHkaMojT23vg9xDW1mqrJ5qQA9HfCTaTTHeaRygTvlEThvdja5KfJMsqqWcmIvZ9H2 CijpykaGVYeN+qosH6QABZtiu0JnIwJ1q3mrHZvapcd6/5ncmdh5eql0KPnwjuuHBXQX fAWQ== 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 a9si5728525ila.32.2021.09.13.00.56.10; Mon, 13 Sep 2021 00:56:21 -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 S237945AbhIMHzr (ORCPT + 99 others); Mon, 13 Sep 2021 03:55:47 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:59255 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237886AbhIMHzm (ORCPT ); Mon, 13 Sep 2021 03:55:42 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 18D7VMBa004725; Mon, 13 Sep 2021 15:31:22 +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, 13 Sep 2021 15:51:07 +0800 From: Billy Tsai To: , , , , , , , , , , , , , CC: Subject: [v6 10/11] iio: adc: aspeed: Support battery sensing. Date: Mon, 13 Sep 2021 15:53:36 +0800 Message-ID: <20210913075337.19991-11-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210913075337.19991-1-billy_tsai@aspeedtech.com> References: <20210913075337.19991-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 18D7VMBa004725 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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. The offset interface of ch7 will be separated when enabling the battery sensing mode. Signed-off-by: Billy Tsai --- drivers/iio/adc/aspeed_adc.c | 81 ++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index cc3a195dd45b..c4112284fe07 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -87,10 +87,16 @@ struct aspeed_adc_model_data { unsigned int vref_fixed_mv; bool wait_init_sequence; bool need_prescaler; + bool bat_sense_sup; u8 scaler_bit_width; unsigned int num_channels; }; +struct adc_gain { + u8 mult; + u8 div; +}; + struct aspeed_adc_data { struct device *dev; const struct aspeed_adc_model_data *model_data; @@ -104,6 +110,8 @@ struct aspeed_adc_data { int vref_mv; u32 sample_period_ns; int cv; + bool battery_sensing; + struct adc_gain battery_mode_gain; }; #define ASPEED_CHAN(_idx, _data_reg_addr) { \ @@ -136,6 +144,27 @@ static const struct iio_chan_spec aspeed_adc_iio_channels[] = { ASPEED_CHAN(15, 0x2E), }; +#define ASPEED_BAT_CHAN(_idx, _data_reg_addr) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (_idx), \ + .address = (_data_reg_addr), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ +} +static const struct iio_chan_spec aspeed_adc_iio_bat_channels[] = { + ASPEED_CHAN(0, 0x10), + ASPEED_CHAN(1, 0x12), + ASPEED_CHAN(2, 0x14), + ASPEED_CHAN(3, 0x16), + ASPEED_CHAN(4, 0x18), + ASPEED_CHAN(5, 0x1A), + ASPEED_CHAN(6, 0x1C), + ASPEED_BAT_CHAN(7, 0x1E), +}; + static int aspeed_adc_compensation(struct iio_dev *indio_dev) { struct aspeed_adc_data *data = iio_priv(indio_dev); @@ -204,14 +233,39 @@ 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); + if (data->battery_sensing && chan->channel == 7) { + adc_engine_control_reg_val = + readl(data->base + ASPEED_REG_ENGINE_CONTROL); + writel(adc_engine_control_reg_val | + FIELD_PREP(ASPEED_ADC_CH7_MODE, + ASPEED_ADC_CH7_BAT) | + ASPEED_ADC_BAT_SENSING_ENABLE, + data->base + ASPEED_REG_ENGINE_CONTROL); + /* + * 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); + *val = (*val * data->battery_mode_gain.mult) / + data->battery_mode_gain.div; + /* Restore control register value */ + writel(adc_engine_control_reg_val, + data->base + ASPEED_REG_ENGINE_CONTROL); + } else + *val = readw(data->base + chan->address); return IIO_VAL_INT; case IIO_CHAN_INFO_OFFSET: - *val = data->cv; + if (data->battery_sensing && chan->channel == 7) + *val = (data->cv * data->battery_mode_gain.mult) / + data->battery_mode_gain.div; + else + *val = data->cv; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -460,6 +514,23 @@ static int aspeed_adc_probe(struct platform_device *pdev) if (ret) return ret; + if (of_find_property(data->dev->of_node, "aspeed,battery-sensing", + NULL)) { + if (data->model_data->bat_sense_sup) { + data->battery_sensing = 1; + if (readl(data->base + ASPEED_REG_ENGINE_CONTROL) & + ASPEED_ADC_BAT_SENSING_DIV) { + data->battery_mode_gain.mult = 3; + data->battery_mode_gain.div = 1; + } else { + data->battery_mode_gain.mult = 3; + data->battery_mode_gain.div = 2; + } + } else + dev_warn(&pdev->dev, + "Failed to enable battey-sensing mode\n"); + } + ret = clk_prepare_enable(data->clk_scaler->clk); if (ret) return ret; @@ -510,7 +581,9 @@ static int aspeed_adc_probe(struct platform_device *pdev) indio_dev->name = data->model_data->model_name; indio_dev->info = &aspeed_adc_iio_info; indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = aspeed_adc_iio_channels; + indio_dev->channels = data->battery_sensing ? + aspeed_adc_iio_bat_channels : + aspeed_adc_iio_channels; indio_dev->num_channels = data->model_data->num_channels; ret = devm_iio_device_register(data->dev, indio_dev); @@ -543,6 +616,7 @@ static const struct aspeed_adc_model_data ast2600_adc0_model_data = { .min_sampling_rate = 10000, .max_sampling_rate = 500000, .wait_init_sequence = true, + .bat_sense_sup = true, .scaler_bit_width = 16, .num_channels = 8, }; @@ -552,6 +626,7 @@ static const struct aspeed_adc_model_data ast2600_adc1_model_data = { .min_sampling_rate = 10000, .max_sampling_rate = 500000, .wait_init_sequence = true, + .bat_sense_sup = true, .scaler_bit_width = 16, .num_channels = 8, }; -- 2.25.1