Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp481951imu; Tue, 20 Nov 2018 02:14:48 -0800 (PST) X-Google-Smtp-Source: AFSGD/WURUJBF8gbhgeIRXY5kTjSA/PQEpzyf8ynQ/p9A8PrLW5JKF2F+OG6TCEvODBkyCbxRMOI X-Received: by 2002:a65:66ce:: with SMTP id c14mr1335250pgw.450.1542708888177; Tue, 20 Nov 2018 02:14:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542708888; cv=none; d=google.com; s=arc-20160816; b=02plwQY8SDbVaNLXhnSUGhydjDR2TKwM1gJvBrXMQO5K/JZSN2TeHx5qRlr2QGCEYQ VZPIiiohiiqGbguK5RoB2MIPMNg5bJgYdSykXeydHLYQwEKdc09dH/576OOJcfOrAyFc SqeYGkQ5qbA8Li+lbppdKxfP6LfZm5DPK92hMPoRXcYbnPYc034FGLxFO7f0XbDZQM1x mkctf87PhrXAGQ6M54Us3kzStLlkAEQh6NhyyAF+sTWyTexpCjOhKY3hskKo2y0qbBjz mMKBIUYzxtKt9El9De+Rf99MwW5aBuqrGcWoguHJ2IGYMzD1zYK/vNsjOnAWZXNKs2gu OiEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=IQW45jqWz8oz7EAny3tXyMmq+wlRVDElWiKF5rYu+zc=; b=lqgIqDJaAOJSjmEl5gqnmfVvmrqTxeshKWfDJKSyn4nTbRdLLFBewrcx+j8dXU2F8r Y2KL3yevHXmHWUQie1n+8AxYH208tNVws8M3N1AmaGc6Zkj27P9DnXYPw2zPBR+GVGSJ OtCDaZzigmvFusZBQFl4PCIUi1VRvGu/PWkJoUUxSQArABY053OjM8uxZsxUqMvuy+2R HqmeW81W32LrafYfdeHQ2NM72O83b91BxQbuRYdAGtnkXMjiQ5nDFmXdsi8XnI1+RWWs Vzo1C2IIPrBxTnqvWGqwpWNtsIfWjWORS1NYcxFm1aJLKovdTTm6z6FL5kp9v/xVzv89 aHzA== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h8si24635043plr.343.2018.11.20.02.14.33; Tue, 20 Nov 2018 02:14:48 -0800 (PST) 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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728092AbeKTUmL (ORCPT + 99 others); Tue, 20 Nov 2018 15:42:11 -0500 Received: from mx07-00178001.pphosted.com ([62.209.51.94]:47326 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725983AbeKTUmK (ORCPT ); Tue, 20 Nov 2018 15:42:10 -0500 Received: from pps.filterd (m0046668.ppops.net [127.0.0.1]) by mx07-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id wAKA8vtr025041; Tue, 20 Nov 2018 11:13:04 +0100 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 2nvg4w0291-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Tue, 20 Nov 2018 11:13:04 +0100 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 962633A; Tue, 20 Nov 2018 10:13:03 +0000 (GMT) Received: from Webmail-eu.st.com (sfhdag5node3.st.com [10.75.127.15]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 69AD42671; Tue, 20 Nov 2018 10:13:03 +0000 (GMT) Received: from localhost (10.75.127.44) by SFHDAG5NODE3.st.com (10.75.127.15) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Tue, 20 Nov 2018 11:13:02 +0100 From: Fabrice Gasnier To: CC: , , , , , , , , , Subject: [PATCH 1/3] iio: adc: stm32-adc: move self-calibration to prepare routine Date: Tue, 20 Nov 2018 11:12:30 +0100 Message-ID: <1542708752-26163-2-git-send-email-fabrice.gasnier@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1542708752-26163-1-git-send-email-fabrice.gasnier@st.com> References: <1542708752-26163-1-git-send-email-fabrice.gasnier@st.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.75.127.44] X-ClientProxiedBy: SFHDAG1NODE3.st.com (10.75.127.3) To SFHDAG5NODE3.st.com (10.75.127.15) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-11-20_04:,, signatures=0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Move self-calibration routine to prepare routine. - This is precursor patch to ease power management handling. - This also allow to factorize few error cases (error handling). Signed-off-by: Fabrice Gasnier --- drivers/iio/adc/stm32-adc.c | 59 ++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 35 deletions(-) diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 3784118..dca8733 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -199,11 +199,13 @@ struct stm32_adc_trig_info { * @calfact_s: Calibration offset for single ended channels * @calfact_d: Calibration offset in differential * @lincalfact: Linearity calibration factor + * @calibrated: Indicates calibration status */ struct stm32_adc_calib { u32 calfact_s; u32 calfact_d; u32 lincalfact[STM32H7_LINCALFACT_NUM]; + bool calibrated; }; /** @@ -251,7 +253,6 @@ struct stm32_adc_regspec { * @trigs: external trigger sources * @clk_required: clock is required * @has_vregready: vregready status flag presence - * @selfcalib: optional routine for self-calibration * @prepare: optional prepare routine (power-up, enable) * @start_conv: routine to start conversions * @stop_conv: routine to stop conversions @@ -264,7 +265,6 @@ struct stm32_adc_cfg { struct stm32_adc_trig_info *trigs; bool clk_required; bool has_vregready; - int (*selfcalib)(struct stm32_adc *); int (*prepare)(struct stm32_adc *); void (*start_conv)(struct stm32_adc *, bool dma); void (*stop_conv)(struct stm32_adc *); @@ -777,6 +777,7 @@ static void stm32h7_adc_disable(struct stm32_adc *adc) /** * stm32h7_adc_read_selfcalib() - read calibration shadow regs, save result * @adc: stm32 adc instance + * Note: Must be called once ADC is enabled, so LINCALRDYW[1..6] are writable */ static int stm32h7_adc_read_selfcalib(struct stm32_adc *adc) { @@ -784,11 +785,6 @@ static int stm32h7_adc_read_selfcalib(struct stm32_adc *adc) int i, ret; u32 lincalrdyw_mask, val; - /* Enable adc so LINCALRDYW1..6 bits are writable */ - ret = stm32h7_adc_enable(adc); - if (ret) - return ret; - /* Read linearity calibration */ lincalrdyw_mask = STM32H7_LINCALRDYW6; for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) { @@ -801,7 +797,7 @@ static int stm32h7_adc_read_selfcalib(struct stm32_adc *adc) 100, STM32_ADC_TIMEOUT_US); if (ret) { dev_err(&indio_dev->dev, "Failed to read calfact\n"); - goto disable; + return ret; } val = stm32_adc_readl(adc, STM32H7_ADC_CALFACT2); @@ -817,11 +813,9 @@ static int stm32h7_adc_read_selfcalib(struct stm32_adc *adc) adc->cal.calfact_s >>= STM32H7_CALFACT_S_SHIFT; adc->cal.calfact_d = (val & STM32H7_CALFACT_D_MASK); adc->cal.calfact_d >>= STM32H7_CALFACT_D_SHIFT; + adc->cal.calibrated = true; -disable: - stm32h7_adc_disable(adc); - - return ret; + return 0; } /** @@ -898,9 +892,9 @@ static int stm32h7_adc_restore_selfcalib(struct stm32_adc *adc) #define STM32H7_ADC_CALIB_TIMEOUT_US 100000 /** - * stm32h7_adc_selfcalib() - Procedure to calibrate ADC (from power down) + * stm32h7_adc_selfcalib() - Procedure to calibrate ADC * @adc: stm32 adc instance - * Exit from power down, calibrate ADC, then return to power down. + * Note: Must be called once ADC is out of power down. */ static int stm32h7_adc_selfcalib(struct stm32_adc *adc) { @@ -908,9 +902,8 @@ static int stm32h7_adc_selfcalib(struct stm32_adc *adc) int ret; u32 val; - ret = stm32h7_adc_exit_pwr_down(adc); - if (ret) - return ret; + if (adc->cal.calibrated) + return adc->cal.calibrated; /* * Select calibration mode: @@ -927,7 +920,7 @@ static int stm32h7_adc_selfcalib(struct stm32_adc *adc) STM32H7_ADC_CALIB_TIMEOUT_US); if (ret) { dev_err(&indio_dev->dev, "calibration failed\n"); - goto pwr_dwn; + goto out; } /* @@ -944,18 +937,13 @@ static int stm32h7_adc_selfcalib(struct stm32_adc *adc) STM32H7_ADC_CALIB_TIMEOUT_US); if (ret) { dev_err(&indio_dev->dev, "calibration failed\n"); - goto pwr_dwn; + goto out; } +out: stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALDIF | STM32H7_ADCALLIN); - /* Read calibration result for future reference */ - ret = stm32h7_adc_read_selfcalib(adc); - -pwr_dwn: - stm32h7_adc_enter_pwr_down(adc); - return ret; } @@ -972,19 +960,28 @@ static int stm32h7_adc_selfcalib(struct stm32_adc *adc) */ static int stm32h7_adc_prepare(struct stm32_adc *adc) { - int ret; + int calib, ret; ret = stm32h7_adc_exit_pwr_down(adc); if (ret) return ret; + ret = stm32h7_adc_selfcalib(adc); + if (ret < 0) + goto pwr_dwn; + calib = ret; + stm32_adc_writel(adc, STM32H7_ADC_DIFSEL, adc->difsel); ret = stm32h7_adc_enable(adc); if (ret) goto pwr_dwn; - ret = stm32h7_adc_restore_selfcalib(adc); + /* Either restore or read calibration result for future reference */ + if (calib) + ret = stm32h7_adc_restore_selfcalib(adc); + else + ret = stm32h7_adc_read_selfcalib(adc); if (ret) goto disable; @@ -1880,12 +1877,6 @@ static int stm32_adc_probe(struct platform_device *pdev) goto err_clk_disable; stm32_adc_set_res(adc); - if (adc->cfg->selfcalib) { - ret = adc->cfg->selfcalib(adc); - if (ret) - goto err_clk_disable; - } - ret = stm32_adc_chan_of_init(indio_dev); if (ret < 0) goto err_clk_disable; @@ -1961,7 +1952,6 @@ static int stm32_adc_remove(struct platform_device *pdev) .regs = &stm32h7_adc_regspec, .adc_info = &stm32h7_adc_info, .trigs = stm32h7_adc_trigs, - .selfcalib = stm32h7_adc_selfcalib, .start_conv = stm32h7_adc_start_conv, .stop_conv = stm32h7_adc_stop_conv, .prepare = stm32h7_adc_prepare, @@ -1974,7 +1964,6 @@ static int stm32_adc_remove(struct platform_device *pdev) .adc_info = &stm32h7_adc_info, .trigs = stm32h7_adc_trigs, .has_vregready = true, - .selfcalib = stm32h7_adc_selfcalib, .start_conv = stm32h7_adc_start_conv, .stop_conv = stm32h7_adc_stop_conv, .prepare = stm32h7_adc_prepare, -- 1.9.1