From patchwork Wed Feb 19 12:30:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matti Vaittinen X-Patchwork-Id: 13982075 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id CF02BC021AA for ; Wed, 19 Feb 2025 12:33:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=1hUrd+Gyy/ajIhuvrP2MqW/IazkO3sAPZGITYXZm04k=; b=muTI1JCWjGcbhjXl9mwDnkEpKE GEqK6DFu52ICqUf43+WXRCqENJble/JZg5DuYFN3XlcnNGWxpPR+m0rAs8XDCMFHjMyPFNMKlrjz5 TypQv6X+vX8QJJ9qkdA8aDzxmC3/sY8Xym4en06ZW+30PGirLLduFnPQjR0kU+gyFqpf96VKDRYwR z4wW28KbTbY/kSCxEjJm/OjwhCk25YItbAVLTWSFVI3Ny4HAfyqapTCQlx39YTnuyfYkfEkJIIjop KoVdyM2VuQXqZEL2FgREn0guv/3Gzi3s1h5dC03oO3YccqveDqAVzhmEqWKQ2XDAAb8hjAK3fwtPj 6ubpeKdw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tkjGH-0000000CglN-2nwC; Wed, 19 Feb 2025 12:33:09 +0000 Received: from mail-lj1-x235.google.com ([2a00:1450:4864:20::235]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tkjDX-0000000CfQu-05VN for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2025 12:30:20 +0000 Received: by mail-lj1-x235.google.com with SMTP id 38308e7fff4ca-30737db1aa9so62785061fa.1 for ; Wed, 19 Feb 2025 04:30:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739968217; x=1740573017; darn=lists.infradead.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=1hUrd+Gyy/ajIhuvrP2MqW/IazkO3sAPZGITYXZm04k=; b=cEU9++BEQYQsczZBPpm2+ArHAwSmPMgZ6y3lY3tezX9BSbBuG5kawJuh9/LHrjsfwH Cci1QyLAqcYx1POezumIBhwnQanB9/PRZFEXY2ZmuhiQ2RILn5nNjG0TjpxgEducxNp1 U9X3OLG57FimaNNurRoTr1xediYvK8WBBVC/wEoPf47Yc1wH2CHmPI8j/6Sy9RC26zt6 AVReqAcSrPzVNfRoKuxGKSONQxIoSDlgGkYEIGrX+a7ulQcrI3DEkV9+oBEEJwYP/efS 37fFyOv9lMZQgLZ/MkF6fhMNQWaaS9uPV4lQ/p87ebYK56DZDa3lThcHbrvsUoJZknk7 ij4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739968217; x=1740573017; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=1hUrd+Gyy/ajIhuvrP2MqW/IazkO3sAPZGITYXZm04k=; b=KPPbTwBypvaG7K/RMMak4PRXShQ2PZUOfgH2bhDeNre9CTxQX5YgyuDw8gWf1mm+l5 +mTySc9XEJosTq4/9yfPFCTwRZowfjQo1HXBj6H7zZWH31QoIlKsQ47htDWg2w9f4s43 /CwMZTnUbNpFBiF5ymNSjz4oNj/KqRtZMPsPL3T4ira6xJqc0VMZTeesWz+Sj/aYuKWi Y0UjGXXWwK5YgQ7Pvau/340Q/TNkGyszQ8DwEP6bYRBoPLxdTUZQtVUS6CFK8V+7oBCy p/QWZXnp7pvGgddkyUazzkJjjrYq0SQL4BVg4a10fP0IsJff8Hy6v5BoildHk3JKiF4I HmJA== X-Forwarded-Encrypted: i=1; AJvYcCUBN0vrupzPffHzraOhENzQd9xX2jCa0RH6Vtdjv+yoGGVX+U7Hs0DKWR21oVcG/RGBDtmcbaPQHWFASntGiGFo@lists.infradead.org X-Gm-Message-State: AOJu0YxvtV2o4dOiSzhEenvzVdvJIUSMIm7XzSGQ6ZBYtib+/L2Q5hCR 9+PAUQo72BHFjAC5O37x/U94RpXK2W0IhYm4VwOkFuSGoeXphvm0 X-Gm-Gg: ASbGncuUBpxq0VQ7u+GJHlu8uijY+LyRsOWeNYnNCgIh4DPM67Y5EkLXk6algmyhQLs 71QGtmg1rJmxm3Rqb/Lu0lJ190KVgpIHsPHQED3oYiQHPyCvl5cbq9MbH9mP/EZJK+Cv/LyRe2r SSfjvPchPAbZhnmACcuigCrTsszo9w0ni/JFJ0GxPKnmlV9TAf2TpkACvAKV4wl1Xv4TmAaAvsj NXd9LQdqYPVWQ38Us17fSjGv3IMNyfX4h8sALdoCI+rWT6W4qPOuWk53FRN8N7p6ADqDYuym43m N6gwhjXjWLcZRk7strzYEg== X-Google-Smtp-Source: AGHT+IFF8ZAOezRn1kWhpmBq+gPrOLGIPq15CfW2c+RFEDW/9HuXUxU0qk6Hp+MJg1WFZfej+FArLQ== X-Received: by 2002:a2e:b176:0:b0:309:25f6:8dcb with SMTP id 38308e7fff4ca-30a44dbb334mr9639561fa.5.1739968216796; Wed, 19 Feb 2025 04:30:16 -0800 (PST) Received: from mva-rohm ([2a10:a5c0:800d:dd00:8fdf:935a:2c85:d703]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-309e57cc68esm13923301fa.114.2025.02.19.04.30.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2025 04:30:14 -0800 (PST) Date: Wed, 19 Feb 2025 14:30:09 +0200 From: Matti Vaittinen To: Matti Vaittinen , Matti Vaittinen Cc: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matti Vaittinen , Lad Prabhakar , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Hugo Villeneuve , Nuno Sa , David Lechner , Javier Carrasco , Andy Shevchenko , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH v3 1/9] dt-bindings: ROHM BD79124 ADC/GPO Message-ID: <52db5ddb99dcd8da847f8fe595efa74c3ab1573c.1739967040.git.mazziesaccount@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250219_043019_061493_75D2EC53 X-CRM114-Status: GOOD ( 15.10 ) 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 Add binding document for the ROHM BD79124 ADC / GPO. ROHM BD79124 is a 8-channel, 12-bit ADC. The input pins can also be used as general purpose outputs. Signed-off-by: Matti Vaittinen Reviewed-by: Conor Dooley --- Revision history: v2 => v3: - Restrict channel numbers to 0-7 as suggested by Conor RFC v1 => v2: - drop MFD and represent directly as ADC - drop pinmux and treat all non ADC channel pins as GPOs --- .../bindings/iio/adc/rohm,bd79124.yaml | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/rohm,bd79124.yaml diff --git a/Documentation/devicetree/bindings/iio/adc/rohm,bd79124.yaml b/Documentation/devicetree/bindings/iio/adc/rohm,bd79124.yaml new file mode 100644 index 000000000000..503285823376 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/rohm,bd79124.yaml @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/rohm,bd79124.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ROHM BD79124 ADC/GPO + +maintainers: + - Matti Vaittinen + +description: | + The ROHM BD79124 is a 12-bit, 8-channel, SAR ADC. The ADC supports + an automatic measurement mode, with an alarm interrupt for out-of-window + measurements. ADC input pins can be also configured as general purpose + outputs. + +properties: + compatible: + const: rohm,bd79124 + + reg: + description: + I2C slave address. + maxItems: 1 + + interrupts: + maxItems: 1 + + gpio-controller: true + + "#gpio-cells": + const: 1 + description: + The pin number. + + vdd-supply: true + + iovdd-supply: true + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +patternProperties: + "^channel@[0-7]+$": + type: object + $ref: /schemas/iio/adc/adc.yaml# + description: Represents ADC channel. + + properties: + reg: + description: AIN pin number + minimum: 0 + maximum: 7 + + required: + - reg + + additionalProperties: false + +required: + - compatible + - reg + - iovdd-supply + - vdd-supply + +additionalProperties: false + +examples: + - | + #include + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + adc: adc@10 { + compatible = "rohm,bd79124"; + reg = <0x10>; + + interrupt-parent = <&gpio1>; + interrupts = <29 8>; + + vdd-supply = <&dummyreg>; + iovdd-supply = <&dummyreg>; + + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + }; + channel@1 { + reg = <1>; + }; + channel@2 { + reg = <2>; + }; + channel@3 { + reg = <3>; + }; + channel@4 { + reg = <4>; + }; + channel@5 { + reg = <5>; + }; + channel@6 { + reg = <6>; + }; + }; + }; From patchwork Wed Feb 19 12:30:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matti Vaittinen X-Patchwork-Id: 13982076 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 0BE30C021AA for ; Wed, 19 Feb 2025 12:34:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=+gRANWQiTUbafkGO9fwshwTqOYl/mRZcDzeC9SF4EWE=; b=QleWAHP/qQIknKM+dFOewlUbGC BHBWVF7iWftT2Js5dGMuqublLi0sZVMJ7oCxSOJ7PLPlF68R6dFR4EIsIOm00FMAyW9hZ3Ww5Tq0H UhjagtPgEz+n6jJzgsMA9V4I4Es2Sh4LeQyJvdqxZE8Hf7/4kWDnwPVFcGc4PTD7ATuAPY0Yyv6sj R1yR2qNRWlp+aBcfzCa3JtU3Y7f0k7USjwnTxn1fRcD0Vav9hdQnFG33bIghbBsZlk2/Eeduxw8cD 0U7zcGZo+cff/5CeIbGwuZeA4BdVQQNnkO+2G8zXySlrHOgk/VTp6HqFZa+W91HuJlsapseXrFq2m KpXElTPw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tkjHj-0000000ChCF-1jKm; Wed, 19 Feb 2025 12:34:39 +0000 Received: from mail-lj1-x235.google.com ([2a00:1450:4864:20::235]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tkjDn-0000000Cfb3-0wh0 for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2025 12:30:36 +0000 Received: by mail-lj1-x235.google.com with SMTP id 38308e7fff4ca-30a440effcfso8823621fa.0 for ; Wed, 19 Feb 2025 04:30:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739968234; x=1740573034; darn=lists.infradead.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=+gRANWQiTUbafkGO9fwshwTqOYl/mRZcDzeC9SF4EWE=; b=LDwwiF6dJSaOT+wrUsvdTbc34Ub1ZMOqnz2dcctmA9vwCUkSY0F2eRpRfpbKyZlXF9 TNwtwRhuu7lvy6a2wyOD1tTENb28B81amgJ8CWmYJvdYtIukCoTJAmQ1HooyZe++C57n QWZHmXoTWqKY7BW4Nu9Q+R/RlLe4Nk0DHPoF2nCdzj5rXXJe3T9ct9cxxJYxw7dPxWeW bui1//Tr3pMXSabqWEOfhXFieJwBZ9S3dqV3SmM/ATzGRYtC3KSq6CmDF8YOJhnXR0ss 6XdIg3pckOk4BwPHGrUeTcost5xHUn6NACgTrBaWRHkUs0fvEG7cv3Gx99zZicsg5w1L OqSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739968234; x=1740573034; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=+gRANWQiTUbafkGO9fwshwTqOYl/mRZcDzeC9SF4EWE=; b=A4eW6oxnsNXUeN5xhS7DkRWDbXZXPBnhJAOhJfALsnL8ZvrpdNDatfdrGmfuInXhLI /tGVH0vSU/t44nEnf85rZwz97tDckOSo6KNHEuLH4yv8dM0WXCCxr+SGIdQZoODpsFdy 8f7voAWBLjIOBtcMBiue66+SlFtTNaWv/aTtMyDr0UZpy+KnFQnUtTGtjBXpFctuhijs NQ4YtcCfjFH5QMhAXF/Dbkiyvakb3Un/mpUwqyf9BXCA2ZdrftKZAwzz/SfN56FUMrFT GExGqQ21bMhV03axk08KQ+KRTmGdNgwobJfhzI3wV9V5d4GEscEEwN2jYXokxHw7rlFv jiuA== X-Forwarded-Encrypted: i=1; AJvYcCV5vrfu90wgC71VUCbaQmigrJStxTXwjpL3UZQQpbHMmAa0+TugcPreOuijpznyGRpa/vHfs1BhAZWrTKP8+X0V@lists.infradead.org X-Gm-Message-State: AOJu0YxfbKCLODjK2D87xqx8zdGq54AHEjjwmJT6sPIUDMKWOz6oFHJ/ ezfB/Bx3W43BOoF64qQEhU6lqBlfmpQiAsZaONU/tpkTwN5XryYR X-Gm-Gg: ASbGncsu61UkZNu9M5kaoAa2wfB0TflJuYV4QGxeNKCBOridmXMQzqiUAOkFc1FkZtE pWH5cLLUor9JfUknmbGA/1jkPKi0gnZYjBKgMjpVzNJv4NqdcjZUC+XOxjAAN4AWtHSm8pQcZw0 GZb6ZRv2jnUUdXjGHhA7c3ECSLYPRfXkjbGozSrKmwmr0YR5rBypVMU7KVgd5kojfA4Mqtqux2h wezq22C1tgTtqClHiqSBAxN1YXCRli6M4aZUPvTGQlZC8Vrar9fL9SzRuMwkfK/PeEXNEM+KQJh X1ASghjNCNzQ8US+PE1Dyg== X-Google-Smtp-Source: AGHT+IHMuqGjJPJmwx6XEk4wd+AYe/hAr14LA7ZB3GETJw2tINvrS45+HcCU40rfNoKlPNXMWabz/g== X-Received: by 2002:a2e:9f15:0:b0:309:2696:c293 with SMTP id 38308e7fff4ca-30a440f8e73mr13589371fa.4.1739968233293; Wed, 19 Feb 2025 04:30:33 -0800 (PST) Received: from mva-rohm ([2a10:a5c0:800d:dd00:8fdf:935a:2c85:d703]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-30a3ce198e6sm5776661fa.3.2025.02.19.04.30.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2025 04:30:31 -0800 (PST) Date: Wed, 19 Feb 2025 14:30:27 +0200 From: Matti Vaittinen To: Matti Vaittinen , Matti Vaittinen Cc: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matti Vaittinen , Lad Prabhakar , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Hugo Villeneuve , Nuno Sa , David Lechner , Javier Carrasco , Andy Shevchenko , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH v3 2/9] iio: adc: add helpers for parsing ADC nodes Message-ID: <6c5b678526e227488592d004c315a967b9809701.1739967040.git.mazziesaccount@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250219_043035_419763_810897CE X-CRM114-Status: GOOD ( 42.25 ) 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 There are ADC ICs which may have some of the AIN pins usable for other functions. These ICs may have some of the AIN pins wired so that they should not be used for ADC. (Preferred?) way for marking pins which can be used as ADC inputs is to add corresponding channels@N nodes in the device tree as described in the ADC binding yaml. Add couple of helper functions which can be used to retrieve the channel information from the device node. Signed-off-by: Matti Vaittinen --- Revision history: v2 => v3: Mostly based on review comments by Jonathan - Support differential and single-ended channels(*) - Rename iio_adc_device_get_channels() as - Improve spelling - Drop support for cases where DT comes from parent device's node - Decrease loop indent by reverting node name check conditions - Don't set 'chan->indexed' by number of channels to keep the interface consistent no matter how many channels are connected. - Fix ID range check and related comment RFC v1 => v2: - New patch (*) The support for single-ended and differential channels is 100% untested. I am not convinced it is actually an improvement over the *_simple() helpers which only supported getting the ID from the "reg". In theory they could be used. In practice, while I skimmed through the in-tree ADC drivers which used the for_each_child_node() construct - it seemed that most of those which supported differential inputs had also some other per-channel properties to read. Those users would in any case need to loop through the nodes to get those other properties. If I am once more allowed to go back to proposing the _simple() variant which only covers the case: "chan ID in 'reg' property"... Dropping support for differential and single-ended channels would simplify this helper a lot. It'd allow dropping the sanity check as well as the extra parameters callers need to pass to tell what kind of properties they expect. That'd (in my opinion) made the last patches (to actual ADC drivers) in this series a much more lean and worthy ;) Finally, we could add own functions for differential/single-ended/all channels when the next driver which uses differential or single-ended channels - and which does not need other per-channel properties - lands in tree. That would still simplify the helper API usage for those drivers touched at the end of this series. I (still) think it might be nice to have helpers for fetching also the other generic (non vendor specific) ADC properties (as listed in the Documentation/devicetree/bindings/iio/adc/adc.yaml) - but as I don't have use for those in BD79124 driver (at least not for now), I don't imnplement them yet. Anyways, this commit creates a place for such helpers. --- drivers/iio/adc/Kconfig | 3 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/industrialio-adc.c | 304 +++++++++++++++++++++++++++++ include/linux/iio/adc-helpers.h | 56 ++++++ 4 files changed, 364 insertions(+) create mode 100644 drivers/iio/adc/industrialio-adc.c create mode 100644 include/linux/iio/adc-helpers.h diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 849c90203071..37b70a65da6f 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -6,6 +6,9 @@ menu "Analog to digital converters" +config IIO_ADC_HELPER + tristate + config AB8500_GPADC bool "ST-Ericsson AB8500 GPADC driver" depends on AB8500_CORE && REGULATOR_AB8500 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index ee19afba62b7..956c121a7544 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o obj-$(CONFIG_GEHC_PMC_ADC) += gehc-pmc-adc.o obj-$(CONFIG_HI8435) += hi8435.o obj-$(CONFIG_HX711) += hx711.o +obj-$(CONFIG_IIO_ADC_HELPER) += industrialio-adc.o obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o obj-$(CONFIG_IMX8QXP_ADC) += imx8qxp-adc.o obj-$(CONFIG_IMX93_ADC) += imx93_adc.o diff --git a/drivers/iio/adc/industrialio-adc.c b/drivers/iio/adc/industrialio-adc.c new file mode 100644 index 000000000000..0281d64ae112 --- /dev/null +++ b/drivers/iio/adc/industrialio-adc.c @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Helpers for parsing common ADC information from a firmware node. + * + * Copyright (c) 2025 Matti Vaittinen + */ + +#include +#include +#include + +#include + +int iio_adc_device_num_channels(struct device *dev) +{ + int num_chan = 0; + + device_for_each_child_node_scoped(dev, child) + if (fwnode_name_eq(child, "channel")) + num_chan++; + + return num_chan; +} +EXPORT_SYMBOL_GPL(iio_adc_device_num_channels); + +static const char *iio_adc_type2prop(int type) +{ + switch (type) { + case IIO_ADC_CHAN_PROP_TYPE_REG: + return "reg"; + case IIO_ADC_CHAN_PROP_TYPE_SINGLE_ENDED: + return "single-channel"; + case IIO_ADC_CHAN_PROP_TYPE_DIFF: + return "diff-channels"; + case IIO_ADC_CHAN_PROP_COMMON: + return "common-mode-channel"; + default: + return "unknown"; + } +} + +/* + * Sanity check. Ensure that: + * - At least some type(s) are allowed + * - All types found are also expected + * - If plain "reg" is not allowed, either single-ended or differential + * properties are found. + */ +static int iio_adc_prop_type_check_sanity(struct device *dev, + const struct iio_adc_props *expected_props, int found_types) +{ + unsigned long allowed_types = expected_props->allowed | + expected_props->required; + + if (!allowed_types || allowed_types & (~IIO_ADC_CHAN_PROP_TYPE_ALL)) { + dev_dbg(dev, "Invalid adc allowed prop types 0x%lx\n", + allowed_types); + + return -EINVAL; + } + if (found_types & (~allowed_types)) { + long unknown_types = found_types & (~allowed_types); + int type; + + for_each_set_bit(type, &unknown_types, + IIO_ADC_CHAN_NUM_PROP_TYPES - 1) { + dev_err(dev, "Unsupported channel property %s\n", + iio_adc_type2prop(type)); + } + + return -EINVAL; + } + + /* + * The IIO_ADC_CHAN_PROP_TYPE_REG is special. We always require it to + * be found in the dt. (If not, we'll error out before calling this + * function.) However, listing it in 'allowed' types means the "reg" + * alone can be used to indicate the channel ID. + * + * Thus, we don't add it in the found properties either - so check for + * found and allowed properties passes even if user hasn't explicitly + * added the 'IIO_ADC_CHAN_PROP_TYPE_REG' to be allowed. (This is the + * case if either differential or single-ended property is required). + * + * Hence, for this check we need to explicitly add the + * IIO_ADC_CHAN_PROP_TYPE_REG to 'found' properties to make the check + * pass when "reg" is the property which is required to have the + * channel ID. + * + * We could of course always add the IIO_ADC_CHAN_PROP_TYPE_REG in + * allowed types and found types - but then we wouldn't catch the case + * where user says the "reg" alone is not sufficient. + */ + if ((~(found_types | IIO_ADC_CHAN_PROP_TYPE_REG)) & expected_props->required) { + long missing_types; + int type; + + missing_types = (~found_types) & expected_props->required; + + for_each_set_bit(type, &missing_types, + IIO_ADC_CHAN_NUM_PROP_TYPES - 1) { + dev_err(dev, "required channel specifier '%s' not found\n", + iio_adc_type2prop(type)); + } + + return -EINVAL; + } + + /* Check if we require something else but the "reg" property */ + if (!(allowed_types & IIO_ADC_CHAN_PROP_TYPE_REG)) { + if (found_types & IIO_ADC_CHAN_PROP_TYPE_SINGLE_ENDED || + found_types & IIO_ADC_CHAN_PROP_TYPE_DIFF) + return 0; + + dev_err(dev, "channel specifier not found\n"); + + return -EINVAL; + } + + return 0; +} + +/** + * iio_adc_device_channels_by_property - get ADC channel IDs + * + * Scan the device node for ADC channel information. Return an array of found + * IDs. Caller needs to provide the memory for the array and provide maximum + * number of IDs the array can store. + * + * @dev: Pointer to the ADC device + * @channels: Array where the found IDs will be stored. + * @max_channels: Number of IDs that fit in the array. + * @expected_props: Bitmaps of channel property types (for checking). + * + * Return: Number of found channels on succes. 0 if no channels + * was found. Negative value to indicate failure. + */ +int iio_adc_device_channels_by_property(struct device *dev, int *channels, + int max_channels, const struct iio_adc_props *expected_props) +{ + int num_chan = 0, ret; + + device_for_each_child_node_scoped(dev, child) { + u32 ch, diff[2], se; + struct iio_adc_props tmp; + int chtypes_found = 0; + + if (!fwnode_name_eq(child, "channel")) + continue; + + if (num_chan == max_channels) + return -EINVAL; + + ret = fwnode_property_read_u32(child, "reg", &ch); + if (ret) + return ret; + + ret = fwnode_property_read_u32_array(child, "diff-channels", + &diff[0], 2); + if (!ret) + chtypes_found |= IIO_ADC_CHAN_PROP_TYPE_DIFF; + + ret = fwnode_property_read_u32(child, "single-channel", &se); + if (!ret) + chtypes_found |= IIO_ADC_CHAN_PROP_TYPE_SINGLE_ENDED; + + tmp = *expected_props; + /* + * We don't bother reading the "common-mode-channel" here as it + * doesn't really affect on the primary channel ID. We remove + * it from the required properties to allow the sanity check + * pass here also for drivers which require it. + */ + tmp.required &= (~BIT(IIO_ADC_CHAN_PROP_COMMON)); + + ret = iio_adc_prop_type_check_sanity(dev, &tmp, chtypes_found); + if (ret) + return ret; + + if (chtypes_found & IIO_ADC_CHAN_PROP_TYPE_DIFF) + ch = diff[0]; + else if (chtypes_found & IIO_ADC_CHAN_PROP_TYPE_SINGLE_ENDED) + ch = se; + + /* + * We assume the channel IDs start from 0. If it seems this is + * not a sane assumption, then we can relax this check or add + * 'allowed ID range' parameter. + * + * Let's just start with this simple assumption. + */ + if (ch >= max_channels) + return -ERANGE; + + channels[num_chan] = ch; + num_chan++; + } + + return num_chan; + +} +EXPORT_SYMBOL_GPL(iio_adc_device_channels_by_property); + +/** + * devm_iio_adc_device_alloc_chaninfo - allocate and fill iio_chan_spec for adc + * + * Scan the device node for ADC channel information. Allocate and populate the + * iio_chan_spec structure corresponding to channels that are found. The memory + * for iio_chan_spec structure will be freed upon device detach. Try parent + * device node if given device has no fwnode associated to cover also MFD + * devices. + * + * @dev: Pointer to the ADC device. + * @template: Template iio_chan_spec from which the fields of all + * found and allocated channels are initialized. + * @cs: Location where pointer to allocated iio_chan_spec + * should be stored. + * @expected_props: Bitmaps of channel property types (for checking). + * + * Return: Number of found channels on succes. Negative value to indicate + * failure. + */ +int devm_iio_adc_device_alloc_chaninfo(struct device *dev, + const struct iio_chan_spec *template, + struct iio_chan_spec **cs, + const struct iio_adc_props *expected_props) +{ + struct iio_chan_spec *chan; + int num_chan = 0, ret; + + num_chan = iio_adc_device_num_channels(dev); + if (num_chan < 1) + return num_chan; + + *cs = devm_kcalloc(dev, num_chan, sizeof(**cs), GFP_KERNEL); + if (!*cs) + return -ENOMEM; + + chan = &(*cs)[0]; + + device_for_each_child_node_scoped(dev, child) { + u32 ch, diff[2], se, common; + int chtypes_found = 0; + + if (!fwnode_name_eq(child, "channel")) + continue; + + ret = fwnode_property_read_u32(child, "reg", &ch); + if (ret) + return ret; + + ret = fwnode_property_read_u32_array(child, "diff-channels", + &diff[0], 2); + if (!ret) + chtypes_found |= IIO_ADC_CHAN_PROP_TYPE_DIFF; + + ret = fwnode_property_read_u32(child, "single-channel", &se); + if (!ret) + chtypes_found |= IIO_ADC_CHAN_PROP_TYPE_SINGLE_ENDED; + + ret = fwnode_property_read_u32(child, "common-mode-channel", + &common); + if (!ret) + chtypes_found |= BIT(IIO_ADC_CHAN_PROP_COMMON); + + ret = iio_adc_prop_type_check_sanity(dev, expected_props, + chtypes_found); + if (ret) + return ret; + + *chan = *template; + chan->channel = ch; + + if (chtypes_found & IIO_ADC_CHAN_PROP_TYPE_DIFF) { + chan->differential = 1; + chan->channel = diff[0]; + chan->channel2 = diff[1]; + + } else if (chtypes_found & IIO_ADC_CHAN_PROP_TYPE_SINGLE_ENDED) { + chan->channel = se; + if (chtypes_found & BIT(IIO_ADC_CHAN_PROP_COMMON)) + chan->channel2 = common; + } + + /* + * We assume the channel IDs start from 0. If it seems this is + * not a sane assumption, then we have to add 'allowed ID ranges' + * to the struct iio_adc_props because some of the callers may + * rely on the IDs being in this range - and have arrays indexed + * by the ID. + */ + if (chan->channel >= num_chan) + return -ERANGE; + + chan++; + } + + return num_chan; +} +EXPORT_SYMBOL_GPL(devm_iio_adc_device_alloc_chaninfo); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_DESCRIPTION("IIO ADC fwnode parsing helpers"); diff --git a/include/linux/iio/adc-helpers.h b/include/linux/iio/adc-helpers.h new file mode 100644 index 000000000000..f7791d45dbd2 --- /dev/null +++ b/include/linux/iio/adc-helpers.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* The industrial I/O ADC helpers + * + * Copyright (c) 2025 Matti Vaittinen + */ + +#ifndef _INDUSTRIAL_IO_ADC_HELPERS_H_ +#define _INDUSTRIAL_IO_ADC_HELPERS_H_ + +#include + +struct device; +struct fwnode_handle; + +enum { + IIO_ADC_CHAN_PROP_REG, + IIO_ADC_CHAN_PROP_SINGLE_ENDED, + IIO_ADC_CHAN_PROP_DIFF, + IIO_ADC_CHAN_PROP_COMMON, + IIO_ADC_CHAN_NUM_PROP_TYPES +}; + +/* + * Channel property types to be used with iio_adc_device_get_channels, + * devm_iio_adc_device_alloc_chaninfo, ... + */ +#define IIO_ADC_CHAN_PROP_TYPE_REG BIT(IIO_ADC_CHAN_PROP_REG) +#define IIO_ADC_CHAN_PROP_TYPE_SINGLE_ENDED BIT(IIO_ADC_CHAN_PROP_SINGLE_ENDED) +#define IIO_ADC_CHAN_PROP_TYPE_SINGLE_COMMON \ + (BIT(IIO_ADC_CHAN_PROP_SINGLE_ENDED) | BIT(IIO_ADC_CHAN_PROP_COMMON)) +#define IIO_ADC_CHAN_PROP_TYPE_DIFF BIT(IIO_ADC_CHAN_PROP_DIFF) +#define IIO_ADC_CHAN_PROP_TYPE_ALL GENMASK(IIO_ADC_CHAN_NUM_PROP_TYPES - 1, 0) + +/** + * iio_adc_chan_props - information of expected device-tree channel properties + * + * @required: Bitmask of property definitions of required channel properties + * @allowed: Bitmask of property definitions of optional channel properties. + * Listing of required properties is not needed here. + */ +struct iio_adc_props { + unsigned long required; + unsigned long allowed; +}; + +int iio_adc_device_num_channels(struct device *dev); +int devm_iio_adc_device_alloc_chaninfo(struct device *dev, + const struct iio_chan_spec *template, + struct iio_chan_spec **cs, + const struct iio_adc_props *expected_props); + +int iio_adc_device_channels_by_property(struct device *dev, int *channels, + int max_channels, + const struct iio_adc_props *expected_props); +#endif /* _INDUSTRIAL_IO_ADC_HELPERS_H_ */ From patchwork Wed Feb 19 12:30:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matti Vaittinen X-Patchwork-Id: 13982077 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 31D0BC021AA for ; Wed, 19 Feb 2025 12:36:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=WeZIae6i5fqo6f26wLpjChgiIOLzZTNNStJ9CeilpHA=; b=JqZz4jqsrxzvkH6+jRT7TMKKVc 2z4OAJh1lECl7wGaIsNv13mFfe5uNTE3/aQlM77x4zrF0v34WceQo+f/BgIHcJggKw78RAma6ZHlV T8f2fYxKN0PpohW5xiOXchGRi/UByxxHgDh/hdP5467MElQizf603o0ucjcl/H1QFTW9IYj+Z0PHd 8pAFDcgxvajA+jnv4dccNeGv0bh2uEqZ1itEr/n6DB0Jg/oLTpT+CxORnS8QrFT4/IRT6/UFDwwup Tm/Bx/ePxvNzEgiO+vUGSKyqeAlVA6h3D1K4Ws9/ayI3gZ/meQ2uscA3/kQKgOxWG06gpc9TSczT7 MbNNr/AA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tkjJB-0000000Chct-0F3e; Wed, 19 Feb 2025 12:36:09 +0000 Received: from mail-lj1-x22e.google.com ([2a00:1450:4864:20::22e]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tkjE2-0000000CfkF-47MQ for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2025 12:30:53 +0000 Received: by mail-lj1-x22e.google.com with SMTP id 38308e7fff4ca-3072f8dc069so69739441fa.3 for ; Wed, 19 Feb 2025 04:30:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739968249; x=1740573049; darn=lists.infradead.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=WeZIae6i5fqo6f26wLpjChgiIOLzZTNNStJ9CeilpHA=; b=Rpgr7ZL6cxrLZc9th1Mt3zIDi4y6VToOOmEDQ++nONQeq8EXSz3IEiHhMZ4WZ6kJVa 91gypv/uf9PJ9YA64ow6VvWyX1897mh9B0qYuNq9spZ6aGvsFMXfvTq4RLldrFidf7bZ 4Kny0CkpPiIy4tEV1ZA2v22WrTcbrkPIJUNvyVO8RoOpPdghElJnAB+84MEz1HwT1DIW b9XIuQMCyz93h6WFKXDjDUfX4/HE7DqZi2/KJs1kcOltnvVmMsXtVW9voHEqYInOgYQt wWDZv7PaMPVpyoQYxxHGztRlCgq2zmQfMC5MPFtS4JG7PiVO9CxYWXlEW0zEfwpopuBJ Q04A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739968249; x=1740573049; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=WeZIae6i5fqo6f26wLpjChgiIOLzZTNNStJ9CeilpHA=; b=VB1d75UUy0DGHstd4QM3vLY9W6oRNmnmP8ZcNXK/VG3OV9A+3Nhn+bJBYrqzOJXVJD ZjjS0npUKrN31mjKi9SrDjdp8+4nXpvayI6jSpwYWF3vfbrqRHuDrEiY/KFjIuwJ5tkn iuAyWC2Lp24lA2WYG5qHLYgd0pH69FqtNFps9EtGd5xZ7BkWomutWDGiWG4dTd7Ye0Dz 7/XPxM6b+TJadL+VN531dvYFdTjz1jf77dAzFfT3INnGy0s1Ur/be5N9Im2B9EeqoVCx ylYFDjt3iVs0fP5JLn7bX2FdmnHdwdHAdSaSE5btMpSt5M9AjqdwuYkiUCtfKWFaDCe8 ot1g== X-Forwarded-Encrypted: i=1; AJvYcCU+RBpHbfWu9Zt/iNSPgIDW+ZuRqqKOYwBjrf5UF+V/bMQxec9NwyvaoXfolXDBgC1xic4hLXAavrUQMhQJP4sb@lists.infradead.org X-Gm-Message-State: AOJu0YwN/1RkL/4qCnTHpQWDCX+RyMMRQsJ/RwrVQrg0UZ+e3TcLvBlQ BLbiSYXMCZFfHJAGKFEHAI0frPGsm1JMvrLFc1Hc5JeoZgS5Qhtx X-Gm-Gg: ASbGncspfvfieVdc3s9CzcVSzJJIQGewk/ePDtZD9G5GyQwajT3ZcDICm23rofoBXfx QeIm6GC7PEWIvgIG4Z2UYYYLUCSvbTLJxFPGZ0MNN3UPJnc3AFcAUyOyBPXIi5bCXsrliBQwJgg REn66ATSk52aQse6wHDsk26JC3skFBeFoon90BC8ITaA4kDN6yOM4medpHkzI/NBZJeAGC8QxM4 1azgjKa0ymeCzqGR3KwwwAuzTXb2c8wVKhjfrYeLyFlaFWD6QNg9Ah/BZpbbsSi2rSYQ2JgZ/YF w8rw8DFJ1kdS11qGd5Oj5w== X-Google-Smtp-Source: AGHT+IGTaJj8u1LcvL8BuKsGXZMBSiCm3qLQBrpBq0Nmi0BjPPHFUYblnxDkNMNFCesuFVIfv7JMCA== X-Received: by 2002:a05:6512:3195:b0:545:aa5:d451 with SMTP id 2adb3069b0e04-5462eef47d6mr1245794e87.25.1739968248680; Wed, 19 Feb 2025 04:30:48 -0800 (PST) Received: from mva-rohm ([2a10:a5c0:800d:dd00:8fdf:935a:2c85:d703]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5452d4fe147sm1715642e87.182.2025.02.19.04.30.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2025 04:30:47 -0800 (PST) Date: Wed, 19 Feb 2025 14:30:43 +0200 From: Matti Vaittinen To: Matti Vaittinen , Matti Vaittinen Cc: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matti Vaittinen , Lad Prabhakar , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Hugo Villeneuve , Nuno Sa , David Lechner , Javier Carrasco , Andy Shevchenko , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, Linus Walleij Subject: [PATCH v3 3/9] iio: adc: Support ROHM BD79124 ADC Message-ID: <67b7713724d7591f6321a8f5dfef8cd711f38d34.1739967040.git.mazziesaccount@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250219_043051_191519_A06165D3 X-CRM114-Status: GOOD ( 36.06 ) 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 The ROHM BD79124 is a 12-bit, 8-channel, SAR ADC. The ADC supports an automatic measurement mode, with an alarm interrupt for out-of-window measurements. The window is configurable for each channel. The I2C protocol for manual start of the measurement and data reading is somewhat peculiar. It requires the master to do clock stretching after sending the I2C slave-address until the slave has captured the data. Needless to say this is not well suopported by the I2C controllers. Thus the driver does not support the BD79124's manual measurement mode but implements the measurements using automatic measurement mode relying on the BD79124's ability of storing latest measurements into register. The driver does also support configuring the threshold events for detecting the out-of-window events. The BD79124 keeps asserting IRQ for as long as the measured voltage is out of the configured window. Thus the driver masks the received event for a fixed duration (1 second) when an event is handled. This prevents the user-space from choking on the events The ADC input pins can be also configured as general purpose outputs. Those pins which don't have corresponding ADC channel node in the device-tree will be controllable as GPO. Signed-off-by: Matti Vaittinen --- Revision history: v2 => v3: - Fix uninitialized return value reported by the kernel test robot - Fix indent - Adapt to adc-helper changes supporting also single-ended and differential channels RFC v1 => v2: - Add event throttling (constant delay of 1 sec) - rename variable 'd' to 'data' - Use ADC helpers to detect pins used for ADC - bd79124 drop MFD and pinmux && handle GPO in this driver - Drop adc suffix from the IIO file name --- drivers/iio/adc/Kconfig | 12 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/rohm-bd79124.c | 1162 ++++++++++++++++++++++++++++++++ 3 files changed, 1175 insertions(+) create mode 100644 drivers/iio/adc/rohm-bd79124.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 37b70a65da6f..a2a36a4ec644 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -1191,6 +1191,18 @@ config RN5T618_ADC This driver can also be built as a module. If so, the module will be called rn5t618-adc. +config ROHM_BD79124 + tristate "Rohm BD79124 ADC driver" + depends on I2C + select REGMAP_I2C + select IIO_ADC_HELPER + help + Say yes here to build support for the ROHM BD79124 ADC. The + ROHM BD79124 is a 12-bit, 8-channel, SAR ADC. The ADC supports + also an automatic measurement mode, with an alarm interrupt for + out-of-window measurements. The window is configurable for each + channel. + config ROCKCHIP_SARADC tristate "Rockchip SARADC driver" depends on ARCH_ROCKCHIP || COMPILE_TEST diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 956c121a7544..43f159aba390 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -108,6 +108,7 @@ obj-$(CONFIG_QCOM_VADC_COMMON) += qcom-vadc-common.o obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o obj-$(CONFIG_RICHTEK_RTQ6056) += rtq6056.o obj-$(CONFIG_RN5T618_ADC) += rn5t618-adc.o +obj-$(CONFIG_ROHM_BD79124) += rohm-bd79124.o obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o obj-$(CONFIG_RZG2L_ADC) += rzg2l_adc.o obj-$(CONFIG_SC27XX_ADC) += sc27xx_adc.o diff --git a/drivers/iio/adc/rohm-bd79124.c b/drivers/iio/adc/rohm-bd79124.c new file mode 100644 index 000000000000..5e23bc8d9ce2 --- /dev/null +++ b/drivers/iio/adc/rohm-bd79124.c @@ -0,0 +1,1162 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * ROHM ADC driver for BD79124 ADC/GPO device + * https://fscdn.rohm.com/en/products/databook/datasheet/ic/data_converter/dac/bd79124muf-c-e.pdf + * + * Copyright (c) 2025, ROHM Semiconductor. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define BD79124_I2C_MULTI_READ 0x30 +#define BD79124_I2C_MULTI_WRITE 0x28 +#define BD79124_REG_MAX 0xaf + +#define BD79124_REG_SYSTEM_STATUS 0x0 +#define BD79124_REG_GEN_CFG 0x01 +#define BD79124_REG_OPMODE_CFG 0x04 +#define BD79124_REG_PINCFG 0x05 +#define BD79124_REG_GPO_VAL 0x0B +#define BD79124_REG_SEQUENCE_CFG 0x10 +#define BD79124_REG_MANUAL_CHANNELS 0x11 +#define BD79124_REG_AUTO_CHANNELS 0x12 +#define BD79124_REG_ALERT_CH_SEL 0x14 +#define BD79124_REG_EVENT_FLAG 0x18 +#define BD79124_REG_EVENT_FLAG_HI 0x1a +#define BD79124_REG_EVENT_FLAG_LO 0x1c +#define BD79124_REG_HYSTERESIS_CH0 0x20 +#define BD79124_REG_EVENTCOUNT_CH0 0x22 +#define BD79124_REG_RECENT_CH0_LSB 0xa0 +#define BD79124_REG_RECENT_CH7_MSB 0xaf + +#define BD79124_ADC_BITS 12 +#define BD79124_MASK_CONV_MODE GENMASK(6, 5) +#define BD79124_MASK_AUTO_INTERVAL GENMASK(1, 0) +#define BD79124_CONV_MODE_MANSEQ 0 +#define BD79124_CONV_MODE_AUTO 1 +#define BD79124_INTERVAL_075 0 +#define BD79124_INTERVAL_150 1 +#define BD79124_INTERVAL_300 2 +#define BD79124_INTERVAL_600 3 + +#define BD79124_MASK_DWC_EN BIT(4) +#define BD79124_MASK_STATS_EN BIT(5) +#define BD79124_MASK_SEQ_START BIT(4) +#define BD79124_MASK_SEQ_MODE GENMASK(1, 0) +#define BD79124_MASK_SEQ_MANUAL 0 +#define BD79124_MASK_SEQ_SEQ 1 + +#define BD79124_MASK_HYSTERESIS GENMASK(3, 0) +#define BD79124_LOW_LIMIT_MIN 0 +#define BD79124_HIGH_LIMIT_MAX GENMASK(11, 0) + +/* + * The high limit, low limit and last measurement result are each stored in + * 2 consequtive registers. 4 bits are in the high bits of the 1.st register + * and 8 bits in the next register. + * + * These macros return the address of the 1.st reg for the given channel + */ +#define BD79124_GET_HIGH_LIMIT_REG(ch) (BD79124_REG_HYSTERESIS_CH0 + (ch) * 4) +#define BD79124_GET_LOW_LIMIT_REG(ch) (BD79124_REG_EVENTCOUNT_CH0 + (ch) * 4) +#define BD79124_GET_LIMIT_REG(ch, dir) ((dir) == IIO_EV_DIR_RISING ? \ + BD79124_GET_HIGH_LIMIT_REG(ch) : BD79124_GET_LOW_LIMIT_REG(ch)) +#define BD79124_GET_RECENT_RES_REG(ch) (BD79124_REG_RECENT_CH0_LSB + (ch) * 2) + +/* + * The hysteresis for a channel is stored in the same register where the + * 4 bits of high limit reside. + */ +#define BD79124_GET_HYSTERESIS_REG(ch) BD79124_GET_HIGH_LIMIT_REG(ch) + +#define BD79124_MAX_NUM_CHANNELS 8 + +/* + * We require the "reg" property and allow no other + * channel specifiers for the BD79124. + */ +static const struct iio_adc_props expected_props = { + .required = IIO_ADC_CHAN_PROP_TYPE_REG, +}; + +struct bd79124_data { + s64 timestamp; + struct regmap *map; + struct device *dev; + int vmax; + /* + * Keep measurement status so read_raw() knows if the measurement needs + * to be started. + */ + int alarm_monitored[BD79124_MAX_NUM_CHANNELS]; + /* + * The BD79124 does not allow disabling/enabling limit separately for + * one direction only. Hence, we do the disabling by changing the limit + * to maximum/minimum measurable value. This means we need to cache + * the limit in order to maintain it over the time limit is disabled. + */ + u16 alarm_r_limit[BD79124_MAX_NUM_CHANNELS]; + u16 alarm_f_limit[BD79124_MAX_NUM_CHANNELS]; + /* Bitmask of disabled events (for rate limiting) for each channel. */ + int alarm_suppressed[BD79124_MAX_NUM_CHANNELS]; + /* + * The BD79124 is configured to run the measurements in the background. + * This is done for the event monitoring as well as for the read_raw(). + * Protect the measurement starting/stopping using a mutex. + */ + struct mutex mutex; + struct delayed_work alm_enable_work; + struct gpio_chip gc; +}; + +/* Read-only regs */ +static const struct regmap_range bd79124_ro_ranges[] = { + { + .range_min = BD79124_REG_EVENT_FLAG, + .range_max = BD79124_REG_EVENT_FLAG, + }, { + .range_min = BD79124_REG_RECENT_CH0_LSB, + .range_max = BD79124_REG_RECENT_CH7_MSB, + }, +}; + +static const struct regmap_access_table bd79124_ro_regs = { + .no_ranges = &bd79124_ro_ranges[0], + .n_no_ranges = ARRAY_SIZE(bd79124_ro_ranges), +}; + +static const struct regmap_range bd79124_volatile_ranges[] = { + { + .range_min = BD79124_REG_RECENT_CH0_LSB, + .range_max = BD79124_REG_RECENT_CH7_MSB, + }, { + .range_min = BD79124_REG_EVENT_FLAG, + .range_max = BD79124_REG_EVENT_FLAG, + }, { + .range_min = BD79124_REG_EVENT_FLAG_HI, + .range_max = BD79124_REG_EVENT_FLAG_HI, + }, { + .range_min = BD79124_REG_EVENT_FLAG_LO, + .range_max = BD79124_REG_EVENT_FLAG_LO, + }, { + .range_min = BD79124_REG_SYSTEM_STATUS, + .range_max = BD79124_REG_SYSTEM_STATUS, + }, +}; + +static const struct regmap_access_table bd79124_volatile_regs = { + .yes_ranges = &bd79124_volatile_ranges[0], + .n_yes_ranges = ARRAY_SIZE(bd79124_volatile_ranges), +}; + +static const struct regmap_range bd79124_precious_ranges[] = { + { + .range_min = BD79124_REG_EVENT_FLAG_HI, + .range_max = BD79124_REG_EVENT_FLAG_HI, + }, { + .range_min = BD79124_REG_EVENT_FLAG_LO, + .range_max = BD79124_REG_EVENT_FLAG_LO, + }, +}; + +static const struct regmap_access_table bd79124_precious_regs = { + .yes_ranges = &bd79124_precious_ranges[0], + .n_yes_ranges = ARRAY_SIZE(bd79124_precious_ranges), +}; + +static const struct regmap_config bd79124_regmap = { + .reg_bits = 16, + .val_bits = 8, + .read_flag_mask = BD79124_I2C_MULTI_READ, + .write_flag_mask = BD79124_I2C_MULTI_WRITE, + .max_register = BD79124_REG_MAX, + .cache_type = REGCACHE_MAPLE, + .volatile_table = &bd79124_volatile_regs, + .wr_table = &bd79124_ro_regs, + .precious_table = &bd79124_precious_regs, +}; + +static int bd79124gpo_direction_get(struct gpio_chip *gc, unsigned int offset) +{ + return GPIO_LINE_DIRECTION_OUT; +} + +static void bd79124gpo_set(struct gpio_chip *gc, unsigned int offset, int value) +{ + struct bd79124_data *data = gpiochip_get_data(gc); + + if (value) + regmap_set_bits(data->map, BD79124_REG_GPO_VAL, BIT(offset)); + else + regmap_clear_bits(data->map, BD79124_REG_GPO_VAL, BIT(offset)); +} + +static void bd79124gpo_set_multiple(struct gpio_chip *gc, unsigned long *mask, + unsigned long *bits) +{ + int ret, val; + struct bd79124_data *data = gpiochip_get_data(gc); + + /* Ensure all GPIOs in 'mask' are set to be GPIOs */ + ret = regmap_read(data->map, BD79124_REG_PINCFG, &val); + if (ret) + return; + + if ((val & *mask) != *mask) { + dev_dbg(data->dev, "Invalid mux config. Can't set value.\n"); + /* Do not set value for pins configured as ADC inputs */ + *mask &= val; + } + + regmap_update_bits(data->map, BD79124_REG_GPO_VAL, *mask, *bits); +} + +static int bd79124_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + int adc_channels[BD79124_MAX_NUM_CHANNELS]; + int ret, num_channels, gpo_chan, j; + + *valid_mask = 0; + + ret = iio_adc_device_channels_by_property(gc->parent, adc_channels, + BD79124_MAX_NUM_CHANNELS, + &expected_props); + if (ret < 0) + return ret; + + num_channels = ret; + + for (gpo_chan = 0; gpo_chan < BD79124_MAX_NUM_CHANNELS; gpo_chan++) { + for (j = 0; j < num_channels; j++) { + if (adc_channels[j] == gpo_chan) + break; + } + if (j == num_channels) + *valid_mask |= BIT(gpo_chan); + } + + return 0; +} + +/* Template for GPIO chip */ +static const struct gpio_chip bd79124gpo_chip = { + .label = "bd79124-gpo", + .get_direction = bd79124gpo_direction_get, + .set = bd79124gpo_set, + .set_multiple = bd79124gpo_set_multiple, + .init_valid_mask = bd79124_init_valid_mask, + .can_sleep = true, + .ngpio = 8, + .base = -1, +}; + +struct bd79124_raw { + u8 bit0_3; /* Is set in high bits of the byte */ + u8 bit4_11; +}; +#define BD79124_RAW_TO_INT(r) ((r.bit4_11 << 4) | (r.bit0_3 >> 4)) + +/* + * The high and low limits as well as the recent result values are stored in + * the same way in 2 consequent registers. The first register contains 4 bits + * of the value. These bits are stored in the high bits [7:4] of register, but + * they represent the low bits [3:0] of the value. + * The value bits [11:4] are stored in the next register. + * + * Read data from register and convert to integer. + */ +static int bd79124_read_reg_to_int(struct bd79124_data *data, int reg, + unsigned int *val) +{ + int ret; + struct bd79124_raw raw; + + ret = regmap_bulk_read(data->map, reg, &raw, sizeof(raw)); + if (ret) { + dev_dbg(data->dev, "bulk_read failed %d\n", ret); + + return ret; + } + + *val = BD79124_RAW_TO_INT(raw); + + return 0; +} + +/* + * The high and low limits as well as the recent result values are stored in + * the same way in 2 consequent registers. The first register contains 4 bits + * of the value. These bits are stored in the high bits [7:4] of register, but + * they represent the low bits [3:0] of the value. + * The value bits [11:4] are stored in the next regoster. + * + * Conver the integer to register format and write it using rmw cycle. + */ +static int bd79124_write_int_to_reg(struct bd79124_data *data, int reg, + unsigned int val) +{ + struct bd79124_raw raw; + int ret, tmp; + + raw.bit4_11 = (u8)(val >> 4); + raw.bit0_3 = (u8)(val << 4); + + ret = regmap_read(data->map, reg, &tmp); + if (ret) + return ret; + + raw.bit0_3 |= (0xf & tmp); + + return regmap_bulk_write(data->map, reg, &raw, sizeof(raw)); +} + +static const struct iio_event_spec bd79124_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS), + }, +}; + +static const struct iio_chan_spec bd79124_chan_template_noirq = { + .type = IIO_VOLTAGE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + .indexed = 1, +}; + +static const struct iio_chan_spec bd79124_chan_template = { + .type = IIO_VOLTAGE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), + .indexed = 1, + .event_spec = bd79124_events, + .num_event_specs = ARRAY_SIZE(bd79124_events), +}; + +static int bd79124_read_event_value(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int *val, + int *val2) +{ + struct bd79124_data *data = iio_priv(iio_dev); + int ret, reg; + + if (chan->channel >= BD79124_MAX_NUM_CHANNELS) + return -EINVAL; + + switch (info) { + case IIO_EV_INFO_VALUE: + if (dir == IIO_EV_DIR_RISING) + *val = data->alarm_r_limit[chan->channel]; + else if (dir == IIO_EV_DIR_FALLING) + *val = data->alarm_f_limit[chan->channel]; + else + return -EINVAL; + + return IIO_VAL_INT; + + case IIO_EV_INFO_HYSTERESIS: + reg = BD79124_GET_HYSTERESIS_REG(chan->channel); + ret = regmap_read(data->map, reg, val); + if (ret) + return ret; + /* Mask the non hysteresis bits */ + *val &= BD79124_MASK_HYSTERESIS; + /* + * The data-sheet says the hysteresis register value needs to be + * sifted left by 3 (or multiplied by 8, depending on the + * page :] ) + */ + *val <<= 3; + + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int bd79124_start_measurement(struct bd79124_data *data, int chan) +{ + int val, ret, regval; + + /* See if already started */ + ret = regmap_read(data->map, BD79124_REG_AUTO_CHANNELS, &val); + if (val & BIT(chan)) + return 0; + + ret = regmap_clear_bits(data->map, BD79124_REG_SEQUENCE_CFG, + BD79124_MASK_SEQ_START); + if (ret) + return ret; + + /* Add the channel to measured channels */ + ret = regmap_write(data->map, BD79124_REG_AUTO_CHANNELS, val | BIT(chan)); + if (ret) + return ret; + + ret = regmap_set_bits(data->map, BD79124_REG_SEQUENCE_CFG, + BD79124_MASK_SEQ_START); + if (ret) + return ret; + + /* + * Start the measurement at the background. Don't bother checking if + * it was started, regmap has cache. + */ + regval = FIELD_PREP(BD79124_MASK_CONV_MODE, BD79124_CONV_MODE_AUTO); + + return regmap_update_bits(data->map, BD79124_REG_OPMODE_CFG, + BD79124_MASK_CONV_MODE, regval); +} + +static int bd79124_stop_measurement(struct bd79124_data *data, int chan) +{ + int val, ret; + + /* See if already stopped */ + ret = regmap_read(data->map, BD79124_REG_AUTO_CHANNELS, &val); + if (!(val & BIT(chan))) + return 0; + + ret = regmap_clear_bits(data->map, BD79124_REG_SEQUENCE_CFG, + BD79124_MASK_SEQ_START); + + /* Clear the channel from the measured channels */ + ret = regmap_write(data->map, BD79124_REG_AUTO_CHANNELS, + (~BIT(chan)) & val); + if (ret) + return ret; + + /* + * Stop background conversion for power saving if it was the last + * channel + */ + if (!((~BIT(chan)) & val)) { + int regval = FIELD_PREP(BD79124_MASK_CONV_MODE, + BD79124_CONV_MODE_MANSEQ); + + ret = regmap_update_bits(data->map, BD79124_REG_OPMODE_CFG, + BD79124_MASK_CONV_MODE, regval); + if (ret) + return ret; + } + + return regmap_set_bits(data->map, BD79124_REG_SEQUENCE_CFG, + BD79124_MASK_SEQ_START); +} + +static int bd79124_read_event_config(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct bd79124_data *data = iio_priv(iio_dev); + + if (chan->channel >= BD79124_MAX_NUM_CHANNELS) + return -EINVAL; + + return (data->alarm_monitored[chan->channel] & BIT(dir)); +} + +static int bd79124_disable_event(struct bd79124_data *data, + enum iio_event_direction dir, int channel) +{ + int dir_bit = BIT(dir), reg; + unsigned int limit; + + guard(mutex)(&data->mutex); + /* + * Set thresholds either to 0 or to 2^12 - 1 as appropriate to prevent + * alerts and thus disable event generation. + */ + if (dir == IIO_EV_DIR_RISING) { + reg = BD79124_GET_HIGH_LIMIT_REG(channel); + limit = BD79124_HIGH_LIMIT_MAX; + } else if (dir == IIO_EV_DIR_FALLING) { + reg = BD79124_GET_LOW_LIMIT_REG(channel); + limit = BD79124_LOW_LIMIT_MIN; + } else { + return -EINVAL; + } + + data->alarm_monitored[channel] &= (~dir_bit); + /* + * Stop measurement if there is no more events to monitor. + * We don't bother checking the retval because the limit + * setting should in any case effectively disable the alarm. + */ + if (!data->alarm_monitored[channel]) { + bd79124_stop_measurement(data, channel); + regmap_clear_bits(data->map, BD79124_REG_ALERT_CH_SEL, + BIT(channel)); + } + + return bd79124_write_int_to_reg(data, reg, limit); +} + +static int bd79124_enable_event(struct bd79124_data *data, + enum iio_event_direction dir, unsigned int channel) +{ + int dir_bit = BIT(dir); + int reg; + u16 *limit; + int ret; + + guard(mutex)(&data->mutex); + /* Set channel to be measured */ + ret = bd79124_start_measurement(data, channel); + if (ret) + return ret; + + data->alarm_monitored[channel] |= dir_bit; + + /* Add the channel to the list of monitored channels */ + ret = regmap_set_bits(data->map, BD79124_REG_ALERT_CH_SEL, + BIT(channel)); + if (ret) + return ret; + + if (dir == IIO_EV_DIR_RISING) { + limit = &data->alarm_f_limit[channel]; + reg = BD79124_GET_HIGH_LIMIT_REG(channel); + } else { + limit = &data->alarm_f_limit[channel]; + reg = BD79124_GET_LOW_LIMIT_REG(channel); + } + /* Don't write the new limit to the hardware if we are in the + * rate-limit period. The timer which re-enables the event will set + * the limit. + */ + if (!(data->alarm_suppressed[channel] & dir_bit)) { + ret = bd79124_write_int_to_reg(data, reg, *limit); + if (ret) + return ret; + } + + /* + * Enable comparator. Trust the regmap cache, no need to check + * if it was already enabled. + * + * We could do this in the hw-init, but there may be users who + * never enable alarms and for them it makes sense to not + * enable the comparator at probe. + */ + return regmap_set_bits(data->map, BD79124_REG_GEN_CFG, + BD79124_MASK_DWC_EN); + +} + +static int bd79124_write_event_config(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, bool state) +{ + struct bd79124_data *data = iio_priv(iio_dev); + + if (chan->channel >= BD79124_MAX_NUM_CHANNELS) + return -EINVAL; + + if (state) + return bd79124_enable_event(data, dir, chan->channel); + + return bd79124_disable_event(data, dir, chan->channel); +} + +static int bd79124_write_event_value(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int val, + int val2) +{ + struct bd79124_data *data = iio_priv(iio_dev); + int reg; + + if (chan->channel >= BD79124_MAX_NUM_CHANNELS) + return -EINVAL; + + switch (info) { + case IIO_EV_INFO_VALUE: + if (dir == IIO_EV_DIR_RISING) { + guard(mutex)(&data->mutex); + + data->alarm_r_limit[chan->channel] = val; + reg = BD79124_GET_HIGH_LIMIT_REG(chan->channel); + } else if (dir == IIO_EV_DIR_FALLING) { + guard(mutex)(&data->mutex); + + data->alarm_f_limit[chan->channel] = val; + reg = BD79124_GET_LOW_LIMIT_REG(chan->channel); + } else { + return -EINVAL; + } + /* + * We don't want to enable the alarm if it is not enabled or + * if it is suppressed. In that case skip writing to the + * register. + */ + if (!(data->alarm_monitored[chan->channel] & BIT(dir)) || + data->alarm_suppressed[chan->channel] & BIT(dir)) + return 0; + + return bd79124_write_int_to_reg(data, reg, val); + + case IIO_EV_INFO_HYSTERESIS: + reg = BD79124_GET_HYSTERESIS_REG(chan->channel); + val >>= 3; + + return regmap_update_bits(data->map, reg, BD79124_MASK_HYSTERESIS, + val); + default: + return -EINVAL; + } +} + +static int bd79124_single_chan_seq(struct bd79124_data *data, int chan, int *old) +{ + int ret; + + ret = regmap_clear_bits(data->map, BD79124_REG_SEQUENCE_CFG, + BD79124_MASK_SEQ_START); + if (ret) + return ret; + + /* + * It may be we have some channels monitored for alarms so we want to + * cache the old config and return it when the single channel + * measurement has been completed. + */ + ret = regmap_read(data->map, BD79124_REG_AUTO_CHANNELS, old); + if (ret) + return ret; + + ret = regmap_write(data->map, BD79124_REG_AUTO_CHANNELS, BIT(chan)); + if (ret) + return ret; + + /* Restart the sequencer */ + return regmap_set_bits(data->map, BD79124_REG_SEQUENCE_CFG, + BD79124_MASK_SEQ_START); +} + +static int bd79124_single_chan_seq_end(struct bd79124_data *data, int old) +{ + int ret; + + ret = regmap_clear_bits(data->map, BD79124_REG_SEQUENCE_CFG, + BD79124_MASK_SEQ_START); + if (ret) + return ret; + + ret = regmap_write(data->map, BD79124_REG_AUTO_CHANNELS, old); + if (ret) + return ret; + + return regmap_set_bits(data->map, BD79124_REG_SEQUENCE_CFG, + BD79124_MASK_SEQ_START); +} + +static int bd79124_read_raw(struct iio_dev *iio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long m) +{ + struct bd79124_data *data = iio_priv(iio_dev); + int ret; + + if (chan->channel >= BD79124_MAX_NUM_CHANNELS) + return -EINVAL; + + switch (m) { + case IIO_CHAN_INFO_RAW: + { + int old_chan_cfg, tmp; + int regval; + + guard(mutex)(&data->mutex); + + /* + * Start the automatic conversion. This is needed here if no + * events have been enabled. + */ + regval = FIELD_PREP(BD79124_MASK_CONV_MODE, + BD79124_CONV_MODE_AUTO); + ret = regmap_update_bits(data->map, BD79124_REG_OPMODE_CFG, + BD79124_MASK_CONV_MODE, regval); + if (ret) + return ret; + + ret = bd79124_single_chan_seq(data, chan->channel, &old_chan_cfg); + if (ret) + return ret; + + /* The maximum conversion time is 6 uS. */ + udelay(6); + + ret = bd79124_read_reg_to_int(data, + BD79124_GET_RECENT_RES_REG(chan->channel), + val); + /* + * Return the old chan config even if data reading failed in + * order to re-enable the event monitoring. + */ + tmp = bd79124_single_chan_seq_end(data, old_chan_cfg); + if (tmp) + dev_err(data->dev, + "Failed to return config. Alarms may be disabled\n"); + + if (ret) + return ret; + + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_SCALE: + *val = data->vmax / 1000; + *val2 = BD79124_ADC_BITS; + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; + } +} + +static const struct iio_info bd79124_info = { + .read_raw = bd79124_read_raw, + .read_event_config = &bd79124_read_event_config, + .write_event_config = &bd79124_write_event_config, + .read_event_value = &bd79124_read_event_value, + .write_event_value = &bd79124_write_event_value, +}; + +static void bd79124_re_enable_lo(struct bd79124_data *data, unsigned int channel) +{ + int ret, evbit = BIT(IIO_EV_DIR_FALLING); + + if (!(data->alarm_suppressed[channel] & evbit)) + return; + + data->alarm_suppressed[channel] &= (~evbit); + + if (!(data->alarm_monitored[channel] & evbit)) + return; + + ret = bd79124_write_int_to_reg(data, BD79124_GET_LOW_LIMIT_REG(channel), + data->alarm_f_limit[channel]); + if (ret) + dev_warn(data->dev, "Low limit enabling failed for channel%d\n", + channel); +} + +static void bd79124_re_enable_hi(struct bd79124_data *data, unsigned int channel) +{ + int ret, evbit = BIT(IIO_EV_DIR_RISING); + + if (!(data->alarm_suppressed[channel] & evbit)) + return; + + data->alarm_suppressed[channel] &= (~evbit); + + if (!(data->alarm_monitored[channel] & evbit)) + return; + + ret = bd79124_write_int_to_reg(data, BD79124_GET_HIGH_LIMIT_REG(channel), + data->alarm_r_limit[channel]); + if (ret) + dev_warn(data->dev, "High limit enabling failed for channel%d\n", + channel); +} + +static void bd79124_alm_enable_worker(struct work_struct *work) +{ + int i; + struct bd79124_data *data = container_of(work, struct bd79124_data, + alm_enable_work.work); + + guard(mutex)(&data->mutex); + /* + * We should not re-enable the event if user has disabled it while + * rate-limiting was enabled. + */ + for (i = 0; i < BD79124_MAX_NUM_CHANNELS; i++) { + bd79124_re_enable_hi(data, i); + bd79124_re_enable_lo(data, i); + } +} + +static int __bd79124_event_ratelimit(struct bd79124_data *data, int reg, + unsigned int limit) +{ + int ret; + + if (limit > BD79124_HIGH_LIMIT_MAX) + return -EINVAL; + + ret = bd79124_write_int_to_reg(data, reg, limit); + if (ret) + return ret; + + /* + * We use 1 sec 'grace period'. At the moment I see no reason to make + * this user configurable. We need an ABI for this if configuration is + * needed. + */ + schedule_delayed_work(&data->alm_enable_work, + msecs_to_jiffies(1000)); + + return 0; +} + +static int bd79124_event_ratelimit_hi(struct bd79124_data *data, + unsigned int channel) +{ + int reg, limit; + + guard(mutex)(&data->mutex); + data->alarm_suppressed[channel] |= BIT(IIO_EV_DIR_RISING); + + reg = BD79124_GET_HIGH_LIMIT_REG(channel); + limit = BD79124_HIGH_LIMIT_MAX; + + return __bd79124_event_ratelimit(data, reg, limit); +} + +static int bd79124_event_ratelimit_lo(struct bd79124_data *data, + unsigned int channel) +{ + int reg, limit; + + guard(mutex)(&data->mutex); + data->alarm_suppressed[channel] |= BIT(IIO_EV_DIR_FALLING); + + reg = BD79124_GET_LOW_LIMIT_REG(channel); + limit = BD79124_LOW_LIMIT_MIN; + + return __bd79124_event_ratelimit(data, reg, limit); +} + +static irqreturn_t bd79124_event_handler(int irq, void *priv) +{ + int ret, i_hi, i_lo, i; + struct iio_dev *iio_dev = priv; + struct bd79124_data *data = iio_priv(iio_dev); + + /* + * Return IRQ_NONE if bailing-out without acking. This allows the IRQ + * subsystem to disable the offending IRQ line if we get a hardware + * problem. This behaviour has saved my poor bottom a few times in the + * past as, instead of getting unusably unresponsive, the system has + * spilled out the magic words "...nobody cared". + */ + ret = regmap_read(data->map, BD79124_REG_EVENT_FLAG_HI, &i_hi); + if (ret) + return IRQ_NONE; + + ret = regmap_read(data->map, BD79124_REG_EVENT_FLAG_LO, &i_lo); + if (ret) + return IRQ_NONE; + + if (!i_lo && !i_hi) + return IRQ_NONE; + + for (i = 0; i < BD79124_MAX_NUM_CHANNELS; i++) { + u64 ecode; + + if (BIT(i) & i_hi) { + ecode = IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING); + + iio_push_event(iio_dev, ecode, data->timestamp); + /* + * The BD79124 keeps the IRQ asserted for as long as + * the voltage exceeds the threshold. It causes the IRQ + * to keep firing. + * + * Disable the event for the channel and schedule the + * re-enabling the event later to prevent storm of + * events. + */ + ret = bd79124_event_ratelimit_hi(data, i); + if (ret) + return IRQ_NONE; + } + if (BIT(i) & i_lo) { + ecode = IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING); + + iio_push_event(iio_dev, ecode, data->timestamp); + ret = bd79124_event_ratelimit_lo(data, i); + if (ret) + return IRQ_NONE; + } + } + + ret = regmap_write(data->map, BD79124_REG_EVENT_FLAG_HI, i_hi); + if (ret) + return IRQ_NONE; + + ret = regmap_write(data->map, BD79124_REG_EVENT_FLAG_LO, i_lo); + if (ret) + return IRQ_NONE; + + return IRQ_HANDLED; +} + +static irqreturn_t bd79124_irq_handler(int irq, void *priv) +{ + struct iio_dev *iio_dev = priv; + struct bd79124_data *data = iio_priv(iio_dev); + + data->timestamp = iio_get_time_ns(iio_dev); + + return IRQ_WAKE_THREAD; +} + +struct bd79124_reg_init { + int reg; + int val; +}; + +static int bd79124_chan_init(struct bd79124_data *data, int channel) +{ + struct bd79124_reg_init inits[] = { + { .reg = BD79124_GET_HIGH_LIMIT_REG(channel), .val = 4095 }, + { .reg = BD79124_GET_LOW_LIMIT_REG(channel), .val = 0 }, + }; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(inits); i++) { + ret = regmap_write(data->map, inits[i].reg, inits[i].val); + if (ret) + return ret; + } + + return 0; +} + +static bool bd79124_is_in_array(int *arr, int num_items, int val) +{ + int i; + + for (i = 0; i < num_items; i++) + if (arr[i] == val) + return true; + + return false; +} + +static int bd79124_mux_init(struct bd79124_data *data) +{ + int adc_chans[BD79124_MAX_NUM_CHANNELS]; + int num_adc, chan, regval = 0; + + num_adc = iio_adc_device_channels_by_property(data->dev, &adc_chans[0], + BD79124_MAX_NUM_CHANNELS, + &expected_props); + if (num_adc < 0) + return num_adc; + + /* + * Set a mux register bit for each pin which is free to be used as + * a GPO. + */ + for (chan = 0; chan < BD79124_MAX_NUM_CHANNELS; chan++) + if (!bd79124_is_in_array(&adc_chans[0], num_adc, chan)) + regval |= BIT(chan); + + return regmap_write(data->map, BD79124_REG_PINCFG, regval); +} + +static int bd79124_hw_init(struct bd79124_data *data) +{ + int ret, regval, i; + + ret = bd79124_mux_init(data); + if (ret) + return ret; + + for (i = 0; i < BD79124_MAX_NUM_CHANNELS; i++) { + ret = bd79124_chan_init(data, i); + if (ret) + return ret; + data->alarm_r_limit[i] = 4095; + } + /* Stop auto sequencer */ + ret = regmap_clear_bits(data->map, BD79124_REG_SEQUENCE_CFG, + BD79124_MASK_SEQ_START); + if (ret) + return ret; + + /* Enable writing the measured values to the regsters */ + ret = regmap_set_bits(data->map, BD79124_REG_GEN_CFG, + BD79124_MASK_STATS_EN); + if (ret) + return ret; + + /* Set no channels to be auto-measured */ + ret = regmap_write(data->map, BD79124_REG_AUTO_CHANNELS, 0x0); + if (ret) + return ret; + + /* Set no channels to be manually measured */ + ret = regmap_write(data->map, BD79124_REG_MANUAL_CHANNELS, 0x0); + if (ret) + return ret; + + /* Set the measurement interval to 0.75 mS */ + regval = FIELD_PREP(BD79124_MASK_AUTO_INTERVAL, BD79124_INTERVAL_075); + ret = regmap_update_bits(data->map, BD79124_REG_OPMODE_CFG, + BD79124_MASK_AUTO_INTERVAL, regval); + if (ret) + return ret; + + /* Sequencer mode to auto */ + ret = regmap_set_bits(data->map, BD79124_REG_SEQUENCE_CFG, + BD79124_MASK_SEQ_SEQ); + if (ret) + return ret; + + /* Don't start the measurement */ + regval = FIELD_PREP(BD79124_MASK_CONV_MODE, BD79124_CONV_MODE_MANSEQ); + + return regmap_update_bits(data->map, BD79124_REG_OPMODE_CFG, + BD79124_MASK_CONV_MODE, BD79124_CONV_MODE_MANSEQ); + +} + +static int bd79124_probe(struct i2c_client *i2c) +{ + struct bd79124_data *data; + struct iio_dev *iio_dev; + const struct iio_chan_spec *template; + struct iio_chan_spec *cs; + struct device *dev = &i2c->dev; + int ret; + + iio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!iio_dev) + return -ENOMEM; + + data = iio_priv(iio_dev); + data->dev = dev; + data->map = devm_regmap_init_i2c(i2c, &bd79124_regmap); + if (IS_ERR(data->map)) + return dev_err_probe(dev, PTR_ERR(data->map), + "Failed to initialize Regmap\n"); + + ret = devm_regulator_get_enable_read_voltage(dev, "vdd"); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to get the Vdd\n"); + + data->vmax = ret; + + ret = devm_regulator_get_enable(dev, "iovdd"); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to enable I/O voltage\n"); + + ret = devm_delayed_work_autocancel(dev, &data->alm_enable_work, + bd79124_alm_enable_worker); + if (ret) + return ret; + + if (i2c->irq) { + template = &bd79124_chan_template; + } else { + template = &bd79124_chan_template_noirq; + dev_dbg(dev, "No IRQ found, events disabled\n"); + } + ret = devm_iio_adc_device_alloc_chaninfo(dev, template, &cs, + &expected_props); + if (ret < 0) + return ret; + + iio_dev->channels = cs; + iio_dev->num_channels = ret; + iio_dev->info = &bd79124_info; + iio_dev->name = "bd79124"; + iio_dev->modes = INDIO_DIRECT_MODE; + + data->gc = bd79124gpo_chip; + data->gc.parent = dev; + + mutex_init(&data->mutex); + + ret = bd79124_hw_init(data); + if (ret) + return ret; + + ret = devm_gpiochip_add_data(data->dev, &data->gc, data); + if (ret) + return dev_err_probe(data->dev, ret, "gpio init Failed\n"); + + if (i2c->irq > 0) { + ret = devm_request_threaded_irq(data->dev, i2c->irq, + bd79124_irq_handler, + &bd79124_event_handler, IRQF_ONESHOT, + "adc-thresh-alert", iio_dev); + if (ret) + return dev_err_probe(data->dev, ret, + "Failed to register IRQ\n"); + } + + return devm_iio_device_register(data->dev, iio_dev); +} + +static const struct of_device_id bd79124_of_match[] = { + { .compatible = "rohm,bd79124" }, + { } +}; +MODULE_DEVICE_TABLE(of, bd79124_of_match); + +static const struct i2c_device_id bd79124_id[] = { + { "bd79124", }, + { } +}; +MODULE_DEVICE_TABLE(i2c, bd79124_id); + +static struct i2c_driver bd79124_driver = { + .driver = { + .name = "bd79124", + .of_match_table = bd79124_of_match, + }, + .probe = bd79124_probe, + .id_table = bd79124_id, +}; +module_i2c_driver(bd79124_driver); + +MODULE_AUTHOR("Matti Vaittinen "); +MODULE_DESCRIPTION("Driver for ROHM BD79124 ADC"); +MODULE_LICENSE("GPL"); From patchwork Wed Feb 19 12:30:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matti Vaittinen X-Patchwork-Id: 13982078 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 323CBC021AA for ; Wed, 19 Feb 2025 12:37:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=XNzXBsdWjpLDVsAJfw/fASRvRFeX+ndkn8tRpPOZpL4=; b=o5Y2AfnIZU5+HTnrUwek8XEaZL mBC92RO+H+bAd+xQ3uVUX8zGCrLMp+mXMKWr/vc0VGUPJXuN2jEs2mogFZs45wWbkICebBlQNCcja PSDBNuCXif08WEHuczlwTZcNSlg9WnLke8/C8i81PVrxCmbBsisnj0zcI3eivs5+FNKBEQ+blgPbj qbdA6zuwTOdz1vodXHEfzcUdfpe+gqG47EPehsQhOzp6spZu1iX+bUR9FUBXMyXiDBcdaVY+RY+5A Roqg7A7ayHSpQsZj3/lCuNjdOMk8ubPvOkWYsRjudYUAzD9we7m1k0TL1bjct8xZLBRxBSrNPpYvF omOogp3w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tkjKd-0000000Ci4l-37Ub; Wed, 19 Feb 2025 12:37:39 +0000 Received: from mail-lf1-x12a.google.com ([2a00:1450:4864:20::12a]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tkjEK-0000000CftO-24MI for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2025 12:31:09 +0000 Received: by mail-lf1-x12a.google.com with SMTP id 2adb3069b0e04-54626a71b40so2570552e87.3 for ; Wed, 19 Feb 2025 04:31:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739968266; x=1740573066; darn=lists.infradead.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=XNzXBsdWjpLDVsAJfw/fASRvRFeX+ndkn8tRpPOZpL4=; b=IQxGpoogsTc64J9My3CR2FpcvduivZXn7PSvWdw+uQFB3kioBzfRFV3dVRSSe8Dd4x 1aAQFP1pCjE0C2EVcMQF4udv4hRLruBDFRypQURxZ0N5aoY1GU/gc7ToeAIgpRg/panI VZeD0shciMYp0c/bm/S0sOq984Sb/ifRJkbVI2jaWZQOZPIg60adKpASyCQizeSVDXL+ RMsXhPX0eP1Spz1Jv2Bgr1VU3ibo34KIY3RE3p5wdnl99MP8UTmTvgplHnQo37DYLNT4 cBDdvtDSW0LdLu+rWPKwZZ24buWw+vfhqAeUAoDDeNYpMPL66Ca+s9lNw+mCiWpC8Wod Md7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739968266; x=1740573066; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=XNzXBsdWjpLDVsAJfw/fASRvRFeX+ndkn8tRpPOZpL4=; b=Dr3ufBLDj+SGpJgxm93xG5iFr3kwG3LatkN9MQBHXh4cqo1Uh8NOYFQk8lVVYUaI7G HpLA5ZEntTsECBsh6ivZN2qxpyGnPKh9CplGYYy2LjL8tQ907ZmN5nizuohJkyHVZb+8 V0J0UyOGm9Dx+deINlaU3Zm8FjkPqiG9bBAPVskmKhigYxlgo+SZM9DhPjlAIwknAAxl NwlmXqfIlyI/J/YxfAbMOaKkvcG3MkoP1N5zjzF1llMIcjF0gzAtXHMpPS44H2KZPOEs BS1bGbMBOT/EJIjS2H9QNHxdwRcbCgcDL/uSa3GPYY9sM/bgkZDPsPQ5aZQ8ST48e2fG NEXg== X-Forwarded-Encrypted: i=1; AJvYcCU0rmEQhj+hQMiV1wqLbd5WdB76QQEghjBoegfDMMe//z0N4fPt4Rb0InDLpJlbo/S0BxOU2AHAVlsacR2HYhDC@lists.infradead.org X-Gm-Message-State: AOJu0YwKBH3U5861ixfmMVKE9OKci0sE84jJepPH6o7X8FH3HIdhLJSK PKS5vjzVgCvTFjSL4kpaSxGrRm9FpRAeUE750K+Lf8dlZciy/kYE X-Gm-Gg: ASbGncvBuvYHrYIiv3+x0V/3G45v86FnBkiqiN9b+eHZemvHAmd76wCa1jbMbpKJJzC BCEOp3YMNGxRtlWEo8tgwiwdIq+VcOhP+H+OFn9D3qDL6mBpNNHXGi1kLIbC2FBb+PPoYtKoZyU OI5kQEXdl/xyrYgIwfLkpqVx0DZwrYCagFNbpjPiastrAKW16XYsST2h8TSnH+gKEFiaiWbXJ8G jhDHYx3HHWOGMDPWxErzVjheZFZV/zE61L6Fdff6nU5rqYwyHSaMTHqlGjdGjMFSfthF2pnKh3D Gr6ASRlWX9K3zViCWU/3IQ== X-Google-Smtp-Source: AGHT+IGbVYVIJzf3Ky5RtSpHDBC96A6gAGmLe92KwdhKJGUa87dA9Nei6u7W+ae65z5/SkdH7rRhrA== X-Received: by 2002:a05:6512:114e:b0:545:b9a:b4b4 with SMTP id 2adb3069b0e04-5452fe8fd01mr6567349e87.52.1739968266349; Wed, 19 Feb 2025 04:31:06 -0800 (PST) Received: from mva-rohm ([2a10:a5c0:800d:dd00:8fdf:935a:2c85:d703]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5461cfe3a7fsm1193290e87.34.2025.02.19.04.31.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2025 04:31:03 -0800 (PST) Date: Wed, 19 Feb 2025 14:30:58 +0200 From: Matti Vaittinen To: Matti Vaittinen , Matti Vaittinen Cc: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matti Vaittinen , Lad Prabhakar , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Hugo Villeneuve , Nuno Sa , David Lechner , Javier Carrasco , Andy Shevchenko , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH v3 4/9] MAINTAINERS: Add IIO ADC helpers Message-ID: <65fa17207c7c716d66efb95733e6a37512465605.1739967040.git.mazziesaccount@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250219_043108_534218_0208CAEE X-CRM114-Status: GOOD ( 12.29 ) 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 Add undersigned as a maintainer for the IIO ADC helpers. Signed-off-by: Matti Vaittinen --- Revision history: RFC v1 => v2: - New patch --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index a87ddad78e26..bfe2f53fa74d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11099,6 +11099,13 @@ L: linux-media@vger.kernel.org S: Maintained F: drivers/media/rc/iguanair.c +IIO ADC HELPERS +M: Matti Vaittinen +L: linux-iio@vger.kernel.org +S: Maintained +F: drivers/iio/adc/industrialio-adc.c +F: include/linux/iio/adc-helpers.h + IIO BACKEND FRAMEWORK M: Nuno Sa R: Olivier Moysan From patchwork Wed Feb 19 12:31:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matti Vaittinen X-Patchwork-Id: 13982079 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 4C622C021B0 for ; Wed, 19 Feb 2025 12:39:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=B9YlWf0udibHi5PYSeWM2mVi7/K2aWeL2dI07eP9SBw=; b=Z2uhiCLBO/oYg4XT9yAOxEy5zr i2dRTEsp1g+UwbqtwdgX+s5TnBlquluzNorwEmVyDi9izsalcvjrPomszAvmSomUFRCUkHzFB5NRr gfOYXWnkyCpnkLdLI7oPoDse/pzvnaATzrTcph788fP7iGP7lKtMdeh2dbnsQa6nUXCayGwU+ArcZ s0Vp7Lj0pPmVUM7Ns+bnj9JkOrr3JYaFtdBDIjaLNJ8n0UEQsWTypgGusBCmIOhnHgGwTWlJdnPna DkpPtO0YLati8MrFRv/ZfF4nmu2RjeOVl+lez7qBjmGxs9J4XK46UC6ZVrC3owwsvBFxGR9HRKIi8 pbgDyv4A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tkjM5-0000000CiVw-1fiY; Wed, 19 Feb 2025 12:39:09 +0000 Received: from mail-lf1-x132.google.com ([2a00:1450:4864:20::132]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tkjEd-0000000Cg0x-3Cek for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2025 12:31:28 +0000 Received: by mail-lf1-x132.google.com with SMTP id 2adb3069b0e04-5462ea9691cso1111584e87.2 for ; Wed, 19 Feb 2025 04:31:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739968286; x=1740573086; darn=lists.infradead.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=B9YlWf0udibHi5PYSeWM2mVi7/K2aWeL2dI07eP9SBw=; b=UT1EkYgh1TUHpT0VQFQPx9gbbhPuG+YttfWfR+d42HQIKOOntBgZZz6mDOEuRwFzKO 4yX7ee5jpOVVCCwSsylM9P0d1/ycF28D/C/dCzxJdHJVuIy+1ClczyDZaUf5eLWnI0yW HqMPekAFYqkGIoYObj+4HD4o4AtX1OlUqJoTu+b8ErLcKRweC9OaoxEnhcWGj7SPBMJa y3Bw19DmKN2jsh7FNZW6TlJGB8qUflyw8WNAAleGbA3dypfToMEmCM+L0SErTaoYZA/x riCVSIQChUIM0aLTkL7dlKKd14QyLgLq+AiAavSutYQpd/dlxT6OQ4eUCVT8Yu1uPMAj pdEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739968286; x=1740573086; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=B9YlWf0udibHi5PYSeWM2mVi7/K2aWeL2dI07eP9SBw=; b=kcd68sqGXyc6NR5J/vFCmBKbXVvM4CYJ7Gn5xkOxScTdh7vhLFKysccw0uq+4ufHX2 qnh6320v1aLZd2eeVpZHvY5z4rec50LnVUkcY4XNcWoERmmMoOwP3/3MvqCx4TQba1jK OlDRSjj8XNGxEM/nWVZ7b7R/PqeRiAzf1rSSFyW/PaBXn8LN6+gf7hgVekdd5xPh2nz7 wB3kckvoS5/2R6x5hRdL4e7vYPy44vIeXN2RV4WM05nZ41MAxgCbvafcWZqAymP1ssib LQp/QHcadjhcabL5niArJPf2M/GCqPmnPQUnInF8esZUlHDi4ONBkZy6HNVEjNBsAij8 4Bdw== X-Forwarded-Encrypted: i=1; AJvYcCV8+fblI73FGad5+P0BaAd0uzq1saKEIGnrad10D7lMwKpZohL1/1Jr3lY9S6J9BYW9mBJTWpDogCDGamuOw5zw@lists.infradead.org X-Gm-Message-State: AOJu0YwIFrDf/GtOj4aOrI9LyvodRKvFmane5J3/iaEBLf+3oeSIA2Mf MJ4L4/NHBlaN1vOcFX2uhOdlim8CyTcNs5LYtYT8BeG6fW7FrRAs X-Gm-Gg: ASbGnctAzGtQY2ZSc3nCyCDc/J2txZDcN4fdVN3qvUgHZeaOn6/aJXKfSHTMrMDBLGU O9JzZ5q4LS39KVl/Vogl5ALJzwl6AWgDUZ8nGlup7SFU8KNBt/jAR5tPPGvYcfbOIG42qWxcdbz 38W/qYpHgiRLoDWqTWTBoyZVrq9QM9tPWRuvk5OqPMmzNOgnvN/qabd8gwPRmxtG/+fYyj1NmSu 0OSefIpbyQMuyza21vu38vbncAZLirOk83iTeXZhP/XH5flQq7vo/D5r9a7sUqDihhVO70SHubq B9GzhtYULGgkCQ/K2Fykww== X-Google-Smtp-Source: AGHT+IECGLbBg8/Gfg56YN71xZxnO3b9XbM0HqSAvG6g7x6DJxq2h38ifv+YIKS+tWOSHyQD921kRg== X-Received: by 2002:a05:6512:131a:b0:545:cc2:accd with SMTP id 2adb3069b0e04-5462eee4789mr1463016e87.20.1739968285827; Wed, 19 Feb 2025 04:31:25 -0800 (PST) Received: from mva-rohm ([2a10:a5c0:800d:dd00:8fdf:935a:2c85:d703]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5451f08332bsm2121536e87.48.2025.02.19.04.31.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2025 04:31:24 -0800 (PST) Date: Wed, 19 Feb 2025 14:31:20 +0200 From: Matti Vaittinen To: Matti Vaittinen , Matti Vaittinen Cc: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matti Vaittinen , Lad Prabhakar , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Hugo Villeneuve , Nuno Sa , David Lechner , Javier Carrasco , Andy Shevchenko , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH v3 5/9] MAINTAINERS: Add ROHM BD79124 ADC/GPO Message-ID: <33dd64a9f43ded7809e9d96de81c975cf9d68a5c.1739967040.git.mazziesaccount@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250219_043127_834953_DBDB1F0E X-CRM114-Status: GOOD ( 12.68 ) 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 Add undersigned as a maintainer for the ROHM BD79124 ADC/GPO driver. Signed-off-by: Matti Vaittinen --- Revision history: RFC v1 => v2: - Drop MFD and pinmux drivers --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index bfe2f53fa74d..2021327e665e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -20299,6 +20299,11 @@ S: Supported F: drivers/power/supply/bd99954-charger.c F: drivers/power/supply/bd99954-charger.h +ROHM BD79124 ADC / GPO IC +M: Matti Vaittinen +S: Supported +F: drivers/iio/adc/rohm-bd79124.c + ROHM BH1745 COLOUR SENSOR M: Mudit Sharma L: linux-iio@vger.kernel.org From patchwork Wed Feb 19 12:31:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matti Vaittinen X-Patchwork-Id: 13982081 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 0732FC021AA for ; Wed, 19 Feb 2025 12:40:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=KWwxIm6ZCjF1USQojkSFaiOLUy9epdYG89n1EjgogqY=; b=AB8kG209jMXJzO+5viG397wijX I5mhKZllD9Sj1nAgZEIOOTJEnSC2MGJEH92tfhY3ar0ph+q48x6nEHrIva0AgEYU61kaGZbmPhn+6 FeAhAe8rILtYjjf9YNAlgxxdcGt0rwdeliWJlK3XJvuWg8OljOB6+LVOTEYu9yBv/fN0qlRsP750e Hxbnx6Q3CeHKczNXy4tt97zlzSuTwIcTED+TLRFuiE8U+ImpR3YowfXbakuqV4MOHYTbshVAVCoA/ kXIKW+JUBiVJgZnieOBz1HljTU3RFMj7FHmQaY4ZbSezvNS7oo+v+5I/n6RUofp8hjXXAtYpU5Mqz /sAINAGA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tkjNY-0000000Ciqd-0ZFF; Wed, 19 Feb 2025 12:40:40 +0000 Received: from mail-lf1-x12b.google.com ([2a00:1450:4864:20::12b]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tkjEu-0000000CgA1-2ajr for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2025 12:31:45 +0000 Received: by mail-lf1-x12b.google.com with SMTP id 2adb3069b0e04-54527a7270eso5222440e87.0 for ; Wed, 19 Feb 2025 04:31:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739968303; x=1740573103; darn=lists.infradead.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=KWwxIm6ZCjF1USQojkSFaiOLUy9epdYG89n1EjgogqY=; b=XzTtZDrOmCBO19O+THvu0ShUjFCc0AErtxRQDdfeOpdKlrcq9OKSrVEDOjvc9t9FTC MVGDjAgYoOnylltoKd0S3lHM+AGLvkfCUwgWtBr70gkViT2HPF7Jgn29MJjuhrWIRtvK GqN7a4qga/DrwwgR/hLliHs7p4plcFHObN/+j/XV1xaYhG6TiWChjmfes2P6ASxDQISF UGta4iD8EPe2DBt3DS2nmEvpFdQPp+eVtOVubaHBfk0P6FDR1t4mZBD5qWNQvC5qnzLP syqf/5edK4pNexQiQz3/M/WBx+fPN5FVmDnkAf8KlqHFWS7Z4sWCbzXEU7o3BysEHDZ8 oICA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739968303; x=1740573103; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=KWwxIm6ZCjF1USQojkSFaiOLUy9epdYG89n1EjgogqY=; b=obTAnYcKJUsxTTZNIPjEd4+TwLlgpcP45UMGbcZsyY0BeFFVtoLgjsEU7maSDpRARL WFBb1Lks745/dM+MyBIeW1qH/BWVanNZeXL2/v37+a3ms+NPjjzrTQtPH1Gh7yujjbGH rbFMoPmnDbDEtlLyuDOntOEP66BpZoYiIBFF+aM4hq69Wu6/roJdPMTrhyceBHpJLKh4 pTS2d76SPg403aE3qKQ9N89YX+AaQ4U3nDMc7La6JlUSN/HBG9yD0aOMRX0fXpLlZg8q CPaX1+3uAJD8XXsE+CNsDdkMg9vng48zqTk3hxMbwEPXuZFQOPsqzlH5X7KdpdxrcGtM a3vg== X-Forwarded-Encrypted: i=1; AJvYcCVHIK8kWAW/Vvb09cxQa9GQ+xLkj47HQNr+fEUw/gk0fRMmMb8cD4ECmDsYwy5EOHtm5fjuTLNjr6djdFAoJHrO@lists.infradead.org X-Gm-Message-State: AOJu0Yylx5t2wAbXo1F1ZOlLGTiBJajBzgrvLscVIGaEBsqGrncPrl4b MsOs7QfGy7xrIGzJhNR8gGYmrtAHYRXlelLFAVW5yCGTXfse/AN/ X-Gm-Gg: ASbGncu7uckI+2ykliRvMXtQbRs3/y4Me2vVUOEdCRiKqQDnOgDWP4LE8ckBr5vx+8P 7frEhP6lErV/zqdOUo+3jqYvi1Vowl/epbbk0clFIfSviZLCjCNc8FlQDPX7pfCUjH/OMFkf1Pp G2t/pm+xAWpWtxAtOdihJgXa+jdDf28r9TLP0nW+77JbvYRCj7tWv7lNUl6pztBg0DoPF9oH+80 axuQsnzbECUF5JWd0O6+2dUHVd4etKAYupQ8VR+uPNRnfcgM1V1uMJnFkCWeG40OR3Eu9MhH7pD kI0/TCl2scJ1bb/Zh+JmjQ== X-Google-Smtp-Source: AGHT+IG3W//1SoXeekfyezOA2c+1vtKbVddXk84fyMfPvHE7Xk/Tk638LkqZRnBlykN65C1+4lMkfQ== X-Received: by 2002:a19:2d11:0:b0:546:27f0:21a7 with SMTP id 2adb3069b0e04-54627f02773mr3187290e87.49.1739968302667; Wed, 19 Feb 2025 04:31:42 -0800 (PST) Received: from mva-rohm ([2a10:a5c0:800d:dd00:8fdf:935a:2c85:d703]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5453961f67fsm1390216e87.23.2025.02.19.04.31.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2025 04:31:41 -0800 (PST) Date: Wed, 19 Feb 2025 14:31:38 +0200 From: Matti Vaittinen To: Matti Vaittinen , Matti Vaittinen Cc: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matti Vaittinen , Lad Prabhakar , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Hugo Villeneuve , Nuno Sa , David Lechner , Javier Carrasco , Andy Shevchenko , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH v3 6/9] iio: adc: rzg2l_adc: Use adc-helpers Message-ID: <25c5d22f6f0cbd1355eee2e9d9103c3ee71cebdc.1739967040.git.mazziesaccount@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250219_043144_666077_013BAD57 X-CRM114-Status: GOOD ( 22.88 ) 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 The new devm_iio_adc_device_alloc_chaninfo() -helper is intended to help drivers avoid open-coding the for_each_node -loop for getting the channel IDs. The helper provides standard way to detect the ADC channel nodes (by the node name), and a standard way to convert the "reg", "diff-channels", "single-channel" and the "common-mode-channel" to channel identification numbers used in the struct iio_chan_spec. Furthermore, the helper checks the ID is in range of 0 ... num-channels. The original driver treated all found child nodes as channel nodes. The new helper requires channel nodes to be named channel[@N]. This should help avoid problems with devices which may contain also other but ADC child nodes. Quick grep from arch/* with the rzg2l_adc's compatible string didn't reveal any in-tree .dts with channel nodes named othervice. Also, same grep shows all the .dts seem to have channel IDs between 0..num of channels. Use the new helper. Signed-off-by: Matti Vaittinen --- Revision history: v2 => v3: - New patch I picked the rzg2l_adc in this series because it has a straightforward approach for populating the struct iio_chan_spec. Only other member in the stuct besides the .channel, which can't use a 'template' -data, is the .datasheet_name. This makes the rzg2l_adc well suited for example user of this new helper. I hope this patch helps to evaluate whether these helpers are worth the hassle. The change is compile tested only!! Testing before applying is highly appreciated (as always!). --- drivers/iio/adc/rzg2l_adc.c | 41 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/drivers/iio/adc/rzg2l_adc.c b/drivers/iio/adc/rzg2l_adc.c index cd3a7e46ea53..3e1c74019785 100644 --- a/drivers/iio/adc/rzg2l_adc.c +++ b/drivers/iio/adc/rzg2l_adc.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -299,20 +300,34 @@ static irqreturn_t rzg2l_adc_isr(int irq, void *dev_id) return IRQ_HANDLED; } +static const struct iio_chan_spec rzg2l_adc_chan_template = { + .type = IIO_VOLTAGE, + .indexed = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), +}; + +static const struct iio_adc_props rzg2l_adc_chan_props = { + .required = IIO_ADC_CHAN_PROP_TYPE_REG, +}; + static int rzg2l_adc_parse_properties(struct platform_device *pdev, struct rzg2l_adc *adc) { struct iio_chan_spec *chan_array; struct rzg2l_adc_data *data; - unsigned int channel; int num_channels; - int ret; u8 i; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; - num_channels = device_get_child_node_count(&pdev->dev); + num_channels = devm_iio_adc_device_alloc_chaninfo(&pdev->dev, + &rzg2l_adc_chan_template, &chan_array, + &rzg2l_adc_chan_props); + + if (num_channels < 0) + return num_channels; + if (!num_channels) { dev_err(&pdev->dev, "no channel children\n"); return -ENODEV; @@ -323,26 +338,10 @@ static int rzg2l_adc_parse_properties(struct platform_device *pdev, struct rzg2l return -EINVAL; } - chan_array = devm_kcalloc(&pdev->dev, num_channels, sizeof(*chan_array), - GFP_KERNEL); - if (!chan_array) - return -ENOMEM; - - i = 0; - device_for_each_child_node_scoped(&pdev->dev, fwnode) { - ret = fwnode_property_read_u32(fwnode, "reg", &channel); - if (ret) - return ret; - - if (channel >= RZG2L_ADC_MAX_CHANNELS) - return -EINVAL; + for (i = 0; i < num_channels; i++) { + int channel = chan_array[i].channel; - chan_array[i].type = IIO_VOLTAGE; - chan_array[i].indexed = 1; - chan_array[i].channel = channel; - chan_array[i].info_mask_separate = BIT(IIO_CHAN_INFO_RAW); chan_array[i].datasheet_name = rzg2l_adc_channel_name[channel]; - i++; } data->num_channels = num_channels; From patchwork Wed Feb 19 12:31:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matti Vaittinen X-Patchwork-Id: 13982082 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 64D2FC021AA for ; Wed, 19 Feb 2025 12:43:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=K/8lsdpKrVRGvDk8bdsIYhaiCtFIej4Yk5OWrIJakDc=; b=epA4cL8NBFi3Vx18uhAkNV9ULS Gw6MxmFoXwRLkv+UJRAQ7haiY6FxCxoRze34fzHY/vOFTyHMHlAtnV1JYpaWjVh+CQFHEhDM9MOWR 4wb0eDo/cfys1kHopkRq1OpnJfEyHfOBxSSj38I4AyNDpGYvXNscYGtVcF3C4EM07tctNZXbC2Llx nVVo3kvjS6zCI6zLnUXUtwrKC1e3fjR1NSoCYmJzf35yK4Q19VvEFFyoNXLkbeHLh/UW2NzH2szmO keumK12Zs8pQ36ZEBFIYdgCSN25PeqF7LyXujdrDQNr4N0ZBjZHA5MDvZHn8JHPS4PfLn2wFDXYJI DNnPVInA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tkjQR-0000000Cja8-3ItM; Wed, 19 Feb 2025 12:43:39 +0000 Received: from mail-lf1-x136.google.com ([2a00:1450:4864:20::136]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tkjF8-0000000CgId-3moR for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2025 12:32:00 +0000 Received: by mail-lf1-x136.google.com with SMTP id 2adb3069b0e04-5452c2805bcso5435414e87.2 for ; Wed, 19 Feb 2025 04:31:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739968317; x=1740573117; darn=lists.infradead.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=K/8lsdpKrVRGvDk8bdsIYhaiCtFIej4Yk5OWrIJakDc=; b=gGl7nLsKuTvqIxstN2IJ4B55fYbisl4Q8udPCwveW/9GykHHwOumMzzp6Rekfo+E3s Y4A6+rAiGHkbWfNN1lN1MPM6tAiqFZ3MV8fEZ4HLQK2kwqp1U8ceeE2dx0ifRbtws2ck P5zRePpFZBM2Lka01icf0U13XTgFfyunTtdH3P98KEKY3egEkBGxKYKy00R3j4/MxZMj 5ZoSeflzDccF2o2Z+3hV1smj05x0BgXAwXL+4rBaOdId/3tESd92r5+WIl17BE1GQmHm 4IBHvzbB2VPqcq/g6u2VfxAT8wN4XZAaSFXRwppB1HnoSvcbGT6v6+4SEzkTuP8V8c28 o31Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739968317; x=1740573117; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=K/8lsdpKrVRGvDk8bdsIYhaiCtFIej4Yk5OWrIJakDc=; b=A97gzTREk3dFTYT87YYkvScb6gvwFO9nrvPa0dXcPCwOXKqIoad74YW7U0y0vpbXtB sRNeac7QmL79ngGGzE5idjrWdVvkAMj517w6DHZjowT5gf5fdTIOTtMImboqYTiNaBLT 1obCBhEFSRQ/CD0Qr21Dixz/y5jSP4Cqr5ZdY9npq/ssjeWaNYo+62cBIqcddU1HzfQG r/L4kFHfD7j0B/EDrXDxg08IjhIO9RA7uC+TNxmXhudGTfRfEbkhcWKjEyg96z136lw5 eNz4iZwrtIo0DZOOqmlf5vQKn99O7grs1bmkrq7NNJI5h/ByCTHFGvU1vh8wkl7yXoE4 QlvQ== X-Forwarded-Encrypted: i=1; AJvYcCW0iFZ5sXc3GlUt8PREI9Iq9BqR2cT9pzY5m3uQ9sibtYRJNjoOaGHtrzIK5CfyDtUKb4EibzX94VrINYQ3t+yj@lists.infradead.org X-Gm-Message-State: AOJu0YznB8FGNpJ7r5iFs7fLT3GdZkQDl/VX48Wg8IkczWFgvHkmVvwH PGxj0xMdpFlk+vxPhKjwUJTf3RLS9NK8VC3pZaHHh0VavuN9yNXa X-Gm-Gg: ASbGncuBkHxICtqallJXxh4Imf9+dAUtODTs1ZoTYLL3rNVIRnJ6cWY0gGnqd1OKiGG C4MHR2107BAWtn7BK1GsKOmWZha4CrcMCNGE9rSXxJv3IcPC4eoSX8gy049pPhGsUw6KyfXdqBA 6mrPRdOI1IpFCGuV0iKzkEkqgsLQriIgm5XifhgPxkGEgu6zOMwDnzOcopRqx8B6/75giCbank4 LKivET2GEWVRifDUmsVPyuJ3DMH5mcGqbgnoB4BhrXCmI9wVpq90oEg5fGkNTZsv/s7RfklFMVP 5dv2PbTId/KLBmlbKqKtJg== X-Google-Smtp-Source: AGHT+IHxBzOtMjJ6R20Hyns4SI3S/h1XqzVvWjCS9fdPX3gfnk60+xs7fGA4Wr7UNOkuWHPHq9EJQw== X-Received: by 2002:a05:6512:1286:b0:545:2950:5360 with SMTP id 2adb3069b0e04-5452fe570a5mr6750403e87.22.1739968316988; Wed, 19 Feb 2025 04:31:56 -0800 (PST) Received: from mva-rohm ([2a10:a5c0:800d:dd00:8fdf:935a:2c85:d703]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5461db6474bsm1137730e87.58.2025.02.19.04.31.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2025 04:31:56 -0800 (PST) Date: Wed, 19 Feb 2025 14:31:51 +0200 From: Matti Vaittinen To: Matti Vaittinen , Matti Vaittinen Cc: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matti Vaittinen , Lad Prabhakar , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Hugo Villeneuve , Nuno Sa , David Lechner , Javier Carrasco , Andy Shevchenko , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH v3 7/9] iio: adc: sun20i-gpadc: Use adc-helpers Message-ID: <21b9af362b64a1d9c2a13cc46242dd6955996c46.1739967040.git.mazziesaccount@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250219_043158_942818_DF01CCF5 X-CRM114-Status: GOOD ( 20.85 ) 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 The new devm_iio_adc_device_alloc_chaninfo() -helper is intended to help drivers avoid open-coding the for_each_node -loop for getting the channel IDs. The helper provides standard way to detect the ADC channel nodes (by the node name), and a standard way to convert the "reg", "diff-channels", "single-channel" and the "common-mode-channel" to channel identification numbers used in the struct iio_chan_spec. Furthermore, the helper checks the ID is in range of 0 ... num-channels. The original driver treated all found child nodes as channel nodes. The new helper requires channel nodes to be named channel[@N]. This should help avoid problems with devices which may contain also other but ADC child nodes. Quick grep from arch/* with the sun20i-gpadc's compatible string didn't reveal any in-tree .dts with channel nodes named othervice. Also, same grep shows all the in-tree .dts seem to have channel IDs between 0..num of channels. Use the new helper. Signed-off-by: Matti Vaittinen --- Revision history: v2 => v3: - New patch I picked the sun20i-gpadc in this series because it has a straightforward approach for populating the struct iio_chan_spec. Everything else except the .channel can use 'template'-data. This makes the sun20i-gpadc well suited to be an example user of this new helper. I hope this patch helps to evaluate whether these helpers are worth the hassle. The change is compile tested only!! Testing before applying is highly appreciated (as always!). Also, even though I tried to audit the dts files for the reg-properties in the channel nodes, use of references didn't make it easy. I can't guarantee I didn't miss anything. --- drivers/iio/adc/sun20i-gpadc-iio.c | 42 ++++++++++++++---------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/drivers/iio/adc/sun20i-gpadc-iio.c b/drivers/iio/adc/sun20i-gpadc-iio.c index 136b8d9c294f..36d48d95f029 100644 --- a/drivers/iio/adc/sun20i-gpadc-iio.c +++ b/drivers/iio/adc/sun20i-gpadc-iio.c @@ -15,6 +15,7 @@ #include #include +#include #include #define SUN20I_GPADC_DRIVER_NAME "sun20i-gpadc" @@ -149,37 +150,32 @@ static void sun20i_gpadc_reset_assert(void *data) reset_control_assert(rst); } +static const struct iio_chan_spec sun20i_gpadc_chan_template = { + .type = IIO_VOLTAGE, + .indexed = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), +}; + +static const struct iio_adc_props sun20i_gpadc_chan_props = { + .required = IIO_ADC_CHAN_PROP_TYPE_REG, +}; + static int sun20i_gpadc_alloc_channels(struct iio_dev *indio_dev, struct device *dev) { - unsigned int channel; - int num_channels, i, ret; + int num_channels; struct iio_chan_spec *channels; - num_channels = device_get_child_node_count(dev); + num_channels = devm_iio_adc_device_alloc_chaninfo(dev, + &sun20i_gpadc_chan_template, &channels, + &sun20i_gpadc_chan_props); + if (num_channels < 0) + return num_channels; + if (num_channels == 0) return dev_err_probe(dev, -ENODEV, "no channel children\n"); - channels = devm_kcalloc(dev, num_channels, sizeof(*channels), - GFP_KERNEL); - if (!channels) - return -ENOMEM; - - i = 0; - device_for_each_child_node_scoped(dev, node) { - ret = fwnode_property_read_u32(node, "reg", &channel); - if (ret) - return dev_err_probe(dev, ret, "invalid channel number\n"); - - channels[i].type = IIO_VOLTAGE; - channels[i].indexed = 1; - channels[i].channel = channel; - channels[i].info_mask_separate = BIT(IIO_CHAN_INFO_RAW); - channels[i].info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); - - i++; - } - indio_dev->channels = channels; indio_dev->num_channels = num_channels; From patchwork Wed Feb 19 12:32:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matti Vaittinen X-Patchwork-Id: 13982083 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id BC334C021AA for ; Wed, 19 Feb 2025 12:45:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=872sDDSaszSL1+yhyVainkn552F70TCEUEKtazE+wZs=; b=Ek+dk8eu8TtNHihN5vHHCqVgeH gehuLQf5ib0D0GHskU/TBT5V0CTN/sVSVdgmBP5QbAGho7/dxSqCp5SftDg+AwyTxC960Pv+UYf9A pvzu0wKc/afjT47gANl+kmLSOsbIVisPdHghyNGsD+QO7SmsczI0zkMpvU6qVezOqECNSfDTXTOjO gtWWMuO6n0rBpqTpNXftNso38dcajF7Pqx6WvKxZHlxIY2JXlCn/JsbYQa6mEYB3/0sWFuOeYbBfI 3o/fUlYzi2E4h6nSdvfPpd/6Vp0WLN8EBWlS9C+Z1XbRQiV9olxJTcGrfRLiGVOre5T+LVyKcTeN5 crQw3LUg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tkjRt-0000000CjvZ-1lSm; Wed, 19 Feb 2025 12:45:09 +0000 Received: from mail-lf1-x12c.google.com ([2a00:1450:4864:20::12c]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tkjFO-0000000CgQN-3gut for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2025 12:32:16 +0000 Received: by mail-lf1-x12c.google.com with SMTP id 2adb3069b0e04-5462ea9691cso1112462e87.2 for ; Wed, 19 Feb 2025 04:32:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739968333; x=1740573133; darn=lists.infradead.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=872sDDSaszSL1+yhyVainkn552F70TCEUEKtazE+wZs=; b=kS+Oo/O/wuS4IM7AjerkxJTDroNEYUC4FS5qcoGEw2crviBHhdY3+jjaE3jL3V1Co6 xhoWC0iPJupu4Jg+kmVmEbCEWvLnfXd3Ug/H5Ir4wfAyDntUifmCA2P5BgoCsE9t1K4e HJ1QbuROG+jHIJSWYN3lRPlag/HebXNPi4wdg4GGnnPrR+9SHIltILVehWRCGH3PKWhs KeBdgcgeCxX9vtMQ7GQTgwc2dxILRPC1i+PE9yu8OhyHo4+4dJbhAyX0VUdnMW2CGRA+ zfE8EAARMlztzyWkCNEFQyvobzoPaEk7apF71w3rbIvGAnAhUTujldvf/EI03qepgbvK cy0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739968333; x=1740573133; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=872sDDSaszSL1+yhyVainkn552F70TCEUEKtazE+wZs=; b=r307O7jIybe91sc8ALTCaTTFL6IIZD5ipCE38/SXzbqGPb7hNYSyqUAOPbBqZA2+KN arIkwi5JILmW2G79kwllfW930td4CTzs51nIk5Tn1k/hr7vgP1zu+XUqMZ+7MgLc3U3Y xulWEzh6b8XHzhTAMyASZsE1l7uoyrBG8Igcsxl6KVN+p58xLiPVH3nNNXxur7v3kjG9 GPG2BjGlxpVAsBriWvviTEJERW1FoRpFhIb9cc47XB5b9SOvyvHuMfZbtlX7UbI6JNwi 57OnnrkHOo+OEGrSMiCsNnvqizka9YypsMZP/GEXP3nRvAoWUD2GZ62SzDpT21HInJFA LoDA== X-Forwarded-Encrypted: i=1; AJvYcCV/BJQKceTyvlsq1TpVXLbGCKjEJI2NPCogQ9CgWkxymSPUbIFzGDTIJJrw28mL2d3+5q8R6ZNfDDjdXuq5Mjdj@lists.infradead.org X-Gm-Message-State: AOJu0Yx1+qRrcqGW80/T17nCmCkAmdAFnNMfiKBmVCJW3N9ZT2vviS8U I8LjE2x+rUMZQy1XcPdEMHCGASm9bq05eo5xVc7KLUTPCdy0MK4n X-Gm-Gg: ASbGncvEH3efT7VDT4xmUQ4NtYew40QxoBZPXe00DkoL4ZxYGqx8kATy2gjKO3PQNsV kyLsgSbzq9jA6PzQXO2ooYTeXXM49c9HrWaimQvtnFNKUYiprqaIjGRDt70gXuzrdVO7rqAwm4O tqa6V+dxt3gkrjKXuw7Lc2NsAK6VtRYW0WoYKwvdc5Oni1KKcXzmHcWRNUu50hNqEGC/f7Uskyh egH5OzdHMV6qNrRmFVq2oRKDELZb0zp7IqcWs6OU4zvNhfFvgyn/VYb+GwKG9b+aoqAHDtRu+YF pzIn/t2Z9biiznPHD0vZ7g== X-Google-Smtp-Source: AGHT+IET+JJuBMU3Y/6jzse1ZgT54+aygXA9AXNLRXFpXqkVIx7/7mkYzYqgDRV3tj+3kjGQpH/r/A== X-Received: by 2002:a05:6512:2249:b0:545:c08:e17b with SMTP id 2adb3069b0e04-5462eef2242mr1448277e87.23.1739968332998; Wed, 19 Feb 2025 04:32:12 -0800 (PST) Received: from mva-rohm ([2a10:a5c0:800d:dd00:8fdf:935a:2c85:d703]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5452f6efbf5sm1596646e87.18.2025.02.19.04.32.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2025 04:32:11 -0800 (PST) Date: Wed, 19 Feb 2025 14:32:06 +0200 From: Matti Vaittinen To: Matti Vaittinen , Matti Vaittinen Cc: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matti Vaittinen , Lad Prabhakar , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Hugo Villeneuve , Nuno Sa , David Lechner , Javier Carrasco , Andy Shevchenko , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH v3 8/9] iio: adc: ti-ads7924 Drop unnecessary function parameters Message-ID: <3155f491753944d6511d058a09f6f6c505d551f9.1739967040.git.mazziesaccount@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250219_043214_918996_95420237 X-CRM114-Status: GOOD ( 17.22 ) 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 Device pointer is the only variable which is used by the ads7924_get_channels_config() and which is declared outside this function. Still, the function gets the iio_device and i2c_client as parameters. The sole caller of this function (probe) already has the device pointer which it can directly pass to the function. Simplify code by passing the device pointer directly as a parameter instead of digging it from the iio_device's private data. Signed-off-by: Matti Vaittinen --- This commit is compile-tested only! All further testing is appreciated. --- drivers/iio/adc/ti-ads7924.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/ti-ads7924.c b/drivers/iio/adc/ti-ads7924.c index 66b54c0d75aa..b1f745f75dbe 100644 --- a/drivers/iio/adc/ti-ads7924.c +++ b/drivers/iio/adc/ti-ads7924.c @@ -251,11 +251,8 @@ static const struct iio_info ads7924_info = { .read_raw = ads7924_read_raw, }; -static int ads7924_get_channels_config(struct i2c_client *client, - struct iio_dev *indio_dev) +static int ads7924_get_channels_config(struct device *dev) { - struct ads7924_data *priv = iio_priv(indio_dev); - struct device *dev = priv->dev; struct fwnode_handle *node; int num_channels = 0; @@ -380,7 +377,7 @@ static int ads7924_probe(struct i2c_client *client) indio_dev->num_channels = ARRAY_SIZE(ads7924_channels); indio_dev->info = &ads7924_info; - ret = ads7924_get_channels_config(client, indio_dev); + ret = ads7924_get_channels_config(dev); if (ret < 0) return dev_err_probe(dev, ret, "failed to get channels configuration\n"); From patchwork Wed Feb 19 12:32:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matti Vaittinen X-Patchwork-Id: 13982088 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id A28C2C021AA for ; Wed, 19 Feb 2025 12:46:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=0DYvjW5f0VauVHlYQoEoi+1LNEnpUSDiH5KvYpk6CeA=; b=s+/qOknFCUkwb9FoXj/yAAg3rg toRiHoVZQjXxdbS+Sf/aRPzCp6dA+ZN0j8a8vCm2QHt5cUOcI5twxwmB9mA6iJ05UkegnZ9LNBDvX NFt8MlyUKo8QKPptF8RdGKyfRWTV24MZux6vOnd5SoCVeXj0a9gTPyn+Kw11mCrt6Llfr7MeanW07 fuN2qZBaVebE5VS6noR4tnVMcLCLXBZSpzIL6d6m0aeoxdZWkhpyoicgjuoBZTQMWcIkbYj2CRu7P o0CF5pQOldUooOc4ldJTocReUWzW6043r0PfqEZVoink2AtO3ey0hIg+86c+Mc+azeh842bKk2oBX J669hbLA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tkjTM-0000000CkOr-0epc; Wed, 19 Feb 2025 12:46:40 +0000 Received: from mail-lj1-x236.google.com ([2a00:1450:4864:20::236]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tkjFe-0000000CgYK-1FXx for linux-arm-kernel@lists.infradead.org; Wed, 19 Feb 2025 12:32:31 +0000 Received: by mail-lj1-x236.google.com with SMTP id 38308e7fff4ca-30227c56b11so71230941fa.3 for ; Wed, 19 Feb 2025 04:32:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1739968348; x=1740573148; darn=lists.infradead.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=0DYvjW5f0VauVHlYQoEoi+1LNEnpUSDiH5KvYpk6CeA=; b=Bx98tzod09Yf19YdrYd0I+oTP9x3YhEYef3ikWgYQrn2+sSQQlBCbpq62jgdyCVZws whKYLHY2BvltmvrBQN6Hwi+gOpBBUMau1xBRUi83wqRS/msRkx75GWCbMDg+pMtlT1N/ Am3PXogoN+TZ6Ok+F8LDCIDe9w45gYejDRvH6eKuwGncCz5CXJ0FWbREJ0fro6hDPViW KgYpnPXLA96fVizOeaJHOZ1qdWvllGPrrXn8GzLysHv3Q9AiXdR+0gtrgQSnNfTiy6Wq ZTceH0//gZijxoYo5T+a+Z56H4wvpl8uzt+GVg6Xxru4ohW+mBTc1cEbH2Rb/WTlVEta p2qQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739968348; x=1740573148; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=0DYvjW5f0VauVHlYQoEoi+1LNEnpUSDiH5KvYpk6CeA=; b=ND7RnZ0EOdIMmvHQl7/AYxhyan05mCz8uR2CdszhWhqVcwiQuxWit6FOwJxePc8BCz pU1rphPo+bPx/lqPgIvBTvDOUCKoHExfxEIXD/Z2J1j9iOMP5Y5MPxzvo8l3F+Qe/Z0O KrKLFoAl5/LyH0ItUiSFijxOlkmzGtIuOniKyK7ekRKVCvclZm+u2WZw4R+lbmOQ+Ljx fuMMSndKNnNctfuibP828ACqZMJVYGVdBr29XePcrj/MAMpv/01HfDM1vI6RXdfKP6GD JzkrRdckjSUCxtzILbPfNI+pxZQS2GldqZz+MoSBb5e8rWVBC8ZuDR72mVzrkpIKshK5 rPlw== X-Forwarded-Encrypted: i=1; AJvYcCX6UgZ8x7wqJ4hDdt4BiRCyTxhofsMe925OHZtlL00JQ0s/UkDOf45DqsQ/PZjFcGYDLXLikIwmJHJgqzkOx3Qd@lists.infradead.org X-Gm-Message-State: AOJu0YyN1jUjAodjLn4FV8yKanLNcHvF1ZujQ8Gxjk5HNKf9kn2cOCEh 960AgXlSSJCWFtmNbykKCW/UkmmNK7umFudp53S8cqbjUwbM/k+Q X-Gm-Gg: ASbGncsJrd2PjS9yZFwU8X+YYIJV7f/OWQqHAnf53pcMlXYWnP/M6r5zQZ4CkyrE0Gi k7YNT6Bp5uqB8OwlDrQ7tvK9esq1E/i21FdP9xYl8/TQ0SkOSMOH7fT6/IMp0H6c7NDoNSOVyp8 FUmncQOR/OBK7MJGEMaRA5dPm1ZhI9CnM+MHoahWOgBv0rH3gJnfkqXugoVAgPk+6ckdVa58Q3v yaQnJb88P7cx8jeBvd8zddfQC1E0IZGUbT2Hx308M9NdAUHxaNuMAU0oRDZFQrxhLHpR0ZM6uel I5zIZLSaoFm4GJpnnLRLWQ== X-Google-Smtp-Source: AGHT+IGpj+sXTk9ydInkrFSzD/8u3Ea569jfA3qPAyfTIDaLYJDMfGIteoPF8DQijF1k+5z6DuXOPg== X-Received: by 2002:a2e:9905:0:b0:308:f01f:181f with SMTP id 38308e7fff4ca-30927aff022mr48385981fa.31.1739968348109; Wed, 19 Feb 2025 04:32:28 -0800 (PST) Received: from mva-rohm ([2a10:a5c0:800d:dd00:8fdf:935a:2c85:d703]) by smtp.gmail.com with ESMTPSA id 38308e7fff4ca-30a344c8900sm9350131fa.22.2025.02.19.04.32.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 19 Feb 2025 04:32:27 -0800 (PST) Date: Wed, 19 Feb 2025 14:32:23 +0200 From: Matti Vaittinen To: Matti Vaittinen , Matti Vaittinen Cc: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Matti Vaittinen , Lad Prabhakar , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Hugo Villeneuve , Nuno Sa , David Lechner , Javier Carrasco , Andy Shevchenko , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: [PATCH v3 9/9] iio: adc: ti-ads7924: Respect device tree config Message-ID: <3279aa9348e7149bfbd433daaa201f2eb5873e1f.1739967040.git.mazziesaccount@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250219_043230_342590_17965E01 X-CRM114-Status: GOOD ( 25.06 ) 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 The ti-ads7924 driver ignores the device-tree ADC channel specification and always exposes all 4 channels to users whether they are present in the device-tree or not. Additionally, the "reg" values in the channel nodes are ignored, although an error is printed if they are out of range. Register only the channels described in the device-tree, and use the reg property as a channel ID. Signed-off-by: Matti Vaittinen --- Revision history: v2 => v3: New patch Please note that this is potentially breaking existing users if they have wrong values in the device-tree. I believe the device-tree should ideally be respected, and if it says device X has only one channel, then we should believe it and not register 4. Well, we don't live in the ideal world, so even though I believe this is TheRightThingToDo - it may cause havoc because correct device-tree has not been required from the day 1. So, please review and test and apply at your own risk :) As a side note, this might warrant a fixes tag but the adc-helper -stuff is hardly worth to be backported... (And I've already exceeded my time budget with this series - hence I'll leave crafting backportable fix to TI people ;) ) This has only been compile tested! All testing is highly appreciated. --- drivers/iio/adc/ti-ads7924.c | 80 +++++++++++++++++------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/drivers/iio/adc/ti-ads7924.c b/drivers/iio/adc/ti-ads7924.c index b1f745f75dbe..a5b8f7c81b8a 100644 --- a/drivers/iio/adc/ti-ads7924.c +++ b/drivers/iio/adc/ti-ads7924.c @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -119,15 +120,12 @@ #define ADS7924_TOTAL_CONVTIME_US (ADS7924_PWRUPTIME_US + ADS7924_ACQTIME_US + \ ADS7924_CONVTIME_US) -#define ADS7924_V_CHAN(_chan, _addr) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = _chan, \ - .address = _addr, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ - .datasheet_name = "AIN"#_chan, \ -} +static const struct iio_chan_spec ads7924_chan_template = { + .type = IIO_VOLTAGE, + .indexed = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), +}; struct ads7924_data { struct device *dev; @@ -182,13 +180,6 @@ static const struct regmap_config ads7924_regmap_config = { .writeable_reg = ads7924_is_writeable_reg, }; -static const struct iio_chan_spec ads7924_channels[] = { - ADS7924_V_CHAN(0, ADS7924_DATA0_U_REG), - ADS7924_V_CHAN(1, ADS7924_DATA1_U_REG), - ADS7924_V_CHAN(2, ADS7924_DATA2_U_REG), - ADS7924_V_CHAN(3, ADS7924_DATA3_U_REG), -}; - static int ads7924_get_adc_result(struct ads7924_data *data, struct iio_chan_spec const *chan, int *val) { @@ -251,32 +242,38 @@ static const struct iio_info ads7924_info = { .read_raw = ads7924_read_raw, }; -static int ads7924_get_channels_config(struct device *dev) +static const struct iio_adc_props ads7924_chan_props = { + .required = IIO_ADC_CHAN_PROP_TYPE_REG, +}; + +static int ads7924_get_channels_config(struct iio_dev *indio_dev, + struct device *dev) { - struct fwnode_handle *node; - int num_channels = 0; + struct iio_chan_spec *chan_array; + int num_channels = 0, i; - device_for_each_child_node(dev, node) { - u32 pval; - unsigned int channel; + num_channels = devm_iio_adc_device_alloc_chaninfo(dev, + &ads7924_chan_template, &chan_array, + &ads7924_chan_props); - if (fwnode_property_read_u32(node, "reg", &pval)) { - dev_err(dev, "invalid reg on %pfw\n", node); - continue; - } + if (num_channels < 0) + return num_channels; - channel = pval; - if (channel >= ADS7924_CHANNELS) { - dev_err(dev, "invalid channel index %d on %pfw\n", - channel, node); - continue; - } + if (!num_channels) + return -EINVAL; + + for (i = 0; i < num_channels; i++) { + static const char * const datasheet_names[] = { + "AIN0", "AIN1", "AIN2", "AIN3" + }; + int ch_id = chan_array[i].channel; - num_channels++; + chan_array[i].address = ADS7924_DATA0_U_REG + ch_id; + chan_array[i].datasheet_name = datasheet_names[ch_id]; } - if (!num_channels) - return -EINVAL; + indio_dev->channels = chan_array; + indio_dev->num_channels = num_channels; return 0; } @@ -370,18 +367,15 @@ static int ads7924_probe(struct i2c_client *client) mutex_init(&data->lock); - indio_dev->name = "ads7924"; - indio_dev->modes = INDIO_DIRECT_MODE; - - indio_dev->channels = ads7924_channels; - indio_dev->num_channels = ARRAY_SIZE(ads7924_channels); - indio_dev->info = &ads7924_info; - - ret = ads7924_get_channels_config(dev); + ret = ads7924_get_channels_config(indio_dev, dev); if (ret < 0) return dev_err_probe(dev, ret, "failed to get channels configuration\n"); + indio_dev->name = "ads7924"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &ads7924_info; + data->regmap = devm_regmap_init_i2c(client, &ads7924_regmap_config); if (IS_ERR(data->regmap)) return dev_err_probe(dev, PTR_ERR(data->regmap),