Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp4260579pxb; Tue, 31 Aug 2021 00:17:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzq3wFE2JFIZmdMKyqHkvYTcw8OY/MDtHpmp9Achc7tsuoJnYYCM9cHIv3SOm0iOUanF20c X-Received: by 2002:a02:5107:: with SMTP id s7mr1520802jaa.65.1630394256169; Tue, 31 Aug 2021 00:17:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1630394256; cv=none; d=google.com; s=arc-20160816; b=jyDHe2WVeWgrk68PzhYytx61HVICouc1/7LGJDhv4oEYJgk7l/M4zeQQZK9S8Ybg+H U5vSEfjcs65ISAHPHPXXYd3yHKn+K1I2CIHASXbl7es263g0cWH+2IdzYDq8tdhPZkX8 +gjF4fBszZ+zWRxldoUvqNrxKmuN2iMvQookMpmWaanDGF0MVUWZTCojT8NijIKAOp5o LuOJiht+6dADPrrbZq6Cd1oGxlL5U7ry1gnDxwU/xhf8fFZ+i54eYnw9dTnk08/DDals kMESeW+11GDkWglgjvBDoyC4Z956YEnVI0plKP4WoUJ7Mtlq4MQ8VDD3252MIsb0Wq2B xHAQ== 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=isz+ZnfyxoDZp1K1f0pdwzzmpOBgF2nbHYdpKFoAIH0=; b=FuSI+Y3JEdFrItnzTvO85hFp8LFglUFGtKuf5JqrnoxGBJs9drgBPN6e3aBiLyZsLf dTS2fCL7jpICmjYCzyvEkQPbrT3MbK+6mbM5I9Hsz1/Qy/J536ot5MrtQudmjLopjE39 8//VUud77c6SfnL47Dhn4w4EdGZJwAC090P+R9NnD/TN4KpdmJyPKrZ24r05MvX3iAwk lwtgUlza82bvqP+6YDIAVx5xhMlaGfRCjEeFq+DJkZz8G7m0jg1W36o2WltaKLW327A+ em5roPYSGJ5cbM/hjpUkV5AC6p+FkagoAtoGbuJumRpXEQi8EW2sp574RgrFBZVbR3lq ZKyg== 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 p31si21030085jac.95.2021.08.31.00.17.24; Tue, 31 Aug 2021 00:17:36 -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 S239832AbhHaHRF (ORCPT + 99 others); Tue, 31 Aug 2021 03:17:05 -0400 Received: from twspam01.aspeedtech.com ([211.20.114.71]:62726 "EHLO twspam01.aspeedtech.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239784AbhHaHQ5 (ORCPT ); Tue, 31 Aug 2021 03:16:57 -0400 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 17V6sd51028282; Tue, 31 Aug 2021 14: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; Tue, 31 Aug 2021 15:13:36 +0800 From: Billy Tsai To: , , , , , , , , , , , , , CC: Subject: [v5 14/15] iio: adc: aspeed: Support battery sensing. Date: Tue, 31 Aug 2021 15:14:57 +0800 Message-ID: <20210831071458.2334-15-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210831071458.2334-1-billy_tsai@aspeedtech.com> References: <20210831071458.2334-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 17V6sd51028282 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 121c96de03bd..b594a723db2e 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: @@ -491,6 +545,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"); + } + if (data->model_data->wait_init_sequence) { adc_engine_control_reg_val = readl(data->base + ASPEED_REG_ENGINE_CONTROL); @@ -536,7 +607,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); @@ -569,6 +642,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, }; @@ -578,6 +652,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