From patchwork Tue Oct 12 13:19:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olivier Moysan X-Patchwork-Id: 12552649 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 08ECFC433F5 for ; Tue, 12 Oct 2021 13:33:51 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CA4DC60F3A for ; Tue, 12 Oct 2021 13:33:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org CA4DC60F3A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=foss.st.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=3EWTK76msXPV5gaDEQTiuQt8kmYYjoYcEElYe+0PCjI=; b=krHEYxQsPhvGxP kDpiMPiDig691CPuzwa2MJwNnxfN9Fsm2YDCvB/pYwpVB/UXoVh7O3FxNErlMzQKcDCd7I7ZFijnm etayKE4cebJQ2GxBiCEQT5bo3EB66LW8/ylAaL/OOXBtDh/5d00ZyFKqpq+Jy7S0Nbo3SB0LubLgt /CJqb8q5snWY2jOQoSUyLojhaZmPh7X24M2YAJRJev91s/oe4OkB1Eb96depxrEUCdNTsjyvRCpWt tdyAp0uiM+aGmughGnq/8Kup/LtPf7/mIhUtnNXdtpqTX4LwuliHOA4NSiwEUGwwPZmgiU9NWBb5O d0JGuMSaA13O5/IR3Sjg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1maHrx-00CyCo-8H; Tue, 12 Oct 2021 13:31:02 +0000 Received: from mx08-00178001.pphosted.com ([91.207.212.93] helo=mx07-00178001.pphosted.com) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1maHhC-00Csmc-Ex for linux-arm-kernel@lists.infradead.org; Tue, 12 Oct 2021 13:19:56 +0000 Received: from pps.filterd (m0046660.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 19CAvEYs006890; Tue, 12 Oct 2021 15:19:50 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=selector1; bh=9rOZYlkf5voByr7hgqT920hjGkGE84+icfZuj16RzCA=; b=D+pAwZewcS6+G5X3dXnPHzovRr0DgufPigU+7eDlHnEKvr7m0QRGtDVGFigI1oGPd/XP P1LItmFNxrjveYE4sVCG2Jje9DjbqPag/YX6v2088rm3RwoAc6KteClqXSJtnbd563fG aVGy5crG1TErUdJNJdy+QFbM4W8DquTbjntZn3xALyw/xgxg2h1UM3gv5hr9VdwDw+pj kpYseooQyFPb5WPDP665NijiQ1d9iap0ncYdF5sLkeKUFj0KVQLFSros3ya0ZR/slLxo iyBnoTQ5zIuPTYJXhysNEeyzZeO0ZSgAdJCA9hMfkhr5VYekR/5L9dRB1R5IjaBwh9po kA== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 3bmyevmr6a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 12 Oct 2021 15:19:50 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 15740100034; Tue, 12 Oct 2021 15:19:50 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag2node2.st.com [10.75.127.5]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 0598121ED33; Tue, 12 Oct 2021 15:19:50 +0200 (CEST) Received: from localhost (10.75.127.50) by SFHDAG2NODE2.st.com (10.75.127.5) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Tue, 12 Oct 2021 15:19:49 +0200 From: Olivier Moysan To: Alexandre Torgue , Fabrice Gasnier , Jonathan Cameron , Lars-Peter Clausen , Maxime Coquelin , Olivier Moysan , Rob Herring CC: , , , , Subject: [PATCH v4 3/7] iio: adc: stm32-adc: split channel init into several routines Date: Tue, 12 Oct 2021 15:19:20 +0200 Message-ID: <20211012131924.31952-4-olivier.moysan@foss.st.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211012131924.31952-1-olivier.moysan@foss.st.com> References: <20211012131924.31952-1-olivier.moysan@foss.st.com> MIME-Version: 1.0 X-Originating-IP: [10.75.127.50] X-ClientProxiedBy: SFHDAG2NODE3.st.com (10.75.127.6) To SFHDAG2NODE2.st.com (10.75.127.5) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.182.1,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.0.607.475 definitions=2021-10-12_03,2021-10-12_01,2020-04-07_01 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211012_061954_828835_CF4EBA48 X-CRM114-Status: GOOD ( 24.50 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Split stm32_adc_chan_of_init channel initialization function into several routines to increase readability and prepare channel generic binding handling. Signed-off-by: Olivier Moysan Reviewed-by: Fabrice Gasnier --- drivers/iio/adc/stm32-adc.c | 131 ++++++++++++++++++++++++------------ 1 file changed, 87 insertions(+), 44 deletions(-) diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c index 5088de835bb1..2f137d14f141 100644 --- a/drivers/iio/adc/stm32-adc.c +++ b/drivers/iio/adc/stm32-adc.c @@ -194,6 +194,7 @@ struct stm32_adc_cfg { * @smpr_val: sampling time settings (e.g. smpr1 / smpr2) * @cal: optional calibration data on some devices * @chan_name: channel name array + * @num_diff: number of differential channels */ struct stm32_adc { struct stm32_adc_common *common; @@ -217,6 +218,7 @@ struct stm32_adc { u32 smpr_val[2]; struct stm32_adc_calib cal; char chan_name[STM32_ADC_CH_MAX][STM32_ADC_CH_SZ]; + u32 num_diff; }; struct stm32_adc_diff_channel { @@ -1706,17 +1708,11 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev, } } -static int stm32_adc_chan_of_init(struct iio_dev *indio_dev, bool timestamping) +static int stm32_adc_get_legacy_chan_count(struct iio_dev *indio_dev, struct stm32_adc *adc) { struct device_node *node = indio_dev->dev.of_node; - struct stm32_adc *adc = iio_priv(indio_dev); const struct stm32_adc_info *adc_info = adc->cfg->adc_info; - struct stm32_adc_diff_channel diff[STM32_ADC_CH_MAX]; - struct property *prop; - const __be32 *cur; - struct iio_chan_spec *channels; - int scan_index = 0, num_channels = 0, num_diff = 0, ret, i; - u32 val, smp = 0; + int num_channels = 0, ret; ret = of_property_count_u32_elems(node, "st,adc-channels"); if (ret > adc_info->max_channels) { @@ -1727,41 +1723,54 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev, bool timestamping) } ret = of_property_count_elems_of_size(node, "st,adc-diff-channels", - sizeof(*diff)); + sizeof(struct stm32_adc_diff_channel)); if (ret > adc_info->max_channels) { dev_err(&indio_dev->dev, "Bad st,adc-diff-channels?\n"); return -EINVAL; } else if (ret > 0) { - int size = ret * sizeof(*diff) / sizeof(u32); - - num_diff = ret; + adc->num_diff = ret; num_channels += ret; + } + + return num_channels; +} + +static int stm32_adc_legacy_chan_init(struct iio_dev *indio_dev, + struct stm32_adc *adc, + struct iio_chan_spec *channels) +{ + struct device_node *node = indio_dev->dev.of_node; + const struct stm32_adc_info *adc_info = adc->cfg->adc_info; + struct stm32_adc_diff_channel diff[STM32_ADC_CH_MAX]; + u32 num_diff = adc->num_diff; + int size = num_diff * sizeof(*diff) / sizeof(u32); + int scan_index = 0, val, ret, i; + struct property *prop; + const __be32 *cur; + + if (num_diff) { ret = of_property_read_u32_array(node, "st,adc-diff-channels", (u32 *)diff, size); - if (ret) + if (ret) { + dev_err(&indio_dev->dev, "Failed to get diff channels %d\n", ret); return ret; - } + } - if (!num_channels) { - dev_err(&indio_dev->dev, "No channels configured\n"); - return -ENODATA; - } + for (i = 0; i < num_diff; i++) { + if (diff[i].vinp >= adc_info->max_channels || + diff[i].vinn >= adc_info->max_channels) { + dev_err(&indio_dev->dev, "Invalid channel in%d-in%d\n", + diff[i].vinp, diff[i].vinn); + return -EINVAL; + } - /* Optional sample time is provided either for each, or all channels */ - ret = of_property_count_u32_elems(node, "st,min-sample-time-nsecs"); - if (ret > 1 && ret != num_channels) { - dev_err(&indio_dev->dev, "Invalid st,min-sample-time-nsecs\n"); - return -EINVAL; + stm32_adc_chan_init_one(indio_dev, &channels[scan_index], + diff[i].vinp, diff[i].vinn, + scan_index, true); + scan_index++; + } } - if (timestamping) - num_channels++; - - channels = devm_kcalloc(&indio_dev->dev, num_channels, - sizeof(struct iio_chan_spec), GFP_KERNEL); - if (!channels) - return -ENOMEM; - of_property_for_each_u32(node, "st,adc-channels", prop, cur, val) { if (val >= adc_info->max_channels) { dev_err(&indio_dev->dev, "Invalid channel %d\n", val); @@ -1771,8 +1780,7 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev, bool timestamping) /* Channel can't be configured both as single-ended & diff */ for (i = 0; i < num_diff; i++) { if (val == diff[i].vinp) { - dev_err(&indio_dev->dev, - "channel %d miss-configured\n", val); + dev_err(&indio_dev->dev, "channel %d misconfigured\n", val); return -EINVAL; } } @@ -1781,19 +1789,54 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev, bool timestamping) scan_index++; } - for (i = 0; i < num_diff; i++) { - if (diff[i].vinp >= adc_info->max_channels || - diff[i].vinn >= adc_info->max_channels) { - dev_err(&indio_dev->dev, "Invalid channel in%d-in%d\n", - diff[i].vinp, diff[i].vinn); - return -EINVAL; - } - stm32_adc_chan_init_one(indio_dev, &channels[scan_index], - diff[i].vinp, diff[i].vinn, scan_index, - true); - scan_index++; + return scan_index; +} + +static int stm32_adc_chan_of_init(struct iio_dev *indio_dev, bool timestamping) +{ + struct device_node *node = indio_dev->dev.of_node; + struct stm32_adc *adc = iio_priv(indio_dev); + const struct stm32_adc_info *adc_info = adc->cfg->adc_info; + struct iio_chan_spec *channels; + int scan_index = 0, num_channels = 0, ret, i; + u32 smp = 0; + + ret = stm32_adc_get_legacy_chan_count(indio_dev, adc); + if (ret < 0) + return ret; + num_channels = ret; + + if (!num_channels) { + dev_err(&indio_dev->dev, "No channels configured\n"); + return -ENODATA; } + if (num_channels > adc_info->max_channels) { + dev_err(&indio_dev->dev, "Channel number [%d] exceeds %d\n", + num_channels, adc_info->max_channels); + return -EINVAL; + } + + /* Optional sample time is provided either for each, or all channels */ + ret = of_property_count_u32_elems(node, "st,min-sample-time-nsecs"); + if (ret > 1 && ret != num_channels) { + dev_err(&indio_dev->dev, "Invalid st,min-sample-time-nsecs\n"); + return -EINVAL; + } + + if (timestamping) + num_channels++; + + channels = devm_kcalloc(&indio_dev->dev, num_channels, + sizeof(struct iio_chan_spec), GFP_KERNEL); + if (!channels) + return -ENOMEM; + + ret = stm32_adc_legacy_chan_init(indio_dev, adc, channels); + if (ret < 0) + return ret; + scan_index = ret; + for (i = 0; i < scan_index; i++) { /* * Using of_property_read_u32_index(), smp value will only be