From nobody Thu Dec 18 10:58:09 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 74A9B33D6CE; Wed, 17 Dec 2025 12:14:17 +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=1765973659; cv=none; b=fPHqIVhA9TXtV+v/RgN8v16oUtXVdzn9u/vugX9PRA/aRmFYOkYqHHi3icLF+NJMV86fweJ0RphpZykbTPoVb1/AFwvsZyWvbPVu0iWDczXiIBPYU6H/aqbqE9WKATiBs1/ElAGEqG0jTXaFVs4KGjY7w74YWPLFpFLXWpBThWA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765973659; c=relaxed/simple; bh=XMHgFlcph+hjiJBoruxvKS8ORHPLsT08GUu7BcsJ6w0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=plGBWdw8Mr7pPqKPR7Hg46j4tz0M8u36OXU84MQ4JHexwkEe99z+SSwdx35gtjrlf6pvS7STFH92Eg50ViYuBULreo5COP8ceCtgW2sXfcXZ/F+lXOgboQSqE2f7+32mS3M62nB8BOHC77Mmphf8KS0pKsmoAUYi3cIh8s8SKiI= 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=KEPwSgiv; 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="KEPwSgiv" 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 5BHAf3EL3838948; Wed, 17 Dec 2025 07:13:48 -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=L+eIq togxlz1Wcn5tOARQmcvO0+cuebCV50KF8s+gGU=; b=KEPwSgivbzC1h06qDhAvq HE6NH8ECSFmo4hFM5silPHLTq9OqFJ3IKzn96Y/+75babhocn2nrcKLDzbF7XS6P oYPDu666NV9/yro6otrOcSrALHHFGgmcj9asd1Sdyy415rqlyOmN3jBiZoU5riw7 FoJBFGi97a4kFmYh07vx6AxxLVUvmCWcjyV70EWfn+Lw0QWucOjTiJe1EKYKgCeM nUu3jnz9diuz08tHdU8DPwzrA+BY89AKi+kXzGlywuvUOIf1vbfq41nglKLyg5gY wbwY0XM7fXRiUhiebnuEirvR2bSi8F0d2MEJizEJqwvQtcfa4YFnlH3kjb9OGqtp Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 4b3jw9jeg9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 17 Dec 2025 07:13:48 -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 5BHCDl8q041077 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 17 Dec 2025 07:13:47 -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; Wed, 17 Dec 2025 07:13:47 -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; Wed, 17 Dec 2025 07:13:47 -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; Wed, 17 Dec 2025 07:13:47 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.73]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5BHCDUv7014815; Wed, 17 Dec 2025 07:13:40 -0500 From: Jorge Marques Date: Wed, 17 Dec 2025 13:13:24 +0100 Subject: [PATCH v4 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: <20251217-staging-ad4062-v4-1-7890a2951a8f@analog.com> References: <20251217-staging-ad4062-v4-0-7890a2951a8f@analog.com> In-Reply-To: <20251217-staging-ad4062-v4-0-7890a2951a8f@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=1765973610; l=4736; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=XMHgFlcph+hjiJBoruxvKS8ORHPLsT08GUu7BcsJ6w0=; b=pJAqmwOOxZ5yFDLEHx1/4LjfZzQZWPVwIRzmpKbf4+5Mu8AUajGjEMWL050Jk79ek/uAoxLXu a8aXAOxh1GhCABcGFT+ShGvgMm58/T/+irUoV2s+1DlaN2A1kKc5d/C X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE3MDA5NCBTYWx0ZWRfX3eAa+ScZLljl 8dTOaxXBhnKlSml6byxyTUse87M53eAoFrw/dnBXUtpus2ZHEZ53GF5OZPcZkeRZ2PZC7yK8MSr Wm0jS7E3enziUlgx+8hhj6opntNFrHDy0ILy5kHGMA6FpMj/Zy3IU0rdaCDdWTxIL2V1LnwTfJc FE/Iq621kYGkCvUUkZbpXP7/8W7IAIjJNFiNA6Q+e4Wr1ZRHFYL2W/XoCBtaLHJkXgXq2lMFGUQ xsiB/g5MzJ1qH9EImPAbq6MC4WX2CuAUISm4r+C5X896Ql3IibY/8d/j0UjGH3eiETdVjniedcy YbbMQoHw1oSw/jRVLhZrpmdisVxtHVrd+1gnGHIwKPF740/z6DmKWISEzjiGPCArJRwGQpwz+l+ rLVjVq01f2XVy2RaLkyozdw5H7NNdw== X-Authority-Analysis: v=2.4 cv=TZGbdBQh c=1 sm=1 tr=0 ts=69429e7c cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=gEfo2CItAAAA:8 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=COXgcu1q7tYCwoEp4oAA:9 a=QEXdDO2ut3YA:10 a=sptkURWiP4Gy88Gu7hUp:22 X-Proofpoint-GUID: PHjD3JXWfmEtTdbp81o3kVN4_3wFoPdn X-Proofpoint-ORIG-GUID: PHjD3JXWfmEtTdbp81o3kVN4_3wFoPdn 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-12-17_01,2025-12-16_05,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 adultscore=0 impostorscore=0 spamscore=0 priorityscore=1501 bulkscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512170094 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 | 120 +++++++++++++++++= ++++ MAINTAINERS | 6 ++ 2 files changed, 126 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..eeb148081663c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2025 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: + Two pins are available that can be configured as either a general pu= rpose + digital output, device enable signal (used to synchronise other part= s of + the signal chain with ADC sampling), device ready (GP1 only) or vari= ous + interrupt signals. If intended for use as a GPIO or device enable, w= ill not + present here. + minItems: 1 + items: + - description: + GP0 pin, cannot be configured as DEV_RDY. + - description: + GP1 pin, can be configured to any setting. + + interrupt-names: + minItems: 1 + items: + - const: gp0 + - const: gp1 + + gpio-controller: + description: + Marks the device node as a GPIO controller. GPs not listed as interr= upts + 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 29340394ac9d7..bc1d6b2d0a11e 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 Thu Dec 18 10:58:09 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 9BC9833F8BF; Wed, 17 Dec 2025 12:14:18 +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=1765973660; cv=none; b=e8OOtTSn7Uy3KA3DCM74BLCPkDavWpisYwVutnqnJ0ZM/2cgJONsJQ7MGgdQ2XM1cPzXRPwMksabQzzqNed4YNbAukIjJKrr7/0HigcZc9ovTYzud5Efr2es8xxH4zHStTV/1vl5wdLft+mJUjaIjwXwY+VpfHChbTSUaQ+79Ag= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765973660; c=relaxed/simple; bh=MuHYsLjxwdN8IkJNsHAUBMs6LN4MRGpg5MuRP0IoWa8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=rdb7ZmoxlaxYG/w9Np/yPi53sYk4Ql0vfOfxsXXdcxMpV5I6mVZ4KnnJzMhjyjkh7Bya9b7bdcXR1OfsbKjOERgnn/MaytWUBlvyn8tQo300DGsS3Y7Wj9YMuxVoiJqhQl4GZaofQ7dLrtwy4wg4zo49fJcRgwXYfEV+/lxlsh0= 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=n1Qy5ZF0; 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="n1Qy5ZF0" 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 5BHAsJYx3839967; Wed, 17 Dec 2025 07:13:50 -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=xrV4J cgO8S4mlg0S60Bb6DHITfHakEA08GWxAiwTfrU=; b=n1Qy5ZF0aRb252PGD/GMg 9UHoAtDMUK//AkXKre7U8qz3qnWfPzH9dw+RJOQU2d/1mBVzvmob1YgHznVDEqhM Qisctj/o1htCVzP6+WDVlfzlL8aCIh+PU4luafAxgayRad5zBz+O4DrPetfTNv6Y 7zO2R248YEZYzSlrRguPig7zoXEiUwLXPu1MidaiFdaIalmB2nrhZSnTB0b5D8YJ E3xGkwWsmAhxIYj7y9lBW5AG21lxU5u+0DskW98bbkBdVDqDb57nXY2SF5qu/9z0 e1NlVZy0GLQAWmkMQF7yQKqtFv6Fp2KnH39AVtOkEt7bgZFKxfpcboDP99wD08k0 Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 4b3jw9jegb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 17 Dec 2025 07:13:50 -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 5BHCDnho041082 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 17 Dec 2025 07:13:49 -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; Wed, 17 Dec 2025 07:13:49 -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; Wed, 17 Dec 2025 07:13:49 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.73]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5BHCDUv8014815; Wed, 17 Dec 2025 07:13:42 -0500 From: Jorge Marques Date: Wed, 17 Dec 2025 13:13:25 +0100 Subject: [PATCH v4 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: <20251217-staging-ad4062-v4-2-7890a2951a8f@analog.com> References: <20251217-staging-ad4062-v4-0-7890a2951a8f@analog.com> In-Reply-To: <20251217-staging-ad4062-v4-0-7890a2951a8f@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=1765973610; l=4189; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=MuHYsLjxwdN8IkJNsHAUBMs6LN4MRGpg5MuRP0IoWa8=; b=X20dKF/QcN5DGrpOir73v8AawVMq83fiQvD+On/JHzQg4YhNG+nKSdazkThkWQ4u28i+XPhsS kewKQnbj1iWBhsk5UPa3TvNU0tUn9U3VytacQgTR1nnxXUWgv3g3so5 X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE3MDA5NCBTYWx0ZWRfXwR+c+D0k6ocy gR7Q4vehIDyyW5XaSBONmRpu5nTxOJwsOwBR1urcYN8H2eWvtL6zveFoQod4MdzWLpBIh3cUhgY BL9Y6HW0pEtEKNAPVworFoLebTkU2eJ9k3A4B+P2py5pETjOtVW0/xez3AynI4W4yiASCDn9fn2 w1QgN86B1uRxO8rgsynoY57jx3+/vOx3tpgOgUFFoR8baNcR/4wy/MB1eHVZX/YiMuzz/26LQpN PCwvLg5xQlaoSY/Tccngv281QzltMOTVWE9J4E0f7dlmVM2LnPhYwKrnEPwnnyFc/A0znvqpofm d6FR8ehjxt1qOLvErMMRm/Xe0yUOl0Y7B2cqUzgqjfdI6NdgEzDEZ5MEUX/uKUlJjVa+TJ4o35p DW14NvxCqgTtozmlsigLKG98T6ugjg== X-Authority-Analysis: v=2.4 cv=TZGbdBQh c=1 sm=1 tr=0 ts=69429e7e cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=5m_mccj1f-mIrhuec74A:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: GHcQ39509lgPrKWvMBbAGQCkocVIVqxt X-Proofpoint-ORIG-GUID: GHcQ39509lgPrKWvMBbAGQCkocVIVqxt 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-12-17_01,2025-12-16_05,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 adultscore=0 impostorscore=0 spamscore=0 priorityscore=1501 bulkscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512170094 This adds a new page to document how to use the ad4062 ADC driver. Signed-off-by: Jorge Marques --- Documentation/iio/ad4062.rst | 86 ++++++++++++++++++++++++++++++++++++++++= ++++ Documentation/iio/index.rst | 1 + MAINTAINERS | 1 + 3 files changed, 88 insertions(+) diff --git a/Documentation/iio/ad4062.rst b/Documentation/iio/ad4062.rst new file mode 100644 index 0000000000000..30200adf90c38 --- /dev/null +++ b/Documentation/iio/ad4062.rst @@ -0,0 +1,86 @@ +.. 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. 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 bc1d6b2d0a11e..0730b79c3dd0d 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 Thu Dec 18 10:58:09 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 62EE433F377; Wed, 17 Dec 2025 12:14:17 +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=1765973659; cv=none; b=TGmPj0kPxOOqZ5/G7WblNmvoSDv5jbIq+4LQXctNxR2swZr2SVpkS8S7/34zcq/rP2Bgp7gh9vzvKT6eBxYuV3etuK3zFhmF7swZSZSwPDdhrvkj8P9dR0keD0kCGYjeAZPAvVPDp0Uhmn5sC4qQw+kuW0fVZ4DPwRZqcURVRxA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765973659; c=relaxed/simple; bh=LWXQ4/4Li7osJ/KwR7gbjFgHvTSW4+Ar40cZGHR0InQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=QoKFH1FFAtmNNdChQ9LCSNbYlR0NC6YItg+KOgzLTNsuheWp8LnwAxcAP/g9NtuIDB0gIy67yKMfuSUob5A2CuvNqUWw9gRErBLtU+0H2WhaI5f4zlpt8qlj3GExmsiJas5KqEvb+vR6kfS3h3zakqlYCAC1STDid+hbssfSMxw= 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=LCN80RrK; 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="LCN80RrK" 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 5BH8SXrl3979344; Wed, 17 Dec 2025 07:13:54 -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=wcP/k w40zLFnIUUIa2BpuSq1xwY/eJALWByii50H47I=; b=LCN80RrKAYuxxGrKHFgwF 4mZsflAyawveklTpy9MS5DzTGJcj+a6zjy94p8zTYJ3/826qn0WJhOS636kLZu7B cZFJz7VcRskQMi9pnFOHCcL4GTfzdi9FkeKwCRRpjxmZXymmZtWUbFuQ5TBbxpTs rx97YelOqPXIU+a/dp140d2uXjs5sBHhHkFbl09ZoN6dVQGFJ7q+fNLDYGzxENI5 7xZRZyTNS16uXs+EOOeWeq5I2HiLr/adpeuF/xHxBUfR+gf9XnrGKei6Kb+9PEPA G2SKde/pPHMl/Odse8rAUtE3QcyrnV/D1i2WNvy8Ge+8GY3V4mTyfW2MBPT7VVUh w== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4b3bbevk5q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 17 Dec 2025 07:13:53 -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 5BHCDqNE041088 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 17 Dec 2025 07:13:52 -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; Wed, 17 Dec 2025 07:13:51 -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; Wed, 17 Dec 2025 07:13:51 -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; Wed, 17 Dec 2025 07:13:51 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.73]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5BHCDUv9014815; Wed, 17 Dec 2025 07:13:45 -0500 From: Jorge Marques Date: Wed, 17 Dec 2025 13:13:26 +0100 Subject: [PATCH v4 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: <20251217-staging-ad4062-v4-3-7890a2951a8f@analog.com> References: <20251217-staging-ad4062-v4-0-7890a2951a8f@analog.com> In-Reply-To: <20251217-staging-ad4062-v4-0-7890a2951a8f@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=1765973610; l=25485; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=LWXQ4/4Li7osJ/KwR7gbjFgHvTSW4+Ar40cZGHR0InQ=; b=zIhOP8IoXiXl9OAPMi0PGIye1weo0Q8RUixWC8cg0avrO0GMm5TtkjIhRz7e+O33VEHy49aWg BOIOA/WFU5gA724cPM8ssHBTDYYjzF5pb2rUlAjWkqIv8+oPLD+fEKJ X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: CvpnPnbeIdMjOqWwlryrk8vlavvYlocp X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE3MDA5NSBTYWx0ZWRfX9JdG+e+fRxu5 ++QqEq0tBAjY0AZnsOdMzNWpOtE4qZmlBn1ZqI0m3QLj/zx2BnwSlJBVbgCgznAiCJkmnSejH0y q6aI2nQ5uz8ZeEIUSQLqjOlfydCFJfCjMPI59R1oCToCjr8bIibJaL+1P+wHpcmD/+7nUiSD1la 7rDlMfXasXqnkQE+5SnV9SxRDS3OzG+FtPHReOJRZiWFPJ5iLNJFXZWIbNN4GU7/uZRyOzjJ1Jg 1woZ1ZfzRcL+1k1f20FtSAwlX9hTgQvrE22ZOneP+n3qVU23Axuxxtsw9AMSBJyeFv/OuuTqYxT 6DHmnr4mGUl2PZUCQ+rVBssFc/gOqtx6wylpSQvgfWRJ+la9871/Pap9AE+iSbT2xoelN8weXDh gJQ+xtvn+g24bp5Pr/rBRtmWj3Y4KQ== X-Authority-Analysis: v=2.4 cv=YqsChoYX c=1 sm=1 tr=0 ts=69429e81 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=npeQ3yjGmb6k4UAFlcAA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: CvpnPnbeIdMjOqWwlryrk8vlavvYlocp 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-12-17_01,2025-12-16_05,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 malwarescore=0 bulkscore=0 suspectscore=0 lowpriorityscore=0 phishscore=0 impostorscore=0 clxscore=1015 adultscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512170095 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 | 819 +++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 832 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0730b79c3dd0d..301318de29af7 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 576480e3ac4a4..fda0da422c675 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 b1b1d5a2273f2..0a199630c0812 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..1a7829c507e53 --- /dev/null +++ b/drivers/iio/adc/ad4062.c @@ -0,0 +1,819 @@ +// 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 + +#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_32BITS 0x59 +#define AD4062_REG_CONV_AUTO 0x61 +#define AD4062_MAX_REG AD4062_REG_CONV_AUTO + +#define AD4062_MON_VAL_MIDDLE_POINT 0x8000 + +#define AD4062_I3C_VENDOR 0x0177 +#define AD4062_SOFT_RESET 0x81 +#define AD4060_PROD_ID 0x7A +#define AD4062_PROD_ID 0x7C + +#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; + u16 avg_max; +}; + +enum { + AD4062_SCAN_TYPE_SAMPLE, + AD4062_SCAN_TYPE_BURST_AVG, +}; + +static const unsigned 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; + int vref_uV; + unsigned int samp_freqs[ARRAY_SIZE(ad4062_conversion_freqs)]; + u16 sampling_frequency; + u8 oversamp_ratio; + u8 conv_addr; + union { + __be32 be32; + __be16 be16; + } buf __aligned(IIO_DMA_MINALIGN); +}; + +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), +}; + +#define AD4062_CHAN { \ + .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, \ +} + +static const struct ad4062_chip_info ad4060_chip_info =3D { + .name =3D "ad4060", + .channels =3D { AD4062_CHAN }, + .prod_id =3D AD4060_PROD_ID, + .avg_max =3D 256, +}; + +static const struct ad4062_chip_info ad4062_chip_info =3D { + .name =3D "ad4062", + .channels =3D { AD4062_CHAN }, + .prod_id =3D AD4062_PROD_ID, + .avg_max =3D 4096, +}; + +static int ad4062_set_oversampling_ratio(struct ad4062_state *st, int val,= int val2) +{ + const u32 _max =3D st->chip->avg_max; + const u32 _min =3D 1; + int ret; + + if (!in_range(val, _min, _max) || val2 !=3D 0) + 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 val; + + return 0; +} + +static int ad4062_get_oversampling_ratio(struct ad4062_state *st, 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); + if (ret) + return ret; + + *val =3D BIT(buf + 1); + return 0; +} + +static int ad4062_calc_sampling_frequency(unsigned int fosc, unsigned int = oversamp_ratio) +{ + /* From datasheet p.31: (n_avg - 1)/fosc + tconv */ + u32 n_avg =3D BIT(oversamp_ratio) - 1; + u32 period_ns =3D NSEC_PER_SEC / fosc; + + /* Result is less than 1 Hz */ + if (n_avg >=3D fosc) + return 1; + + return NSEC_PER_SEC / (n_avg * period_ns + AD4062_TCONV_NS); +} + +static int ad4062_populate_sampling_frequency(struct ad4062_state *st) +{ + for (u8 i =3D 0; i < ARRAY_SIZE(ad4062_conversion_freqs); i++) + st->samp_freqs[i] =3D + ad4062_calc_sampling_frequency(ad4062_conversion_freqs[i], + st->oversamp_ratio); + return 0; +} + +static int ad4062_get_sampling_frequency(struct ad4062_state *st, int *val) +{ + int freq =3D ad4062_conversion_freqs[st->sampling_frequency]; + + *val =3D ad4062_calc_sampling_frequency(freq, st->oversamp_ratio); + return IIO_VAL_INT; +} + +static int ad4062_set_sampling_frequency(struct ad4062_state *st, int val,= int val2) +{ + int ret; + + if (val2 !=3D 0) + return -EINVAL; + + 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) +{ + struct device *dev =3D &st->i3cdev->dev; + 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 be16_to_cpu(st->buf.be16); + if (val !=3D st->chip->prod_id) + dev_warn(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 be16_to_cpu(st->buf.be16); + if (val !=3D AD4062_I3C_VENDOR) { + dev_err(dev, "Vendor ID x%x does not match expected value\n", val); + return -ENODEV; + } + + return 0; +} + +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)); +} + +static int ad4062_set_operation_mode(struct ad4062_state *st, + enum ad4062_operation_mode mode) +{ + int ret; + + 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, datasheet p8 */ + ndelay(60); + + 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); + int ret; + + ret =3D 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, + AD4062_GP_DRDY)); + 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; + + ret =3D regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, + AD4062_REG_INTR_CONF_EN_MSK_1, + FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_1, + AD4062_INTR_EN_NEITHER)); + if (ret) + return ret; + + st->buf.be16 =3D cpu_to_be16(AD4062_MON_VAL_MIDDLE_POINT); + 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_disable_ibi(void *data) +{ + struct i3c_device *i3cdev =3D data; + + i3c_device_disable_ibi(i3cdev); +} + +static void ad4062_free_ibi(void *data) +{ + struct i3c_device *i3cdev =3D data; + + 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 devm_add_action_or_reset(&i3cdev->dev, ad4062_free_ibi, i3cdev); + if (ret) + return ret; + + ret =3D i3c_device_enable_ibi(i3cdev); + if (ret) + return ret; + + return devm_add_action_or_reset(&i3cdev->dev, ad4062_disable_ibi, i3cdev); +} + +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; + + if (ret < 0) + return regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, + AD4062_REG_ADC_IBI_EN_CONV_TRIGGER, + AD4062_REG_ADC_IBI_EN_CONV_TRIGGER); + + return devm_request_threaded_irq(dev, ret, + ad4062_irq_handler_drdy, + NULL, IRQF_ONESHOT, indio_dev->name, + indio_dev); +} + +static const int ad4062_oversampling_avail[] =3D { + 1, 2, 4, 8, 16, 32, 64, 128, /* 0 - 7 */ + 256, 512, 1024, 2048, 4096, /* 8 - 12 */ +}; + +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); + *len -=3D st->chip->avg_max =3D=3D 256 ? 4 : 0; + *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 ? ARRAY_SIZE(ad4062_conversion_freqs) : 1; + *type =3D IIO_VAL_INT; + + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int ad4062_get_chan_calibscale(struct ad4062_state *st, int *val, i= nt *val2) +{ + int ret; + + ret =3D regmap_bulk_read(st->regmap, AD4062_REG_MON_VAL, + &st->buf.be16, sizeof(st->buf.be16)); + if (ret) + return ret; + + /* From datasheet: code out =3D code in =C3=97 mon_val/0x8000 */ + *val =3D be16_to_cpu(st->buf.be16) * 2; + *val2 =3D 16; + + return IIO_VAL_FRACTIONAL_LOG2; +} + +static int ad4062_set_chan_calibscale(struct ad4062_state *st, int gain_in= t, + int gain_frac) +{ + /* Divide numerator and denumerator by known great common divider */ + const u32 mon_val =3D AD4062_MON_VAL_MIDDLE_POINT / 64; + const u32 micro =3D MICRO / 64; + const u32 gain_fp =3D gain_int * MICRO + gain_frac; + const u32 reg_val =3D DIV_ROUND_CLOSEST(gain_fp * mon_val, micro); + int ret; + + /* Checks if the gain is in range and the value fits the field */ + if (gain_int < 0 || gain_int > 1 || reg_val > BIT(16) - 1) + return -EINVAL; + + st->buf.be16 =3D cpu_to_be16(reg_val); + 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 equal to 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 xfer_trigger =3D { + .data.out =3D &st->conv_addr, + .len =3D sizeof(st->conv_addr), + .rnw =3D false, + }; + struct i3c_priv_xfer xfer_sample =3D { + .data.in =3D &st->buf.be32, + .len =3D sizeof(st->buf.be32), + .rnw =3D true, + }; + int ret; + + PM_RUNTIME_ACQUIRE(&st->i3cdev->dev, pm); + ret =3D PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + ret =3D ad4062_set_operation_mode(st, st->mode); + if (ret) + return ret; + + reinit_completion(&st->completion); + /* Change address pointer to trigger conversion */ + st->conv_addr =3D AD4062_REG_CONV_TRIGGER_32BITS; + ret =3D i3c_device_do_priv_xfers(i3cdev, &xfer_trigger, 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, &xfer_sample, 1); + if (ret) + return ret; + *val =3D be32_to_cpu(st->buf.be32); + return 0; +} + +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); + + 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; + + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + return ad4062_get_sampling_frequency(st, val); + } + + 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 ?: 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, val2); + + case IIO_CHAN_INFO_CALIBSCALE: + return ad4062_set_chan_calibscale(st, val, val2); + + 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; + + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + return ad4062_set_sampling_frequency(st, val, val2); + } + + 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); + + if (readval) + return regmap_read(st->regmap, reg, readval); + else + return regmap_write(st->regmap, reg, writeval); +} + +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, + .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 && !*ref_sel) + return dev_err_probe(dev, st->vref_uV, + "Failed to enable and read ref voltage\n"); + + if (*ref_sel) { + 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_PROD_ID, &ad4060_chip_info), + I3C_DEVICE(AD4062_I3C_VENDOR, AD4062_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 0; + st->indio_dev =3D indio_dev; + + 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; + + /* Wait device functional blocks to power up */ + fsleep(3 * USEC_PER_MSEC); + 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 Thu Dec 18 10:58:09 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 6638933E35D; Wed, 17 Dec 2025 12:14:18 +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=1765973661; cv=none; b=DmW3g01JgWUBVhczUm4ar6/1UwliJCYApuhSx3lSVVzlWvRQpVqCaoXup0b9e2bUdaNiyRWZeZ6oDKV94imtO5WFZkPHryGbrjgjQ3bIRUSexO3ioSZbU7hIYfzcFFY3h0aFh8KDENlCVVF2r08ipYmSTnFArWiCT4znuGFuEi0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765973661; c=relaxed/simple; bh=/w7oOA/B3dH9ls50EHLd2kMvf7DHQF62+nmV4V79E9Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=Q972U+2OJuaEZzvgR8fGTAhbTNeQSZZK11bzIay8r5zIqosC/4lauqm24SGHgQd8iLvIe83OZh5Fy35G3+uIVWf49oJykrntitogpbZLRKiP+XYGdtRJdVQT8/9XqdU40KBBMEPIUAifNz/9d58Y2JP3bo3WoSQtZ5RFtas0Mhg= 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=csHaW6Bj; 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="csHaW6Bj" 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 5BH9aYqb964276; Wed, 17 Dec 2025 07:13:57 -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=VoM28 YD60AjeHkEDvz/99VVhXnynVtIRpAhzO0y5exw=; b=csHaW6BjOCGHE+Ojt21C+ n2kxb1ROT2yAT1uWBokKdicua0vMGHt1v27DBmmpIvOGFtJkR2g1c7Qg+ypiZRH0 dfdQono/Akxm6OMt4zgWtxxsUh320ZCku7ay0Yt+uYl2FUzx/9x9VjALPwHNwlO7 ALER4NffGlXJ6sGDo97B3M3Dmc0ZmRpi+d65U/+6pkei+JbfABj191oXIlx2pVA6 GRs1pbAjDOkJOiLMx2MUeU+J6ErYP3nt9VetQL2PtxZGVBYcRJPgX0mng8baMv+I ZpoifuKJdPiygKGodJGmpCAsezLaqhnPCOeOWbK98OZu5At0hpuVpkO6N9muJxDn A== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4b3jt2thq9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 17 Dec 2025 07:13:56 -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 5BHCDtbW041094 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 17 Dec 2025 07:13:55 -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; Wed, 17 Dec 2025 07:13:55 -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; Wed, 17 Dec 2025 07:13:55 -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; Wed, 17 Dec 2025 07:13:55 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.73]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5BHCDUvA014815; Wed, 17 Dec 2025 07:13:47 -0500 From: Jorge Marques Date: Wed, 17 Dec 2025 13:13:27 +0100 Subject: [PATCH v4 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: <20251217-staging-ad4062-v4-4-7890a2951a8f@analog.com> References: <20251217-staging-ad4062-v4-0-7890a2951a8f@analog.com> In-Reply-To: <20251217-staging-ad4062-v4-0-7890a2951a8f@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=1765973610; l=1228; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=/w7oOA/B3dH9ls50EHLd2kMvf7DHQF62+nmV4V79E9Q=; b=OEhJeotjHPWVNgYu1dSZtU4is61Sx88gHvWLYJah+jUIpm2o4q36UxPu1wcyhhOcwyh4j+Jda BvNbY4s43HKBjoALeQbuxtUbZtO5uIeaiDaqBM9Fr4FfYuATvvXXpCF X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: G5pfLfbyNduPZfNqf72_IS0femo9dXOt X-Authority-Analysis: v=2.4 cv=Ct6ys34D c=1 sm=1 tr=0 ts=69429e84 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=pTCSo2s0eJJONGnsYSsA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: G5pfLfbyNduPZfNqf72_IS0femo9dXOt X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE3MDA5NSBTYWx0ZWRfX7wfrNohDFFQ1 5bpUtsoo5jyE0a9B345KaUQKs2HBYyeo8tMyQMctBudGe70mnenPWX607EfC22kmNwmDaNeOrn2 PiQXb9qjL/sW13Li0gSdosEh+iQcX7RZhIsUxViCXNrFvvMg3+gSkGX6yvdcnblfM01lZ9RovQj 7gnpFqP6/N7N4es3tnweZXUmlJyJ6zt+4m/ZDVTGeucKOJEJZl1x6UBI17yfCy5LP7fYfyeIC4E sZ8qLXGuDdVaGYlN/Qw/e0XdsABIZmbMXaHLovGBuwgk4ULFUhyMju1POkUmoDuWQG2Ofh31x+L NkAoqoa1cQHFyvQyMxy4kC/fFgh5jtbC6j75eiJ4Sr+xdWzwA1F9MAS2wV6T5jHk44vCLyrY7VI a+1LLsrmBltQqc5EOxuIBC7PWDn1yg== 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-12-17_01,2025-12-16_05,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 spamscore=0 adultscore=0 priorityscore=1501 phishscore=0 suspectscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512170095 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 30200adf90c38..12ac16dfc3028 100644 --- a/Documentation/iio/ad4062.rst +++ b/Documentation/iio/ad4062.rst @@ -84,3 +84,16 @@ Low-power mode 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. + +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. --=20 2.51.1 From nobody Thu Dec 18 10:58:09 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 DFBF733F395; Wed, 17 Dec 2025 12:14:17 +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=1765973659; cv=none; b=ckOwx53c0vt2/fgk+ItMA7VPdcLeQ7PHnDoJbd/eSHJGgYFwpvKfeyA2q4OyqfvFBBqIUaLlJEtgrnmL0Wt2OpcN1nupunWp4iwJhvTmKH0Uc0y6oXct6zYZwQNedPO+QNctWJJcOtepN0hVsYJ7nFMnwDTJciWLuCaJwW2FJ0k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765973659; c=relaxed/simple; bh=IXC04bKVME1MIN4tc1hJfbQ469/2PvuAl9H57VoRJtg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=oG7MS8m9cBAoVct6i+rd7gKUrktEyd/+0rafQb5HkV0QTDGIReGN5WcG135HU3g9CdB8sl0XWEOqHnl2NudSGHyOiv+4WEh4nK2EHFSm8hGOpUvofe4QmumnlHJ+qRE3CoED3qdBoE/Kx2D76s26iMzx7fHW6bNO1/KlSO0ZcSM= 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=KvAQk4Eo; 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="KvAQk4Eo" 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 5BHAUCA93839029; Wed, 17 Dec 2025 07:14:02 -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=F6kMV vXDxJtwauqyYrgwjcDvWbFhv8SJKq/0AaQJMTc=; b=KvAQk4EoEemoruT6YjjLS jABtfuV2ewRYT07T5ws9XVLj92mqVJUKByyfAdwGKKRvy2D59bYm1gIjwRD+jVpI bdcqPU+7794jo3vPdpADSBaHn4fsq8kOegbvRwAK1E3DhckdZlDtFQ17pwGqwu0w CMMM0i1+6v+NNUszyQuv/hYddyKOsounuPLLnZG/jWrFJwYQyqnvg1WlzOn/hRK7 P+a79ombVpE2sGIKOmyiknNcyp7Gwawtr3bys+7bnzBWdjlRYQhyd9t9hr7kUtv/ LqLQxOorkINqv0fU3nsfu/SmLJmCnutWX8skT8bqPtCqp+VtTdmUTV3VhxS2bYq5 g== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 4b3jw9jeh1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 17 Dec 2025 07:14:01 -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 5BHCDv0D041098 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 17 Dec 2025 07:13:57 -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; Wed, 17 Dec 2025 07:13:57 -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; Wed, 17 Dec 2025 07:13:57 -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; Wed, 17 Dec 2025 07:13:57 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.73]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5BHCDUvB014815; Wed, 17 Dec 2025 07:13:49 -0500 From: Jorge Marques Date: Wed, 17 Dec 2025 13:13:28 +0100 Subject: [PATCH v4 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: <20251217-staging-ad4062-v4-5-7890a2951a8f@analog.com> References: <20251217-staging-ad4062-v4-0-7890a2951a8f@analog.com> In-Reply-To: <20251217-staging-ad4062-v4-0-7890a2951a8f@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=1765973610; l=13791; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=IXC04bKVME1MIN4tc1hJfbQ469/2PvuAl9H57VoRJtg=; b=EWwMfcOd/vD0HQEUKajE53jWMwygkprMq8sjPM69M+p15Kd7cE1wyMcYoDFzyEA8HYSfsxx2t 0MKeXhukijMAG4bOLJXlg5fIJ4vPIZ54jmtPDbX/yuTgcSrz+moDjaz X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE3MDA5NSBTYWx0ZWRfX4/zfXKgWTbNJ 0Lh5rr10LRxmbXZiAwa21I8Y46zmRdKybagAEcFNO3RvVIIZlqzUORSvGXS2MN6q9vFRdYnQVOF FY6Dp+W+HeDq+xDXLVKWipxciSbeBwdLrOCwhoDLfYTrfNo14Y0OdF6IRZHQIqtbCHj9LemGiH5 23gefQYQbTdc4pIcMtvfc07Jz7sFJUDtdq7pvLrCJCyfT8H0xJMj3KfOdHHxDTFWXL/3hz8BRWY 7eOBCPUQppupafDtA1Y/YBf+FtBLeDFlh6YwWiDx2jaYw/hOCELwGrpoPabC4dw185SAMxkXdBs 8bXJIU3X7mAL5+cZQLOb1aYsUeJkt5Jq315NGe07yUfJJ6/h6TKrpW1dAt+Pn5+v7JkQjzfzrKI ZZV/ufffcjvxbCiYP9CBVtepo78fow== X-Authority-Analysis: v=2.4 cv=TZGbdBQh c=1 sm=1 tr=0 ts=69429e89 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=CGgXswB9vpsB3GpN9NgA:9 a=QEXdDO2ut3YA:10 a=br55WurUj89AL1qEz8Q6:22 X-Proofpoint-GUID: 58jtYC6xYq98BaqlaI-3aCnbUWEWU4eJ X-Proofpoint-ORIG-GUID: 58jtYC6xYq98BaqlaI-3aCnbUWEWU4eJ 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-12-17_01,2025-12-16_05,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 adultscore=0 impostorscore=0 spamscore=0 priorityscore=1501 bulkscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512170095 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 | 272 +++++++++++++++++++++++++++++++++++++++++++= ++-- 2 files changed, 268 insertions(+), 6 deletions(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index fda0da422c675..89a6486135f60 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 1a7829c507e53..afc8b6969cf08 100644 --- a/drivers/iio/adc/ad4062.c +++ b/drivers/iio/adc/ad4062.c @@ -9,10 +9,15 @@ #include #include #include +#include #include #include #include +#include #include +#include +#include +#include #include #include #include @@ -59,6 +64,9 @@ #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_16BITS 0x51 +#define AD4062_REG_CONV_READ_32BITS 0x53 +#define AD4062_REG_CONV_TRIGGER_16BITS 0x57 #define AD4062_REG_CONV_TRIGGER_32BITS 0x59 #define AD4062_REG_CONV_AUTO 0x61 #define AD4062_MAX_REG AD4062_REG_CONV_AUTO @@ -94,6 +102,36 @@ enum { AD4062_SCAN_TYPE_BURST_AVG, }; =20 +static const struct iio_scan_type ad4062_scan_type_12_s[] =3D { + [AD4062_SCAN_TYPE_SAMPLE] =3D { + .sign =3D 's', + .realbits =3D 12, + .storagebits =3D 16, + .endianness =3D IIO_BE, + }, + [AD4062_SCAN_TYPE_BURST_AVG] =3D { + .sign =3D 's', + .realbits =3D 14, + .storagebits =3D 16, + .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 16, + .endianness =3D IIO_BE, + }, + [AD4062_SCAN_TYPE_BURST_AVG] =3D { + .sign =3D 's', + .realbits =3D 20, + .storagebits =3D 32, + .endianness =3D IIO_BE, + }, +}; + static const unsigned int ad4062_conversion_freqs[] =3D { 2000000, 1000000, 300000, 100000, /* 0 - 3 */ 33300, 10000, 3000, 500, /* 4 - 7 */ @@ -105,6 +143,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; @@ -112,8 +151,10 @@ struct ad4062_state { struct regmap *regmap; int vref_uV; unsigned int samp_freqs[ARRAY_SIZE(ad4062_conversion_freqs)]; + bool gpo_irq[2]; u16 sampling_frequency; u8 oversamp_ratio; + u8 conv_sizeof; u8 conv_addr; union { __be32 be32; @@ -147,7 +188,7 @@ static const struct regmap_access_table ad4062_regmap_w= r_table =3D { .n_yes_ranges =3D ARRAY_SIZE(ad4062_regmap_wr_ranges), }; =20 -#define AD4062_CHAN { \ +#define AD4062_CHAN(bits) { \ .type =3D IIO_VOLTAGE, \ .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE) | \ @@ -158,18 +199,21 @@ static const struct regmap_access_table ad4062_regmap= _wr_table =3D { .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), \ } =20 static const struct ad4062_chip_info ad4060_chip_info =3D { .name =3D "ad4060", - .channels =3D { AD4062_CHAN }, + .channels =3D { AD4062_CHAN(12) }, .prod_id =3D AD4060_PROD_ID, .avg_max =3D 256, }; =20 static const struct ad4062_chip_info ad4062_chip_info =3D { .name =3D "ad4062", - .channels =3D { AD4062_CHAN }, + .channels =3D { AD4062_CHAN(16) }, .prod_id =3D AD4062_PROD_ID, .avg_max =3D 4096, }; @@ -334,8 +378,13 @@ static int ad4062_setup(struct iio_dev *indio_dev, str= uct iio_chan_spec const *c const bool *ref_sel) { struct ad4062_state *st =3D iio_priv(indio_dev); + const struct iio_scan_type *scan_type; int ret; =20 + scan_type =3D iio_get_current_scan_type(indio_dev, chan); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); + ret =3D 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, @@ -372,7 +421,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; } @@ -382,7 +434,55 @@ 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 xfer_sample =3D { + .data.in =3D &st->buf.be32, + .len =3D st->conv_sizeof, + .rnw =3D true, + }; + struct i3c_priv_xfer xfer_trigger =3D { + .data.out =3D &st->conv_addr, + .len =3D sizeof(st->conv_addr), + .rnw =3D false, + }; + + ret =3D i3c_device_do_priv_xfers(st->i3cdev, &xfer_sample, 1); + if (ret) + return; + + iio_push_to_buffers_with_ts(st->indio_dev, &st->buf.be32, st->conv_sizeof, + iio_get_time_ns(st->indio_dev)); + if (st->gpo_irq[1]) + return; + + i3c_device_do_priv_xfers(st->i3cdev, &xfer_trigger, 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_disable_ibi(void *data) @@ -433,10 +533,13 @@ static int ad4062_request_irq(struct iio_dev *indio_d= ev) if (ret =3D=3D -EPROBE_DEFER) return ret; =20 - if (ret < 0) + if (ret < 0) { + st->gpo_irq[1] =3D false; return regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, AD4062_REG_ADC_IBI_EN_CONV_TRIGGER, AD4062_REG_ADC_IBI_EN_CONV_TRIGGER); + } + st->gpo_irq[1] =3D true; =20 return devm_request_threaded_irq(dev, ret, ad4062_irq_handler_drdy, @@ -444,6 +547,34 @@ static int ad4062_request_irq(struct iio_dev *indio_de= v) indio_dev); } =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, /* 0 - 7 */ 256, 512, 1024, 2048, 4096, /* 8 - 12 */ @@ -478,6 +609,25 @@ static int ad4062_read_avail(struct iio_dev *indio_dev, } } =20 +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; + + /* + * In burst averaging mode the averaging filter accumulates resulting + * in a sample with increased precision. + */ + 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) / (MICRO / MILLI); /* signed */ + *val2 =3D scan_type->realbits - 1; + + return IIO_VAL_FRACTIONAL_LOG2; +} + static int ad4062_get_chan_calibscale(struct ad4062_state *st, int *val, i= nt *val2) { int ret; @@ -593,6 +743,9 @@ static int ad4062_read_raw(struct iio_dev *indio_dev, int ret; =20 switch (info) { + case IIO_CHAN_INFO_SCALE: + return ad4062_get_chan_scale(indio_dev, val, val2); + case IIO_CHAN_INFO_SAMP_FREQ: return ad4062_get_sampling_frequency(st, val); } @@ -641,6 +794,87 @@ static int ad4062_write_raw(struct iio_dev *indio_dev, return ret; } =20 +/* + * The AD4062 in burst averaging mode increases realbits from 16-bits to + * 20-bits, increasing the storagebits from 16-bits to 32-bits. + */ +static inline size_t ad4062_sizeof_storagebits(struct ad4062_state *st) +{ + const struct iio_scan_type *scan_type =3D + iio_get_current_scan_type(st->indio_dev, st->chip->channels); + + return BITS_TO_BYTES(scan_type->storagebits); +} + +/* Read registers only with realbits (no sign extension bytes) */ +static inline size_t ad4062_get_conv_addr(struct ad4062_state *st, size_t = _sizeof) +{ + if (st->gpo_irq[1]) + return _sizeof =3D=3D sizeof(u32) ? AD4062_REG_CONV_READ_32BITS : + AD4062_REG_CONV_READ_16BITS; + return _sizeof =3D=3D sizeof(u32) ? AD4062_REG_CONV_TRIGGER_32BITS : + AD4062_REG_CONV_TRIGGER_16BITS; +} + +static int pm_ad4062_triggered_buffer_postenable(struct ad4062_state *st) +{ + int ret; + + PM_RUNTIME_ACQUIRE(&st->i3cdev->dev, pm); + ret =3D PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + ret =3D ad4062_set_operation_mode(st, st->mode); + if (ret) + return ret; + + st->conv_sizeof =3D ad4062_sizeof_storagebits(st); + st->conv_addr =3D ad4062_get_conv_addr(st, st->conv_sizeof); + /* CONV_READ requires read to trigger first sample. */ + struct i3c_priv_xfer xfer_sample[2] =3D { + { + .data.out =3D &st->conv_addr, + .len =3D sizeof(st->conv_addr), + .rnw =3D false, + }, + { + .data.in =3D &st->buf.be32, + .len =3D sizeof(st->buf.be32), + .rnw =3D true, + } + }; + + return i3c_device_do_priv_xfers(st->i3cdev, xfer_sample, + st->gpo_irq[1] ? 2 : 1); +} + +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_ad4062_triggered_buffer_postenable(st); + if (ret) + return ret; + + pm_runtime_get_noresume(&st->i3cdev->dev); + return 0; +} + +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) { @@ -652,10 +886,21 @@ static int ad4062_debugfs_reg_access(struct iio_dev *= indio_dev, unsigned int reg return regmap_write(st->regmap, reg, writeval); } =20 +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, }; =20 @@ -762,6 +1007,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) @@ -774,6 +1030,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 devm_work_autocancel(dev, &st->trig_conv, ad4062_trigger_work); + if (ret) + return ret; + return devm_iio_device_register(dev, indio_dev); } =20 --=20 2.51.1 From nobody Thu Dec 18 10:58:09 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 45DBC342CB0; Wed, 17 Dec 2025 12:14:22 +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=1765973664; cv=none; b=Zi3wFjndLRCAWd/w7SdWOD3lGnroBZATCx//yXplJv2yGoUfoUCfKP3trw8B6cYt9L1ej6cs8Oti19FnDb3swToifpxa1M3Fcyt4IpECrtqTJ8vW04KlFG+7O5qmHJuqWxf0ZLeg6gpkm59W38xfX73UGilukYMCC2Y2yMIK1Io= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765973664; c=relaxed/simple; bh=fyI5mimULp3XgcPi56o1DTpa5TxXCpPMzp3xNKiC0zI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=RIhjT21v+ZSywq9zzEyfZrx+UArK5dd2SZKnhMJpyJqjgSUK8WO2OEZXqhOGxshE5d1vgKk+/gVNTWehFhII904dREM+ns+8l3DCUJXxTsP+OWWBSZyZeBVYq7TyEA5X7fDTTNEL1elKK4t5s9ZDrI1FQoOHGtHjo9eGWvn8fbA= 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=x75ZIWV9; 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="x75ZIWV9" 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 5BH8SXrn3979344; Wed, 17 Dec 2025 07:14:01 -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=JbhBG 99E83UqESzQ32vc9RiIs22UMws2gIJLz89/fyI=; b=x75ZIWV9kOBU4wBxvPfgt HvKvmP7Cls/78gIq2aVQaR0V3lJwt8mDUTYH16yzy6MbXAU8WhkXc8I4JK/JqWbq Ka9mbJHdJxPlZ9S9KdrFhonjZoTCtFSugSXIvOUtzag5/D34oPQmik1xNCNwOAnV Jld3EqgEdYwR8UKiXXt68L0jPmqtYcS/xUvWB9VQS4iSi6bQB3LI4SOYFOVgnVTX 7Y/BBAPZQKUelrELhG/PhX5SNdZDZUtajxgj7yQJOqeb0CY/iAhPFm+s9VeIVzEP 4SJIE5k2g16EcUPsLSJJ33gztx+RDw505QIcXMnec2NhyMvKXabbXCFkyeDTPmUn Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4b3bbevk6b-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 17 Dec 2025 07:14:00 -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 5BHCDxTO041108 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 17 Dec 2025 07:13:59 -0500 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) 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; Wed, 17 Dec 2025 07:13:59 -0500 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) 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; Wed, 17 Dec 2025 07:13:59 -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; Wed, 17 Dec 2025 07:13:59 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.73]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5BHCDUvC014815; Wed, 17 Dec 2025 07:13:51 -0500 From: Jorge Marques Date: Wed, 17 Dec 2025 13:13:29 +0100 Subject: [PATCH v4 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: <20251217-staging-ad4062-v4-6-7890a2951a8f@analog.com> References: <20251217-staging-ad4062-v4-0-7890a2951a8f@analog.com> In-Reply-To: <20251217-staging-ad4062-v4-0-7890a2951a8f@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=1765973610; l=2816; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=fyI5mimULp3XgcPi56o1DTpa5TxXCpPMzp3xNKiC0zI=; b=n+fFm/A4fzfxg4GCV0+SoIdOmW9cqpy+xvpYG2kImHbQV9ZVfISofSc+NuISFYxQnu/rb+Uz6 HC9DFqkLAFgDOULJyLqpJ2x+WkphOz9gK6EQU66EpBdBK1ASaRLCd+r X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: LYtmni-30NM7F9igFN9ubYRqSV7ir1yO X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE3MDA5NSBTYWx0ZWRfX3a9SgOE/J12a Q5lY4BKuxfhu1mmXxgJOkzz5jtTIUNmGIIc/xkzf2Gd/zM3Au/w+dz3xA67zzpj3zGlG/bG3EoA O0Zr2RvfbXR5WlnszbWx5qXBKFr0dsd00bd1k6Zl1uVmLhEeWfsAcQTdMcP/Okf0fRyj262NKcA dxVW8LQYhqgmX2hHKdXkgIf+pm3b/JVZ+feB+d/jshz5ws47l48Qh1wAy/6XfpEwN5AmLqk4oAD l0p4+pcaLFjb+LLYCbiJGxsxzHdN6bSZOZg1WBBmjIsYp3O960GgFtk+47cgZgaDajfPNXezC4j 9NiZs3QAuWRwDsAAjskuDr29sTTm+v48FOvljLsrYqw/CE0xOWIEya8aJVDI9SdsQ7lm+8wAK3l MU10iuLTBCZ8cedbdMGVR8HNuVhQIw== X-Authority-Analysis: v=2.4 cv=YqsChoYX c=1 sm=1 tr=0 ts=69429e88 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=RvCAy4sPJie4B97SFe0A:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: LYtmni-30NM7F9igFN9ubYRqSV7ir1yO 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-12-17_01,2025-12-16_05,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 malwarescore=0 bulkscore=0 suspectscore=0 lowpriorityscore=0 phishscore=0 impostorscore=0 clxscore=1015 adultscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512170095 Explains the IIO Events support. Signed-off-by: Jorge Marques --- Documentation/iio/ad4062.rst | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/Documentation/iio/ad4062.rst b/Documentation/iio/ad4062.rst index 12ac16dfc3028..8d388f9e2f450 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 @@ -97,3 +100,37 @@ The acquisition is sequential and bounded by the protoc= ol 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. + +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. --=20 2.51.1 From nobody Thu Dec 18 10:58:09 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 D5324340DAD; Wed, 17 Dec 2025 12:14:19 +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=1765973662; cv=none; b=J+P63WDc1dHwrrSjgf1+fdngUbEc0i1NkkZ1qPgFIthgsOyZX3IvlTvBwJ2saZfQYh8uUjIC4GdTNvwC9I7jXLSYIwbKR0CWbxboMtvLzVtsbD+nmNm896D0ElCYRSh9urr0oH3OoWHvt07qTfJpNhYcVrtKZBY/R2juRadTwAY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765973662; c=relaxed/simple; bh=c5sxELgxedBXy9/Ij3kKXZWr3/c8v9Q6WMmKuYjKC5o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=njyBlSt9zsAEO2H7zJvui/sSszdIY17dIyp7iD09kt0xG9ei68cormguVnOXmmqydCMGXuZZu+xQlG8OEAYNYCeHV5PzxM+7+Nf4CjSgfKXESuJclDKD4JP5YZwr4CpQYpv7njTNcSeb5GSmL8Q+EmjZwdrye+A9q2oSNCvND+c= 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=kbVKa8X/; 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="kbVKa8X/" 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 5BH9aYqg964276; Wed, 17 Dec 2025 07:14:03 -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=lDKvg UzCvseni4RnfEC198s9SBS1tFxpX7x/zdIz5Z4=; b=kbVKa8X/qL4TRTz+nDpMy 3dX3ranY5AxEQpJZ3hM9JuAcMpd/YbNFKJnglCxxLZUm0ljv1Q201EuIf8u8L1Yk XBRX6ze8oJa8p3xx0ISpjpmeE45VLwrx1JzHmNfeIy+3Rfl4nidtfpJtAOdiIx0B OsadlPMcJf3Ls+CcdsztAjUMFocttEBkdZ9uexdbWM6GA4vojOfvD6ywrQzM3wA2 8tYRJr7XOkL1yQ9ntvv5ynMdetTRzR03HbvgoF/ktt2g6v+sgyEDTHbYLfi6WKGO icQyJiXDpFXFz1tv9jBAPMpxpGHK1Yr6uPcnEnkVXs5oagbFwezW8OL32UpNFWcy g== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4b3jt2thqq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 17 Dec 2025 07:14:03 -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 5BHCE2Wb041117 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 17 Dec 2025 07:14:02 -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; Wed, 17 Dec 2025 07:14:01 -0500 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) 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; Wed, 17 Dec 2025 07:14:01 -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; Wed, 17 Dec 2025 07:14:01 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.73]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5BHCDUvD014815; Wed, 17 Dec 2025 07:13:53 -0500 From: Jorge Marques Date: Wed, 17 Dec 2025 13:13:30 +0100 Subject: [PATCH v4 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: <20251217-staging-ad4062-v4-7-7890a2951a8f@analog.com> References: <20251217-staging-ad4062-v4-0-7890a2951a8f@analog.com> In-Reply-To: <20251217-staging-ad4062-v4-0-7890a2951a8f@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=1765973610; l=17372; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=c5sxELgxedBXy9/Ij3kKXZWr3/c8v9Q6WMmKuYjKC5o=; b=o9KNm64Ei5wL3Ycn4jYOfLwiH5eWBl598nFvjuPsAh+8sii4yYG7WK6pEk9bpWrUV6+wRp4yE XGdWkqwcqYuC/uFc4V0yp4WhOrDfrIWCnltSQpkhIbRJTHTSC1Qrhcj X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: sxj_IoQzF0gH5z0LEd3mZtSroXNlQCri X-Authority-Analysis: v=2.4 cv=Ct6ys34D c=1 sm=1 tr=0 ts=69429e8b cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=ctgkBTGrW6sVLClIBwcA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: sxj_IoQzF0gH5z0LEd3mZtSroXNlQCri X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE3MDA5NSBTYWx0ZWRfXyhoKX3g30VIp tUxTAJXVsXFQUwPgBeyMr/u82rLhkafSlvdUvTy50FjO2uhvGp2gp7GfsJTFwP23VD1CDQthKC4 SmM/sb7Rgkg2y8MiHXtghRhlHw6RlDbG+tDtnGh0PdTw6sZgGXhfoSbFha/qB4E0geTXGb4w9GJ LlqRzz9tuyz1VKREHiOHYSceFdCsGGfBoVC4NBHWuYMmHQAmGpCFDUz0vfmLKC0J7FBU8xEhWY0 WilyZvpWuDAV/F2HobKkuTyk/jpEMP/ZVD6fO0yQjDWs+SinXd7iaF8LAKd3KjpPnK2dv56sj8M LOTmZ2cmDEddWSBmib2r7SaCpg/tY6OcbamV0NMyY/paIjg3c5lcl4P+MDdxLMNg2RulZXsm5dJ H3/5tK4sVEdxC20lZJ96XGhkdsdGbQ== 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-12-17_01,2025-12-16_05,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 spamscore=0 adultscore=0 priorityscore=1501 phishscore=0 suspectscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512170095 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 | 407 +++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 406 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad4062.c b/drivers/iio/adc/ad4062.c index afc8b6969cf08..2084f0058627d 100644 --- a/drivers/iio/adc/ad4062.c +++ b/drivers/iio/adc/ad4062.c @@ -14,7 +14,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -51,14 +53,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) @@ -78,9 +88,13 @@ #define AD4060_PROD_ID 0x7A #define AD4062_PROD_ID 0x7C =20 +#define AD4062_GP_INTR 0x1 #define AD4062_GP_DRDY 0x2 =20 +#define AD4062_LIMIT_BITS 12 + #define AD4062_INTR_EN_NEITHER 0x0 +#define AD4062_INTR_EN_EITHER 0x3 =20 #define AD4062_TCONV_NS 270 =20 @@ -149,10 +163,12 @@ struct ad4062_state { struct iio_dev *indio_dev; struct i3c_device *i3cdev; struct regmap *regmap; + bool wait_event; int vref_uV; unsigned int samp_freqs[ARRAY_SIZE(ad4062_conversion_freqs)]; bool gpo_irq[2]; u16 sampling_frequency; + u16 events_frequency; u8 oversamp_ratio; u8 conv_sizeof; u8 conv_addr; @@ -188,6 +204,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), + }, +}; + #define AD4062_CHAN(bits) { \ .type =3D IIO_VOLTAGE, \ .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_RAW) | \ @@ -199,6 +235,8 @@ static const struct regmap_access_table ad4062_regmap_w= r_table =3D { .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), \ @@ -218,6 +256,73 @@ static const struct ad4062_chip_info ad4062_chip_info = =3D { .avg_max =3D 4096, }; =20 +static ssize_t sampling_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 int sampling_frequency_store_dispatch(struct iio_dev *indio_dev, + const char *buf) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int val, ret; + + if (st->wait_event) + return -EBUSY; + + ret =3D kstrtoint(buf, 10, &val); + if (ret) + return ret; + + st->events_frequency =3D find_closest_descending(val, ad4062_conversion_f= reqs, + ARRAY_SIZE(ad4062_conversion_freqs)); + return 0; +} + +static ssize_t sampling_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); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret =3D sampling_frequency_store_dispatch(indio_dev, buf); + iio_device_release_direct(indio_dev); + return ret ?: len; +} + +static IIO_DEVICE_ATTR_RW(sampling_frequency, 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, int val,= int val2) { const u32 _max =3D st->chip->avg_max; @@ -344,9 +449,11 @@ static int ad4062_conversion_frequency_set(struct ad40= 62_state *st, u8 val) static int ad4062_set_operation_mode(struct ad4062_state *st, enum ad4062_operation_mode mode) { + const unsigned int samp_freq =3D mode =3D=3D AD4062_MONITOR_MODE ? + st->events_frequency : st->sampling_frequency; int ret; =20 - ret =3D ad4062_conversion_frequency_set(st, st->sampling_frequency); + ret =3D ad4062_conversion_frequency_set(st, samp_freq); if (ret) return ret; =20 @@ -355,6 +462,17 @@ static int ad4062_set_operation_mode(struct ad4062_sta= te *st, if (ret) return ret; =20 + if (mode =3D=3D AD4062_MONITOR_MODE) { + /* Change address pointer to enter monitor mode */ + struct i3c_priv_xfer xfer_trigger =3D { + .data.out =3D &st->conv_addr, + .len =3D sizeof(st->conv_addr), + .rnw =3D false, + }; + st->conv_addr =3D AD4062_REG_CONV_TRIGGER_32BITS; + return i3c_device_do_priv_xfers(st->i3cdev, &xfer_trigger, 1); + } + return regmap_write(st->regmap, AD4062_REG_MODE_SET, AD4062_REG_MODE_SET_ENTER_ADC); } @@ -385,6 +503,13 @@ 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 + ret =3D 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, + AD4062_GP_INTR)); + if (ret) + return ret; + ret =3D 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, @@ -404,6 +529,13 @@ static int ad4062_setup(struct iio_dev *indio_dev, str= uct iio_chan_spec const *c if (ret) return ret; =20 + ret =3D regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, + AD4062_REG_INTR_CONF_EN_MSK_0, + FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_0, + AD4062_INTR_EN_EITHER)); + if (ret) + return ret; + ret =3D regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, AD4062_REG_INTR_CONF_EN_MSK_1, FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_1, @@ -416,6 +548,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; @@ -434,6 +579,14 @@ static void ad4062_ibi_handler(struct i3c_device *i3cd= ev, { struct ad4062_state *st =3D i3cdev_get_drvdata(i3cdev); =20 + 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)); + return; + } if (iio_buffer_enabled(st->indio_dev)) iio_trigger_poll_nested(st->trigger); else @@ -529,6 +682,25 @@ 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; + + 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; @@ -720,6 +892,9 @@ static int ad4062_read_chan_raw(struct ad4062_state *st= , int *val) static int ad4062_read_raw_dispatch(struct ad4062_state *st, int *val, int *val2, long info) { + if (st->wait_event) + return -EBUSY; + switch (info) { case IIO_CHAN_INFO_RAW: return ad4062_read_chan_raw(st, val); @@ -761,6 +936,9 @@ static int ad4062_read_raw(struct iio_dev *indio_dev, static int ad4062_write_raw_dispatch(struct ad4062_state *st, int val, int= val2, long info) { + if (st->wait_event) + return -EBUSY; + switch (info) { case IIO_CHAN_INFO_OVERSAMPLING_RATIO: return ad4062_set_oversampling_ratio(st, val, val2); @@ -789,7 +967,224 @@ static int ad4062_write_raw(struct iio_dev *indio_dev, return -EBUSY; =20 ret =3D ad4062_write_raw_dispatch(st, val, val2, info); + iio_device_release_direct(indio_dev); + return ret; +} + +static int pm_ad4062_monitor_mode_enable(struct ad4062_state *st) +{ + int ret; + + PM_RUNTIME_ACQUIRE(&st->i3cdev->dev, pm); + ret =3D PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + return ad4062_set_operation_mode(st, AD4062_MONITOR_MODE); +} + +static int ad4062_monitor_mode_enable(struct ad4062_state *st) +{ + int ret; + + ret =3D pm_ad4062_monitor_mode_enable(st); + if (ret) + return ret; + + pm_runtime_get_noresume(&st->i3cdev->dev); + return 0; +} =20 +static int ad4062_monitor_mode_disable(struct ad4062_state *st) +{ + pm_runtime_put_autosuspend(&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_dispatch(struct iio_dev *indio_dev, + bool state) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (st->wait_event =3D=3D state) + ret =3D 0; + else if (state) + ret =3D ad4062_monitor_mode_enable(st); + else + ret =3D ad4062_monitor_mode_disable(st); + if (ret) + return ret; + + st->wait_event =3D state; + return 0; +} + +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) +{ + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret =3D ad4062_write_event_config_dispatch(indio_dev, state); + 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(be16_to_cpu(st->buf.be16), AD4062_LIMIT_BITS - 1); + + 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_config_dispatch(struct iio_dev *indio_dev, + enum iio_event_direction dir, + enum iio_event_info info, int *val) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + + if (st->wait_event) + return -EBUSY; + + switch (info) { + case IIO_EV_INFO_VALUE: + return __ad4062_read_event_info_value(st, dir, val); + case IIO_EV_INFO_HYSTERESIS: + return __ad4062_read_event_info_hysteresis(st, dir, val); + default: + return -EINVAL; + } +} + +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) +{ + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret =3D ad4062_read_event_config_dispatch(indio_dev, dir, info, val); + iio_device_release_direct(indio_dev); + return 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 !=3D sign_extend32(val, AD4062_LIMIT_BITS - 1)) + return -EINVAL; + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4062_REG_MAX_LIMIT; + else + reg =3D AD4062_REG_MIN_LIMIT; + st->buf.be16 =3D cpu_to_be16(val); + + 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 > BIT(7) - 1) + 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_dispatch(struct iio_dev *indio_dev, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int val) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + + if (st->wait_event) + return -EBUSY; + + switch (type) { + case IIO_EV_TYPE_THRESH: + switch (info) { + case IIO_EV_INFO_VALUE: + return __ad4062_write_event_info_value(st, dir, val); + case IIO_EV_INFO_HYSTERESIS: + return __ad4062_write_event_info_hysteresis(st, dir, val); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +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) +{ + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret =3D ad4062_write_event_value_dispatch(indio_dev, type, dir, info, val= ); iio_device_release_direct(indio_dev); return ret; } @@ -825,6 +1220,9 @@ static int pm_ad4062_triggered_buffer_postenable(struc= t ad4062_state *st) if (ret) return ret; =20 + if (st->wait_event) + return -EBUSY; + ret =3D ad4062_set_operation_mode(st, st->mode); if (ret) return ret; @@ -900,6 +1298,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, }; @@ -980,8 +1383,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 0; st->indio_dev =3D indio_dev; =20 --=20 2.51.1 From nobody Thu Dec 18 10:58:09 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 7AC0C34165F; Wed, 17 Dec 2025 12:14:21 +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=1765973663; cv=none; b=bmSRfk2OeLlF9+/bEHl4s5wmbcHRIxAvpJKzoDDbHmN3K5/NlMJSQKAPsj/LYxg0l4AguHEaGYfGaKCTUES/7WtEexSGhQ/GSiBuWDkykvBRX/A5NltrXizo6IwXBGI+zE6YcDCSzIL0WaMzRDeERLA/9nsLlbpKsxarU+HpgL8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765973663; c=relaxed/simple; bh=DaaLNQLpb3vDc1eYDeL/oEoMbkwxl9yfrm8dY/iu+eE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=HfFCM10Ec0X3jTZ/6uNr41M+2ZJW0+jfuopZaN/nsuuiAI4FJMKMNgZtIhZ6rw4LpWbiEpRJYQ0dTS14MwPg0r1pfHGe60gZ3KJQicUzxvsQn46xMYBLbrKclqXoPfQ0UsE6LiCOnReZBT70ig6CwSVUgZLzEWUE8Li6UxCQU8w= 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=bD+uDH/Y; 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="bD+uDH/Y" 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 5BHAqqxt3839561; Wed, 17 Dec 2025 07:14:05 -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=0fNzO ZMS1MeY6GqG5tP+I0AoDb+uwPRd0H1aFV5RFRk=; b=bD+uDH/Yk0k/JinWsc2jb i77iAm5I5qA2hn/0h4Al3v0CzGfGxxk3AiYohqDWVB8KE+i2Vn9ZWSwhhW16DFNd v84pt/t0ad3VPi1dPGDwCgRmpufAJ8YAweXo0pm0cVCsnWHYJQHWTaWCYh+qHtWR uIwY8x/oi43WaBRIleA5J8ZxfMCH6+hEavfwiFZgZWnD+avuz/30P3vu2mRCe2PG 77QAPGOE7daQdbQvqNwXd+fbzSl56kK98pkFyjnT03TnrFEp2C/R1dIM1ARGBFSh gpMYjgonfPHFIGsTxyAektfLZYqKk+9zN3vVFUQz7x3pnkMaDexP3QJwjzpCOjWS A== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 4b3jw9jehb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 17 Dec 2025 07:14:05 -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 5BHCE40A041121 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 17 Dec 2025 07:14:04 -0500 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) 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; Wed, 17 Dec 2025 07:14:04 -0500 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) 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; Wed, 17 Dec 2025 07:14:04 -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; Wed, 17 Dec 2025 07:14:04 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.73]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5BHCDUvE014815; Wed, 17 Dec 2025 07:13:55 -0500 From: Jorge Marques Date: Wed, 17 Dec 2025 13:13:31 +0100 Subject: [PATCH v4 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: <20251217-staging-ad4062-v4-8-7890a2951a8f@analog.com> References: <20251217-staging-ad4062-v4-0-7890a2951a8f@analog.com> In-Reply-To: <20251217-staging-ad4062-v4-0-7890a2951a8f@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 , "Linus Walleij" X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1765973610; l=1479; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=DaaLNQLpb3vDc1eYDeL/oEoMbkwxl9yfrm8dY/iu+eE=; b=Fec71dDvyVAzEylQQv6z6ZB1seqgWqpnZDppwFKLL6ere58wMAPgClC3o7yxTX8nQBFGFVBlf Pn1d14NFr3uDIIc/gDChfV2ntQDvBZ4zODnBkV6+20Tt9XqBQykcKa7 X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE3MDA5NSBTYWx0ZWRfX0W6XscDXYt4E 3Ppwy/HB+Ygd8LvJ7xeUomge9mbuKWJAB24x01k2tgwWtDB7Ss3LgbIPx+Ug97FjthY7pzZCtMh P6tkToA5EKUYa+hHq1GvhWVsTdToa4ipOewUkQP0VCOYaRUYpfu/oX0yRDIHLyChg+VnEetx374 Mwcstg8FB04UZ0COTQP/4C1QxF9eXQcTUGWw1m38RvKXfOoS5KPMaPNZi104arB0LovC3xzWcV8 fNY9qezTSuIICcZ6snm+DIhG3a1Hf0gBLDJGvZ+wfsSlRzxKu8LmwYbmbkX6BSBV/kJqrxLd1Bf 0tVVB/8ixiAPn8rgzLUtJm8bgmAIoRykgvaVIY0R49m74i3yAgpmRCeBi6LOn8rLoSSRGTwvVVX Aj0f/vdRf3LsRmVq76t9vwG0SCljbw== X-Authority-Analysis: v=2.4 cv=TZGbdBQh c=1 sm=1 tr=0 ts=69429e8d cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=EBGExmvx8FPMp0bAM4MA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: JIQs7TvOEAiN6CFmOHymmSn14qwfMAGa X-Proofpoint-ORIG-GUID: JIQs7TvOEAiN6CFmOHymmSn14qwfMAGa 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-12-17_01,2025-12-16_05,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 adultscore=0 impostorscore=0 spamscore=0 priorityscore=1501 bulkscore=0 lowpriorityscore=0 clxscore=1011 malwarescore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512170095 Explains the GPIO controller support with emphasis on the mask depending on which GPs are exposed. Signed-off-by: Jorge Marques Reviewed-by: Linus Walleij --- Documentation/iio/ad4062.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Documentation/iio/ad4062.rst b/Documentation/iio/ad4062.rst index 8d388f9e2f450..d77287836430c 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 @@ -134,3 +137,12 @@ The following event attributes are available: - Set the hysteresis value for the maximum threshold. * - ``thresh_rising_value`` - Set the maximum threshold value. + +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. --=20 2.51.1 From nobody Thu Dec 18 10:58:09 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 DF7593446C0; Wed, 17 Dec 2025 12:14:24 +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=1765973666; cv=none; b=FjnFOLA++RpjMDDOPcmht0Yyx3mLhgI5C7COG9Rl0PJlRhhKBxeBYDO7wUjiqWX5y5I6jItc75coo4bl+xBkdib0Uh5K0xT1EHK/1ZmgzDKfn6z7I+/afLmLLK2cdLzUkCKbCLlGzv+557641iVe2BHHtDhp7LPBGjMRITERrq4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765973666; c=relaxed/simple; bh=rWhz1qhXX5cZm+GWRaQ9ciBLBk8IoCqoYZlI/GtAfiU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=lljBBkP4ko5LLJL/1Q+9XdeixaOgSh4vBSG4LQWsrrHVGazAhFDBILgB16X9HhwGJeVHcqcsdujaK8wtpDmu7uEDAjyFXxvcBO/04co3pnDQ0ZtJzlYMq+yGAaoEp7e/SFAez0WLzWGvBKzAeUmGe1XUtKjnwRxw2m4xlytmN4I= 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=sgeD5y49; 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="sgeD5y49" 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 5BHC7Tx23978997; Wed, 17 Dec 2025 07:14:07 -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=KHwHt qQuusmzdK7NM7ocl1bh8RRVDH4lMJb8lzPokRI=; b=sgeD5y490ivnBlHVayFX6 NxU5z7mRE39VNGYf1AVEE2q2y7ZHQTQrBy+usEJTmkyy+iLiM12J4NKNU/0a0dbk OlLUDHDMnKkjg1gUYNWGLcFzXbWyurXUHNNZrNutRnJPiH7JxWIwYb176seDP2x6 w4DOPBhVWHwUWfVEfMIHeZgR/CInXW9vUatvb4u8XSJePFY2TGEiyrvJltGr5MXI GAEcmi2hkuy3R/AR9l86+lZN02pLwtj7ZONlANTGATNNN7wCK/YF+dHduQWnozKq WQX9d2FLLgxS2p7yK5KORlQoKcXs0lLvSyPZlN6f/U8pBGaYVrft2iEAuBuDAWES Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4b3bbevk6u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 17 Dec 2025 07:14:07 -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 5BHCE6FF041126 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 17 Dec 2025 07:14:06 -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; Wed, 17 Dec 2025 07:14:06 -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; Wed, 17 Dec 2025 07:14:06 -0500 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.73]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 5BHCDUvF014815; Wed, 17 Dec 2025 07:13:57 -0500 From: Jorge Marques Date: Wed, 17 Dec 2025 13:13:32 +0100 Subject: [PATCH v4 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: <20251217-staging-ad4062-v4-9-7890a2951a8f@analog.com> References: <20251217-staging-ad4062-v4-0-7890a2951a8f@analog.com> In-Reply-To: <20251217-staging-ad4062-v4-0-7890a2951a8f@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 , Linus Walleij X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1765973610; l=5630; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=rWhz1qhXX5cZm+GWRaQ9ciBLBk8IoCqoYZlI/GtAfiU=; b=h16QtNehE13q2APVGRNCeEMKpMfldJrbGJvTDRVuABLEbYt7oxYkLRAKNQmg8+ALzaizen8Ym oTUbxYvehAQAfOzzKGbEuTXlBrnsFx/opjcwaZoxHAsuIZrsrWNLFup X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: ckUSgF4LPP59bHdYNifnVx-5YPN-zhUu X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMjE3MDA5NSBTYWx0ZWRfX6dHUfdknNgPL 9FVSstJkgNDxfckZxjcWQB2/JmskCToaAi252B97jS86QmiMPPZOOZUUO7pLeJnELJTFScuMOBQ gt5ZGmYRyIUsq/hlrSzIXyWwCko4hl9gxChnxYKNeCm2EC/t5P6ApxQbtkMP9ZF1wzdrR7Vz9Rg OmSiLmbGzLujoio7rGtGkzsqQ7AZKD9Ts5RlRDcjgeGHFSo1bTjMMdQ/YVIQsZWjmoLJbnDmemq iDcNQgvbw/IlYgB9Xj9xzhVqOKee2zw9fbptimU5YqNWcbQ+ZGmAMDV/Fsgzv3ktlpmhhkjMyO7 0y6T4xArldYx3tBAetS4ADcVeZ/4/mp3i1/S9kd0I2+HEBoWE68w6C6PJ2mSeSm4VS2nee2dY5q ASsFPXI1zFvjycYpCs5DSh0VzMHs2A== X-Authority-Analysis: v=2.4 cv=YqsChoYX c=1 sm=1 tr=0 ts=69429e8f cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=wP3pNCr1ah4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=xMyuZJbwAj7bCYiyej4A:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: ckUSgF4LPP59bHdYNifnVx-5YPN-zhUu 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-12-17_01,2025-12-16_05,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 malwarescore=0 bulkscore=0 suspectscore=0 lowpriorityscore=0 phishscore=0 impostorscore=0 clxscore=1011 adultscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2510240001 definitions=main-2512170095 When gp0 or gp1 is not taken as an interrupt, expose them as GPO if gpio-contoller is set in the devicetree. gpio-regmap is not used because the GPO static low is 'b101 and static high is 0b110; low state requires setting bit 0, not fitting the abstraction of low=3D0 and high=3Dmask. Signed-off-by: Jorge Marques Reviewed-by: Linus Walleij Acked-by: Bartosz Golaszewski --- drivers/iio/adc/ad4062.c | 125 +++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 125 insertions(+) diff --git a/drivers/iio/adc/ad4062.c b/drivers/iio/adc/ad4062.c index 2084f0058627d..a6b3ccc98acfc 100644 --- a/drivers/iio/adc/ad4062.c +++ b/drivers/iio/adc/ad4062.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -88,8 +89,11 @@ #define AD4060_PROD_ID 0x7A #define AD4062_PROD_ID 0x7C =20 +#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 =20 #define AD4062_LIMIT_BITS 12 =20 @@ -687,12 +691,14 @@ static int ad4062_request_irq(struct iio_dev *indio_d= ev) return ret; =20 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, @@ -1347,6 +1353,121 @@ 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 (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 ret; + + 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; +} + +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); + + for (unsigned int i =3D 0; i < ARRAY_SIZE(st->gpo_irq); i++) + __assign_bit(i, valid_mask, !st->gpo_irq[i]); + + 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 (!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_PROD_ID, &ad4060_chip_info), I3C_DEVICE(AD4062_I3C_VENDOR, AD4062_PROD_ID, &ad4062_chip_info), @@ -1435,6 +1556,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; + ret =3D devm_work_autocancel(dev, &st->trig_conv, ad4062_trigger_work); if (ret) return ret; --=20 2.51.1