From nobody Tue Dec 2 00:46:53 2025 Received: from mx0b-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 933A72E975F; Mon, 24 Nov 2025 09:18:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975942; cv=none; b=WGZyawWcjfb21554WIFF6yW+7/6fV6U97+9mDlCo0Mv7uS2khGL1aujL7czRYU1+or0xysu6pEG4BA7zMffzRmU/I0Tft2VBH6/d49UStWlylmVBRVQSvrfmMiANNRzv5VMTlGiVPpBVQP4zT8kcK36PBXf7/UUG+RnikAK1Lpg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975942; c=relaxed/simple; bh=aimic6kj2sqeybnlXxxmgqYOKreM6Xsl1lxRdNDh5rw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=Lf3YRf0Th0G5xKGHBstGom+vL+9y58Yfbla0Gr4Rzdy/mzge1pB/IfKRxEGVNbC7luh421eRGGTWGCu7juvCDhmEG15v97WvPpOdTXEm5jASYwdCHFXQtrquhxCUHFgO/t2e/Dm3xAQMvPGz0B1PrwKM+BudqMzhC5KPFGFp9mI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=e692b7bh; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="e692b7bh" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5AO72rRs3692062; Mon, 24 Nov 2025 04:18:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=1+k63 l1rnim23b0NAkdD+DTOB1vy/YqvY+H9q5cXpiM=; b=e692b7bhq7xw8PQ2y2Jsx wD2byAhrhA9dThAH8aOv9YemnkakU+euESXmyeOqw1WS1xYlTGCgAFv1Y/2ZV6DW JZSTIxMs4VcF1XWSySputcVB/4qAqlMxTggIVr2WmCFoiVmnb1GO2wwjkK5Obko2 h2ybUExkbsPRAPsUUMzBjIGrddc+rXhB+e1+LxwUu9yaBpfU73c/Mhkmi8qAEFnR k+Fy8sjYvy5QuROZG7tvqUejLt2hOzmHq8rzJY6ZUMfPwTEkr1mhUeHIUP0q62ii afWWO6dYcSm5H2fzph2WZB1t4QRxZ6SFOmpQo1WYc0TRth4zZJWsPwBUdTIs3I/S w== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 4akvcjmw7w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Nov 2025 04:18:26 -0500 (EST) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 5AO9IP9m050879 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 24 Nov 2025 04:18:25 -0500 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:25 -0500 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:25 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 24 Nov 2025 04:18:25 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.82]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5AO9I8VK024016; Mon, 24 Nov 2025 04:18:18 -0500 From: Jorge Marques Date: Mon, 24 Nov 2025 10:18:00 +0100 Subject: [PATCH v2 1/9] dt-bindings: iio: adc: Add adi,ad4062 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251124-staging-ad4062-v2-1-a375609afbb7@analog.com> References: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> In-Reply-To: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> To: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , "David Lechner" , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Linus Walleij , Bartosz Golaszewski CC: , , , , , Jorge Marques X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763975888; l=5123; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=aimic6kj2sqeybnlXxxmgqYOKreM6Xsl1lxRdNDh5rw=; b=8qUBq1a+HA6SOgh8zl/eDDPpOfmUWdRpkk25fNApLNHPRo0jw8f0HMJK/L0/M21AB6GJfFOQZ X6CZwC+ws6vA/tIPPx4K2mn7kczAqBCjpgj3G4zYrL008IWLt/iVOHU X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTI0MDA4MSBTYWx0ZWRfXz1bnTPtJGkZ9 PRu1KwSr2PJe2SVEmiU+nMrRUasYAqjG7/IZRw30RHl2nShLLTPQdh2Zs5G9nibbRWGStjnZtNk PyjfHmt/p7z+rRgQO0MOWjKflqwDMzJE+tU62I9lbCm614rDaWq2Vt05Bwd9p8JDxCj8OQKcd7Z tkNNR105gsRWD86ZbOGdsh8irNZVMRMYARNGd+qu+LqzJ34YpvhtVhO3WQPJ64vX9FTYndLm+5s GajaHrszbCMUju/PZDjqit+tLzubLzV6qOuXnGSDm3wR5gRuutNFIbPl4I0QVVs5GXKLxxnAuAT Ad7P9lfTC5qQIltGpGnQ09nYLE1HEGSqAhlrkoZPaUtOhtzMCHyZS/H4cOBaVwsRo3IXsCA+JMm k/IZ0PBHs7uyIxXJdSIMXcD3IQ/s/w== X-Authority-Analysis: v=2.4 cv=EqrfbCcA c=1 sm=1 tr=0 ts=692422e2 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gEfo2CItAAAA:8 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=7dW3d56Owd-7Eugxv60A:9 a=QEXdDO2ut3YA:10 a=sptkURWiP4Gy88Gu7hUp:22 X-Proofpoint-ORIG-GUID: 8oTHBlp9DO_FO_P1lCSlLoaRuM_fWyog X-Proofpoint-GUID: 8oTHBlp9DO_FO_P1lCSlLoaRuM_fWyog X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-24_03,2025-11-21_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 phishscore=0 bulkscore=0 malwarescore=0 adultscore=0 spamscore=0 clxscore=1011 priorityscore=1501 impostorscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511240081 Add dt-bindings for AD4062 family, devices AD4060/AD4062, low-power with monitor capabilities SAR ADCs. Each variant of the family differs in resolution. The device contains two outputs (gp0, gp1). The outputs can be configured for range of options, such as threshold and data ready. The device uses a 2-wire I3C interface. Signed-off-by: Jorge Marques --- .../devicetree/bindings/iio/adc/adi,ad4062.yaml | 123 +++++++++++++++++= ++++ MAINTAINERS | 6 + 2 files changed, 129 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml b/Do= cumentation/devicetree/bindings/iio/adc/adi,ad4062.yaml new file mode 100644 index 0000000000000..a25af66dd64d2 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml @@ -0,0 +1,123 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2024 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad4062.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD4062 ADC family device driver + +maintainers: + - Jorge Marques + +description: | + Analog Devices AD4062 Single Channel Precision SAR ADC family + + https://www.analog.com/media/en/technical-documentation/data-sheets/ad40= 60.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad40= 62.pdf + +properties: + compatible: + enum: + - adi,ad4060 + - adi,ad4062 + + reg: + maxItems: 1 + + interrupts: + description: + The interrupt pins are digital outputs that can be configured at run= time + as multiple interrupt signals. Each can be configured as GP_INTR, RD= Y, + DEV_EN, logic low, logic high and DEV_RDY (GP1 only). RDY is the + active-low data ready signal, indicates when new ADC data are ready = to + read. DEV_EN synchronizes the enable and power-down states of signal + chain devices with the ADC sampling instant. DEV_RDY is an active-hi= gh + signal that indicates when the device is ready to accept serial inte= rface + communications. In GP_INTR mode, the interrupt outputs one of the + threshold detection interrupt signals (MIN_INTR, MAX_INTR or either). + minItems: 1 + items: + - description: + gp0, interrupt line for GP0 pin, cannot be configured as DEV_RDY. + - description: + gp1, interrupt line for GP1 pin, can be configured to any settin= g. + + interrupt-names: + items: + - const: gp0 + - const: gp1 + + gpio-controller: + description: + Marks the device node as a GPIO controller. GPs not listed in + interrupt-names are exposed as a GPO. + + '#gpio-cells': + const: 2 + description: + The first cell is the GPIO number and the second cell specifies + GPIO flags, as defined in . + + vdd-supply: + description: Analog power supply. + + vio-supply: + description: Digital interface logic power supply. + + ref-supply: + description: + Reference voltage to set the ADC full-scale range. If not present, + vdd-supply is used as the reference voltage. + +required: + - compatible + - reg + - vdd-supply + - vio-supply + +allOf: + - $ref: /schemas/i3c/i3c.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + + i3c { + #address-cells =3D <3>; + #size-cells =3D <0>; + + adc@0,2ee007c0000 { + reg =3D <0x0 0x2ee 0x7c0000>; + vdd-supply =3D <&vdd>; + vio-supply =3D <&vio>; + ref-supply =3D <&ref>; + + interrupt-parent =3D <&gpio>; + interrupts =3D <0 0 IRQ_TYPE_EDGE_RISING>, + <0 1 IRQ_TYPE_EDGE_FALLING>; + interrupt-names =3D "gp0", "gp1"; + }; + }; + + - | + #include + #include + + i3c { + #address-cells =3D <3>; + #size-cells =3D <0>; + + adc@0,2ee007c0000 { + reg =3D <0x0 0x2ee 0x7c0000>; + vdd-supply =3D <&vdd>; + vio-supply =3D <&vio>; + ref-supply =3D <&ref>; + + gpio-controller; + #gpio-cells =3D <2>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 31d98efb1ad15..e22ba5ec8c849 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1432,6 +1432,12 @@ F: Documentation/devicetree/bindings/iio/adc/adi,ad4= 030.yaml F: Documentation/iio/ad4030.rst F: drivers/iio/adc/ad4030.c =20 +ANALOG DEVICES INC AD4062 DRIVER +M: Jorge Marques +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml + ANALOG DEVICES INC AD4080 DRIVER M: Antoniu Miclaus L: linux-iio@vger.kernel.org --=20 2.51.1 From nobody Tue Dec 2 00:46:53 2025 Received: from mx0b-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A8162F4A16; Mon, 24 Nov 2025 09:18:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975939; cv=none; b=EDmIrSThYPfbYZJRZ7U4G7BJuril6O300IhERF4d/ZH7bxrPmdcgn7P2kximdFRsVG+fCi35J+QKk5/1DNXC7RtGlJTmHgYlp2JyDUVHJ72UXBuDembSPLETzD6JWjdtw/eUMJ7Xm1ptxkRQSmuKCrc0wkjv3tMhteZkxNpEP6Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975939; c=relaxed/simple; bh=Z8LmT3qY041U83j0q+I/X13ABeV5uquFKXkkjyjU46A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=NyC6rRYySb+Q1mLWnNf6A3h8ZgRhyc66+fL59eVYtwDrlY91ohWlbn0fBLdeIqBTZstJYmwe40T671iIh8E/RzCFevD1CAFaM6W4d2TXCweI8V+45mLMI5JPMrjwQX9gQV8G7NLgAiVKZQ7q1K/K3TBwkHXa3JYqgQ76IEhgluk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=SmA7eRj5; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="SmA7eRj5" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5AO72rRt3692062; Mon, 24 Nov 2025 04:18:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=P0sLh +LxqQq6lmxSuci+6Il+GFar9iBr5Mc1DPZRFLY=; b=SmA7eRj5rcxN6NdXvvuIA psb/Zr4QvNJnTJ017G5Xjsk2x9bdwlpUYvqJe+5jVQwG5upymSj06pHFIyxnbJoF +SyUmmiJ1+4a5iTPnelTJakirAoVfShtpdWn0bR6+maz9B4spPGHv11xEJr7GLom Jtm0JU07RYE1DBSD2qHfMcn8qVBIgs+Q/P1MinhsofZAZawG2XN/iNtpH7b3jIlR ObrwfmOVsXWF0dcsMy6FXJtqP21pACcBtoS7Fji0UUxRv7kJAodfoQf50SwhIDED HADYz1phOnkjyDK3apj0fc7CIV+OwieL52K7Q4Depfd0IcqI9y2UGLF/7GEFwXk+ w== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 4akvcjmw7y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Nov 2025 04:18:28 -0500 (EST) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 5AO9IR8J050884 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 24 Nov 2025 04:18:27 -0500 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:27 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 24 Nov 2025 04:18:27 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.82]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5AO9I8VL024016; Mon, 24 Nov 2025 04:18:20 -0500 From: Jorge Marques Date: Mon, 24 Nov 2025 10:18:01 +0100 Subject: [PATCH v2 2/9] docs: iio: New docs for ad4062 driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251124-staging-ad4062-v2-2-a375609afbb7@analog.com> References: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> In-Reply-To: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> To: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Linus Walleij , Bartosz Golaszewski CC: , , , , , Jorge Marques X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763975888; l=4325; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=Z8LmT3qY041U83j0q+I/X13ABeV5uquFKXkkjyjU46A=; b=jJNj03hkSeBFF9vkNqDG9dZrPgoF43A3DbjgZmysB03r5VB5qLsuCbuY1b7za0N/W/1cYfFHj 0PiDJzywFR2CLYi5wEkJ2/N3l89jXQ6YjlhOjWT01RXrD4yoNtJaKYi X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTI0MDA4MSBTYWx0ZWRfXxZ/qTJBhbYe5 tBhuWZhMaw4340Jmr9lVy9tASE1Xbsxi2/CTtBEicUE2aZO5Oa4kK7STr1yD9vD5+X5M6QWIrZi DSgLnZE18WHRQks8b5aU8f3L33OYF9TiOjv8Vow1hih+Q4eM4N9SHZDScXd/5lKXkjTAFiGBLkS TwZ+RkDt89RyZcaMqRBfsZqfbqM3qpUiJHf5s5jymXbmIUxAUvIaHT0alcUwOW7GZVcEEcxYf2j e5sMzE9vtzepHsCMAGDkRItLUOkvihy9OGC0WskPsDYRfF4yzDsB90TXDTTcJC0vFJTIG/SOcLg 5yWQfDS0KmnCfOTB0M9hQOGLqxEtQBMY/yY7RCyVJcpJvERn7cgOlTPDShdwYCR8Lup40to0W67 AjNaLsFlH9bH6jpBo2CEHouJP+dqYw== X-Authority-Analysis: v=2.4 cv=EqrfbCcA c=1 sm=1 tr=0 ts=692422e4 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=5m_mccj1f-mIrhuec74A:9 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: NlgkzN2oYlEEivSc8m3yj9ygm_2uOyVt X-Proofpoint-GUID: NlgkzN2oYlEEivSc8m3yj9ygm_2uOyVt X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-24_03,2025-11-21_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 phishscore=0 bulkscore=0 malwarescore=0 adultscore=0 spamscore=0 clxscore=1011 priorityscore=1501 impostorscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511240081 This adds a new page to document how to use the ad4062 ADC driver. Signed-off-by: Jorge Marques --- Documentation/iio/ad4062.rst | 94 ++++++++++++++++++++++++++++++++++++++++= ++++ Documentation/iio/index.rst | 1 + MAINTAINERS | 1 + 3 files changed, 96 insertions(+) diff --git a/Documentation/iio/ad4062.rst b/Documentation/iio/ad4062.rst new file mode 100644 index 0000000000000..e6bcca2bef24b --- /dev/null +++ b/Documentation/iio/ad4062.rst @@ -0,0 +1,94 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +AD4062 driver +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +ADC driver for Analog Devices Inc. AD4060/AD4062 devices. The module name = is +``ad4062``. + +Supported devices +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The following chips are supported by this driver: + +* `AD4060 `_ +* `AD4062 `_ + +Wiring modes +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The ADC is interfaced through an I3C bus, and contains two programmable GP= IOs. + +The ADC convert-start happens on the SDA rising edge of the I3C stop (P) b= it +at the end of the read command. + +The two programmable GPIOS are optional and have a role assigned if presen= t in +the devicetree ``interrupt-names`` property: + +- GP1: Is assigned the role of Data Ready signal. + +Device attributes +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The ADC contains only one channel with following attributes: + +.. list-table:: Channel attributes + :header-rows: 1 + + * - Attribute + - Description + * - ``in_voltage_calibscale`` + - Sets the gain scaling factor that the hardware applies to the sampl= e, + to compensate for system gain error. + * - ``in_voltage_oversampling_ratio`` + - Sets device's burst averaging mode to over sample using the + internal sample rate. Value 1 disable the burst averaging mode. + * - ``in_voltage_oversampling_ratio_available`` + - List of available oversampling values. + * - ``in_voltage_raw`` + - Returns the raw ADC voltage value. + * - ``in_voltage_scale`` + - Returns the channel scale in reference to the reference voltage + ``ref-supply`` or ``vdd-supply`` if the former not present. + +Also contain the following device attributes: + +.. list-table:: Device attributes + :header-rows: 1 + + * - Attribute + - Description + * - ``sampling_frequency`` + - Sets the duration of a single scan, used in the burst averaging mod= e. + The duration is described by ``(n_avg - 1) / fosc + tconv``, where + ``n_avg`` is the oversampling ratio, ``fosc`` is the internal sample + rate and ``tconv`` is the ADC conversion time. + * - ``sampling_frequency_available`` + - Lists the available sampling frequencies, computed on the current + oversampling ratio. If the ratio is 1, the frequency is ``1/tconv``. + +Interrupts +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The interrupts are mapped through the ``interrupt-names`` and ``interrupts= `` +properties. + +The ``interrupt-names`` ``gp1`` entry sets the role of Data Ready signal. +If it is not present, the driver fallback to enabling the same role as an +I3C IBI. + +Low-power mode +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The device enters low-power mode on idle to save power. Enabling an event = puts +the device out of the low-power since the ADC autonomously samples to asse= rt +the event condition. + +Unimplemented features +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +- Monitor mode +- Trigger mode +- Averaging mode +- General purpose output diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index 315ae37d6fd4b..ba3e609c6a13c 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -22,6 +22,7 @@ Industrial I/O Kernel Drivers ad3552r ad4000 ad4030 + ad4062 ad4695 ad7191 ad7380 diff --git a/MAINTAINERS b/MAINTAINERS index e22ba5ec8c849..8fc28b789d639 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1437,6 +1437,7 @@ M: Jorge Marques S: Supported W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml +F: Documentation/iio/ad4062.rst =20 ANALOG DEVICES INC AD4080 DRIVER M: Antoniu Miclaus --=20 2.51.1 From nobody Tue Dec 2 00:46:53 2025 Received: from mx0b-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9341F2F362D; Mon, 24 Nov 2025 09:18:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975941; cv=none; b=n5G36VuE1VEbmu0f84Pn18ghWhnp6bNkpb4/IJX6hZ7S/aKrWfLD7LADj1Axp6CfOFhKzafQiPP0fdMAsn9Yw788e6h3+IKZfyzREk4v4BnaLCgdgqR7LjdFsqInqqXsKFbsp1mBFFit48aK2mI/BYtlA46wt3IHSk16DLT5hPE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975941; c=relaxed/simple; bh=EGqnRUIZ88XhAFWn4QO7hpGwrC+uXo5B8lnXB90TgQg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=XBkDZlVf6q7/ui9Qb6SGmqQzsVciCdGNUvNt7N2Vntef05JXdKSpHd6jot+o62l1t8m9PBgcI5Nn7eAOmf3qxJ0bPna1klaR1rxPUeUWhDPWzvswpokd8IzbNWmxU5BzfKBc+0KbYDjPKunmA+pBNecMTdveC0FoBDDDZ6F2LxY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=Z+GHzqs4; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="Z+GHzqs4" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5AO6pmEo3691513; Mon, 24 Nov 2025 04:18:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=AXRG/ cFkj+CyiAXAi/zi6KitRch88deGb+3V+LLFRic=; b=Z+GHzqs4CMt9DKD3SBRY3 xjnpvmqoPar5wpzmLP5lVkwHoMaQsSvmlJJBkpf/2wdruZDYeGyWt7CAbTOEKzNg fdHGTbsBUsfuKeixn6j4YoY9n2n7HcOgPXNl9N/iZIDIVHEEJsnHDZRpnkHXTzN9 lLZlSCQBOmqFtX3zgu96qjpcKYVM2CgWqUHOFlIhvogBAAjaf9opYTNn6+ZenqpD v1rTocM/bU5mDF4WMfwcC7pwVJ1JxQOiheAldDJ9/unSYQTgLmIPBBe9GL2hcGbU XAwg0M0Pqd/C3sBIHd2PXLSbyj5K9m00omiIFTRdaofex/AX8d0yAg2tniYC5usJ A== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 4akvcjmw8f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Nov 2025 04:18:33 -0500 (EST) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 5AO9IWd3050905 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 24 Nov 2025 04:18:32 -0500 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:32 -0500 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:31 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 24 Nov 2025 04:18:31 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.82]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5AO9I8VM024016; Mon, 24 Nov 2025 04:18:23 -0500 From: Jorge Marques Date: Mon, 24 Nov 2025 10:18:02 +0100 Subject: [PATCH v2 3/9] iio: adc: Add support for ad4062 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251124-staging-ad4062-v2-3-a375609afbb7@analog.com> References: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> In-Reply-To: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> To: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , "David Lechner" , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Linus Walleij , Bartosz Golaszewski CC: , , , , , Jorge Marques X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763975888; l=27152; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=EGqnRUIZ88XhAFWn4QO7hpGwrC+uXo5B8lnXB90TgQg=; b=qEegrXG76NyHDfyd0U2khGUG+Q75sZSDyUY9YnF2cmEdxATazPzPrt7T5AWmq7XBQW6FeQgzk bJ6h5rDU2tpCasv5TmwYfl4dUABMANa47ZPPqirA1EfXhaZPit+wB/M X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTI0MDA4MSBTYWx0ZWRfX/zbbA4tyt/UM JFNgXhqewBN/czeos9QA5kTx0aWm9AgyW3GdhsMdJb2C51SYuKCvFOpWlmp7p/4DS/4sc7w1I1c j8WJgAmIS3nSrTDL8nt2onEe7g97mEi/n24jlqnCDCzCzYEv5m39hS1vbGi+hyd9DBJdINa0odn MUP7mC1Yqy7+1t/RKm+Cu+zpin2rkNUToIRR3fIG0yjKZpSnKpa1gBHEJ1ewEXEuBuvLL99Iq8W XixtJoIyWDQc6Ti8T8I5CW0ilmKKGw6AAgRK8o2IBwifyTk7sOBMOWiEZB+WWUduu+HOiyHvpmt jmgVQjiFaaKQfx3CYJFScVbRP2x/S/MsgT/esFTNzL/XWnYG8o3Ok0cKxZSTT+55mCmhA6NWmT8 vV0kCmRFJRyRtjVbR4xHF6Jt0dCsXQ== X-Authority-Analysis: v=2.4 cv=EqrfbCcA c=1 sm=1 tr=0 ts=692422e9 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=wY3Oww9YKB1vFLSdLmoA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: RtM4wrKGC-O-gakpp2LudEgBmK3lAuZV X-Proofpoint-GUID: RtM4wrKGC-O-gakpp2LudEgBmK3lAuZV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-24_03,2025-11-21_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 phishscore=0 bulkscore=0 malwarescore=0 adultscore=0 spamscore=0 clxscore=1011 priorityscore=1501 impostorscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511240081 The AD4060/AD4062 are versatile, 16-bit/12-bit, successive approximation register (SAR) analog-to-digital converter (ADC) with low-power and threshold monitoring modes. Signed-off-by: Jorge Marques --- MAINTAINERS | 1 + drivers/iio/adc/Kconfig | 11 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad4062.c | 881 +++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 894 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8fc28b789d639..003f51cfb0d07 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1438,6 +1438,7 @@ S: Supported W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml F: Documentation/iio/ad4062.rst +F: drivers/iio/adc/ad4062.c =20 ANALOG DEVICES INC AD4080 DRIVER M: Antoniu Miclaus diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 58da8255525e4..e506dbe83f488 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -70,6 +70,17 @@ config AD4030 To compile this driver as a module, choose M here: the module will be called ad4030. =20 +config AD4062 + tristate "Analog Devices AD4062 Driver" + depends on I3C + select REGMAP_I3C + help + Say yes here to build support for Analog Devices AD4062 I3C analog + to digital converters (ADC). + + To compile this driver as a module, choose M here: the module will be + called ad4062. + config AD4080 tristate "Analog Devices AD4080 high speed ADC" depends on SPI diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 7cc8f9a12f763..a897252eeed40 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_AB8500_GPADC) +=3D ab8500-gpadc.o obj-$(CONFIG_AD_SIGMA_DELTA) +=3D ad_sigma_delta.o obj-$(CONFIG_AD4000) +=3D ad4000.o obj-$(CONFIG_AD4030) +=3D ad4030.o +obj-$(CONFIG_AD4062) +=3D ad4062.o obj-$(CONFIG_AD4080) +=3D ad4080.o obj-$(CONFIG_AD4130) +=3D ad4130.o obj-$(CONFIG_AD4170_4) +=3D ad4170-4.o diff --git a/drivers/iio/adc/ad4062.c b/drivers/iio/adc/ad4062.c new file mode 100644 index 0000000000000..6866393ffef8d --- /dev/null +++ b/drivers/iio/adc/ad4062.c @@ -0,0 +1,881 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Analog Devices AD4062 I3C ADC driver + * + * Copyright 2025 Analog Devices Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AD4062_REG_INTERFACE_CONFIG_A 0x00 +#define AD4062_REG_DEVICE_CONFIG 0x02 +#define AD4062_REG_DEVICE_CONFIG_POWER_MODE_MSK GENMASK(1, 0) +#define AD4062_REG_DEVICE_CONFIG_LOW_POWER_MODE 3 +#define AD4062_REG_PROD_ID_1 0x05 +#define AD4062_REG_DEVICE_GRADE 0x06 +#define AD4062_REG_SCRATCH_PAD 0x0A +#define AD4062_REG_VENDOR_H 0x0D +#define AD4062_REG_STREAM_MODE 0x0E +#define AD4062_REG_INTERFACE_STATUS 0x11 +#define AD4062_REG_MODE_SET 0x20 +#define AD4062_REG_MODE_SET_ENTER_ADC BIT(0) +#define AD4062_REG_ADC_MODES 0x21 +#define AD4062_REG_ADC_MODES_MODE_MSK GENMASK(1, 0) +#define AD4062_REG_ADC_CONFIG 0x22 +#define AD4062_REG_ADC_CONFIG_REF_EN_MSK BIT(5) +#define AD4062_REG_ADC_CONFIG_SCALE_EN_MSK BIT(4) +#define AD4062_REG_AVG_CONFIG 0x23 +#define AD4062_REG_GP_CONF 0x24 +#define AD4062_REG_GP_CONF_MODE_MSK_1 GENMASK(6, 4) +#define AD4062_REG_INTR_CONF 0x25 +#define AD4062_REG_INTR_CONF_EN_MSK_1 GENMASK(5, 4) +#define AD4062_REG_TIMER_CONFIG 0x27 +#define AD4062_REG_TIMER_CONFIG_FS_MASK GENMASK(7, 4) +#define AD4062_REG_MON_VAL 0x2F +#define AD4062_REG_ADC_IBI_EN 0x31 +#define AD4062_REG_ADC_IBI_EN_CONV_TRIGGER BIT(2) +#define AD4062_REG_FUSE_CRC 0x40 +#define AD4062_REG_DEVICE_STATUS 0x41 +#define AD4062_REG_DEVICE_STATUS_DEVICE_RESET BIT(6) +#define AD4062_REG_IBI_STATUS 0x48 +#define AD4062_REG_CONV_READ_LSB 0x50 +#define AD4062_REG_CONV_TRIGGER 0x59 +#define AD4062_REG_CONV_AUTO 0x61 +#define AD4062_MAX_REG AD4062_REG_CONV_AUTO + +#define AD4062_I3C_VENDOR 0x0177 + +#define AD4062_SOFT_RESET 0x81 +#define AD4060_MAX_AVG 0x7 +#define AD4062_MAX_AVG 0xB +#define AD4062_MON_VAL_MAX_GAIN 1999970 +#define AD4062_MON_VAL_MIDDLE_POINT 0x8000 +#define AD4062_GP_DRDY 0x2 +#define AD4062_INTR_EN_NEITHER 0x0 +#define AD4062_TCONV_NS 270 + +enum ad4062_operation_mode { + AD4062_SAMPLE_MODE =3D 0x0, + AD4062_BURST_AVERAGING_MODE =3D 0x1, + AD4062_MONITOR_MODE =3D 0x3, +}; + +struct ad4062_chip_info { + const struct iio_chan_spec channels[1]; + const char *name; + u16 prod_id; + u8 max_avg; +}; + +enum { + AD4062_SCAN_TYPE_SAMPLE, + AD4062_SCAN_TYPE_BURST_AVG, +}; + +static const struct iio_scan_type ad4062_scan_type_12_s[] =3D { + [AD4062_SCAN_TYPE_SAMPLE] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_BE, + }, + [AD4062_SCAN_TYPE_BURST_AVG] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_BE, + }, +}; + +static const struct iio_scan_type ad4062_scan_type_16_s[] =3D { + [AD4062_SCAN_TYPE_SAMPLE] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_BE, + }, + [AD4062_SCAN_TYPE_BURST_AVG] =3D { + .sign =3D 's', + .realbits =3D 24, + .storagebits =3D 32, + .endianness =3D IIO_BE, + }, +}; + +static const int ad4062_conversion_freqs[] =3D { + 2000000, 1000000, 300000, 100000, /* 0 - 3 */ + 33300, 10000, 3000, 500, /* 4 - 7 */ + 333, 250, 200, 166, /* 8 - 11 */ + 140, 124, 111, /* 12 - 15 */ +}; + +struct ad4062_state { + const struct ad4062_chip_info *chip; + const struct ad4062_bus_ops *ops; + enum ad4062_operation_mode mode; + struct completion completion; + struct iio_trigger *trigger; + struct iio_dev *indio_dev; + struct i3c_device *i3cdev; + struct regmap *regmap; + u16 sampling_frequency; + int vref_uv; + int samp_freqs[ARRAY_SIZE(ad4062_conversion_freqs)]; + u8 oversamp_ratio; + union { + __be32 be32; + __be16 be16; + u8 bytes[4]; + } buf __aligned(IIO_DMA_MINALIGN); + u8 reg_addr_conv; +}; + +static const struct regmap_range ad4062_regmap_rd_ranges[] =3D { + regmap_reg_range(AD4062_REG_INTERFACE_CONFIG_A, AD4062_REG_DEVICE_GRADE), + regmap_reg_range(AD4062_REG_SCRATCH_PAD, AD4062_REG_INTERFACE_STATUS), + regmap_reg_range(AD4062_REG_MODE_SET, AD4062_REG_ADC_IBI_EN), + regmap_reg_range(AD4062_REG_FUSE_CRC, AD4062_REG_IBI_STATUS), + regmap_reg_range(AD4062_REG_CONV_READ_LSB, AD4062_REG_CONV_AUTO), +}; + +static const struct regmap_access_table ad4062_regmap_rd_table =3D { + .yes_ranges =3D ad4062_regmap_rd_ranges, + .n_yes_ranges =3D ARRAY_SIZE(ad4062_regmap_rd_ranges), +}; + +static const struct regmap_range ad4062_regmap_wr_ranges[] =3D { + regmap_reg_range(AD4062_REG_INTERFACE_CONFIG_A, AD4062_REG_DEVICE_CONFIG), + regmap_reg_range(AD4062_REG_SCRATCH_PAD, AD4062_REG_SCRATCH_PAD), + regmap_reg_range(AD4062_REG_STREAM_MODE, AD4062_REG_INTERFACE_STATUS), + regmap_reg_range(AD4062_REG_MODE_SET, AD4062_REG_ADC_IBI_EN), + regmap_reg_range(AD4062_REG_FUSE_CRC, AD4062_REG_DEVICE_STATUS), +}; + +static const struct regmap_access_table ad4062_regmap_wr_table =3D { + .yes_ranges =3D ad4062_regmap_wr_ranges, + .n_yes_ranges =3D ARRAY_SIZE(ad4062_regmap_wr_ranges), +}; + +static int ad4062_conversion_frequency_set(struct ad4062_state *st, u8 val) +{ + return regmap_write(st->regmap, AD4062_REG_TIMER_CONFIG, + FIELD_PREP(AD4062_REG_TIMER_CONFIG_FS_MASK, val)); +} + +#define AD4062_CHAN(bits) { \ + .type =3D IIO_VOLTAGE, \ + .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_CALIBSCALE) | \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .info_mask_shared_by_all =3D BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available =3D BIT(IIO_CHAN_INFO_OVERSAMPLING_RA= TIO), \ + .info_mask_shared_by_all_available =3D BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .indexed =3D 1, \ + .channel =3D 0, \ + .has_ext_scan_type =3D 1, \ + .ext_scan_type =3D ad4062_scan_type_##bits##_s, \ + .num_ext_scan_type =3D ARRAY_SIZE(ad4062_scan_type_##bits##_s), \ +} + +static const struct ad4062_chip_info ad4060_chip_info =3D { + .name =3D "ad4060", + .channels =3D { AD4062_CHAN(12) }, + .prod_id =3D 0x7A, + .max_avg =3D AD4060_MAX_AVG, +}; + +static const struct ad4062_chip_info ad4062_chip_info =3D { + .name =3D "ad4062", + .channels =3D { AD4062_CHAN(16) }, + .prod_id =3D 0x7C, + .max_avg =3D AD4062_MAX_AVG, +}; + +static int ad4062_set_oversampling_ratio(struct ad4062_state *st, unsigned= int val) +{ + int ret; + + if (val < 1 || val > BIT(st->chip->max_avg + 1)) + return -EINVAL; + + /* 1 disables oversampling */ + val =3D ilog2(val); + if (val =3D=3D 0) { + st->mode =3D AD4062_SAMPLE_MODE; + } else { + st->mode =3D AD4062_BURST_AVERAGING_MODE; + ret =3D regmap_write(st->regmap, AD4062_REG_AVG_CONFIG, val - 1); + if (ret) + return ret; + } + st->oversamp_ratio =3D BIT(val); + + return 0; +} + +static int ad4062_get_oversampling_ratio(struct ad4062_state *st, + unsigned int *val) +{ + int ret, buf; + + if (st->mode =3D=3D AD4062_SAMPLE_MODE) { + *val =3D 1; + return 0; + } + + ret =3D regmap_read(st->regmap, AD4062_REG_AVG_CONFIG, &buf); + return 0; +} + +static int ad4062_calc_sampling_frequency(int fosc, unsigned int n_avg) +{ + /* See datasheet page 31 */ + u64 duration =3D div_u64((u64)(n_avg - 1) * NSEC_PER_SEC, fosc) + AD4062_= TCONV_NS; + + return DIV_ROUND_UP_ULL(NSEC_PER_SEC, duration); +} + +static int ad4062_populate_sampling_frequency(struct ad4062_state *st) +{ + for (int i =3D 0; i < ARRAY_SIZE(ad4062_conversion_freqs); i++) + st->samp_freqs[i] =3D ad4062_calc_sampling_frequency(ad4062_conversion_f= reqs[i], + st->oversamp_ratio); + return 0; +} + +static int ad4062_get_sampling_frequency(struct ad4062_state *st, int *val) +{ + *val =3D ad4062_calc_sampling_frequency(ad4062_conversion_freqs[st->sampl= ing_frequency], + st->oversamp_ratio); + return 0; +} + +static int ad4062_set_sampling_frequency(struct ad4062_state *st, int val) +{ + int ret; + + ret =3D ad4062_populate_sampling_frequency(st); + if (ret) + return ret; + + st->sampling_frequency =3D find_closest_descending(val, st->samp_freqs, + ARRAY_SIZE(ad4062_conversion_freqs)); + return 0; +} + +static int ad4062_check_ids(struct ad4062_state *st) +{ + int ret; + u16 val; + + ret =3D regmap_bulk_read(st->regmap, AD4062_REG_PROD_ID_1, + &st->buf.be16, sizeof(st->buf.be16)); + if (ret) + return ret; + + val =3D get_unaligned_be16(st->buf.bytes); + if (val !=3D st->chip->prod_id) + dev_warn(&st->i3cdev->dev, + "Production ID x%x does not match known values", val); + + ret =3D regmap_bulk_read(st->regmap, AD4062_REG_VENDOR_H, + &st->buf.be16, sizeof(st->buf.be16)); + if (ret) + return ret; + + val =3D get_unaligned_be16(st->buf.bytes); + if (val !=3D AD4062_I3C_VENDOR) { + dev_err(&st->i3cdev->dev, + "Vendor ID x%x does not match expected value\n", val); + return -ENODEV; + } + + return 0; +} + +static int ad4062_set_operation_mode(struct ad4062_state *st, + enum ad4062_operation_mode mode) +{ + int ret; + + if (mode =3D=3D AD4062_BURST_AVERAGING_MODE) { + ret =3D ad4062_conversion_frequency_set(st, st->sampling_frequency); + if (ret) + return ret; + } + + ret =3D regmap_update_bits(st->regmap, AD4062_REG_ADC_MODES, + AD4062_REG_ADC_MODES_MODE_MSK, mode); + if (ret) + return ret; + + return regmap_write(st->regmap, AD4062_REG_MODE_SET, + AD4062_REG_MODE_SET_ENTER_ADC); +} + +static int ad4062_soft_reset(struct ad4062_state *st) +{ + u8 val =3D AD4062_SOFT_RESET; + int ret; + + ret =3D regmap_write(st->regmap, AD4062_REG_INTERFACE_CONFIG_A, val); + if (ret) + return ret; + + /* Wait AD4062 treset time */ + fsleep(5000); + + return 0; +} + +static int ad4062_setup(struct iio_dev *indio_dev, struct iio_chan_spec co= nst *chan, + const bool *ref_sel) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + const struct iio_scan_type *scan_type; + int ret; + u8 val; + + scan_type =3D iio_get_current_scan_type(indio_dev, chan); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); + + val =3D FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, AD4062_GP_DRDY); + ret =3D regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + AD4062_REG_GP_CONF_MODE_MSK_1, val); + if (ret) + return ret; + + ret =3D regmap_update_bits(st->regmap, AD4062_REG_ADC_CONFIG, + AD4062_REG_ADC_CONFIG_REF_EN_MSK, + FIELD_PREP(AD4062_REG_ADC_CONFIG_REF_EN_MSK, + *ref_sel)); + if (ret) + return ret; + + ret =3D regmap_write(st->regmap, AD4062_REG_DEVICE_STATUS, + AD4062_REG_DEVICE_STATUS_DEVICE_RESET); + if (ret) + return ret; + + val =3D FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_1, AD4062_INTR_EN_NEITHER); + ret =3D regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, + AD4062_REG_INTR_CONF_EN_MSK_1, val); + if (ret) + return ret; + + put_unaligned_be16(AD4062_MON_VAL_MIDDLE_POINT, st->buf.bytes); + return regmap_bulk_write(st->regmap, AD4062_REG_MON_VAL, + &st->buf.be16, sizeof(st->buf.be16)); +} + +static irqreturn_t ad4062_irq_handler_drdy(int irq, void *private) +{ + struct iio_dev *indio_dev =3D private; + struct ad4062_state *st =3D iio_priv(indio_dev); + + complete(&st->completion); + + return IRQ_HANDLED; +} + +static void ad4062_ibi_handler(struct i3c_device *i3cdev, + const struct i3c_ibi_payload *payload) +{ + struct ad4062_state *st =3D i3cdev_get_drvdata(i3cdev); + + complete(&st->completion); +} + +static void ad4062_remove_ibi(void *data) +{ + struct i3c_device *i3cdev =3D data; + + i3c_device_disable_ibi(i3cdev); + i3c_device_free_ibi(i3cdev); +} + +static int ad4062_request_ibi(struct i3c_device *i3cdev) +{ + const struct i3c_ibi_setup ibireq =3D { + .max_payload_len =3D 1, + .num_slots =3D 1, + .handler =3D ad4062_ibi_handler, + }; + int ret; + + ret =3D i3c_device_request_ibi(i3cdev, &ibireq); + if (ret) + return ret; + + ret =3D i3c_device_enable_ibi(i3cdev); + if (ret) + goto err_enable_ibi; + + return devm_add_action_or_reset(&i3cdev->dev, ad4062_remove_ibi, i3cdev); + +err_enable_ibi: + i3c_device_free_ibi(i3cdev); + return ret; +} + +static int ad4062_request_irq(struct iio_dev *indio_dev) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + struct device *dev =3D &st->i3cdev->dev; + int ret; + + ret =3D fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp1"); + if (ret =3D=3D -EPROBE_DEFER) { + return ret; + } else if (ret < 0) { + ret =3D regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, + AD4062_REG_ADC_IBI_EN_CONV_TRIGGER, + AD4062_REG_ADC_IBI_EN_CONV_TRIGGER); + } else { + ret =3D devm_request_threaded_irq(dev, ret, + ad4062_irq_handler_drdy, + NULL, IRQF_ONESHOT, indio_dev->name, + indio_dev); + } + + return ret; +} + +static const int ad4062_oversampling_avail[] =3D { + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, +}; + +static int ad4062_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, const int **vals, + int *type, int *len, long mask) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + *vals =3D ad4062_oversampling_avail; + *len =3D ARRAY_SIZE(ad4062_oversampling_avail); + *type =3D IIO_VAL_INT; + + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + ret =3D ad4062_populate_sampling_frequency(st); + if (ret) + return ret; + *vals =3D st->samp_freqs; + *len =3D st->oversamp_ratio !=3D 1 ? ARRAY_SIZE(ad4062_conversion_freqs)= : 1; + *type =3D IIO_VAL_INT; + + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int ad4062_get_chan_scale(struct iio_dev *indio_dev, int *val, int = *val2) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + const struct iio_scan_type *scan_type; + + scan_type =3D iio_get_current_scan_type(indio_dev, st->chip->channels); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); + + *val =3D (st->vref_uv * 2) / MILLI; + + *val2 =3D scan_type->realbits - 1; /* signed */ + + return IIO_VAL_FRACTIONAL_LOG2; +} + +static int ad4062_get_chan_calibscale(struct ad4062_state *st, int *val, i= nt *val2) +{ + u16 gain; + int ret; + + ret =3D regmap_bulk_read(st->regmap, AD4062_REG_MON_VAL, + &st->buf.be16, sizeof(st->buf.be16)); + if (ret) + return ret; + + gain =3D get_unaligned_be16(st->buf.bytes); + + /* From datasheet: code out =3D code in =C3=97 mon_val/0x8000 */ + *val =3D gain / AD4062_MON_VAL_MIDDLE_POINT; + *val2 =3D mul_u64_u32_div(gain % AD4062_MON_VAL_MIDDLE_POINT, NANO, + AD4062_MON_VAL_MIDDLE_POINT); + + return IIO_VAL_INT_PLUS_NANO; +} + +static int ad4062_set_chan_calibscale(struct ad4062_state *st, int gain_in= t, int gain_frac) +{ + u64 gain; + int ret; + + if (gain_int < 0 || gain_frac < 0) + return -EINVAL; + + gain =3D mul_u32_u32(gain_int, MICRO) + gain_frac; + + if (gain > AD4062_MON_VAL_MAX_GAIN) + return -EINVAL; + + put_unaligned_be16(DIV_ROUND_CLOSEST_ULL(gain * AD4062_MON_VAL_MIDDLE_POI= NT, + MICRO), + st->buf.bytes); + + ret =3D regmap_bulk_write(st->regmap, AD4062_REG_MON_VAL, + &st->buf.be16, sizeof(st->buf.be16)); + if (ret) + return ret; + + /* Enable scale if gain is not one. */ + return regmap_update_bits(st->regmap, AD4062_REG_ADC_CONFIG, + AD4062_REG_ADC_CONFIG_SCALE_EN_MSK, + FIELD_PREP(AD4062_REG_ADC_CONFIG_SCALE_EN_MSK, + !(gain_int =3D=3D 1 && gain_frac =3D=3D 0))); +} + +static int __ad4062_read_chan_raw(struct ad4062_state *st, int *val) +{ + struct i3c_device *i3cdev =3D st->i3cdev; + struct i3c_priv_xfer t[2] =3D { + { + .data.out =3D &st->reg_addr_conv, + .len =3D sizeof(st->reg_addr_conv), + .rnw =3D false, + }, + { + .data.in =3D &st->buf.be32, + .len =3D sizeof(st->buf.be32), + .rnw =3D true, + } + }; + int ret; + + reinit_completion(&st->completion); + /* Change address pointer to trigger conversion */ + ret =3D i3c_device_do_priv_xfers(i3cdev, &t[0], 1); + if (ret) + return ret; + /* + * Single sample read should be used only for oversampling and + * sampling frequency pairs that take less than 1 sec. + */ + ret =3D wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(1000)); + if (!ret) + return -ETIMEDOUT; + + ret =3D i3c_device_do_priv_xfers(i3cdev, &t[1], 1); + if (ret) + return ret; + *val =3D get_unaligned_be32(st->buf.bytes); + return 0; +} + +static int ad4062_read_chan_raw(struct ad4062_state *st, int *val) +{ + int ret; + + ACQUIRE(pm_runtime_active_try_enabled, pm)(&st->i3cdev->dev); + ret =3D ACQUIRE_ERR(pm_runtime_active_try_enabled, &pm); + if (ret) + return ret; + + ret =3D ad4062_set_operation_mode(st, st->mode); + if (ret) + return ret; + + return __ad4062_read_chan_raw(st, val); +} + +static int ad4062_read_raw_dispatch(struct ad4062_state *st, int *val, int= *val2, + long info) +{ + switch (info) { + case IIO_CHAN_INFO_RAW: + return ad4062_read_chan_raw(st, val); + + case IIO_CHAN_INFO_CALIBSCALE: + return ad4062_get_chan_calibscale(st, val, val2); + + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + return ad4062_get_oversampling_ratio(st, val); + + case IIO_CHAN_INFO_SAMP_FREQ: + return ad4062_get_sampling_frequency(st, val); + + default: + return -EINVAL; + } +} + +static int ad4062_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long info) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (info =3D=3D IIO_CHAN_INFO_SCALE) + return ad4062_get_chan_scale(indio_dev, val, val2); + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret =3D ad4062_read_raw_dispatch(st, val, val2, info); + + iio_device_release_direct(indio_dev); + return ret ? ret : IIO_VAL_INT; +} + +static int ad4062_write_raw_dispatch(struct ad4062_state *st, int val, int= val2, + long info) +{ + switch (info) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + return ad4062_set_oversampling_ratio(st, val); + + case IIO_CHAN_INFO_CALIBSCALE: + return ad4062_set_chan_calibscale(st, val, val2); + + case IIO_CHAN_INFO_SAMP_FREQ: + return ad4062_set_sampling_frequency(st, val); + + default: + return -EINVAL; + } +}; + +static int ad4062_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, + int val2, long info) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret =3D ad4062_write_raw_dispatch(st, val, val2, info); + + iio_device_release_direct(indio_dev); + return ret; +} + +static int ad4062_debugfs_reg_access(struct iio_dev *indio_dev, unsigned i= nt reg, + unsigned int writeval, unsigned int *readval) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (readval) + ret =3D regmap_read(st->regmap, reg, readval); + else + ret =3D regmap_write(st->regmap, reg, writeval); + + return ret; +} + +static int ad4062_get_current_scan_type(const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + + return st->mode =3D=3D AD4062_BURST_AVERAGING_MODE ? + AD4062_SCAN_TYPE_BURST_AVG : + AD4062_SCAN_TYPE_SAMPLE; +} + +static const struct iio_info ad4062_info =3D { + .read_raw =3D ad4062_read_raw, + .write_raw =3D ad4062_write_raw, + .read_avail =3D ad4062_read_avail, + .get_current_scan_type =3D &ad4062_get_current_scan_type, + .debugfs_reg_access =3D &ad4062_debugfs_reg_access, +}; + +static const struct regmap_config ad4062_regmap_config =3D { + .name =3D "ad4062", + .reg_bits =3D 8, + .val_bits =3D 8, + .max_register =3D AD4062_MAX_REG, + .rd_table =3D &ad4062_regmap_rd_table, + .wr_table =3D &ad4062_regmap_wr_table, + .can_sleep =3D true, +}; + +static int ad4062_regulators_get(struct ad4062_state *st, bool *ref_sel) +{ + struct device *dev =3D &st->i3cdev->dev; + int ret; + + ret =3D devm_regulator_get_enable(dev, "vio"); + if (ret) + return dev_err_probe(dev, ret, + "Failed to enable vio voltage\n"); + + st->vref_uv =3D devm_regulator_get_enable_read_voltage(dev, "ref"); + *ref_sel =3D st->vref_uv =3D=3D -ENODEV; + if (st->vref_uv < 0 && st->vref_uv !=3D -ENODEV) { + return dev_err_probe(dev, st->vref_uv, + "Failed to enable and read ref voltage\n"); + } else if (st->vref_uv =3D=3D -ENODEV) { + st->vref_uv =3D devm_regulator_get_enable_read_voltage(dev, "vdd"); + if (st->vref_uv < 0) + return dev_err_probe(dev, st->vref_uv, + "Failed to enable and read vdd voltage\n"); + } else { + ret =3D devm_regulator_get_enable(dev, "vdd"); + if (ret) + return dev_err_probe(dev, ret, + "Failed to enable vdd regulator\n"); + } + + return 0; +} + +static const struct i3c_device_id ad4062_id_table[] =3D { + I3C_DEVICE(AD4062_I3C_VENDOR, ad4060_chip_info.prod_id, &ad4060_chip_info= ), + I3C_DEVICE(AD4062_I3C_VENDOR, ad4062_chip_info.prod_id, &ad4062_chip_info= ), + { } +}; +MODULE_DEVICE_TABLE(i3c, ad4062_id_table); + +static int ad4062_probe(struct i3c_device *i3cdev) +{ + const struct i3c_device_id *id =3D i3c_device_match_id(i3cdev, ad4062_id_= table); + const struct ad4062_chip_info *chip =3D id->data; + struct device *dev =3D &i3cdev->dev; + struct iio_dev *indio_dev; + struct ad4062_state *st; + bool ref_sel; + int ret; + + indio_dev =3D devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st =3D iio_priv(indio_dev); + st->i3cdev =3D i3cdev; + i3cdev_set_drvdata(i3cdev, st); + init_completion(&st->completion); + + ret =3D ad4062_regulators_get(st, &ref_sel); + if (ret) + return ret; + + st->regmap =3D devm_regmap_init_i3c(i3cdev, &ad4062_regmap_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(dev, PTR_ERR(st->regmap), + "Failed to initialize regmap\n"); + + st->mode =3D AD4062_SAMPLE_MODE; + st->chip =3D chip; + st->sampling_frequency =3D 0; + st->oversamp_ratio =3D BIT(0); + st->indio_dev =3D indio_dev; + st->reg_addr_conv =3D AD4062_REG_CONV_TRIGGER; + + indio_dev->modes =3D INDIO_DIRECT_MODE; + indio_dev->num_channels =3D 1; + indio_dev->info =3D &ad4062_info; + indio_dev->name =3D chip->name; + indio_dev->channels =3D chip->channels; + + ret =3D ad4062_soft_reset(st); + if (ret) + return dev_err_probe(dev, ret, "AD4062 failed to soft reset\n"); + + ret =3D ad4062_check_ids(st); + if (ret) + return ret; + + ret =3D ad4062_setup(indio_dev, indio_dev->channels, &ref_sel); + if (ret) + return ret; + + ret =3D ad4062_request_irq(indio_dev); + if (ret) + return ret; + + pm_runtime_set_active(dev); + ret =3D devm_pm_runtime_enable(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable pm_runtime\n"); + + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); + + ret =3D ad4062_request_ibi(i3cdev); + if (ret) + return dev_err_probe(dev, ret, "Failed to request i3c ibi\n"); + + return devm_iio_device_register(dev, indio_dev); +} + +static int ad4062_runtime_suspend(struct device *dev) +{ + struct ad4062_state *st =3D dev_get_drvdata(dev); + + return regmap_write(st->regmap, AD4062_REG_DEVICE_CONFIG, + FIELD_PREP(AD4062_REG_DEVICE_CONFIG_POWER_MODE_MSK, + AD4062_REG_DEVICE_CONFIG_LOW_POWER_MODE)); +} + +static int ad4062_runtime_resume(struct device *dev) +{ + struct ad4062_state *st =3D dev_get_drvdata(dev); + int ret; + + ret =3D regmap_clear_bits(st->regmap, AD4062_REG_DEVICE_CONFIG, + AD4062_REG_DEVICE_CONFIG_POWER_MODE_MSK); + if (ret) + return ret; + + fsleep(4000); + return 0; +} + +static DEFINE_RUNTIME_DEV_PM_OPS(ad4062_pm_ops, ad4062_runtime_suspend, + ad4062_runtime_resume, NULL); + +static struct i3c_driver ad4062_driver =3D { + .driver =3D { + .name =3D "ad4062", + .pm =3D pm_ptr(&ad4062_pm_ops), + }, + .probe =3D ad4062_probe, + .id_table =3D ad4062_id_table, +}; +module_i3c_driver(ad4062_driver); + +MODULE_AUTHOR("Jorge Marques "); +MODULE_DESCRIPTION("Analog Devices AD4062"); +MODULE_LICENSE("GPL"); --=20 2.51.1 From nobody Tue Dec 2 00:46:53 2025 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8DD5A246335; Mon, 24 Nov 2025 09:18:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975940; cv=none; b=SaiTTT8jWlF/4TtJmMCQpg3HNAijdsShD2zRNiBA6oi3p/Icifg2IiNS+XQHEOr9NUrcQZqV1PAvO+SJq7HpFdPDqDG/ItiJKciP7C2rUl82YHBZ5T8w3tDLjo+AzqgjDYmX4QDS6n/9A50Yr2UeVbk5XOueGHNs2WTaqTCOR2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975940; c=relaxed/simple; bh=k24J9SVSpBNTE0t7Rk8CGprxFuIseSx9ccE+WbjYn5c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=RdW02majGMDgPorCJ2i6n5cpWEBnmh+yjOfqMM77bhz8BlrZrzX/if4PiuU1kfCtEbVobCr/L7P2Rez9DG+LTPPCr/JM9cCeay9AkLBVsgkXvBtQ3/iVLjkYldcRN0gWsM4DELNJggRnECdVTAptkjMF80rSKhKxI5oecVxN9gE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=lPqxYHS7; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="lPqxYHS7" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5AO5529b1958717; Mon, 24 Nov 2025 04:18:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=LcuBF z0e1njXZW4JimsU1D5rhEqnojcDga+gDFRgqmA=; b=lPqxYHS7sDviL12QI4ZhD rBiYgllMp+wACtE9e8CCKFx05+PnbSZaOXtkaul1ItCM4T82kLbR6FJtvVmqaz9N kp5PhzZLz0V29vpRYRbcEZacC5LRWK0ATCZyp6nUyjGDtrPVZ6xyC+qmMUIEYK7u AIBlu3mIUWFOy/flWORhADDM8huQe+fMmKkA6vqRBgwHXgourlx8GrX0L3Neqk1E xwYaUsA+J/AonU6J3KmT7jcqCWE0NTZnM2RpGBtljHkmSk88m9t38hkQ4pg0PT5e EwM6EQVYX59MIWMlMrIurLJ9nmHn4X1UYqNvDoNRgZ/8t26wfwTzRgLfXKQgFeBy Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4akay688ev-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Nov 2025 04:18:34 -0500 (EST) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 5AO9IXaI050917 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 24 Nov 2025 04:18:33 -0500 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:33 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 24 Nov 2025 04:18:33 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.82]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5AO9I8VN024016; Mon, 24 Nov 2025 04:18:25 -0500 From: Jorge Marques Date: Mon, 24 Nov 2025 10:18:03 +0100 Subject: [PATCH v2 4/9] docs: iio: ad4062: Add IIO Trigger support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251124-staging-ad4062-v2-4-a375609afbb7@analog.com> References: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> In-Reply-To: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> To: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Linus Walleij , Bartosz Golaszewski CC: , , , , , Jorge Marques X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763975888; l=1267; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=k24J9SVSpBNTE0t7Rk8CGprxFuIseSx9ccE+WbjYn5c=; b=IDMnU3cR86/zfAqCJ1c5MFBmbGRKk2a/cXJBcVAm1YiLuB12QmklExod60gxgKpWxffLB9SHy Jb5aVq+9uaCAFka8s/B9KvuT/YS+T01nSa8twd9XIc6WhkF4lKiZphC X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: 26VU68WNwjcoHsTbwaT_MfR8YZO6n4i3 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTI0MDA4MSBTYWx0ZWRfX5AbTjT4GITZz qW5XyFFiymJ1LVT/W0OlpRNHuwDWMF8I+fjRzDQ98hikVxQYdKpWYLCNFEyc4QkZ6PoAUazzmdh tufPNESCGlnF6kwJVnbtm/Nn0KFCXavVLLxeHT6APr+2CcpNFNEZo734O+X+CsB+/kOmuINsYjM 9aV7pm3103NAjfdNmy/foasIDMvbFJqdJgNX13+Y1ZoXINNuPvGXRIbNG6RqNvq4x/jggg5h6BQ bcO5TTl/7L9pDDvD44gwhMATbtGyLvyYiyzfI1UA9d7Rr97nFKv8ro0WwkmppfiHcF6H+JMEPku osKYeZ11sczD4hgPXUHufLwI9GvMIURduT5oQsZOnZTkkt014yRQOSYLDusaL1rZaB3oszp88ex v5Szqptg6DomeERuoFlK6mec8DRmBg== X-Authority-Analysis: v=2.4 cv=f8lFxeyM c=1 sm=1 tr=0 ts=692422ea cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=pTCSo2s0eJJONGnsYSsA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: 26VU68WNwjcoHsTbwaT_MfR8YZO6n4i3 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-24_03,2025-11-21_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 impostorscore=0 clxscore=1015 malwarescore=0 spamscore=0 bulkscore=0 priorityscore=1501 suspectscore=0 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511240081 Explains the IIO Trigger support and timings involved. Signed-off-by: Jorge Marques --- Documentation/iio/ad4062.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Documentation/iio/ad4062.rst b/Documentation/iio/ad4062.rst index e6bcca2bef24b..9dda4eb782a02 100644 --- a/Documentation/iio/ad4062.rst +++ b/Documentation/iio/ad4062.rst @@ -85,6 +85,19 @@ The device enters low-power mode on idle to save power. = Enabling an event puts the device out of the low-power since the ADC autonomously samples to asse= rt the event condition. =20 +IIO trigger support +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +An IIO trigger ``ad4062-devX`` is registered by the driver to be used by t= he +same device, to capture samples to a software buffer. It is required to at= tach +the trigger to the device by setting the ``current_trigger`` before enabli= ng +and reading the buffer. + +The acquisition is sequential and bounded by the protocol timings, software +latency and internal timings, the sample rate is not configurable. The bur= st +averaging mode does impact the effective sample rate, since it increases t= he +internal timing to output a single sample. + Unimplemented features =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 --=20 2.51.1 From nobody Tue Dec 2 00:46:53 2025 Received: from mx0b-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80ECB2F5463; Mon, 24 Nov 2025 09:18:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975941; cv=none; b=ZekdLrnfI7A56ZDa+hAytGWXfy7iApsVoBTJGWrdD7mcv2Xnwq+sSZsI6uFU6Z6cCL65l/Ql4lD7He667RkXjX0wqz3anR2DxShXSxZf1QtExchQhjoQZ4dHCaWfXUwoFcXtriCquCDOSV1WhWhPM6uliXI3Xx/0+NMjI2Lwf5g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975941; c=relaxed/simple; bh=hu050DO+BNHVTgfy/Aqpo0tHFJg9UZpfOA98D/AmQW0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=KEG1eoyoBaqKQIezEolZuXrmwBVDH1FaqKjtUscQQ/xnEnqWXHHcJutQiOv1M0t7Ja7A3LFxrP2VIlAMkdG2THrRieq00I3aeXBERauOCzdory9KtLpH4GRgXYVz/FsiDz/kEiW9nt+UTBJI3rkkwWdKtHc/wquVOeYJ8jh/k10= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=e9urTALP; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="e9urTALP" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5AO7s6bW3692007; Mon, 24 Nov 2025 04:18:35 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=XgrMl VOA7gDVhm1Cvl4wAdO6PwLvaB9T0L/C018bk60=; b=e9urTALPUdARg/X2OWUfn DmfA3GV6IxWvfKPhKKD4kL/Il7QMeb2pEt3EWM2qK/EVp/foxv7WEwdc5VordLSg +AFhSIg5YbZBCeVVKU4/i/kiwKhFNhGinF5uLEEb9ZHEqqXaKpr+KS8Mg8af8HXO O4s1uI8GgFzXLrqxSGAdf//4bmtvq78xSctCAtOksNRfdAJ0aN7oeKJeb3YfqJ93 Ub8/zb5lVTO54i1oMM+lvUxNPcnZ5Ai/wsEKui4csIv7LDHeBTSpUVNyQprU23Wm 07cVKVEaDYCIhmuHJpHE6hH95JuoIbFIEcRIYeEmsarqEdoGKMpRiBM16gJzoO2v Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 4akvcjmw8r-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Nov 2025 04:18:35 -0500 (EST) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 5AO9IYUk050927 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 24 Nov 2025 04:18:34 -0500 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:34 -0500 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:34 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 24 Nov 2025 04:18:34 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.82]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5AO9I8VO024016; Mon, 24 Nov 2025 04:18:29 -0500 From: Jorge Marques Date: Mon, 24 Nov 2025 10:18:04 +0100 Subject: [PATCH v2 5/9] iio: adc: ad4062: Add IIO Trigger support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251124-staging-ad4062-v2-5-a375609afbb7@analog.com> References: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> In-Reply-To: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> To: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , "David Lechner" , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Linus Walleij , Bartosz Golaszewski CC: , , , , , Jorge Marques X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763975888; l=8868; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=hu050DO+BNHVTgfy/Aqpo0tHFJg9UZpfOA98D/AmQW0=; b=E7PLiApZLJ6J4QAv9LFUGmcceWQhO8XwZWbwNj/3HM3Ye4LNPuU/ojJ9pZGrqqJfhelouM3ZZ FQb4ViPbnEXBc2/FYDRnDj5UvRdcqkrNgKyK6uCErYbDB4nCqV16C5m X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTI0MDA4MSBTYWx0ZWRfX1CyA/2fDwAGD x9bbUt3gY42lxto4rME2ybqZXnXg3jpSKrp7ZOVw1RQP8RyoLDyV1n9IjOcCmtsDbmz4wdm9g39 RPN8ZnxvCfvWFewHscRrmzW0cplNKOTIMwJwai5pAfpupiRIUqNAEb51fgqDkdlIdeZrXWv1Xc0 mh8lRW9p5pZdXujFbjpOFNsvB3POYPCWdtb2K5NJHJcKJVJN4nA4TkzNvmbQ20kd4l06CJ5eFoa Cf+9ykKUIwJMxblJ0rbFx4HS0KeRDQK6ESgjwD46sCfGhWSzwbyc3eKcxx4A8Rxb03072871ayf EmLwi9nxlLfRplpZOG6UMXde9EMkuic0oTMnhjpyTPdhNqtGfcvIMwkzpY7Xm3YBmQNPh1B6FL9 lKTOvpEJT0XPuc80yyggs5yv0bProg== X-Authority-Analysis: v=2.4 cv=EqrfbCcA c=1 sm=1 tr=0 ts=692422eb cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=zez8XUbOA3qj_dAOEuEA:9 a=QEXdDO2ut3YA:10 a=br55WurUj89AL1qEz8Q6:22 X-Proofpoint-ORIG-GUID: M7JYxr5dq5cjUhciy3nd7mO-RsNdoPMm X-Proofpoint-GUID: M7JYxr5dq5cjUhciy3nd7mO-RsNdoPMm X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-24_03,2025-11-21_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 phishscore=0 bulkscore=0 malwarescore=0 adultscore=0 spamscore=0 clxscore=1011 priorityscore=1501 impostorscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511240081 Adds support for IIO Trigger. Optionally, gp1 is assigned as Data Ready signal, if not present, fallback to an I3C IBI with the same role. The software trigger is allocated by the device, but must be attached by the user before enabling the buffer. The purpose is to not impede removing the driver due to the increased reference count when iio_trigger_set_immutable or iio_trigger_get is used. Signed-off-by: Jorge Marques --- drivers/iio/adc/Kconfig | 2 + drivers/iio/adc/ad4062.c | 164 +++++++++++++++++++++++++++++++++++++++++++= ++-- 2 files changed, 161 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index e506dbe83f488..ddb7820f0bdcc 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -74,6 +74,8 @@ config AD4062 tristate "Analog Devices AD4062 Driver" depends on I3C select REGMAP_I3C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Analog Devices AD4062 I3C analog to digital converters (ADC). diff --git a/drivers/iio/adc/ad4062.c b/drivers/iio/adc/ad4062.c index 6866393ffef8d..4e4be7358047f 100644 --- a/drivers/iio/adc/ad4062.c +++ b/drivers/iio/adc/ad4062.c @@ -12,8 +12,12 @@ #include #include #include +#include #include #include +#include +#include +#include #include #include #include @@ -60,6 +64,7 @@ #define AD4062_REG_DEVICE_STATUS_DEVICE_RESET BIT(6) #define AD4062_REG_IBI_STATUS 0x48 #define AD4062_REG_CONV_READ_LSB 0x50 +#define AD4062_REG_CONV_READ 0x53 #define AD4062_REG_CONV_TRIGGER 0x59 #define AD4062_REG_CONV_AUTO 0x61 #define AD4062_MAX_REG AD4062_REG_CONV_AUTO @@ -134,6 +139,7 @@ struct ad4062_state { const struct ad4062_chip_info *chip; const struct ad4062_bus_ops *ops; enum ad4062_operation_mode mode; + struct work_struct trig_conv; struct completion completion; struct iio_trigger *trigger; struct iio_dev *indio_dev; @@ -143,6 +149,7 @@ struct ad4062_state { int vref_uv; int samp_freqs[ARRAY_SIZE(ad4062_conversion_freqs)]; u8 oversamp_ratio; + bool gpo_irq[2]; union { __be32 be32; __be16 be16; @@ -396,7 +403,10 @@ static irqreturn_t ad4062_irq_handler_drdy(int irq, vo= id *private) struct iio_dev *indio_dev =3D private; struct ad4062_state *st =3D iio_priv(indio_dev); =20 - complete(&st->completion); + if (iio_buffer_enabled(indio_dev) && iio_trigger_using_own(indio_dev)) + iio_trigger_poll(st->trigger); + else + complete(&st->completion); =20 return IRQ_HANDLED; } @@ -406,7 +416,56 @@ static void ad4062_ibi_handler(struct i3c_device *i3cd= ev, { struct ad4062_state *st =3D i3cdev_get_drvdata(i3cdev); =20 - complete(&st->completion); + if (iio_buffer_enabled(st->indio_dev)) + iio_trigger_poll_nested(st->trigger); + else + complete(&st->completion); +} + +static void ad4062_trigger_work(struct work_struct *work) +{ + struct ad4062_state *st =3D container_of(work, struct ad4062_state, + trig_conv); + int ret; + + /* Read current conversion, if at reg CONV_READ, stop bit triggers + * next sample and does not need writing the address. + */ + struct i3c_priv_xfer t[2] =3D { + { + .data.in =3D &st->buf.be32, + .len =3D sizeof(st->buf.be32), + .rnw =3D true, + }, + { + .data.out =3D &st->reg_addr_conv, + .len =3D sizeof(st->reg_addr_conv), + .rnw =3D false, + }, + }; + + ret =3D i3c_device_do_priv_xfers(st->i3cdev, &t[0], 1); + if (ret) + return; + + iio_push_to_buffers_with_timestamp(st->indio_dev, &st->buf.be32, + iio_get_time_ns(st->indio_dev)); + if (st->gpo_irq[1]) + return; + + i3c_device_do_priv_xfers(st->i3cdev, &t[1], 1); +} + +static irqreturn_t ad4062_poll_handler(int irq, void *p) +{ + struct iio_poll_func *pf =3D p; + struct iio_dev *indio_dev =3D pf->indio_dev; + struct ad4062_state *st =3D iio_priv(indio_dev); + + iio_trigger_notify_done(indio_dev->trig); + schedule_work(&st->trig_conv); + + return IRQ_HANDLED; } =20 static void ad4062_remove_ibi(void *data) @@ -451,10 +510,14 @@ static int ad4062_request_irq(struct iio_dev *indio_d= ev) if (ret =3D=3D -EPROBE_DEFER) { return ret; } else if (ret < 0) { + st->gpo_irq[1] =3D false; + st->reg_addr_conv =3D AD4062_REG_CONV_TRIGGER; ret =3D regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, AD4062_REG_ADC_IBI_EN_CONV_TRIGGER, AD4062_REG_ADC_IBI_EN_CONV_TRIGGER); } else { + st->gpo_irq[1] =3D true; + st->reg_addr_conv =3D AD4062_REG_CONV_READ; ret =3D devm_request_threaded_irq(dev, ret, ad4062_irq_handler_drdy, NULL, IRQF_ONESHOT, indio_dev->name, @@ -464,6 +527,34 @@ static int ad4062_request_irq(struct iio_dev *indio_de= v) return ret; } =20 +static const struct iio_trigger_ops ad4062_trigger_ops =3D { + .validate_device =3D &iio_trigger_validate_own_device, +}; + +static int ad4062_request_trigger(struct iio_dev *indio_dev) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + struct device *dev =3D &st->i3cdev->dev; + int ret; + + st->trigger =3D devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!st->trigger) + return -ENOMEM; + + st->trigger->ops =3D &ad4062_trigger_ops; + iio_trigger_set_drvdata(st->trigger, indio_dev); + + ret =3D devm_iio_trigger_register(dev, st->trigger); + if (ret) + return ret; + + indio_dev->trig =3D iio_trigger_get(st->trigger); + + return 0; +} + static const int ad4062_oversampling_avail[] =3D { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, }; @@ -579,8 +670,8 @@ static int __ad4062_read_chan_raw(struct ad4062_state *= st, int *val) int ret; =20 reinit_completion(&st->completion); - /* Change address pointer to trigger conversion */ - ret =3D i3c_device_do_priv_xfers(i3cdev, &t[0], 1); + /* Change address pointer (and read if CONV_READ) to trigger conversion. = */ + ret =3D i3c_device_do_priv_xfers(i3cdev, t, st->gpo_irq[1] ? 2 : 1); if (ret) return ret; /* @@ -689,6 +780,57 @@ static int ad4062_write_raw(struct iio_dev *indio_dev, return ret; } =20 +static int ad4062_triggered_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + ret =3D pm_runtime_resume_and_get(&st->i3cdev->dev); + if (ret) + return ret; + + ret =3D ad4062_set_operation_mode(st, st->mode); + if (ret) + goto out_mode_error; + + /* CONV_READ requires read to trigger first sample. */ + struct i3c_priv_xfer t[2] =3D { + { + .data.out =3D &st->reg_addr_conv, + .len =3D sizeof(st->reg_addr_conv), + .rnw =3D false, + }, + { + .data.in =3D &st->buf.be32, + .len =3D sizeof(st->buf.be32), + .rnw =3D true, + } + }; + + ret =3D i3c_device_do_priv_xfers(st->i3cdev, t, st->gpo_irq[1] ? 2 : 1); + if (ret) + goto out_mode_error; + return 0; + +out_mode_error: + pm_runtime_put_autosuspend(&st->i3cdev->dev); + + return ret; +} + +static int ad4062_triggered_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + + pm_runtime_put_autosuspend(&st->i3cdev->dev); + return 0; +} + +static const struct iio_buffer_setup_ops ad4062_triggered_buffer_setup_ops= =3D { + .postenable =3D &ad4062_triggered_buffer_postenable, + .predisable =3D &ad4062_triggered_buffer_predisable, +}; + static int ad4062_debugfs_reg_access(struct iio_dev *indio_dev, unsigned i= nt reg, unsigned int writeval, unsigned int *readval) { @@ -801,7 +943,6 @@ static int ad4062_probe(struct i3c_device *i3cdev) st->sampling_frequency =3D 0; st->oversamp_ratio =3D BIT(0); st->indio_dev =3D indio_dev; - st->reg_addr_conv =3D AD4062_REG_CONV_TRIGGER; =20 indio_dev->modes =3D INDIO_DIRECT_MODE; indio_dev->num_channels =3D 1; @@ -825,6 +966,17 @@ static int ad4062_probe(struct i3c_device *i3cdev) if (ret) return ret; =20 + ret =3D ad4062_request_trigger(indio_dev); + if (ret) + return ret; + + ret =3D devm_iio_triggered_buffer_setup(&i3cdev->dev, indio_dev, + iio_pollfunc_store_time, + ad4062_poll_handler, + &ad4062_triggered_buffer_setup_ops); + if (ret) + return ret; + pm_runtime_set_active(dev); ret =3D devm_pm_runtime_enable(dev); if (ret) @@ -837,6 +989,8 @@ static int ad4062_probe(struct i3c_device *i3cdev) if (ret) return dev_err_probe(dev, ret, "Failed to request i3c ibi\n"); =20 + INIT_WORK(&st->trig_conv, ad4062_trigger_work); + return devm_iio_device_register(dev, indio_dev); } =20 --=20 2.51.1 From nobody Tue Dec 2 00:46:53 2025 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 83F402F5465; Mon, 24 Nov 2025 09:18:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975941; cv=none; b=YbOf4C/9n8oGJSQ37NLJP4NB+RV0ayn+IihFCOs8qsoIRN5uaRnTa/8WA9ioaq4g34Ui4udQ5Pp1blsdLkmMh4rG7JqNNxh3s8O3baB1Wvizwty9UC3y9UVrMMoxPuuX83W+X6zXWU59+BvttBIyGEW1khOk2i1y/QZpsAkqt7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975941; c=relaxed/simple; bh=xHwoyhIzRbWGKDaTyQIddc8KJjvj2Dfsz8ghN0EKd3k=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=YETlvOokNuqMf4pQUEM1tgHTVaws1WDbp2t1Tho0tGEX2z5R7xHrUzgO+tvolsg25hru1yPqFnhEIpZs4TKhp0zeYRvrhDXSb2pX5JjXm34W4OjEEt1hS1Qyvn9UDUlnOf+qhk6dO2nH12GUBP27IItCs6Adr8r9913+mp2aHc4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=zIXr4Sq3; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="zIXr4Sq3" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5AO688IZ1957860; Mon, 24 Nov 2025 04:18:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=d3+FV rAESf8tt7WOmc9s2QHGzplfw/21aGU9TQs1uN0=; b=zIXr4Sq3lYlCvC9pd3OFU bGJUhigBZ0wxbwAG7pj2R+j+Yb2LwnSUe+6NnJT4nXHU3X+WUQNe9tPOaLdcOFlV qCe2xrJg4O34cP1iH3bchgbHbUvUx3nWoXpWueStWITd+7OLZePTW0meQet5PkSo CldUz7HDUo7ft00QVJdMsiKz6lhmctY+cdG24G/i158IBjfEJ/eli7kPRCCIDc65 1XRmeougb0lcg20kPy0pHvZgd07ECqOjsOcQFlA2AAwvs6m+Hy0/EUFaMyxQ9zb6 umTn/LbjoCsPEFE3kyyD8LX7W9ceKwvrtRaW8PCk5r05GzVZr+3gQ03dAF4HbdhY g== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4akay688f6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Nov 2025 04:18:37 -0500 (EST) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 5AO9IaYf050939 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 24 Nov 2025 04:18:36 -0500 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:36 -0500 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:36 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 24 Nov 2025 04:18:36 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.82]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5AO9I8VP024016; Mon, 24 Nov 2025 04:18:31 -0500 From: Jorge Marques Date: Mon, 24 Nov 2025 10:18:05 +0100 Subject: [PATCH v2 6/9] docs: iio: ad4062: Add IIO Events support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251124-staging-ad4062-v2-6-a375609afbb7@analog.com> References: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> In-Reply-To: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> To: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , "David Lechner" , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Linus Walleij , Bartosz Golaszewski CC: , , , , , Jorge Marques X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763975888; l=2876; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=xHwoyhIzRbWGKDaTyQIddc8KJjvj2Dfsz8ghN0EKd3k=; b=BRQz6KOhJlRC4wO3ADCoSCSammX/JuS1nijkafIwLwTLat2RLID51lPWRISl8aG7DkgCo8FEb keQ+1CR8ErRDFE+LpIMWguRy2NnsKAYbTCoG6foJ8Tii2rXZemxQr4m X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: x2jNNsDkv2P-nAtRyaOJkEX7Iapu9HIm X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTI0MDA4MSBTYWx0ZWRfX2wl3SitevzYa NdKlEXZTwUmxzXacml7hmRVLxWtR+Z7XNXrEssx1jKgy5GqPKtXcwFkZ/ustQIiv4XT0MX3yCY8 BSKdk2uwWvMaz2rwD9YGujk+PQDsqwYu7fqc6I5+QBRrzwSIPkmOYiTBFxWwhrCHOH3ji7Yo5Zc EIgU0Fxwb3xFMGeL8qKeaYP881Qr366o2Il7RtTMuCM31eAEACP/1EK3xcQtf1wW/3L+vjiQ3Vd mccs/covWqZI70spcVsgYvnU72wWkMB5l80T4J3VujhAdp0IKl5MnWXDqDxH49F2ip4EpJ2b65z G6cJuDLYP0OVFsusf6DJHFKv6faNktmhMnOFvqPLA+onlbvO+cDk170Z2iIq9m5a8EmXrpllK/P IYCep7F48bIVyN6w6USM3VD8irvWzQ== X-Authority-Analysis: v=2.4 cv=f8lFxeyM c=1 sm=1 tr=0 ts=692422ed cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=RvCAy4sPJie4B97SFe0A:9 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: x2jNNsDkv2P-nAtRyaOJkEX7Iapu9HIm X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-24_03,2025-11-21_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 impostorscore=0 clxscore=1011 malwarescore=0 spamscore=0 bulkscore=0 priorityscore=1501 suspectscore=0 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511240081 Explains the IIO Events support. Signed-off-by: Jorge Marques --- Documentation/iio/ad4062.rst | 42 +++++++++++++++++++++++++++++++++++++++-= -- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/Documentation/iio/ad4062.rst b/Documentation/iio/ad4062.rst index 9dda4eb782a02..5afec4d8c2ddb 100644 --- a/Documentation/iio/ad4062.rst +++ b/Documentation/iio/ad4062.rst @@ -26,6 +26,7 @@ at the end of the read command. The two programmable GPIOS are optional and have a role assigned if presen= t in the devicetree ``interrupt-names`` property: =20 +- GP0: Is assigned the role of Threshold Either signal. - GP1: Is assigned the role of Data Ready signal. =20 Device attributes @@ -74,8 +75,10 @@ Interrupts The interrupts are mapped through the ``interrupt-names`` and ``interrupts= `` properties. =20 -The ``interrupt-names`` ``gp1`` entry sets the role of Data Ready signal. -If it is not present, the driver fallback to enabling the same role as an +The ``interrupt-names`` ``gp0`` entry sets the role of Threshold signal, a= nd +entry ``gp1`` the role of Data Ready signal. + +If each is not present, the driver fallback to enabling the same role as an I3C IBI. =20 Low-power mode @@ -98,10 +101,43 @@ latency and internal timings, the sample rate is not c= onfigurable. The burst averaging mode does impact the effective sample rate, since it increases t= he internal timing to output a single sample. =20 +Threshold events +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The ADC supports a monitoring mode to raise threshold events. The driver +supports a single interrupt for both rising and falling readings. + +The feature is enabled/disabled by setting ``thresh_either_en``. During mo= nitor +mode, the device continuously operates in autonomous mode. Any register ac= cess +puts the device back in configuration mode, due to this, any access disabl= es +monitor mode. + +The following event attributes are available: + +.. list-table:: Event attributes + :header-rows: 1 + + * - Attribute + - Description + * - ``sampling_frequency`` + - Frequency used in the monitoring mode, sets the device internal sam= ple + rate when the mode is activated. + * - ``sampling_frequency_available`` + - List of available sample rates. + * - ``thresh_either_en`` + - Enable monitoring mode. + * - ``thresh_falling_hysteresis`` + - Set the hysteresis value for the minimum threshold. + * - ``thresh_falling_value`` + - Set the minimum threshold value. + * - ``thresh_rising_hysteresis`` + - Set the hysteresis value for the maximum threshold. + * - ``thresh_rising_value`` + - Set the maximum threshold value. + Unimplemented features =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -- Monitor mode - Trigger mode - Averaging mode - General purpose output --=20 2.51.1 From nobody Tue Dec 2 00:46:53 2025 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 05800253944; Mon, 24 Nov 2025 09:18:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975940; cv=none; b=QRCRhCZy05eENrPR97YKR4yQSeSRDJhxZrgEbnzNutJGIOEaGluWpJEFDkSeyHRDIkQq9rxICfUEyaF2nFxFvmdj27lZTnKDgz+cByGSOkRFFOMPMG7J9ZuSsxv4KspxVpzvAphTSEgWQibRDjjKrc3kTTfiXfMjzJC10+NJudA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975940; c=relaxed/simple; bh=Wk7gLhilBrNjV30tFr+fJqwITrbCgsMg+UdrRGR20DQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=O2LuycxTawgIbz6T+Q1MxK+1hkEm9CeVlF9xq1KdO7PTzf69sCVp9Qzx2IWHeZhTELk2zMjGDvC07ALxQZ08H8fQ/hWih0XIIfhXL9F3yop8wvGKkWSu6xHUGBXYK6cHCzy0B/6vl4XoaHLOdGuaeIAJckk0esSFXla03PdbICA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=zIAhG8j7; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="zIAhG8j7" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5AO50SDT1958046; Mon, 24 Nov 2025 04:18:41 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=wU5xp uTfIclZQgqqXRbs6B4w9y66KkOmHcXncTuEElc=; b=zIAhG8j7Svu6hz1Q0SsQv x7H/po1nB3W6WLGKjSYb7Y24ZswQ/YMXeSsF1qQGUR/FycIeDbHFydrTSg8UF0eH 4Gj27zxkKTR7tX7f7jGEf/WXkU44MLBKF0qDqo/TFKsZR4HoMHAitZMiEyPPeYBJ J/xnKknbrI3UeKrWC947up4OlvwIirEa/+m8+pnrqMQ/eSRYfQnOZRy8AaPCU5T9 HwMu0uBN54J942OfubRd9m5HaQ4+pKCWpTLtTa6mCDfnGkqD3nbmVt2VFx8Nk2Ri MkrrL8WFEBlJ7MLBJEm7n0IVVXy1G0EokIkix9UaOl5SkPXQhyaXyvLKqKNWtaye g== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4akay688fj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Nov 2025 04:18:41 -0500 (EST) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 5AO9Ie1s007661 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 24 Nov 2025 04:18:40 -0500 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:40 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 24 Nov 2025 04:18:40 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.82]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5AO9I8VQ024016; Mon, 24 Nov 2025 04:18:33 -0500 From: Jorge Marques Date: Mon, 24 Nov 2025 10:18:06 +0100 Subject: [PATCH v2 7/9] iio: adc: ad4062: Add IIO Events support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251124-staging-ad4062-v2-7-a375609afbb7@analog.com> References: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> In-Reply-To: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> To: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Linus Walleij , Bartosz Golaszewski CC: , , , , , Jorge Marques X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763975888; l=16524; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=Wk7gLhilBrNjV30tFr+fJqwITrbCgsMg+UdrRGR20DQ=; b=Ksb8NczD6AqHy/kvypbhX42P0nGJ2yGlfAv2VLde7xcAEFbVkzs1vro6d4Gu79EfZpmn+c/q/ SFNoe2fJIx1AyuTiiK+REfHa5akpwSRrbx3u6B9RMCXW7yUM5i6lFoI X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: BimPvK-uJNflDH-eWWA6hkflShuzNnWj X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTI0MDA4MSBTYWx0ZWRfX6A2FcSEpS1mT x8tRAx2FWJQrK6J3XjKqlgddLnFUz4Y5SyGw7PfwsejM2zcXRPFQUiKi1Xd3pc7IRnbOTFjyvSV 4FhD9lS/T6uU+uxUO0NT5o64amIHyf4t7ORhZDaUkwkpqS2jgr+o/YwgBhU7fvJk53U1ovXDodq YbW/lto+OYnW7VpfCvyV6n7zKmZTJj/N1b8rO2tC0d2Ja9iHJ++rHEz3okdDpRYkYqHc8ynz4OX IJGE7ztBly/EniSJIbsRXSeLXtt9spfSCsK4jvNMgsLxCs+tBhYB1K4/BUgMtvoAy29m32fRYfC y99xD2qPDVPmwd3pD9cjGMYOnbS5plStN2H4P1xaBYd8qV6MY3eSWhrWmAoq3o5qXnuvKggDc6B NHpHG+nhTObK5Zo6zYi74SQcBlHiuQ== X-Authority-Analysis: v=2.4 cv=f8lFxeyM c=1 sm=1 tr=0 ts=692422f1 cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=G_0orfQ0byHZzXNulvsA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: BimPvK-uJNflDH-eWWA6hkflShuzNnWj X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-24_03,2025-11-21_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 impostorscore=0 clxscore=1015 malwarescore=0 spamscore=0 bulkscore=0 priorityscore=1501 suspectscore=0 phishscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511240081 Adds support for IIO Events. Optionally, gp0 is assigned as Threshold Either signal, if not present, fallback to an I3C IBI with the same role. Signed-off-by: Jorge Marques --- drivers/iio/adc/ad4062.c | 394 +++++++++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 378 insertions(+), 16 deletions(-) diff --git a/drivers/iio/adc/ad4062.c b/drivers/iio/adc/ad4062.c index 4e4be7358047f..3df7dbf29ae4a 100644 --- a/drivers/iio/adc/ad4062.c +++ b/drivers/iio/adc/ad4062.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -51,14 +52,22 @@ #define AD4062_REG_ADC_CONFIG_SCALE_EN_MSK BIT(4) #define AD4062_REG_AVG_CONFIG 0x23 #define AD4062_REG_GP_CONF 0x24 +#define AD4062_REG_GP_CONF_MODE_MSK_0 GENMASK(2, 0) #define AD4062_REG_GP_CONF_MODE_MSK_1 GENMASK(6, 4) #define AD4062_REG_INTR_CONF 0x25 +#define AD4062_REG_INTR_CONF_EN_MSK_0 GENMASK(1, 0) #define AD4062_REG_INTR_CONF_EN_MSK_1 GENMASK(5, 4) #define AD4062_REG_TIMER_CONFIG 0x27 #define AD4062_REG_TIMER_CONFIG_FS_MASK GENMASK(7, 4) +#define AD4062_REG_MAX_LIMIT 0x29 +#define AD4062_REG_MIN_LIMIT 0x2B +#define AD4062_REG_MAX_HYST 0x2C +#define AD4062_REG_MIN_HYST 0x2D #define AD4062_REG_MON_VAL 0x2F #define AD4062_REG_ADC_IBI_EN 0x31 #define AD4062_REG_ADC_IBI_EN_CONV_TRIGGER BIT(2) +#define AD4062_REG_ADC_IBI_EN_MAX BIT(1) +#define AD4062_REG_ADC_IBI_EN_MIN BIT(0) #define AD4062_REG_FUSE_CRC 0x40 #define AD4062_REG_DEVICE_STATUS 0x41 #define AD4062_REG_DEVICE_STATUS_DEVICE_RESET BIT(6) @@ -76,8 +85,10 @@ #define AD4062_MAX_AVG 0xB #define AD4062_MON_VAL_MAX_GAIN 1999970 #define AD4062_MON_VAL_MIDDLE_POINT 0x8000 +#define AD4062_GP_INTR 0x1 #define AD4062_GP_DRDY 0x2 #define AD4062_INTR_EN_NEITHER 0x0 +#define AD4062_INTR_EN_EITHER 0x3 #define AD4062_TCONV_NS 270 =20 enum ad4062_operation_mode { @@ -146,6 +157,8 @@ struct ad4062_state { struct i3c_device *i3cdev; struct regmap *regmap; u16 sampling_frequency; + u16 events_frequency; + bool wait_event; int vref_uv; int samp_freqs[ARRAY_SIZE(ad4062_conversion_freqs)]; u8 oversamp_ratio; @@ -184,6 +197,26 @@ static const struct regmap_access_table ad4062_regmap_= wr_table =3D { .n_yes_ranges =3D ARRAY_SIZE(ad4062_regmap_wr_ranges), }; =20 +static const struct iio_event_spec ad4062_events[] =3D { + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_EITHER, + .mask_shared_by_all =3D BIT(IIO_EV_INFO_ENABLE), + }, + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_RISING, + .mask_shared_by_all =3D BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_HYSTERESIS), + }, + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_FALLING, + .mask_shared_by_all =3D BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_HYSTERESIS), + }, +}; + static int ad4062_conversion_frequency_set(struct ad4062_state *st, u8 val) { return regmap_write(st->regmap, AD4062_REG_TIMER_CONFIG, @@ -201,6 +234,8 @@ static int ad4062_conversion_frequency_set(struct ad406= 2_state *st, u8 val) .info_mask_shared_by_all_available =3D BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .indexed =3D 1, \ .channel =3D 0, \ + .event_spec =3D ad4062_events, \ + .num_event_specs =3D ARRAY_SIZE(ad4062_events), \ .has_ext_scan_type =3D 1, \ .ext_scan_type =3D ad4062_scan_type_##bits##_s, \ .num_ext_scan_type =3D ARRAY_SIZE(ad4062_scan_type_##bits##_s), \ @@ -220,6 +255,70 @@ static const struct ad4062_chip_info ad4062_chip_info = =3D { .max_avg =3D AD4062_MAX_AVG, }; =20 +static ssize_t ad4062_events_frequency_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ad4062_state *st =3D iio_priv(dev_to_iio_dev(dev)); + + return sysfs_emit(buf, "%d\n", ad4062_conversion_freqs[st->events_frequen= cy]); +} + +static ssize_t ad4062_events_frequency_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev =3D dev_to_iio_dev(dev); + struct ad4062_state *st =3D iio_priv(indio_dev); + int val, ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } + + ret =3D kstrtoint(buf, 10, &val); + if (ret < 0) + goto out_release; + + st->events_frequency =3D find_closest_descending(val, ad4062_conversion_f= reqs, + ARRAY_SIZE(ad4062_conversion_freqs)); + ret =3D 0; + +out_release: + iio_device_release_direct(indio_dev); + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(sampling_frequency, 0644, ad4062_events_frequency_s= how, + ad4062_events_frequency_store, 0); + +static ssize_t sampling_frequency_available_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret =3D 0; + + for (u8 i =3D 0; i < ARRAY_SIZE(ad4062_conversion_freqs); i++) + ret +=3D sysfs_emit_at(buf, ret, "%d%s", ad4062_conversion_freqs[i], + i !=3D (ARRAY_SIZE(ad4062_conversion_freqs) - 1) ? " " : "\n"); + return ret; +} + +static IIO_DEVICE_ATTR_RO(sampling_frequency_available, 0); + +static struct attribute *ad4062_event_attributes[] =3D { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group ad4062_event_attribute_group =3D { + .attrs =3D ad4062_event_attributes, +}; + static int ad4062_set_oversampling_ratio(struct ad4062_state *st, unsigned= int val) { int ret; @@ -369,9 +468,12 @@ static int ad4062_setup(struct iio_dev *indio_dev, str= uct iio_chan_spec const *c if (IS_ERR(scan_type)) return PTR_ERR(scan_type); =20 - val =3D FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, AD4062_GP_DRDY); + val =3D FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_0, AD4062_GP_INTR) | + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, AD4062_GP_DRDY); + ret =3D regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, - AD4062_REG_GP_CONF_MODE_MSK_1, val); + AD4062_REG_GP_CONF_MODE_MSK_1 | AD4062_REG_GP_CONF_MODE_MSK_0, + val); if (ret) return ret; =20 @@ -387,9 +489,11 @@ static int ad4062_setup(struct iio_dev *indio_dev, str= uct iio_chan_spec const *c if (ret) return ret; =20 - val =3D FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_1, AD4062_INTR_EN_NEITHER); + val =3D FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_0, AD4062_INTR_EN_EITHER) | + FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_1, AD4062_INTR_EN_NEITHER); ret =3D regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, - AD4062_REG_INTR_CONF_EN_MSK_1, val); + AD4062_REG_INTR_CONF_EN_MSK_0 | AD4062_REG_INTR_CONF_EN_MSK_1, + val); if (ret) return ret; =20 @@ -398,6 +502,19 @@ static int ad4062_setup(struct iio_dev *indio_dev, str= uct iio_chan_spec const *c &st->buf.be16, sizeof(st->buf.be16)); } =20 +static irqreturn_t ad4062_irq_handler_thresh(int irq, void *private) +{ + struct iio_dev *indio_dev =3D private; + + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns(indio_dev)); + + return IRQ_HANDLED; +} + static irqreturn_t ad4062_irq_handler_drdy(int irq, void *private) { struct iio_dev *indio_dev =3D private; @@ -416,10 +533,18 @@ static void ad4062_ibi_handler(struct i3c_device *i3c= dev, { struct ad4062_state *st =3D i3cdev_get_drvdata(i3cdev); =20 - if (iio_buffer_enabled(st->indio_dev)) - iio_trigger_poll_nested(st->trigger); - else - complete(&st->completion); + if (st->wait_event) { + iio_push_event(st->indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns(st->indio_dev)); + } else { + if (iio_buffer_enabled(st->indio_dev)) + iio_trigger_poll_nested(st->trigger); + else + complete(&st->completion); + } } =20 static void ad4062_trigger_work(struct work_struct *work) @@ -506,6 +631,24 @@ static int ad4062_request_irq(struct iio_dev *indio_de= v) struct device *dev =3D &st->i3cdev->dev; int ret; =20 + ret =3D fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp0"); + if (ret =3D=3D -EPROBE_DEFER) { + return ret; + } else if (ret < 0) { + ret =3D regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, + AD4062_REG_ADC_IBI_EN_MAX | AD4062_REG_ADC_IBI_EN_MIN, + AD4062_REG_ADC_IBI_EN_MAX | AD4062_REG_ADC_IBI_EN_MIN); + if (ret) + return ret; + } else { + ret =3D devm_request_threaded_irq(dev, ret, NULL, + ad4062_irq_handler_thresh, + IRQF_ONESHOT, indio_dev->name, + indio_dev); + if (ret) + return ret; + } + ret =3D fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp1"); if (ret =3D=3D -EPROBE_DEFER) { return ret; @@ -739,9 +882,14 @@ static int ad4062_read_raw(struct iio_dev *indio_dev, =20 if (!iio_device_claim_direct(indio_dev)) return -EBUSY; + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } =20 ret =3D ad4062_read_raw_dispatch(st, val, val2, info); =20 +out_release: iio_device_release_direct(indio_dev); return ret ? ret : IIO_VAL_INT; } @@ -773,9 +921,215 @@ static int ad4062_write_raw(struct iio_dev *indio_dev, =20 if (!iio_device_claim_direct(indio_dev)) return -EBUSY; + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } =20 ret =3D ad4062_write_raw_dispatch(st, val, val2, info); =20 +out_release: + iio_device_release_direct(indio_dev); + return ret; +} + +static int ad4062_monitor_mode_enable(struct ad4062_state *st, bool enable) +{ + int ret =3D 0; + + if (!enable) { + pm_runtime_put_autosuspend(&st->i3cdev->dev); + return 0; + } + + ACQUIRE(pm_runtime_active_try_enabled, pm)(&st->i3cdev->dev); + ret =3D ACQUIRE_ERR(pm_runtime_active_try_enabled, &pm); + if (ret) + return ret; + + ret =3D ad4062_conversion_frequency_set(st, st->events_frequency); + if (ret) + return ret; + + ret =3D ad4062_set_operation_mode(st, AD4062_MONITOR_MODE); + if (ret) + return ret; + + pm_runtime_get_noresume(&st->i3cdev->dev); + return 0; +} + +static int ad4062_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + + return st->wait_event; +} + +static int ad4062_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + bool state) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + if (st->wait_event =3D=3D state) { + ret =3D 0; + goto out_release; + } + + ret =3D ad4062_monitor_mode_enable(st, state); + if (!ret) + st->wait_event =3D state; + +out_release: + iio_device_release_direct(indio_dev); + return ret; +} + +static int __ad4062_read_event_info_value(struct ad4062_state *st, + enum iio_event_direction dir, int *val) +{ + int ret; + u8 reg; + + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4062_REG_MAX_LIMIT; + else + reg =3D AD4062_REG_MIN_LIMIT; + + ret =3D regmap_bulk_read(st->regmap, reg, &st->buf.be16, + sizeof(st->buf.be16)); + if (ret) + return ret; + + *val =3D sign_extend32(get_unaligned_be16(st->buf.bytes), 11); + + return 0; +} + +static int __ad4062_read_event_info_hysteresis(struct ad4062_state *st, + enum iio_event_direction dir, int *val) +{ + u8 reg; + + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4062_REG_MAX_HYST; + else + reg =3D AD4062_REG_MIN_HYST; + return regmap_read(st->regmap, reg, val); +} + +static int ad4062_read_event_value(struct iio_dev *indio_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 ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } + + switch (info) { + case IIO_EV_INFO_VALUE: + ret =3D __ad4062_read_event_info_value(st, dir, val); + break; + case IIO_EV_INFO_HYSTERESIS: + ret =3D __ad4062_read_event_info_hysteresis(st, dir, val); + break; + default: + ret =3D -EINVAL; + break; + } + +out_release: + iio_device_release_direct(indio_dev); + return ret ? ret : IIO_VAL_INT; +} + +static int __ad4062_write_event_info_value(struct ad4062_state *st, + enum iio_event_direction dir, int val) +{ + u8 reg; + + if (val > 2047 || val < -2048) + return -EINVAL; + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4062_REG_MAX_LIMIT; + else + reg =3D AD4062_REG_MIN_LIMIT; + put_unaligned_be16(val, st->buf.bytes); + + return regmap_bulk_write(st->regmap, reg, &st->buf.be16, + sizeof(st->buf.be16)); +} + +static int __ad4062_write_event_info_hysteresis(struct ad4062_state *st, + enum iio_event_direction dir, int val) +{ + u8 reg; + + if (val >=3D BIT(7)) + return -EINVAL; + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4062_REG_MAX_HYST; + else + reg =3D AD4062_REG_MIN_HYST; + + return regmap_write(st->regmap, reg, val); +} + +static int ad4062_write_event_value(struct iio_dev *indio_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 ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } + + switch (type) { + case IIO_EV_TYPE_THRESH: + switch (info) { + case IIO_EV_INFO_VALUE: + ret =3D __ad4062_write_event_info_value(st, dir, val); + break; + case IIO_EV_INFO_HYSTERESIS: + ret =3D __ad4062_write_event_info_hysteresis(st, dir, val); + break; + default: + ret =3D -EINVAL; + break; + } + break; + default: + ret =3D -EINVAL; + break; + } + +out_release: iio_device_release_direct(indio_dev); return ret; } @@ -785,13 +1139,17 @@ static int ad4062_triggered_buffer_postenable(struct= iio_dev *indio_dev) struct ad4062_state *st =3D iio_priv(indio_dev); int ret; =20 - ret =3D pm_runtime_resume_and_get(&st->i3cdev->dev); + if (st->wait_event) + return -EBUSY; + + ACQUIRE(pm_runtime_active_try_enabled, pm)(&st->i3cdev->dev); + ret =3D ACQUIRE_ERR(pm_runtime_active_try_enabled, &pm); if (ret) return ret; =20 ret =3D ad4062_set_operation_mode(st, st->mode); if (ret) - goto out_mode_error; + return ret; =20 /* CONV_READ requires read to trigger first sample. */ struct i3c_priv_xfer t[2] =3D { @@ -809,13 +1167,10 @@ static int ad4062_triggered_buffer_postenable(struct= iio_dev *indio_dev) =20 ret =3D i3c_device_do_priv_xfers(st->i3cdev, t, st->gpo_irq[1] ? 2 : 1); if (ret) - goto out_mode_error; - return 0; - -out_mode_error: - pm_runtime_put_autosuspend(&st->i3cdev->dev); + return ret; =20 - return ret; + pm_runtime_get_noresume(&st->i3cdev->dev); + return 0; } =20 static int ad4062_triggered_buffer_predisable(struct iio_dev *indio_dev) @@ -859,6 +1214,11 @@ static const struct iio_info ad4062_info =3D { .read_raw =3D ad4062_read_raw, .write_raw =3D ad4062_write_raw, .read_avail =3D ad4062_read_avail, + .read_event_config =3D &ad4062_read_event_config, + .write_event_config =3D &ad4062_write_event_config, + .read_event_value =3D &ad4062_read_event_value, + .write_event_value =3D &ad4062_write_event_value, + .event_attrs =3D &ad4062_event_attribute_group, .get_current_scan_type =3D &ad4062_get_current_scan_type, .debugfs_reg_access =3D &ad4062_debugfs_reg_access, }; @@ -939,8 +1299,10 @@ static int ad4062_probe(struct i3c_device *i3cdev) "Failed to initialize regmap\n"); =20 st->mode =3D AD4062_SAMPLE_MODE; + st->wait_event =3D false; st->chip =3D chip; st->sampling_frequency =3D 0; + st->events_frequency =3D 0; st->oversamp_ratio =3D BIT(0); st->indio_dev =3D indio_dev; =20 --=20 2.51.1 From nobody Tue Dec 2 00:46:53 2025 Received: from mx0b-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 934A42F4A19; Mon, 24 Nov 2025 09:18:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975940; cv=none; b=tCbhZNHVzumSWJ52BKp9BVdW2hRAzUdJ7YnQoVf+BWaIHUI3xRh8XaV4QV1mCxfZ3LyWcRIQyeH8sJXqK5JQCbU3x1mCqXe/Wc8hZYE/NITI2J+39I+2ma4YQ902QsaQj99EDlcYitn6GQTlRE4JFr69yRuwEmSrKqL/b7Sy2Cg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975940; c=relaxed/simple; bh=6qh2wtlLEWTYkrzAloYask7uEYo256fObVki6Akbvps=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=WHeOINyhk9fu4h2eSq/Pp5xgjXwm2ymfJ5xyXLSTSPV84E7r1IgSnnpN90EmxztoapBMk5HkJ4Z4D1k7VUJ2urOfT/Bng5VVDLB6BAr1fK7AqemC5AECOuimfYUDcTlkvs4XKu61E7UDATXUA9Go0Duztvr3s604qKMHfZWo+xo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=XKGMUC/n; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="XKGMUC/n" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5AO56Tp23692335; Mon, 24 Nov 2025 04:18:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=rb4+C /sHOjHR+5QvjPfrp1a3niXH95FjdwnHPb9038U=; b=XKGMUC/nYU6NIaTU1OQdz bR5A25V1NHh+JN+Ig2xOZO01zfOwjRCHBkNdInC8wVZqtfUFrSkQnbQLLDCpVunI mJstSM6/eGgiMYYrFaibSofXs7P3U1BNMsO2kdEUH65d7gbHOt8A4FE21i7OuDmX eGKVzOtfbhKtvxB42kiMAmcngYF1E3lSxf0o9TRlx7yigJzEwS4GZJv5jJKdzv5d 2Jie37JNASiG2QXrBLBtKLbCzjxpopZ9SstXHU5IVNCESth9PIbWuoG2cK7f9Z6k 1ruYiGy6KS/ATQKvgzogsQpKRALKv0j8yNhZxCCRliAVzhZ3l7oXNj8R8pUKcnX4 A== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 4akvcjmw9b-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Nov 2025 04:18:43 -0500 (EST) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 5AO9IgIe007666 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 24 Nov 2025 04:18:42 -0500 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:42 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 24 Nov 2025 04:18:42 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.82]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5AO9I8VR024016; Mon, 24 Nov 2025 04:18:35 -0500 From: Jorge Marques Date: Mon, 24 Nov 2025 10:18:07 +0100 Subject: [PATCH v2 8/9] docs: iio: ad4062: Add GPIO Controller support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251124-staging-ad4062-v2-8-a375609afbb7@analog.com> References: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> In-Reply-To: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> To: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Linus Walleij , Bartosz Golaszewski CC: , , , , , Jorge Marques X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763975888; l=1505; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=6qh2wtlLEWTYkrzAloYask7uEYo256fObVki6Akbvps=; b=0R1fdzzTVNeXidUMkGgMmuPQrTKIaoVQRKy0pErz/L8OTjEXOXt3JjBZjQ5TaxcfhoZYuf7ZQ 2WWASughyGNCtCxME819nk+enapikVASnU3OcKOLQ7+hh9RcHi/l0mL X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTI0MDA4MSBTYWx0ZWRfX8ZZTHgNxXQBz Kb0Mm331JuEVaFgEwX4QhU2hSu4DELP2TaeDjTDumxG6V4PVFvkINQG/9wY8dPgW0LEK0z25yMY stV9t7oNzxQ245sll/U3Vzw9FOVnr/GW/TwsXkzIQUdY1JW0b1L3ShWZioOsvygujnkIaS/YXl8 IRNtfJMzQM7En+cD/Jcwbk+CHG3DZrH+9Q0URxxfAs/qRmzh+MQnevhQBQdwGoRHkkYOWmBf+wU qEl2cPAUkV6eoUnw/KY8RJ5Es5tapa4GS5u/r7UjFk4DBm72OS/7H80At26+IDCZ6W2BpKucssX Spwq9MUnBit7HvqHts2JMdRSeFond5cKWDM+F/BMMAu9ar+ZFJsyqxz5IuZ0zQehdpmRWFSIGyN ky42RczDMFyBeYie9bnx0oUXDHzXCw== X-Authority-Analysis: v=2.4 cv=EqrfbCcA c=1 sm=1 tr=0 ts=692422f3 cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=EBGExmvx8FPMp0bAM4MA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: -L3FhltvY4gx2BSYETRcc87Et124Lonu X-Proofpoint-GUID: -L3FhltvY4gx2BSYETRcc87Et124Lonu X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-24_03,2025-11-21_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 phishscore=0 bulkscore=0 malwarescore=0 adultscore=0 spamscore=0 clxscore=1015 priorityscore=1501 impostorscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511240081 Explains the GPIO controller support with emphasis on the mask depending on which GPs are exposed. Signed-off-by: Jorge Marques --- Documentation/iio/ad4062.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/iio/ad4062.rst b/Documentation/iio/ad4062.rst index 5afec4d8c2ddb..78665755ebebc 100644 --- a/Documentation/iio/ad4062.rst +++ b/Documentation/iio/ad4062.rst @@ -29,6 +29,9 @@ the devicetree ``interrupt-names`` property: - GP0: Is assigned the role of Threshold Either signal. - GP1: Is assigned the role of Data Ready signal. =20 +If the property ``gpio-controller`` is present in the devicetree, then the= GPO +not present in the ``interrupt-names`` is exposed as a GPO. + Device attributes =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -135,9 +138,17 @@ The following event attributes are available: * - ``thresh_rising_value`` - Set the maximum threshold value. =20 +GPO controller support +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The device supports using GP0 and GP1 as GPOs. If the devicetree contains = the +node ``gpio-controller```, the device is marked as a GPIO controller and t= he +GPs not listed in ``interrupt-names`` are exposed as a GPO. The GPIO index +matches the pin name, so if GP0 is not exposed but GP1 is, index 0 is mask= ed +out and only index 1 can be set. + Unimplemented features =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 - Trigger mode - Averaging mode -- General purpose output --=20 2.51.1 From nobody Tue Dec 2 00:46:53 2025 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 824332F5A17; Mon, 24 Nov 2025 09:19:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975942; cv=none; b=k14Xci5wQbzS8TvUSH+ZveEYhrX4aAAzvqlmzJci2byGjYyPQT1sYzGnpbc0Set9qtO6iPIdeqhznorcN2qsWGqijc7nlehpvqb2+nzVu3b5jyNLJ58dkbj00wGz+n+/ARnIpjIiQdoZTGLYKjNJynaZ/YMCdukqf+PoyCnmgxE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763975942; c=relaxed/simple; bh=K+zt3nceOOODApou1DvNcVnqg8L6U+BAmtwiQUTSD/g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=X8LGjFKPWeXkji7lRYMD4RDblXH73RfYyHmE68rSkYoVZnrwNAFvq08jSm7SOLlFpY4b/nrc6N5wbGXtyjyVKsQwTidZwrrUVymOnVAZlANk8NIxySHgLbBcQDrcFX8Aq0xs0VSUMlze9zBeTKlyjWB0cuYdXOLVavHjjEYJ4Kg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=xmUru0DI; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="xmUru0DI" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 5AO9FOq0420237; Mon, 24 Nov 2025 04:18:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=CFxea +0RlEzrXndzpVbk0p5/3GjSlvBMRFAAzli0hlw=; b=xmUru0DI8Es/vIqElXdD8 b6vajFlAD5HEAXo8ofI/reNuod3RMJKUF/rOqV2P/XvEXD8VuCDXcimTPsXWrtRQ ZWoZcVB7sh38JKoNo5xidIQyv8q9bNqYnzZOSrmQFREoNNvL0jGg4ywYzvs05rO5 jE8GjRcic/OUjzfNGVfwxiHyxB0lQfOiuVBOsY4Jt8eww9ilCgouk/XsOil1N2GX KkllLB72pbkGqwjqOHDPg1sH0a9NYs+FmcVSqcZ2CS7p+3flntKN+w0f6eVtWqe3 3nV9t2F58u34L3UHlegiiHb/k2Po9hWyrWXED4SfXuzeRxIflLjWLOaWl1RWFP73 g== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4aky424gt7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 24 Nov 2025 04:18:45 -0500 (EST) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 5AO9IikJ007671 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 24 Nov 2025 04:18:44 -0500 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:44 -0500 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 24 Nov 2025 04:18:43 -0500 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 24 Nov 2025 04:18:43 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.82]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5AO9I8VS024016; Mon, 24 Nov 2025 04:18:37 -0500 From: Jorge Marques Date: Mon, 24 Nov 2025 10:18:08 +0100 Subject: [PATCH v2 9/9] iio: adc: ad4062: Add GPIO Controller support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20251124-staging-ad4062-v2-9-a375609afbb7@analog.com> References: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> In-Reply-To: <20251124-staging-ad4062-v2-0-a375609afbb7@analog.com> To: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , "David Lechner" , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Linus Walleij , Bartosz Golaszewski CC: , , , , , Jorge Marques X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1763975888; l=5730; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=K+zt3nceOOODApou1DvNcVnqg8L6U+BAmtwiQUTSD/g=; b=1VAot/oOiNyakNSh6gDyBPRNszQvAcZm8xQNisXkdA/bzEsIP70eTI0VY9+l3Kb9oasJEsf9O CueObBm8ZDNBgVKmgjWk9wntp7ztaAUEPhpWEIeTCBsejt4IE8rxTcR X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=ffGgCkQF c=1 sm=1 tr=0 ts=692422f5 cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=tsAnktj4w5_xAW6w_LAA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: qnndZnCmPiIo8KBvd6zxKRxwrLjot_Oa X-Proofpoint-ORIG-GUID: qnndZnCmPiIo8KBvd6zxKRxwrLjot_Oa X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTI0MDA4MSBTYWx0ZWRfXzm1H17O3z1ka 58Sk6AOif0vFEOksLwDwuI+DxVIxm7//yL+swNiROzxCdBTePaStLBpoVxx6ldZFdgGS6Lw1NW7 fdwDOc5kVxPEpnF9Vm4CfGyq3TJ28ibutbmB6GeBvol46JNhyb4KIgE/ICTipduEL4dKJ9a4GbL KxRRYgCxgl2i8Nng1BJGN20EDPBdlQo/rDcJwOpEjsU8/erMTNQsLLPidK3ZEZHzTFDNb7iV11v G7AQzmRQ+r5BJkQ/5LyBzRChHK6lfVW6rx/vvnuBi2b35ke8t/JY95bnb0DY/fp6evucUcFEkK1 s/6kjx1ZlAQJjGTAF0Y4JgiQ4jOUD74Pb7/QyiZuwd0QytTT2gqCgecR7mvkhIWcMcDS5CCqs0A Px0Kz/jNJMMSiFs63DwwofN0yHYm7Q== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-24_03,2025-11-21_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 malwarescore=0 priorityscore=1501 bulkscore=0 clxscore=1015 lowpriorityscore=0 adultscore=0 phishscore=0 spamscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2511240081 When gp0 or gp1 is not taken as an interrupt, expose them as gpo if gpio-contoller is set in the devicetree. Signed-off-by: Jorge Marques Reviewed-by: Linus Walleij --- drivers/iio/adc/ad4062.c | 134 +++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 134 insertions(+) diff --git a/drivers/iio/adc/ad4062.c b/drivers/iio/adc/ad4062.c index 3df7dbf29ae4a..203b06276431f 100644 --- a/drivers/iio/adc/ad4062.c +++ b/drivers/iio/adc/ad4062.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -85,8 +86,11 @@ #define AD4062_MAX_AVG 0xB #define AD4062_MON_VAL_MAX_GAIN 1999970 #define AD4062_MON_VAL_MIDDLE_POINT 0x8000 +#define AD4062_GP_DISABLED 0x0 #define AD4062_GP_INTR 0x1 #define AD4062_GP_DRDY 0x2 +#define AD4062_GP_STATIC_LOW 0x5 +#define AD4062_GP_STATIC_HIGH 0x6 #define AD4062_INTR_EN_NEITHER 0x0 #define AD4062_INTR_EN_EITHER 0x3 #define AD4062_TCONV_NS 270 @@ -635,12 +639,14 @@ static int ad4062_request_irq(struct iio_dev *indio_d= ev) if (ret =3D=3D -EPROBE_DEFER) { return ret; } else if (ret < 0) { + st->gpo_irq[0] =3D false; ret =3D regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, AD4062_REG_ADC_IBI_EN_MAX | AD4062_REG_ADC_IBI_EN_MIN, AD4062_REG_ADC_IBI_EN_MAX | AD4062_REG_ADC_IBI_EN_MIN); if (ret) return ret; } else { + st->gpo_irq[0] =3D true; ret =3D devm_request_threaded_irq(dev, ret, NULL, ad4062_irq_handler_thresh, IRQF_ONESHOT, indio_dev->name, @@ -1263,6 +1269,130 @@ static int ad4062_regulators_get(struct ad4062_stat= e *st, bool *ref_sel) return 0; } =20 +static int ad4062_gpio_get_direction(struct gpio_chip *gc, unsigned int of= fset) +{ + return GPIO_LINE_DIRECTION_OUT; +} + +static int ad4062_gpio_set(struct gpio_chip *gc, unsigned int offset, int = value) +{ + struct ad4062_state *st =3D gpiochip_get_data(gc); + unsigned int reg_val =3D value ? AD4062_GP_STATIC_HIGH : AD4062_GP_STATIC= _LOW; + + if (st->gpo_irq[offset]) + return -ENODEV; + + if (offset) + return regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + AD4062_REG_GP_CONF_MODE_MSK_1, + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, reg_val)); + else + return regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + AD4062_REG_GP_CONF_MODE_MSK_0, + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_0, reg_val)); +} + +static int ad4062_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct ad4062_state *st =3D gpiochip_get_data(gc); + unsigned int reg_val; + int ret; + + ret =3D regmap_read(st->regmap, AD4062_REG_GP_CONF, ®_val); + if (ret) + return 0; + + if (st->gpo_irq[offset]) + return -ENODEV; + + if (offset) + reg_val =3D FIELD_GET(AD4062_REG_GP_CONF_MODE_MSK_1, reg_val); + else + reg_val =3D FIELD_GET(AD4062_REG_GP_CONF_MODE_MSK_0, reg_val); + + return reg_val =3D=3D AD4062_GP_STATIC_HIGH ? 1 : 0; +} + +static void ad4062_gpio_disable(void *data) +{ + struct ad4062_state *st =3D data; + u8 val =3D FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_0, AD4062_GP_DISABLED) | + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, AD4062_GP_DISABLED); + + regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + AD4062_REG_GP_CONF_MODE_MSK_1 | AD4062_REG_GP_CONF_MODE_MSK_0, + val); +} + +static int ad4062_gpio_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct ad4062_state *st =3D gpiochip_get_data(gc); + + bitmap_zero(valid_mask, ngpios); + + if (!st->gpo_irq[0]) + set_bit(0, valid_mask); + if (!st->gpo_irq[1]) + set_bit(1, valid_mask); + + return 0; +} + +static int ad4062_gpio_init(struct ad4062_state *st) +{ + struct device *dev =3D &st->i3cdev->dev; + struct gpio_chip *gc; + u8 val, mask; + int ret; + + if ((st->gpo_irq[0] && st->gpo_irq[1]) || + !device_property_read_bool(dev, "gpio-controller")) + return 0; + + gc =3D devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); + if (!gc) + return -ENOMEM; + + val =3D 0; + mask =3D 0; + if (!st->gpo_irq[0]) { + mask |=3D AD4062_REG_GP_CONF_MODE_MSK_0; + val |=3D FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_0, AD4062_GP_STATIC_LOW); + } + if (!st->gpo_irq[1]) { + mask |=3D AD4062_REG_GP_CONF_MODE_MSK_1; + val |=3D FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, AD4062_GP_STATIC_LOW); + } + + ret =3D regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + mask, val); + if (ret) + return ret; + + ret =3D devm_add_action_or_reset(dev, ad4062_gpio_disable, st); + if (ret) + return ret; + + gc->parent =3D dev; + gc->label =3D st->chip->name; + gc->owner =3D THIS_MODULE; + gc->base =3D -1; + gc->ngpio =3D 2; + gc->init_valid_mask =3D ad4062_gpio_init_valid_mask; + gc->get_direction =3D ad4062_gpio_get_direction; + gc->set =3D ad4062_gpio_set; + gc->get =3D ad4062_gpio_get; + gc->can_sleep =3D true; + + ret =3D devm_gpiochip_add_data(dev, gc, st); + if (ret) + return dev_err_probe(dev, ret, "Unable to register GPIO chip\n"); + + return 0; +} + static const struct i3c_device_id ad4062_id_table[] =3D { I3C_DEVICE(AD4062_I3C_VENDOR, ad4060_chip_info.prod_id, &ad4060_chip_info= ), I3C_DEVICE(AD4062_I3C_VENDOR, ad4062_chip_info.prod_id, &ad4062_chip_info= ), @@ -1351,6 +1481,10 @@ static int ad4062_probe(struct i3c_device *i3cdev) if (ret) return dev_err_probe(dev, ret, "Failed to request i3c ibi\n"); =20 + ret =3D ad4062_gpio_init(st); + if (ret) + return ret; + INIT_WORK(&st->trig_conv, ad4062_trigger_work); =20 return devm_iio_device_register(dev, indio_dev); --=20 2.51.1