From patchwork Thu Jul 25 06:33:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "\(Exiting\) Baolin Wang" X-Patchwork-Id: 169678 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp11216830ilk; Wed, 24 Jul 2019 23:34:25 -0700 (PDT) X-Google-Smtp-Source: APXvYqyNGtI6xMqvlUXQ/bu1DlCPNLIlIgUpBXX/Lfq1AG295D9e8PJEIp2IuRdOSNXB90J8YTql X-Received: by 2002:a63:db47:: with SMTP id x7mr84313438pgi.375.1564036465410; Wed, 24 Jul 2019 23:34:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564036465; cv=none; d=google.com; s=arc-20160816; b=rz+QoRPVS0FwI0Bvvxx94N8GRNFFNSr8KAN9giurhllAU022oPOHyXf9hXquAqzYG2 lLrZTkWVeLSnLEcekbagBb+XDv2SAQLmtt4ebaW22oQxI5IVLag5Rvri5L3sI0zhDVWT ZCmNULf/oAqPo3CUMhLYqM2g3zEANK8S/DhzBXb1cxTqB+dAgvPZJ4Vs82eU2XJgBmfz HFyvP2GbaSA9nxuoMzNUaXKxzLm+FSUjjsxDYmtY4NvhhrRfRoLoh4uQplHj4NWwLzts /Dq+B3fuXlQXu/MgXR0KESPmP/qBpS4adA7oJNjhSTBAy6d+9xEOyZRKQLPP0kwa58do 99og== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature; bh=dlVS9wrL3Ud7T0+1eB3/cbuxzq2FNswQPzy/JeSfgyo=; b=nhgpljZi5mNvGAwcS63XHRpkvF3uJD6iHGEQggsRXeS013WPsIdjOqVzR2n5qhHZxG IPqvHROmjmRcvnwp3d16QVHkhzsCmwDWiRhiTkE+V3RqRyXRBzXLcmgF2AI56Rg3BHar aozUOlaa3rHR/FtmoKOBBIhDjYkpPrQGh0c8e78Af2ets3/vh/U8SZe0gizyt4ma4jLZ Ver+WG/QzQKBXdbsXDj952s/Tu05jMOZRFL3Cjz70RluXCv4M9ajy5Md0OIuhfw9fg1F IwronzUXzivUkXjxcAscOkkBnFnh6boNmsdpSOJY0SqiKY1coZDIAiwuW4uj+UdF3mYk mBdw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GTb92mvF; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 145si16096671pfb.262.2019.07.24.23.34.25; Wed, 24 Jul 2019 23:34:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GTb92mvF; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729531AbfGYGeX (ORCPT + 29 others); Thu, 25 Jul 2019 02:34:23 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:44539 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727645AbfGYGeS (ORCPT ); Thu, 25 Jul 2019 02:34:18 -0400 Received: by mail-pl1-f193.google.com with SMTP id t14so22966106plr.11 for ; Wed, 24 Jul 2019 23:34:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=dlVS9wrL3Ud7T0+1eB3/cbuxzq2FNswQPzy/JeSfgyo=; b=GTb92mvFVJ+XqMAuo0hSQ52CQEiKhH6k0ygsgBjwYIu1KAV6Ar4Wh6Syq1oy33lL1w KCZ/5kMmhXSwPq7ZLDVoSVIvP2NkkCOMylaUszovQObgNwlrgy2LP4YU3qpemN5kYk5X vCRwZJnK5timEjLq4RXmoVpDIdD9cS5BRdb17ynBGuSBRokd/ZZDYlYfGabuj6PkoMW7 Z9gJR0i0IgNdsrrc+syUXjF6A90o5EpBjvH+uM0pl13KrBYDvo5VkxrmCIGKDbMpscT3 ePIj49uUO06xDNSIMYTqst/Mqt2Pga61KxjukQH9VqDYVL8/yLxYN+F8xMKfl6yIRQ7T eKaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=dlVS9wrL3Ud7T0+1eB3/cbuxzq2FNswQPzy/JeSfgyo=; b=dOthcZALsJkhussBGOjU/FlMXRWvw5YAZS1rfdJpXuPybqNsfnoqzsJngK5n0NZBci 9ejpeRMQu83SqJ0EYXsxVTfXa/ipUx1SSaRuAWExtpzGoF/Uz8fhKDYH6OBSY8dDq6bG 87P+FL5BHHZaNkx6YsJnogP4h9MInXGjHlenWC87ahHe4qIu4XhFdRMQNeeZdL04nZVa 6fUZ/cD8WADujMgmYm/VoEXtBFDBjpX3aTHsDmeee85fl9DlQwzbYgehmS7jw0ejExyc RbY0idPmyNqmAfy4q3qLek7Wqbhywm5m+D9LDb/dWWMNFE1bobdq6akRlX639T3fBf0K WjIA== X-Gm-Message-State: APjAAAVhKK8da0fr67g//DI0Ee9GRKMF/gR+43uHqHW7+KLKgJJri14c ZLLMuqiLExca6TBk8q8fu6GmtA== X-Received: by 2002:a17:902:ff05:: with SMTP id f5mr86662809plj.116.1564036458081; Wed, 24 Jul 2019 23:34:18 -0700 (PDT) Received: from baolinwangubtpc.spreadtrum.com ([117.18.48.82]) by smtp.gmail.com with ESMTPSA id 81sm43010327pfa.86.2019.07.24.23.34.15 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 24 Jul 2019 23:34:17 -0700 (PDT) From: Baolin Wang To: jic23@kernel.org, knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net Cc: freeman.liu@unisoc.com, baolin.wang@linaro.org, vincent.guittot@linaro.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] iio: adc: sc27xx: Change to polling mode to read data Date: Thu, 25 Jul 2019 14:33:50 +0800 Message-Id: <1870ea18729f93fb36694affaf7e9443733dd988.1564035575.git.baolin.wang@linaro.org> X-Mailer: git-send-email 1.7.9.5 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Freeman Liu On Spreadtrum platform, the headphone will read one ADC channel multiple times to identify the headphone type, and the headphone identification is sensitive of the ADC reading time. And we found it will take longer time to reading ADC data by using interrupt mode comparing with the polling mode, thus we should change to polling mode to improve the efficiency of reading data, which can identify the headphone type successfully. Signed-off-by: Freeman Liu Signed-off-by: Baolin Wang --- drivers/iio/adc/sc27xx_adc.c | 81 ++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 54 deletions(-) -- 1.7.9.5 diff --git a/drivers/iio/adc/sc27xx_adc.c b/drivers/iio/adc/sc27xx_adc.c index f7f7a189..ea864290 100644 --- a/drivers/iio/adc/sc27xx_adc.c +++ b/drivers/iio/adc/sc27xx_adc.c @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -46,14 +45,18 @@ /* Bits definitions for SC27XX_ADC_INT_CLR registers */ #define SC27XX_ADC_IRQ_CLR BIT(0) +/* Bits definitions for SC27XX_ADC_INT_RAW registers */ +#define SC27XX_ADC_IRQ_RAW BIT(0) + /* Mask definition for SC27XX_ADC_DATA register */ #define SC27XX_ADC_DATA_MASK GENMASK(11, 0) /* Timeout (ms) for the trylock of hardware spinlocks */ #define SC27XX_ADC_HWLOCK_TIMEOUT 5000 -/* Timeout (ms) for ADC data conversion according to ADC datasheet */ -#define SC27XX_ADC_RDY_TIMEOUT 100 +/* Timeout (us) for ADC data conversion according to ADC datasheet */ +#define SC27XX_ADC_RDY_TIMEOUT 1000000 +#define SC27XX_ADC_POLL_RAW_STATUS 500 /* Maximum ADC channel number */ #define SC27XX_ADC_CHANNEL_MAX 32 @@ -72,10 +75,8 @@ struct sc27xx_adc_data { * subsystems which will access the unique ADC controller. */ struct hwspinlock *hwlock; - struct completion completion; int channel_scale[SC27XX_ADC_CHANNEL_MAX]; u32 base; - int value; int irq; }; @@ -188,9 +189,7 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, int scale, int *val) { int ret; - u32 tmp; - - reinit_completion(&data->completion); + u32 tmp, value, status; ret = hwspin_lock_timeout_raw(data->hwlock, SC27XX_ADC_HWLOCK_TIMEOUT); if (ret) { @@ -203,6 +202,11 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, if (ret) goto unlock_adc; + ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR, + SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR); + if (ret) + goto disable_adc; + /* Configure the channel id and scale */ tmp = (scale << SC27XX_ADC_SCALE_SHIFT) & SC27XX_ADC_SCALE_MASK; tmp |= channel & SC27XX_ADC_CHN_ID_MASK; @@ -226,15 +230,22 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, if (ret) goto disable_adc; - ret = wait_for_completion_timeout(&data->completion, - msecs_to_jiffies(SC27XX_ADC_RDY_TIMEOUT)); - if (!ret) { - dev_err(data->dev, "read ADC data timeout\n"); - ret = -ETIMEDOUT; - } else { - ret = 0; + ret = regmap_read_poll_timeout(data->regmap, + data->base + SC27XX_ADC_INT_RAW, + status, (status & SC27XX_ADC_IRQ_RAW), + SC27XX_ADC_POLL_RAW_STATUS, + SC27XX_ADC_RDY_TIMEOUT); + if (ret) { + dev_err(data->dev, "read adc timeout, status = 0x%x\n", status); + goto disable_adc; } + ret = regmap_read(data->regmap, data->base + SC27XX_ADC_DATA, &value); + if (ret) + goto disable_adc; + + value &= SC27XX_ADC_DATA_MASK; + disable_adc: regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL, SC27XX_ADC_EN, 0); @@ -242,32 +253,11 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, hwspin_unlock_raw(data->hwlock); if (!ret) - *val = data->value; + *val = value; return ret; } -static irqreturn_t sc27xx_adc_isr(int irq, void *dev_id) -{ - struct sc27xx_adc_data *data = dev_id; - int ret; - - ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR, - SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR); - if (ret) - return IRQ_RETVAL(ret); - - ret = regmap_read(data->regmap, data->base + SC27XX_ADC_DATA, - &data->value); - if (ret) - return IRQ_RETVAL(ret); - - data->value &= SC27XX_ADC_DATA_MASK; - complete(&data->completion); - - return IRQ_HANDLED; -} - static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data, int channel, int scale, u32 *div_numerator, u32 *div_denominator) @@ -454,11 +444,6 @@ static int sc27xx_adc_enable(struct sc27xx_adc_data *data) if (ret) goto disable_adc; - ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_EN, - SC27XX_ADC_IRQ_EN, SC27XX_ADC_IRQ_EN); - if (ret) - goto disable_clk; - /* ADC channel scales' calibration from nvmem device */ ret = sc27xx_adc_scale_calibration(data, true); if (ret) @@ -484,9 +469,6 @@ static void sc27xx_adc_disable(void *_data) { struct sc27xx_adc_data *data = _data; - regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_EN, - SC27XX_ADC_IRQ_EN, 0); - /* Disable ADC work clock and controller clock */ regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN, SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0); @@ -553,7 +535,6 @@ static int sc27xx_adc_probe(struct platform_device *pdev) return ret; } - init_completion(&sc27xx_data->completion); sc27xx_data->dev = &pdev->dev; ret = sc27xx_adc_enable(sc27xx_data); @@ -569,14 +550,6 @@ static int sc27xx_adc_probe(struct platform_device *pdev) return ret; } - ret = devm_request_threaded_irq(&pdev->dev, sc27xx_data->irq, NULL, - sc27xx_adc_isr, IRQF_ONESHOT, - pdev->name, sc27xx_data); - if (ret) { - dev_err(&pdev->dev, "failed to request ADC irq\n"); - return ret; - } - indio_dev->dev.parent = &pdev->dev; indio_dev->name = dev_name(&pdev->dev); indio_dev->modes = INDIO_DIRECT_MODE;