From nobody Fri Dec 19 13:50:54 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 1957D2E88B6; Mon, 13 Oct 2025 07:29:16 +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=1760340558; cv=none; b=GLMNfztAyKtEfziPFonrEvyG4t2WkJhxTsWkVw4gJ3G9kerGWNmnRDDbQc0L+2g5lOfPj2+eIjRaZPML2D6X4oENM6N+pfmyxn68uI9VQ7WCRH2/2Zk8sguU9UcbcxlUI1890odv0lAtKpo51gr1m7P+1kUFYUhori3IMXp73Zg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760340558; c=relaxed/simple; bh=zq4HJPH4Ik+VrMB3jcqaZGYWresdPxYsty42M68jY7Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=GRmODgUvmGXAES5RcSAytl1RVYsaJbgPd3Q+DToHRu2Dv8f3ire4dRCJxV2hKrTmnW/7uN5xPJJRnshbEAgdrP57ARD/m4lqGkZYJW2Tdu+z3MXo35zQMyOaj7LRuRZP8eYNFj6dz4C3JBe5x0Uex8CSeZucyx+o8piwX6LqcKE= 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=Unp2aP/w; 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="Unp2aP/w" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 59D3xRbi008597; Mon, 13 Oct 2025 03:28:59 -0400 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=9KuYT UaBvHffgKSRdReIO44fW1IH7BW2farRK236LoM=; b=Unp2aP/wDZ+ti/A8q8mrO jGkbz6gL2RIkhIp085PaC51/i5X1Jx6Rq0d6yDAOOJWLoa2yHHcFj2+5/ffDmmDl eaXQEY6m8bm/ZTlTvsUB3IbgUQky+CooIyMft/3CndYtkMB1rKK5v5gdywU5U2UB LpcX7h3MPpPQYbW1rMCl4bAamjqJM9daWjwdY/tFJ03oiy6QeD0FsH9k30zanKot kLbrnTpd44MK0vToZfH5bptEub5PXy5331//0cbRDtebIsDVRF7hu7/SCtT8NA0H WpFCxV8s+ucvyl/Qp9TpN22iUHABOwo3YRk9WYQJYS+BEhjveR0MBA1InNrEp6xR Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 49qm508agh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 13 Oct 2025 03:28:59 -0400 (EDT) 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 59D7Swuf022856 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 13 Oct 2025 03:28:58 -0400 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; Mon, 13 Oct 2025 03:28:57 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 13 Oct 2025 03:28:57 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 13 Oct 2025 03:28:57 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.56]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 59D7ShZ7013800; Mon, 13 Oct 2025 03:28:51 -0400 From: Jorge Marques Date: Mon, 13 Oct 2025 09:27:59 +0200 Subject: [PATCH 1/7] 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: <20251013-staging-ad4062-v1-1-0f8ce7fef50c@analog.com> References: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@analog.com> In-Reply-To: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@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 CC: , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1760340523; l=3739; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=zq4HJPH4Ik+VrMB3jcqaZGYWresdPxYsty42M68jY7Q=; b=JF/8DXxclaNzQF/SQ4zh0wPx2IluN0WOV2nckQx1MSD5AHmmEcIr+/dBfaAeS9R57FCuiBw5A axkF7965+hVCk4MLryoeN8U5xjtmU/3fGnOSRxT8dG8CH28v5UNgePG X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=cJ7tc1eN c=1 sm=1 tr=0 ts=68ecaa3b cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=x6icFKpwvdMA:10 a=gEfo2CItAAAA:8 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=rxM01w5YshE-YhStUuUA:9 a=QEXdDO2ut3YA:10 a=sptkURWiP4Gy88Gu7hUp:22 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDExMDA0NyBTYWx0ZWRfX/eldlg+o2QUs M4LIYD6S+3HlJIeQvyLTAyipuuEz85pOWRJju4SoDjin48BXQioOFOAtzn91719f9SiEeLWhI49 JLC1UahKfqwym1mOyLwil3Z6tUhwAft14m+T6FmdvnFPr4U+zxj+qY4z9sTyvwyfFcdpwO8Wqu6 myZxIXBzHZR8zmEf42HQ6h+DpJ4MXSJCrUNRkFhL6i4T7y5LaRqyxI70xTNr8SuiQB9sfEeorSa +gU2/32GGWXcD3fpcj8qPA6SJUWKSEf3SI+Yd6hpuEEcjPXah3lIryXfwi755fuptnngSKxDGRU eT5hTB4MWdoDPyBV3OTnAgYHzl9Fg/aZLNn3qNHLHj/hnnL54lpZEac/TXnu3yJI07Z8+ruaITS Wv9qRZ780V8vvRKfgyvZzjBfRhrqvA== X-Proofpoint-GUID: 1yx3EDDicGaSwXZOKotEcleOvWIUskKY X-Proofpoint-ORIG-GUID: 1yx3EDDicGaSwXZOKotEcleOvWIUskKY X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1117,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-10-13_03,2025-10-06_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 clxscore=1011 suspectscore=0 spamscore=0 priorityscore=1501 adultscore=0 bulkscore=0 malwarescore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2510020000 definitions=main-2510110047 Add dt-bindings for AD4062 family, devices AD4060/AD4062, low-power with monitor capabilities SAR ADCs. Each variant of the family differs in granuality. 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 | 83 ++++++++++++++++++= ++++ MAINTAINERS | 6 ++ 2 files changed, 89 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 0000000000000000000000000000000000000000..dcf86088fc4f32de7ad681561a0= 9bad2755af04c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2024 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad4062.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD4062 ADC family device driver + +maintainers: + - Jorge Marques + +description: | + Analog Devices AD4062 Single Channel Precision SAR ADC family + + https://www.analog.com/media/en/technical-documentation/data-sheets/ad40= 60.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad40= 62.pdf + +properties: + compatible: + enum: + - adi,ad4060 + - adi,ad4062 + + reg: + maxItems: 1 + + interrupts: + minItems: 1 + maxItems: 2 + + interrupt-names: + items: + - const: gp0 + description: Signal coming from the GP0 pin. + - const: gp1 + description: Signal coming from the GP1 pin. + + 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>; + + ad4062: adc@0,2ee007c0000 { + reg =3D <0x0 0x2ee 0x7c0000>; + vdd-supply =3D <&vdd>; + vio-supply =3D <&vio>; + ref-supply =3D <&ref>; + + gp1-gpios =3D <&gpio0 0 GPIO_ACTIVE_HIGH>; + gp0-gpios =3D <&gpio0 1 GPIO_ACTIVE_HIGH>; + interrupt-parent =3D <&gpio>; + interrupts =3D <0 0 IRQ_TYPE_EDGE_RISING>, + <0 1 IRQ_TYPE_EDGE_FALLING>; + interrupt-names =3D "gp0", "gp1"; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index f090c2f6e63a0d255a025885cc4573f5802ef159..afbfaeba5387b9fbfa9bf1443a0= 59c47dd596d45 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1400,6 +1400,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.49.0 From nobody Fri Dec 19 13:50:54 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 194E12E7F29; Mon, 13 Oct 2025 07:29:16 +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=1760340558; cv=none; b=NTYvMLZwHt2fNdMmra1GkncFcHVEgwK9bGiZlTccFoHslS5Y2GoGhvy5LvJjWQpzeJMsIGH3pQvzkfoZDHFe3/T2Oj846bMRXczJy2Sjj8o52NitmnGSvtNVUJrmWneosCwO4hwcXIkltAKoDHjBRw7W5do8sUUf61c56gU9ywM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760340558; c=relaxed/simple; bh=16ST8mC9fFPbFSQ5bTzHqg9UclfNbE/xz75c5MTChP0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=FiWo0SQdXUnS32THnX/BlA3C/ER+GrBC0eaK0yAmDX5peIIfST2wIJxJB4O4sDB7SImajl7/iZ/gkPx4AxK86QVYp5+QwACuWHmzbZ6fZFgQ5ZaXezu/rmq1btf/+EXzDetcQvA4HPaASUKtMtHGfQRcPGrpDsVjsdVm0QWbNVU= 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=aKSuwlZl; 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="aKSuwlZl" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 59D3xRbj008597; Mon, 13 Oct 2025 03:29:01 -0400 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=Pd0Q8 OVyfLr7zlEhQkgFB/ukWlNhG2Q3zVaQpfGFukA=; b=aKSuwlZlJyIJ4AJejhh0a gjsx1o6h3t0nLFQbjdlvE+EV1TLQ5nmXonsZn4tXQHaTGsuLmj2RGjvzD7Jgm3YZ EDB+FlWaObbtlaj69Jho0EZTC+mGCu60hxgUqCr6RtCyA0vv+KFra0NVkUUbS1GO 9SiCiwylfCgSEEwTAr2gdbstT+JGF/6d4qpaK8Cz/pFR3iyph0EYmY60QnJhIgIv B9JB9z6jr3ajElt6hCQv45dBVOGZPSuq8PdHyuD8eOiNOR5CkD0INMPxF5QbxibZ TIcrhpOBlEhtSi3jaUzMsLgRpVjVA25Cv1+mxxdNbf8mx1y0jAyb1OJYEU7ZRS+a w== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 49qm508agk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 13 Oct 2025 03:29:00 -0400 (EDT) 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 59D7SxaW022862 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 13 Oct 2025 03:28:59 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 13 Oct 2025 03:28:59 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 13 Oct 2025 03:28:59 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.56]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 59D7ShZ8013800; Mon, 13 Oct 2025 03:28:53 -0400 From: Jorge Marques Date: Mon, 13 Oct 2025 09:28:00 +0200 Subject: [PATCH 2/7] 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: <20251013-staging-ad4062-v1-2-0f8ce7fef50c@analog.com> References: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@analog.com> In-Reply-To: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@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 CC: , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1760340523; l=3623; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=16ST8mC9fFPbFSQ5bTzHqg9UclfNbE/xz75c5MTChP0=; b=qrwkD4YAS7opmFLWTfg379hPKktEdFaj+YrnL15wT3T7+RIoKycFhMbIervMhLWAWVo+W0pJg YMOoI32yTy2CIKRAoo/clzghAOnbMO0AbyiWy3acjelCJIrUSTwu2wc X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=cJ7tc1eN c=1 sm=1 tr=0 ts=68ecaa3c cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=x6icFKpwvdMA:10 a=gAnH3GRIAAAA:8 a=KQWnvXESmFA-g6fypRYA:9 a=QEXdDO2ut3YA:10 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDExMDA0NyBTYWx0ZWRfX0zZK222toRdz PA0RmsE0U5Yt3Vo+ZTN7GI8FiMnVpS7fpZKVZiTsZDiCGkvxCcswSENUoySvExAs61B7pJyoWjF 79R2ZVNaUW8Y7gGhZrrqCV2/apjguB1JSOolUYmbheml1gezmLnVEQxmpblSDs3NhK40hqLvZWa 6Q8Q6LhGbWdLL4TTyTeKjg3dgv/umQimTvoFVUCYz7d0ybvE7GZzTlnyOpjFy69zmuKyWZDyaXL BrYnfLsedCMQG1rY11USeA/+4GgMXFOH5OxSBQ9rKpzQWToFZ1AyDv9LepxVB/zX3n0FLUiNZtg FnwONEkBp/K0v5o6vP5beC7hnaTk2ca9SiuZQSmQvFGHBLxsnJA/bNsWsF6Iv2cuZ/fOyfoMNfA NYISdfe/IrKDwHVjGNfxc2M1LniHug== X-Proofpoint-GUID: qgJe7Pl9A7NhmhggJrmbf9EQvBa1mTdM X-Proofpoint-ORIG-GUID: qgJe7Pl9A7NhmhggJrmbf9EQvBa1mTdM X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1117,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-10-13_03,2025-10-06_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 clxscore=1011 suspectscore=0 spamscore=0 priorityscore=1501 adultscore=0 bulkscore=0 malwarescore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2510020000 definitions=main-2510110047 This adds a new page to document how to use the ad4062 ADC driver. Signed-off-by: Jorge Marques --- Documentation/iio/ad4062.rst | 89 ++++++++++++++++++++++++++++++++++++++++= ++++ MAINTAINERS | 1 + 2 files changed, 90 insertions(+) diff --git a/Documentation/iio/ad4062.rst b/Documentation/iio/ad4062.rst new file mode 100644 index 0000000000000000000000000000000000000000..b486d7fe1916d2963c94581be36= 96cf58d51ca48 --- /dev/null +++ b/Documentation/iio/ad4062.rst @@ -0,0 +1,89 @@ +.. 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: + +- 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 scale factor to multiply the raw value. + * - ``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`` + - Returs the channel scale in reference to the reference voltage + ``ref-supply``. + +Also contain the following device attributes: + +.. list-table:: Device attributes + :header-rows: 1 + + * - Attribute + - Description + * - ``samling_frequency`` + - Sets the sets the device internal sample rate, used in the burst + averaging mode. + * - ``sampling_frequency_available`` + - Lists the available device internal sample rates. + +Interrupts +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The interrupts are mapped through the ``interrupt-names`` and ``interrupts= `` +properties. + +The ``interrupt-names`` ``gp1`` entry sets the role of Data Ready signal. +If it is not present, the driver fallback to enabling the same role as an +I3C IBI. + +Low-power mode +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The device enters low-power mode on idle to save power. Enabling an event = puts +the device out of the low-power since the ADC autonomously samples to asse= rt +the event condition. + +Unimplemented features +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +- Monitor mode +- Trigger mode +- Averaging mode diff --git a/MAINTAINERS b/MAINTAINERS index afbfaeba5387b9fbfa9bf1443a059c47dd596d45..ce012c6c719023d3c0355676a33= 5a55d92cf424c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1405,6 +1405,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.49.0 From nobody Fri Dec 19 13:50:54 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 66E432E9ED7; Mon, 13 Oct 2025 07:29:20 +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=1760340562; cv=none; b=pA58ljIWdl4+ufqg0nmPpRWOokx9q5chPIvqGukUA8ZDWqk3NXkbsIbo92Fb+udYNIDPTTIVuzQ8oPPuc6teeAh2ZmYIWh4n4LBFqHZwijZB0c/u8vMe7eRkcKu/zTsb/vpaDWDwWe46s0yDe7tig4YPLRD4B91dHVRyQLunOFo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760340562; c=relaxed/simple; bh=XV5p1JNxSarj0AW2myz+nqtHAnC26kP88M//crG6zPY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=gUXy9t6UTHWcqCg2gvwO9wqIqChtVA4yhd8PPNhKiKu9XCqd7KB0Fgk9weK48jbAMKunIelzPvoKuAfRmFN6u+W+LBBXuShhdM7mJlx+mHldKiYut24LaMOQzQ0HjEj7CJEpqrZ/WoxyDxDnrSvLMTy1gh0DCgwBlB61va6TQHo= 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=O1rTDOTN; 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="O1rTDOTN" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 59D3xRbk008597; Mon, 13 Oct 2025 03:29:05 -0400 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=RO/w7 f5Tv6zAUNQ7F9sC7+Zi8ePM3FjqA40n+B2bjRg=; b=O1rTDOTNPaK5Yu99HeP93 +PgJBWBNE2Y6eZLTOjj6knPAv8ABzXgmBjCdIOJ2JnBes8HxecJVrdAuXQVl3Wg/ ZA9fOpJ89Y1rup5qoHaw719b0OJoOE4xmGP8zfl3dJ5VprzGZvFfBM/U3SCLsMwC dA2uZfsPoiLmXTJeWl7hcYI4Fa6T77F1QGKvPDaHZMX43qxmO0kGxhWpommQJKqR oz1fVBK/L3uBSpd3OofyN5IiRhrV7UN1gXRfMZYzgvx7so7CBvhUbcfnXoeunzah TnN2ySpzbIV0IH0fpUqWdvNxncaQi/v186XVMG9+j40em8qC/f97611KzdqDLE9B A== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 49qm508ags-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 13 Oct 2025 03:29:04 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 59D7T3Pc062915 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 13 Oct 2025 03:29:03 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 13 Oct 2025 03:29:03 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 13 Oct 2025 03:29:03 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.56]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 59D7ShZ9013800; Mon, 13 Oct 2025 03:28:55 -0400 From: Jorge Marques Date: Mon, 13 Oct 2025 09:28:01 +0200 Subject: [PATCH 3/7] 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: <20251013-staging-ad4062-v1-3-0f8ce7fef50c@analog.com> References: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@analog.com> In-Reply-To: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@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 CC: , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1760340523; l=28713; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=XV5p1JNxSarj0AW2myz+nqtHAnC26kP88M//crG6zPY=; b=chn7wRcOrhuQPi975t55TVHckMD5d1rlFl19QsHOvn4VCam9C18Ljs5mYF50PPdPzD/VlbQnM s0tV/FVnFp0DK1SDE+LxgDu6fdwf/WX6+v0nq997+zQ6+LtVjdKWfOx X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=cJ7tc1eN c=1 sm=1 tr=0 ts=68ecaa41 cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=x6icFKpwvdMA:10 a=gAnH3GRIAAAA:8 a=OEvQco-YZ5C6mOMsRFgA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDExMDA0NyBTYWx0ZWRfX/ebkFmGwV3kz Co47nkTCnWe53t4rRtsLgzs3NEwgXHfqoRZQN/U6/VsPyIQJHtUoe6PEAnhUDKbQeVDQecFeZOt SSgFuVqyrNWGrKxGL16Y3uT70x6EltSOHeBzIXduQm0aExK1SGmmFfrg72uM2+KH5OVEDv5VYic TP2dZ0Bm6PMr+H7NPw0SnTw9JT8YhnrkLmzjuTsODGHxzb5XXCd6QbQ1j2+lOab2mvRYxbj76oV aluh7DaBZxlfQ+I/msGgqzuJN6d69+GPjnFsgqPkaqXUZx2ai2hsOgbSDPXS8ACr/v49nL3YgHx m3kRqy580V1ZeOj509q/+Q1D094osk9mO1MXmU2Csx7659btT7YwusLks4IsNmYsrBbBRDML19l cYu0GjGLnc+egNhMchBw2Uodg/sfNQ== X-Proofpoint-GUID: ThGRvRD7sfGJ8KZZRe43feSejqwWMW3j X-Proofpoint-ORIG-GUID: ThGRvRD7sfGJ8KZZRe43feSejqwWMW3j X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1117,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-10-13_03,2025-10-06_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 clxscore=1015 suspectscore=0 spamscore=0 priorityscore=1501 adultscore=0 bulkscore=0 malwarescore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2510020000 definitions=main-2510110047 The AD4060/AD4062 are versatile, 16-bit/12-bit, successive approximation register (SAR) analog-to-digital converter (ADC) that enables low-power, high-density data acquisition solutions without sacrificing precision. This ADC offers a unique balance of performance and power efficiency, plus innovative features for seamlessly switching between high-resolution and low-power modes tailored to the immediate needs of the system. The AD4060/AD4062 are ideal for battery-powered, compact data acquisition and edge sensing applications. Signed-off-by: Jorge Marques --- MAINTAINERS | 1 + drivers/iio/adc/Kconfig | 11 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad4062.c | 905 +++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 918 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ce012c6c719023d3c0355676a335a55d92cf424c..ab4c95e331014c18895dc13699d= 616a91a080f8e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1406,6 +1406,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 58a14e6833f60008511838176b8b3ec0789dc95b..490c01d701bdd1543809cdefad4= ed5573c051c24 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 d008f78dc010aff5f76f838283be294e0ebc27dd..ed71b2549c647b9d59d999e107c= a1ee256d8ec04 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 0000000000000000000000000000000000000000..e55a69c62694a71a4e29f29b9a2= bfeec3b16c990 --- /dev/null +++ b/drivers/iio/adc/ad4062.c @@ -0,0 +1,905 @@ +// 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_INTERFACE_STATUS_NOT_RDY BIT(7) +#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_MODES_DATA_FORMAT BIT(7) +#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_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_TIMER_CONFIG_300KSPS 0x2 +#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_RDY BIT(7) +#define AD4062_REG_DEVICE_STATUS_DEVICE_RESET BIT(6) +#define AD4062_REG_MIN_SAMPLE 0x45 +#define AD4062_REG_IBI_STATUS 0x48 +#define AD4062_REG_CONV_READ_LSB 0x50 +#define AD4062_REG_CONV_READ 0x53 +#define AD4062_REG_CONV_TRIGGER 0x59 +#define AD4062_REG_CONV_AUTO 0x61 +#define AD4062_MAX_REG 0x61 + +#define AD4062_I3C_VENDOR 0x0177 + +#define AD4050_MAX_AVG 0x7 +#define AD4062_MAX_AVG 0xB +#define AD4062_MAX_RATE(x) ((x) =3D=3D AD4062_2MSPS ? 2000000 : 500000) +#define AD4062_FS_OFFSET(g) ((g) =3D=3D AD4062_2MSPS ? 0 : 2) +#define AD4062_FS(g) (&ad4062_conversion_freqs[AD4062_FS_OFFSET(g)]) +#define AD4062_FS_LEN(g) (ARRAY_SIZE(ad4062_conversion_freqs) - (AD4062_FS= _OFFSET(g))) +#define AD4062_MON_VAL_MAX_GAIN 1999970 +#define AD4062_MON_VAL_MIDDLE_POINT 0x8000 +#define AD4062_T_CNVH_NS 10 +#define AD4062_VIO_3V3 3300000 +#define AD4062_SPI_MAX_ADC_XFER_SPEED(x) ((x) >=3D AD4062_VIO_3V3 ? 833333= 33 : 58823529) +#define AD4062_SPI_MAX_REG_XFER_SPEED 16000000 + +enum ad4062_grade { + AD4062_2MSPS, +}; + +enum ad4062_operation_mode { + AD4062_SAMPLE_MODE =3D 0, + AD4062_BURST_AVERAGING_MODE =3D 1, + AD4062_MONITOR_MODE =3D 3, +}; + +enum ad4062_gp_mode { + AD4062_GP_DISABLED, + AD4062_GP_INTR, + AD4062_GP_DRDY, +}; + +enum ad4062_interrupt_en { + AD4062_INTR_EN_NEITHER, + AD4062_INTR_EN_MIN, + AD4062_INTR_EN_MAX, + AD4062_INTR_EN_EITHER, +}; + +struct ad4062_chip_info { + const struct iio_chan_spec channels[1]; + const char *name; + u16 prod_id; + u8 max_avg; + u8 grade; +}; + +enum { + AD4062_SCAN_TYPE_SAMPLE, + AD4062_SCAN_TYPE_BURST_AVG, +}; + +static const struct iio_scan_type ad4062_scan_type_12_s[] =3D { + [AD4062_SCAN_TYPE_SAMPLE] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_BE, + }, + [AD4062_SCAN_TYPE_BURST_AVG] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_BE, + }, +}; + +static const struct iio_scan_type ad4062_scan_type_16_s[] =3D { + [AD4062_SCAN_TYPE_SAMPLE] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_BE, + }, + [AD4062_SCAN_TYPE_BURST_AVG] =3D { + .sign =3D 's', + .realbits =3D 24, + .storagebits =3D 32, + .endianness =3D IIO_BE, + }, +}; + +struct ad4062_state { + const struct ad4062_chip_info *chip; + const struct ad4062_bus_ops *ops; + enum ad4062_operation_mode mode; + struct completion completion; + struct iio_trigger *trigger; + struct iio_dev *indio_dev; + struct i3c_device *i3cdev; + struct regmap *regmap; + u16 sampling_frequency; + int vref_uv; + u8 raw[4] __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), +}; + +static const char *const 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 */ +}; + +static int ad4062_conversion_frequency_set(struct ad4062_state *st, u8 val) +{ + val +=3D AD4062_FS_OFFSET(st->chip->grade); + return regmap_write(st->regmap, AD4062_REG_TIMER_CONFIG, + FIELD_PREP(AD4062_REG_TIMER_CONFIG_FS_MASK, val)); +} + +static int ad4062_sampling_frequency_get(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + + return st->sampling_frequency - AD4062_FS_OFFSET(st->chip->grade); +} + +static int ad4062_sampling_frequency_set(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int val) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + + val +=3D AD4062_FS_OFFSET(st->chip->grade); + st->sampling_frequency =3D val; + + return 0; +} + +static const struct iio_enum AD4062_2MSPS_conversion_freq_enum =3D { + .items =3D AD4062_FS(AD4062_2MSPS), + .num_items =3D AD4062_FS_LEN(AD4062_2MSPS), + .set =3D ad4062_sampling_frequency_set, + .get =3D ad4062_sampling_frequency_get, +}; + +#define AD4062_EXT_INFO(grade) \ +static struct iio_chan_spec_ext_info grade##_ext_info[] =3D { \ + IIO_ENUM("sampling_frequency", IIO_SHARED_BY_ALL, \ + &grade##_conversion_freq_enum), \ + IIO_ENUM_AVAILABLE("sampling_frequency", IIO_SHARED_BY_ALL, \ + &grade##_conversion_freq_enum), \ + { } \ +} + +AD4062_EXT_INFO(AD4062_2MSPS); + +#define AD4062_CHAN(bits, grade) { \ + .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_type_available =3D BIT(IIO_CHAN_INFO_OVERSAMPLING_RA= TIO), \ + .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), \ + .ext_info =3D grade##_ext_info, \ +} + +static const struct ad4062_chip_info ad4060_chip_info =3D { + .name =3D "ad4060", + .channels =3D { AD4062_CHAN(12, AD4062_2MSPS) }, + .prod_id =3D 0x7A, + .max_avg =3D AD4050_MAX_AVG, + .grade =3D AD4062_2MSPS, +}; + +static const struct ad4062_chip_info ad4062_chip_info =3D { + .name =3D "ad4062", + .channels =3D { AD4062_CHAN(16, AD4062_2MSPS) }, + .prod_id =3D 0x7C, + .max_avg =3D AD4062_MAX_AVG, + .grade =3D AD4062_2MSPS, +}; + +static int ad4062_set_oversampling_ratio(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int val) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (val < 1 || val > BIT(st->chip->max_avg + 1)) + return -EINVAL; + + /* 1 disables oversampling */ + if (val =3D=3D 1) { + st->mode =3D AD4062_SAMPLE_MODE; + } else { + val =3D ilog2(val); + st->mode =3D AD4062_BURST_AVERAGING_MODE; + ret =3D regmap_write(st->regmap, AD4062_REG_AVG_CONFIG, val - 1); + if (ret) + return ret; + } + + return 0; +} + +static int ad4062_get_oversampling_ratio(struct ad4062_state *st, + unsigned int *val) +{ + int ret, buf; + + if (st->mode =3D=3D AD4062_SAMPLE_MODE) { + *val =3D 1; + return 0; + } + + ret =3D regmap_read(st->regmap, AD4062_REG_AVG_CONFIG, &buf); + if (ret) + return ret; + + *val =3D BIT(buf + 1); + + return 0; +} + +static int ad4062_check_ids(struct ad4062_state *st) +{ + int ret; + u16 val; + + ret =3D regmap_bulk_read(st->regmap, AD4062_REG_PROD_ID_1, &st->raw, 2); + if (ret) + return ret; + + val =3D get_unaligned_be16(st->raw); + if (val !=3D st->chip->prod_id) + dev_warn(&st->i3cdev->dev, + "Production ID x%x does not match known values", val); + + ret =3D regmap_bulk_read(st->regmap, AD4062_REG_VENDOR_H, &st->raw, 2); + if (ret) + return ret; + + val =3D get_unaligned_be16(st->raw); + if (val !=3D AD4062_I3C_VENDOR) { + dev_err(&st->i3cdev->dev, + "Vendor ID x%x does not match expected value\n", val); + return -ENODEV; + } + + return 0; +} + +static int ad4062_set_operation_mode(struct ad4062_state *st, + enum ad4062_operation_mode mode) +{ + int ret; + + if (mode =3D=3D AD4062_BURST_AVERAGING_MODE) { + ret =3D ad4062_conversion_frequency_set(st, st->sampling_frequency); + if (ret) + return ret; + } + + ret =3D regmap_update_bits(st->regmap, AD4062_REG_ADC_MODES, + AD4062_REG_ADC_MODES_MODE_MSK, mode); + if (ret) + return ret; + + return regmap_write(st->regmap, AD4062_REG_MODE_SET, + AD4062_REG_MODE_SET_ENTER_ADC); +} + +static int ad4062_soft_reset(struct ad4062_state *st) +{ + u8 val =3D 0x81; + int ret; + + ret =3D regmap_write(st->regmap, AD4062_REG_INTERFACE_CONFIG_A, val); + if (ret) + return ret; + + /* Wait AD4062 treset time */ + fsleep(5000); + + return 0; +} + +static int ad4062_setup(struct iio_dev *indio_dev, struct iio_chan_spec co= nst *chan, + const bool *ref_sel) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + const struct iio_scan_type *scan_type; + int ret; + + scan_type =3D iio_get_current_scan_type(indio_dev, chan); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); + + u8 val =3D FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_0, AD4062_GP_INTR) | + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, AD4062_GP_DRDY); + + ret =3D regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + AD4062_REG_GP_CONF_MODE_MSK_1 | AD4062_REG_GP_CONF_MODE_MSK_0, + val); + if (ret) + return ret; + + val =3D FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_0, (AD4062_INTR_EN_EITHER)= ) | + FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_1, (AD4062_INTR_EN_NEITHER)); + + ret =3D regmap_update_bits(st->regmap, AD4062_REG_ADC_MODES, + 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; + + return regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, + AD4062_REG_INTR_CONF_EN_MSK_0 | AD4062_REG_INTR_CONF_EN_MSK_1, + val); +} + +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 int ad4062_request_ibi(struct i3c_device *i3cdev) +{ + const struct i3c_ibi_setup ibireq =3D { + .max_payload_len =3D 1, + .num_slots =3D 1, + .handler =3D ad4062_ibi_handler, + }; + int ret; + + ret =3D i3c_device_request_ibi(i3cdev, &ibireq); + if (ret) + return ret; + + ret =3D i3c_device_enable_ibi(i3cdev); + if (ret) + goto err_enable_ibi; + return 0; + +err_enable_ibi: + i3c_device_free_ibi(i3cdev); + return ret; +} + +static int ad4062_request_irq(struct iio_dev *indio_dev) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + struct device *dev =3D &st->i3cdev->dev; + int ret; + + ret =3D fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp1"); + if (ret >=3D 0) { + ret =3D devm_request_threaded_irq(dev, ret, NULL, + ad4062_irq_handler_drdy, + IRQF_ONESHOT, indio_dev->name, + indio_dev); + } else if (ret !=3D -EPROBE_DEFER) { + ret =3D regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, + AD4062_REG_ADC_IBI_EN_CONV_TRIGGER, + AD4062_REG_ADC_IBI_EN_CONV_TRIGGER); + } + + return ret; +} + +static const int ad4062_oversampling_avail[] =3D { + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, +}; + +static int ad4062_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, const int **vals, + int *type, int *len, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + *vals =3D ad4062_oversampling_avail; + *len =3D ARRAY_SIZE(ad4062_oversampling_avail); + *type =3D IIO_VAL_INT; + + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int ad4062_get_chan_scale(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + const struct iio_scan_type *scan_type; + + scan_type =3D iio_get_current_scan_type(indio_dev, st->chip->channels); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); + + *val =3D (st->vref_uv * 2) / MILLI; + + *val2 =3D scan_type->realbits; + + return IIO_VAL_FRACTIONAL_LOG2; +} + +static int ad4062_get_chan_calibscale(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + u16 gain; + int ret; + + ret =3D regmap_bulk_read(st->regmap, AD4062_REG_MON_VAL, &st->raw, 2); + if (ret) + return ret; + + gain =3D get_unaligned_be16(&st->raw); + + /* From datasheet: code out =3D code in =C3=97 mon_val/0x8000 */ + *val =3D gain / AD4062_MON_VAL_MIDDLE_POINT; + *val2 =3D mul_u64_u32_div(gain % AD4062_MON_VAL_MIDDLE_POINT, NANO, + AD4062_MON_VAL_MIDDLE_POINT); + + return IIO_VAL_INT_PLUS_NANO; +} + +static int ad4062_set_chan_calibscale(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int gain_int, int gain_frac) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + u64 gain; + int ret; + + if (gain_int < 0 || gain_frac < 0) + return -EINVAL; + + gain =3D mul_u32_u32(gain_int, MICRO) + gain_frac; + + if (gain > AD4062_MON_VAL_MAX_GAIN) + return -EINVAL; + + put_unaligned_be16(DIV_ROUND_CLOSEST_ULL(gain * AD4062_MON_VAL_MIDDLE_POI= NT, + MICRO), + &st->raw); + + ret =3D regmap_bulk_write(st->regmap, AD4062_REG_MON_VAL, &st->raw, 2); + if (ret) + return ret; + + /* Enable scale if gain is not one. */ + return regmap_update_bits(st->regmap, AD4062_REG_ADC_MODES, + 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; + u8 addr =3D AD4062_REG_CONV_TRIGGER; + struct i3c_priv_xfer t[2] =3D { + { + .data.out =3D &addr, + .len =3D 1, + .rnw =3D false, + }, + { + .data.in =3D &st->raw, + .len =3D 4, + .rnw =3D true, + } + }; + int ret; + + reinit_completion(&st->completion); + /* Change address pointer to trigger conversion */ + ret =3D i3c_device_do_priv_xfers(i3cdev, &t[0], 1); + if (ret) + return ret; + /* + * Single sample read should be used only for oversampling and + * sampling frequency pairs that take less than 1 sec. + */ + ret =3D wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(1000)); + if (!ret) + return -ETIMEDOUT; + + ret =3D i3c_device_do_priv_xfers(i3cdev, &t[1], 1); + if (ret) + return ret; + *val =3D get_unaligned_be32(st->raw); + return ret; +} + +static int ad4062_read_chan_raw(struct iio_dev *indio_dev, int *val) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + ret =3D pm_runtime_resume_and_get(&st->i3cdev->dev); + if (ret) + return ret; + + ret =3D ad4062_set_operation_mode(st, st->mode); + if (ret) + goto out_error; + + ret =3D __ad4062_read_chan_raw(st, val); + +out_error: + pm_runtime_put_autosuspend(&st->i3cdev->dev); + return ret; +} + +static int ad4062_read_raw_dispatch(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); + + switch (info) { + case IIO_CHAN_INFO_RAW: + return ad4062_read_chan_raw(indio_dev, val); + + case IIO_CHAN_INFO_CALIBSCALE: + return ad4062_get_chan_calibscale(indio_dev, chan, 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) +{ + int ret; + + if (info =3D=3D IIO_CHAN_INFO_SCALE) + return ad4062_get_chan_scale(indio_dev, chan, val, val2); + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret =3D ad4062_read_raw_dispatch(indio_dev, chan, val, val2, info); + + iio_device_release_direct(indio_dev); + return ret ? ret : IIO_VAL_INT; +} + +static int ad4062_write_raw_dispatch(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, + int val2, long info) +{ + switch (info) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + return ad4062_set_oversampling_ratio(indio_dev, chan, val); + + case IIO_CHAN_INFO_CALIBSCALE: + return ad4062_set_chan_calibscale(indio_dev, chan, 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) +{ + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret =3D ad4062_write_raw_dispatch(indio_dev, chan, val, val2, info); + + iio_device_release_direct(indio_dev); + return ret; +} + +static int ad4062_debugfs_reg_access(struct iio_dev *indio_dev, unsigned i= nt reg, + unsigned int writeval, unsigned int *readval) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + if (readval) + ret =3D regmap_read(st->regmap, reg, readval); + else + ret =3D regmap_write(st->regmap, reg, writeval); + + iio_device_release_direct(indio_dev); + return ret; +} + +static int ad4062_get_current_scan_type(const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + + return st->mode =3D=3D AD4062_BURST_AVERAGING_MODE ? + AD4062_SCAN_TYPE_BURST_AVG : + AD4062_SCAN_TYPE_SAMPLE; +} + +static const struct iio_info ad4062_info =3D { + .read_raw =3D ad4062_read_raw, + .write_raw =3D ad4062_write_raw, + .read_avail =3D ad4062_read_avail, + .get_current_scan_type =3D &ad4062_get_current_scan_type, + .debugfs_reg_access =3D &ad4062_debugfs_reg_access, +}; + +static const struct regmap_config ad4062_regmap_config =3D { + .name =3D "ad4062", + .reg_bits =3D 8, + .val_bits =3D 8, + .max_register =3D AD4062_MAX_REG, + .rd_table =3D &ad4062_regmap_rd_table, + .wr_table =3D &ad4062_regmap_wr_table, + .can_sleep =3D true, +}; + +static int ad4062_regulators_get(struct ad4062_state *st, bool *ref_sel) +{ + struct device *dev =3D &st->i3cdev->dev; + int uv; + + uv =3D devm_regulator_get_enable_read_voltage(dev, "vio"); + if (uv < 0) + return dev_err_probe(dev, uv, + "Failed to enable and read vio voltage\n"); + + uv =3D devm_regulator_get_enable_read_voltage(dev, "vdd"); + if (uv < 0) + return dev_err_probe(dev, uv, + "Failed to enable vdd regulator\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 =3D=3D -ENODEV) + st->vref_uv =3D uv; + else if (st->vref_uv < 0) + return dev_err_probe(dev, st->vref_uv, + "Failed to enable and read ref voltage\n"); + return 0; +} + +static const struct i3c_device_id ad4062_id_table[] =3D { + I3C_DEVICE(AD4062_I3C_VENDOR, ad4060_chip_info.prod_id, &ad4060_chip_info= ), + I3C_DEVICE(AD4062_I3C_VENDOR, ad4062_chip_info.prod_id, &ad4062_chip_info= ), + {} +}; +MODULE_DEVICE_TABLE(i3c, ad4062_id_table); + +static int ad4062_probe(struct i3c_device *i3cdev) +{ + const struct i3c_device_id *id =3D i3c_device_match_id(i3cdev, ad4062_id_= table); + const struct ad4062_chip_info *chip =3D id->data; + struct device *dev =3D &i3cdev->dev; + struct iio_dev *indio_dev; + struct ad4062_state *st; + bool ref_sel; + int ret; + + indio_dev =3D devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st =3D iio_priv(indio_dev); + st->i3cdev =3D i3cdev; + i3cdev_set_drvdata(i3cdev, st); + init_completion(&st->completion); + + ret =3D ad4062_regulators_get(st, &ref_sel); + if (ret) + return ret; + + st->regmap =3D devm_regmap_init_i3c(i3cdev, &ad4062_regmap_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(dev, PTR_ERR(st->regmap), + "Failed to initialize regmap\n"); + + st->mode =3D AD4062_SAMPLE_MODE; + st->chip =3D chip; + st->sampling_frequency =3D AD4062_FS_OFFSET(st->chip->grade); + 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 dev_err_probe(dev, ret, + "AD4062 fields assertions failed\n"); + + 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 void ad4062_remove(struct i3c_device *i3cdev) +{ + i3c_device_disable_ibi(i3cdev); + i3c_device_free_ibi(i3cdev); +} + +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); + + fsleep(4000); + return ret; +} + +static const struct dev_pm_ops ad4062_pm_ops =3D { + SET_RUNTIME_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, + .remove =3D ad4062_remove, + .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.49.0 From nobody Fri Dec 19 13:50:54 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 B20622EA476; Mon, 13 Oct 2025 07:29: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=1760340563; cv=none; b=VgnsYzpqrhiCJtC8V/nbzHHFQ+Ql5p/NfBiqZFpr1+btNCe6I93YYJN0ZY1muyOr+62/gn1DjkClCSfk/ZY9yKznUUaPcBXN4yz0YHPqNXPk8YQv1o7hOlMb+i09LQNl6ogD8qMnHesdwbZfAKCBYvtoBeLT4iktkPSqJQyKMWU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760340563; c=relaxed/simple; bh=Lu/G9PzkIDILtxQZMU8flwf13WzcLALptfGmNJmAcw0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=gysbPVbOs3ao4ghKsvhUMLyZWbqKz9YvUEUIgLq10fX4Doh3JzeIsPnOgPCvlhHUXUNFCePDYKtoiH53AwDXokgv7j+EadFk8fSvW+peuwTiZ9Dgyo0fpVkR2WLPBUoHDksWgPFUd1DM2PO9Cuekkx4t8nw8UJX+nQ1pHCnETK8= 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=CSdaALHG; 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="CSdaALHG" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 59D6qVYg008744; Mon, 13 Oct 2025 03:29:06 -0400 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=F1da8 CvN/e0YaeaHYmO+uZpPdsDegNvUPiXDxmw+K4M=; b=CSdaALHGRmBF9demd4FqN RbQGUPSTnqatPWPrqi01ySOjUDb9j6MRdNwro6srQD98wW096kmWVnBBsxQF/iky /NKKjK2ARvl4cZK6Ubb85ZHrLwZaC+JbwI1HCRiAj5EOb8KBy9O1dVSq5tIxzfxv fuAjKqUfodAb5WZxDCJRMvbAmd+UOnq0VUrTckt2I1tl1VLIrWMJ0OMYryKUryWW 4IgwvoVQc85q3ssV9mX7mZs8i/J6Y/dfi/1U1rLSvrg4WKr4ktADPMOSOMBNTMoT vvEgDs3GccL1hSVShYW0MuPuQiLnZZ6BjILIfRFRYWGGD1dXh4c1LqlzcAzkiZtb w== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 49r5jc52ck-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 13 Oct 2025 03:29:06 -0400 (EDT) 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 59D7T5Z0022888 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 13 Oct 2025 03:29:05 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 13 Oct 2025 03:29:05 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 13 Oct 2025 03:29:05 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.56]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 59D7ShZA013800; Mon, 13 Oct 2025 03:28:57 -0400 From: Jorge Marques Date: Mon, 13 Oct 2025 09:28:02 +0200 Subject: [PATCH 4/7] 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: <20251013-staging-ad4062-v1-4-0f8ce7fef50c@analog.com> References: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@analog.com> In-Reply-To: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@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 CC: , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1760340523; l=1321; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=Lu/G9PzkIDILtxQZMU8flwf13WzcLALptfGmNJmAcw0=; b=o0T9DIYgGR17qI/VlvZy2F6P1Ns/wwoQkZl6WlMaXvtroo53kAq7T2DYDpooD0tTdoigU+VqS oeDq+LR8fNmB8UVRQPvXxiO9AUuAUzKnlPV53lMfUihzTiCMbZbX/ey X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=OdqVzxTY c=1 sm=1 tr=0 ts=68ecaa42 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=x6icFKpwvdMA:10 a=gAnH3GRIAAAA:8 a=pTCSo2s0eJJONGnsYSsA:9 a=QEXdDO2ut3YA:10 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-ORIG-GUID: 3N-Hv5EpMoW5u6_UVSRIs53qweybBSFV X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDEyMDAyNSBTYWx0ZWRfX8/wxEpaKqUoR AME3hThc2+0X5TWqPbv92VO/a+ZF7EALlRnh+D3tWdV1WOUj5SxhxobsyNJOvXawSJNy6cRkOmv f9NoqQImHq4FiKOXdqPuX/KPtdZlGgvnZ64avrOLdPWblFLTYEvAZ+o1Ua289QBzAbmTK0AP0Ed iA5wLQGBLF29+Q3UOBf4W6wYC5B5Xkl1F70urtyDhajKlkviC88eI1G9fuk6WyPGv7/vwTlhtAd HBUyklsrPBznPptc2qVpmtWnA4DVh6m1DHPbdm9jCCYGcK8PWGKIxLOg+6RolGEFnDAUK05pTir tkdGE31i7wvF7I3Jt8ZnvQ38WiOOPGjLcpYMumIG5LvrI9lMkmZcvBxCP3vjg/h9JEldzzf8ZzZ Rlg/wzPu94RqKbtHr/q32Sq86HDC6Q== X-Proofpoint-GUID: 3N-Hv5EpMoW5u6_UVSRIs53qweybBSFV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1117,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-10-13_03,2025-10-06_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 suspectscore=0 bulkscore=0 clxscore=1011 lowpriorityscore=0 priorityscore=1501 phishscore=0 malwarescore=0 adultscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2510020000 definitions=main-2510120025 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 b486d7fe1916d2963c94581be3696cf58d51ca48..3770740a1a9b1419cd97882a988= 578e514407f59 100644 --- a/Documentation/iio/ad4062.rst +++ b/Documentation/iio/ad4062.rst @@ -81,6 +81,19 @@ The device enters low-power mode on idle to save power. = Enabling an event puts the device out of the low-power since the ADC autonomously samples to asse= rt the event condition. =20 +IIO trigger support +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +An IIO trigger ``ad4062-devX`` is registered by the driver to be used by t= he +same device, to capture samples to a software buffer. It is required to at= tach +the trigger to the device by setting the ``current_trigger`` before enabli= ng +and reading the buffer. + +The acquisition is sequential and bounded by the protocol timings, software +latency and internal timings, the sample rate is not configurable. The bur= st +averaging mode does impact the effective sample rate, since it increases t= he +internal timing to output a single sample. + Unimplemented features =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 --=20 2.49.0 From nobody Fri Dec 19 13:50:54 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 898952EAB6F; Mon, 13 Oct 2025 07:29:23 +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=1760340566; cv=none; b=cB3cDcAn5SXMgiLVc52jT0ooH+Icrhq9//D0i4AB07Qr1Imk8Cc3yu7o6K5rbSsEej0tYcXn3k8kc9HDUacXBzNeG5krdDiYZLb1/pE6hj0Jd1X7vAEHAcoAElADZ/nTgQHrQregrUO5TWIwfXg61k0sOOnU8Y16zWa/RN/dSHY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760340566; c=relaxed/simple; bh=xgj0EtOdtC80DF4Ws10dApUbk6Fw8rfDPxgLygx7MjA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=caxSftfwHFHnLJfTpeB4fDyhVwO38nBst9DXZa9VfyBaY3gNx6Xwxho64ch5sdEVHxZxEuxp13qsQvWTcoJyWAIGOIv6KisTeu9VPKmnyyNXgF2O9GjR4GsNoKjS4nlnPN2dlnBVZvDKJjYvyA2xo1tfGMNqfhFb6Cn5g0jkmj4= 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=ilwXTA6k; 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="ilwXTA6k" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 59D5ZJdn015613; Mon, 13 Oct 2025 03:29:09 -0400 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=IC62L DYVtx7VWM7eJNrKl5wTRKuh53qUxfCfRQdIwvo=; b=ilwXTA6kKA7dwx96+OBKT LzbKmIp4CeUkbWP0Wk6OyFRtNukNLynmmeifXjcLhK8r7Mosw+RvbtCVnKRWd2Aa HXXjHDt7pHFyPedZWITdDfEUnjqG1q5LpyaOx5Vm8sl/AdQzB+rN0seqLoLQgGEX 9rPg9JRb5CeJGdHYuNSLmVfnRtHfqm6kN2LGkMpZe/nle6vvYZjH2Lj+j/OpI6ET XM7L+3+VXYzT+DdCd6vlBIG5sDHEegw+ob6Y5eRWjr0Ay4Mulg+bfoXW33liA3Jl Ot/A4KZ0xJbATeKoUCLHxR0nbkPTJmJvbAQyXXCI1rddJse9og5r1Zt4+39nwKGZ A== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 49qh30gx06-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 13 Oct 2025 03:29:08 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 59D7T71Z062930 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 13 Oct 2025 03:29:07 -0400 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 13 Oct 2025 03:29:07 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 13 Oct 2025 03:29:07 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 13 Oct 2025 03:29:07 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.56]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 59D7ShZB013800; Mon, 13 Oct 2025 03:28:58 -0400 From: Jorge Marques Date: Mon, 13 Oct 2025 09:28:03 +0200 Subject: [PATCH 5/7] 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: <20251013-staging-ad4062-v1-5-0f8ce7fef50c@analog.com> References: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@analog.com> In-Reply-To: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@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 CC: , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1760340523; l=6103; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=xgj0EtOdtC80DF4Ws10dApUbk6Fw8rfDPxgLygx7MjA=; b=1Q25hNTDmQ8cwT2iLWNpLbIITaWTjMT5dqt4ZkRb9sNc4uejj/X0PrKNkmwzEJFPhC6Zm32Ga wZsZKSkCPPCAYOCSijxTM/5/vW3FhCNE7y/12evEwZQWI8AifJ+pVQK X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: PQU4ZzcBXJ8CuNlx1vRwAKnk0FO0FUAy X-Proofpoint-GUID: PQU4ZzcBXJ8CuNlx1vRwAKnk0FO0FUAy X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDExMDAyOSBTYWx0ZWRfXyj93wL4f9jvO YMBrzetXOPZhRLIOKKPc2xwa0SK1O1NYg8MiNhmzl+BG4iJArjXHZy/sbm3cUmBcqvRvCFNYs/w iStFs3SALM2QI7oUlwyT7HAc6P4vOx0RMw87MX30vw4WC5PWB7k/LYDC4FN/Vp9jUJsfSQX3bay 02E308tGK915W37iwDcHzt7+3Gd2mTleC1Hv/CPQBldbnIXV1hpevBA4Eyvn13xH0QQEUseykYL kjgwqua4MwYO6FaN7yucDU5wPfQoWU+Oj2jy2TxmeKRtlpV9iEYHdGluVNFTsRhsF35ESwrXxr7 u+RDVIPXl2Um/z5lFbZ0McRRLT8o12ansMQceOH0ULwRIUuHOi1H1lJlBYUsI1lKeMOMHAhRju7 TQf0z4osDZBs6xR5ks+gfRiwyR+8/Q== X-Authority-Analysis: v=2.4 cv=YscChoYX c=1 sm=1 tr=0 ts=68ecaa44 cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=x6icFKpwvdMA:10 a=gAnH3GRIAAAA:8 a=oA80kLhoCsWfn7L3hZIA:9 a=QEXdDO2ut3YA:10 a=br55WurUj89AL1qEz8Q6:22 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1117,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-10-13_03,2025-10-06_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 impostorscore=0 suspectscore=0 malwarescore=0 spamscore=0 bulkscore=0 phishscore=0 lowpriorityscore=0 adultscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2510020000 definitions=main-2510110029 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 | 131 +++++++++++++++++++++++++++++++++++++++++++= +++- 2 files changed, 131 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 490c01d701bdd1543809cdefad4ed5573c051c24..c7c17f7e04a2f93664ddad3d378= 75079a9d5ab24 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 e55a69c62694a71a4e29f29b9a2bfeec3b16c990..40b7c10b8ce7145b010bb11e8e4= 698baacb6b3d3 100644 --- a/drivers/iio/adc/ad4062.c +++ b/drivers/iio/adc/ad4062.c @@ -12,8 +12,12 @@ #include #include #include +#include #include #include +#include +#include +#include #include #include #include @@ -432,7 +436,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_nested(st->trigger); + else + complete(&st->completion); =20 return IRQ_HANDLED; } @@ -442,7 +449,49 @@ 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(st->trigger); + else + complete(&st->completion); +} + +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); + u8 addr =3D AD4062_REG_CONV_TRIGGER; + int ret; + + /* Read current and trigger next conversion */ + struct i3c_priv_xfer t[2] =3D { + { + .data.in =3D &st->raw, + .len =3D 4, + .rnw =3D true, + }, + { + .data.out =3D &addr, + .len =3D 1, + .rnw =3D false, + } + }; + + /* Separated transfers to not infeer repeated-start */ + ret =3D i3c_device_do_priv_xfers(st->i3cdev, &t[0], 1); + if (ret) + goto out; + ret =3D i3c_device_do_priv_xfers(st->i3cdev, &t[1], 1); + if (ret) + goto out; + + iio_push_to_buffers_with_timestamp(indio_dev, &st->raw, + pf->timestamp); + +out: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; } =20 static int ad4062_request_ibi(struct i3c_device *i3cdev) @@ -489,6 +538,27 @@ static int ad4062_request_irq(struct iio_dev *indio_de= v) return ret; } =20 +static const struct iio_trigger_ops ad4062_trigger_ops =3D { + .validate_device =3D &iio_trigger_validate_own_device, +}; + +static int ad4062_request_trigger(struct iio_dev *indio_dev) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + struct device *dev =3D &st->i3cdev->dev; + + 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); + + return devm_iio_trigger_register(dev, st->trigger); +} + static const int ad4062_oversampling_avail[] =3D { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, }; @@ -709,6 +779,52 @@ static int ad4062_write_raw(struct iio_dev *indio_dev, return ret; } =20 +static int ad4062_triggered_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + u8 addr =3D AD4062_REG_CONV_TRIGGER; + int ret; + + ret =3D pm_runtime_resume_and_get(&st->i3cdev->dev); + if (ret) + return ret; + + ret =3D ad4062_set_operation_mode(st, st->mode); + if (ret) + goto out_mode_error; + + /* Trigger first conversion */ + struct i3c_priv_xfer t =3D { + .data.out =3D &addr, + .len =3D 1, + .rnw =3D false, + }; + + ret =3D i3c_device_do_priv_xfers(st->i3cdev, &t, 1); + if (ret) + goto out_mode_error; + return 0; + +out_mode_error: + pm_runtime_put_autosuspend(&st->i3cdev->dev); + + return ret; +} + +static int ad4062_triggered_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + + pm_runtime_mark_last_busy(&st->i3cdev->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) { @@ -843,6 +959,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) --=20 2.49.0 From nobody Fri Dec 19 13:50:54 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 899422EAB70; Mon, 13 Oct 2025 07:29: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=1760340565; cv=none; b=lEVu4xM1sF6eFsDzUf+PrxDGFYymVNyINwlRUbeaeaiJiKfNTtFn+sWf/h4yDQtY8la9iZc60b4RSJZdyxT1qENwHMRfG5aaTF5bZ2LhREV9iul4dK/rbk2cWsipzcpdbb5DZ2Phzq83U+zNlx3kDkkvfGQmKzKmEB2YJ9diADw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760340565; c=relaxed/simple; bh=YsrV1v9GZv4ByAUMVgIvzqnHgkWpVSUu5ueG6hcSSCs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=M5u44veA3CczzERpSz3tvCnDsiFMjPUOil+ZrLKQhamoR2l2UJw7iA6SmOmnF0w7HGAe9aLU0lIYSFr02W+lPlwJ9gpaVWXBGE7GDZf241L7Y0TH6M/MLhhEivhel53GsztEVxqZT4/CpjQ3M6eMCsJpEXBF+ZUnBQwLbSDQtTU= 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=Y/c8FD6W; 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="Y/c8FD6W" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 59D6Yihd008822; Mon, 13 Oct 2025 03:29:08 -0400 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=zzSfE i9ARLQAt9rVLhDWE/raMm4btPkKu7GDhUgeG2k=; b=Y/c8FD6Wp3LZSQd+DC3I+ Y0QTzhSlPodILiYIaQwIx3xoH1ACO29lWSNy5LNx0EK6salF2dPkLeu8DNz2v8uw 4hYUrZST+mN0ItCsHUTJpRr/Ozd8hCnNcv8zt8ITH4SOZuvpTf5p2UZDAPVQ9YAR B7ZveYylgG8l1BEyUOwYpQWDHoxkslhO5qLsPJ9Q/ATiJ6DZr0D74kS3qRInwVEv mhvM1kQa/RtD5DIfg9dt9nEZBl25cOWVSRg+A5HI/F6skhb69zZp2k94PAPypzI/ 5sIMfq7l/wDM9dKWmLm8Cv42vkHWYyPHJx+i4PSMRgRsrd8i1Tw3i2lDLXNo4Wgq w== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 49r5jc52cq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 13 Oct 2025 03:29:08 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 59D7T7w2062926 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 13 Oct 2025 03:29:07 -0400 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 13 Oct 2025 03:29:07 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 13 Oct 2025 03:29:07 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 13 Oct 2025 03:29:07 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.56]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 59D7ShZC013800; Mon, 13 Oct 2025 03:29:00 -0400 From: Jorge Marques Date: Mon, 13 Oct 2025 09:28:04 +0200 Subject: [PATCH 6/7] 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: <20251013-staging-ad4062-v1-6-0f8ce7fef50c@analog.com> References: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@analog.com> In-Reply-To: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@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 CC: , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1760340523; l=3236; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=YsrV1v9GZv4ByAUMVgIvzqnHgkWpVSUu5ueG6hcSSCs=; b=Q+jIhe9C0PPIWq2r/f1eg4qQjyFV2mRLMoJkFUGlBmHwOKFtpLM0snIecS1I80qyaPCdgw9vK 4wqA33J4uWGDTSMVnY6pbElHQBccnITsCbjJOPyBazy9G7LRWghN1CW X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=OdqVzxTY c=1 sm=1 tr=0 ts=68ecaa44 cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=x6icFKpwvdMA:10 a=gAnH3GRIAAAA:8 a=FYPAJmQbBWBKA0HC2wsA:9 a=QEXdDO2ut3YA:10 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-ORIG-GUID: IauLRs8A14fxiqJ2k_5m-t_Nf5lrMvEW X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDEyMDAyNSBTYWx0ZWRfX8ZfMoL2F/9W+ xEchNYBkzyb0/XRAcFOf87+A+dPOuRuMpER9O44QMCg5hO1AxKtx9vj9Le1lzjLKWc5sKpfTuOp haCsliaxQUze1CcjZZZiGfSYzw+k6hiV/X7DiO5EZKof6j3rZBTbdruRYRhUTCFUck+15Xu7fmG FpyoXaAwm+mlCaF1mVnNBzbGKUb6yZSeFOJcJwh62LBqsfVg5Dmw43cl1flPOjwVapwcmQHQ4Mx hXNUF5LfEkwfxo9uwj72WMjIim2zXaUP7VAbrlOhjOTkm89pOmgfUwffrZv6/igmazgl+wRdlz/ 7CCI9XNXrdU0NLZnM2o9aFhlxitd2SBskICEOV0DW9R7hb7wk2f2FGCvPKne+Q9Hhdy1akQwvv2 1XkfdhhQoI35eQDw+HB0065AwxmK/g== X-Proofpoint-GUID: IauLRs8A14fxiqJ2k_5m-t_Nf5lrMvEW X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1117,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-10-13_03,2025-10-06_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 suspectscore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 priorityscore=1501 phishscore=0 malwarescore=0 adultscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2510020000 definitions=main-2510120025 Explains the IIO Events support. Signed-off-by: Jorge Marques --- Documentation/iio/ad4062.rst | 44 ++++++++++++++++++++++++++++++++++++++++= ---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/Documentation/iio/ad4062.rst b/Documentation/iio/ad4062.rst index 3770740a1a9b1419cd97882a988578e514407f59..f83b2906228ca7fa076a9340a0e= ff94b5c102c77 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: =20 +- GP0: Is assigned the role of Threshold Either signal. - GP1: Is assigned the role of Data Ready signal. =20 Device attributes @@ -60,7 +61,7 @@ Also contain the following device attributes: - Description * - ``samling_frequency`` - Sets the sets the device internal sample rate, used in the burst - averaging mode. + averaging mode and monitor modes. * - ``sampling_frequency_available`` - Lists the available device internal sample rates. =20 @@ -70,8 +71,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 ``interrup-names`` ``gp0`` entry sets the role of Threshold signal, and +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 @@ -94,9 +97,42 @@ latency and internal timings, the sample rate is not con= figurable. The burst averaging mode does impact the effective sample rate, since it increases t= he internal timing to output a single sample. =20 +Threshold events +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The ADC supports a monitoring mode to raise threshold events. The driver +supports a single interrupt for both rising and falling readings. + +The feature is enabled/disabled by setting ``thresh_either_en``. During mo= nitor +mode, the device continuously operates in autonomous mode. Any register ac= cess +puts the device back in configuration mode, due to this, any access disabl= es +monitor mode. + +The following event attributes are available: + +.. list-table:: Event attributes + :header-rows: 1 + + * - Attribute + - Description + * - ``sampling_frequency`` + - Frequency used in the monitoring mode, sets the device internal sam= ple + rate when the mode is activated. + * - ``sampling_frequency_available`` + - List of available sample rates. + * - ``thresh_either_en`` + - Enable monitoring mode. + * - ``thresh_falling_hysteresis`` + - Set the hysteresis value for the minimum threshold. + * - ``thresh_falling_value`` + - Set the minimum threshold value. + * - ``thresh_rising_hysteresis`` + - Set the hysteresis value for the maximum threshold. + * - ``thresh_rising_value`` + - Set the maximum threshold value. + Unimplemented features =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -- Monitor mode - Trigger mode - Averaging mode --=20 2.49.0 From nobody Fri Dec 19 13:50:54 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 BA3E22EB5A3; Mon, 13 Oct 2025 07:29:25 +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=1760340567; cv=none; b=A//0wNJejzgcddw1YzLL5NjAbTP41kGnk0Dy6EAo8Al/DwpmYvIeaJb9sZ3EpJxy98G+4eNjUA7OfyZTWsPZQ5857B5LepfidUbAC11JnuolyLReRU+gys81EOdNbauyMdCgOOzJso1NQxMDClXfYv6yOhRnTAxgI4AbrDw2QhI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760340567; c=relaxed/simple; bh=dyOykNjCpkuKNDTwkALUI9US4XThjJvrY0/a5gAPTGw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=fc3c53QI6ynPyYmBngnN97KoSv5evBX5bp8nCp6K3ZWeOtY8vNyqohzrHKtSk9jAG4QK57KAZQMXwLHHrD1eVMCI46BEYxpilBNLSR9W6CoZjjGdizkHJv+FTMWkXqRfz+7RjROEhkIjDN7X9Bp9gALz6NL7uK1sChO1ATJZKwE= 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=1cAWaJy5; 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="1cAWaJy5" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 59D4wFos015805; Mon, 13 Oct 2025 03:29:12 -0400 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=j8EZw hv5M0qbEm6QYGwoCH/56egOqqjohUInDLSxezU=; b=1cAWaJy5fjC6m/DjBkJpD fzuY0UNhRqJGri11zFo8bf0L7hrxxJ8qhypwyqKFhW2wNm4l2jcZcrb8HYKCCWkO 3kJ/SOybW9WVwZ2HYIfDHyKDVJBv/rUXEErAmZGlali9i4BNN0JwI9u9yO5LH5HU KKDWo5TuV3Jrge5SpqI4huIVJryKmAmVufL4dTYqx+XVjmu6NJYQ55LvHKw3Qsjs 26kyv2zdDBkIaz8fb2jz22l4lSyBVmZX15v7hjzC0VPovzOPgBRGlrUgQKkgPiCC ksRLSr6SuLdvVrYfHjwUF1wN/2FEb1intVwvX0vJoUyPwduuXSMeyTBn0+J1NRr4 Q== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 49qh30gx0f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 13 Oct 2025 03:29:11 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 59D7TA2H062941 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 13 Oct 2025 03:29:10 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Mon, 13 Oct 2025 03:29:10 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Mon, 13 Oct 2025 03:29:10 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.56]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 59D7ShZD013800; Mon, 13 Oct 2025 03:29:02 -0400 From: Jorge Marques Date: Mon, 13 Oct 2025 09:28:05 +0200 Subject: [PATCH 7/7] 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: <20251013-staging-ad4062-v1-7-0f8ce7fef50c@analog.com> References: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@analog.com> In-Reply-To: <20251013-staging-ad4062-v1-0-0f8ce7fef50c@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 CC: , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1760340523; l=14047; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=dyOykNjCpkuKNDTwkALUI9US4XThjJvrY0/a5gAPTGw=; b=qzMT7mVJE2Nl3Vza2wNFADb9Z3YGqvT2NaF8+4q+tZaUhMdZp1iGStSSA9z9WMnB1CAvXUZ6u gDpujzM6dbfA/NfZT1q/dsvHs7sqFktshdNZYuXz2PE/GCEwhlh686+ X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: ZezwGP691u-myRl1GMj4hTCZyo-L1axs X-Proofpoint-GUID: ZezwGP691u-myRl1GMj4hTCZyo-L1axs X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDExMDAyOSBTYWx0ZWRfX1fRZCOAcVRGj LAPejQ8JPoPcL3JOuarwr/yp7yp4eP4Jk9hJ0p1ihyhfTg5b2ECzXToxN0GxPCR6l8JNXQcaca7 ou+ySESdZPXLqZpcpGT7ptfj9H140LGqTYN6karT8sLyDKtIWX5TvcyiNLwGlQ0/y8PCG16d5nG PzVMyz6zLv9CtJ1D16nXxzLqi30Y0i+8MHCkNelVQkQR7fNIwTV8dH6dRDuF25KriZfrXBprlHm 1flJIDy3Fhsj6zQJ7cqe4RoR3ieWfzORBovq/isABIuCvK6LwuUN06iySVFOPAgkco1kpWnVZmK Aw9uA4tliFyRMlyqelVEZ2zMh9QaC2JmBWwnE/sp7eJWeYCXElikulIMPiFm8RWi9TCjgYFMu7W NKdzl5RLE0lyUIOONv9iul18LPC/Aw== X-Authority-Analysis: v=2.4 cv=YscChoYX c=1 sm=1 tr=0 ts=68ecaa48 cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=x6icFKpwvdMA:10 a=gAnH3GRIAAAA:8 a=vWLHQQzp_VqV2la2RWoA:9 a=QEXdDO2ut3YA:10 a=cPQSjfK2_nFv0Q5t_7PE:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1117,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-10-13_03,2025-10-06_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 impostorscore=0 suspectscore=0 malwarescore=0 spamscore=0 bulkscore=0 phishscore=0 lowpriorityscore=0 adultscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2510020000 definitions=main-2510110029 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 | 351 +++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 347 insertions(+), 4 deletions(-) diff --git a/drivers/iio/adc/ad4062.c b/drivers/iio/adc/ad4062.c index 40b7c10b8ce7145b010bb11e8e4698baacb6b3d3..b5b12f81c71b52f244600ed23da= d11253290b868 100644 --- a/drivers/iio/adc/ad4062.c +++ b/drivers/iio/adc/ad4062.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -172,6 +173,8 @@ struct ad4062_state { struct i3c_device *i3cdev; struct regmap *regmap; u16 sampling_frequency; + u16 events_frequency; + bool wait_event; int vref_uv; u8 raw[4] __aligned(IIO_DMA_MINALIGN); }; @@ -202,6 +205,26 @@ static const struct regmap_access_table ad4062_regmap_= wr_table =3D { .n_yes_ranges =3D ARRAY_SIZE(ad4062_regmap_wr_ranges), }; =20 +static const struct iio_event_spec ad4062_events[] =3D { + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_EITHER, + .mask_shared_by_all =3D BIT(IIO_EV_INFO_ENABLE), + }, + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_RISING, + .mask_shared_by_all =3D BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_HYSTERESIS), + }, + { + .type =3D IIO_EV_TYPE_THRESH, + .dir =3D IIO_EV_DIR_FALLING, + .mask_shared_by_all =3D BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_HYSTERESIS), + }, +}; + static const char *const ad4062_conversion_freqs[] =3D { "2000000", "1000000", "300000", "100000", /* 0 - 3 */ "33300", "10000", "3000", "500", /* 4 - 7 */ @@ -263,6 +286,8 @@ AD4062_EXT_INFO(AD4062_2MSPS); .info_mask_shared_by_type_available =3D BIT(IIO_CHAN_INFO_OVERSAMPLING_RA= TIO), \ .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), \ @@ -285,6 +310,82 @@ static const struct ad4062_chip_info ad4062_chip_info = =3D { .grade =3D AD4062_2MSPS, }; =20 +/** + * A register access will cause the device to drop from monitor mode + * into configuration mode, update the state to reflect that. + */ +static void ad4062_exit_monitor_mode(struct ad4062_state *st) +{ + if (st->wait_event) { + pm_runtime_mark_last_busy(&st->i3cdev->dev); + pm_runtime_put_autosuspend(&st->i3cdev->dev); + st->wait_event =3D 0; + } +} + +static ssize_t ad4062_events_frequency_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ad4062_state *st =3D iio_priv(dev_to_iio_dev(dev)); + + return sysfs_emit(buf, "%s\n", ad4062_conversion_freqs[st->events_frequen= cy]); +} + +static ssize_t ad4062_events_frequency_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev =3D dev_to_iio_dev(dev); + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + ad4062_exit_monitor_mode(st); + + ret =3D __sysfs_match_string(AD4062_FS(st->chip->grade), + AD4062_FS_LEN(st->chip->grade), buf); + if (ret < 0) + goto out_release; + + st->events_frequency =3D ret; + +out_release: + iio_device_release_direct(indio_dev); + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(sampling_frequency, 0644, ad4062_events_frequency_s= how, + ad4062_events_frequency_store, 0); + +static ssize_t sampling_frequency_available_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ad4062_state *st =3D iio_priv(dev_to_iio_dev(dev)); + int ret =3D 0; + + for (u8 i =3D AD4062_FS_OFFSET(st->chip->grade); + i < AD4062_FS_LEN(st->chip->grade); i++) + ret +=3D sysfs_emit_at(buf, ret, "%s ", ad4062_conversion_freqs[i]); + + ret +=3D sysfs_emit_at(buf, ret, "\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 iio_dev *indio_dev, const struct iio_chan_spec *chan, unsigned int val) @@ -431,6 +532,19 @@ static int ad4062_setup(struct iio_dev *indio_dev, str= uct iio_chan_spec const *c val); } =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; @@ -449,10 +563,18 @@ static void ad4062_ibi_handler(struct i3c_device *i3c= dev, { struct ad4062_state *st =3D i3cdev_get_drvdata(i3cdev); =20 - if (iio_buffer_enabled(st->indio_dev)) - iio_trigger_poll(st->trigger); - else - complete(&st->completion); + if (st->wait_event) { + iio_push_event(st->indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns(st->indio_dev)); + } else { + if (iio_buffer_enabled(st->indio_dev)) + iio_trigger_poll(st->trigger); + else + complete(&st->completion); + } } =20 static irqreturn_t ad4062_poll_handler(int irq, void *p) @@ -523,6 +645,24 @@ static int ad4062_request_irq(struct iio_dev *indio_de= v) struct device *dev =3D &st->i3cdev->dev; int ret; =20 + ret =3D fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp0"); + if (ret >=3D 0) { + ret =3D devm_request_threaded_irq(dev, ret, NULL, + ad4062_irq_handler_thresh, + IRQF_ONESHOT, indio_dev->name, + indio_dev); + if (ret) + return ret; + } else if (ret !=3D -EPROBE_DEFER) { + 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 { + return ret; + } + ret =3D fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp1"); if (ret >=3D 0) { ret =3D devm_request_threaded_irq(dev, ret, NULL, @@ -734,6 +874,7 @@ 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; =20 if (info =3D=3D IIO_CHAN_INFO_SCALE) @@ -741,6 +882,7 @@ static int ad4062_read_raw(struct iio_dev *indio_dev, =20 if (!iio_device_claim_direct(indio_dev)) return -EBUSY; + ad4062_exit_monitor_mode(st); =20 ret =3D ad4062_read_raw_dispatch(indio_dev, chan, val, val2, info); =20 @@ -768,10 +910,12 @@ 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; =20 if (!iio_device_claim_direct(indio_dev)) return -EBUSY; + ad4062_exit_monitor_mode(st); =20 ret =3D ad4062_write_raw_dispatch(indio_dev, chan, val, val2, info); =20 @@ -779,6 +923,196 @@ static int ad4062_write_raw(struct iio_dev *indio_dev, return ret; } =20 +static int ad4062_monitor_mode_enable(struct ad4062_state *st, bool enable) +{ + int ret =3D 0; + + if (!enable) + goto out_suspend; + + ret =3D pm_runtime_resume_and_get(&st->i3cdev->dev); + if (ret) + return ret; + + ret =3D ad4062_conversion_frequency_set(st, st->events_frequency); + if (ret) + goto out_suspend; + + ret =3D ad4062_set_operation_mode(st, AD4062_MONITOR_MODE); + if (ret) + goto out_suspend; + + return ret; +out_suspend: + pm_runtime_put_autosuspend(&st->i3cdev->dev); + return ret; +} + +static int ad4062_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + + return st->wait_event; +} + +static int ad4062_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + bool state) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + if (st->wait_event =3D=3D state) { + ret =3D 0; + goto out_release; + } + + ret =3D ad4062_monitor_mode_enable(st, state); + if (!ret) + st->wait_event =3D state; + +out_release: + iio_device_release_direct(indio_dev); + return ret; +} + +static int __ad4062_read_event_info_value(struct ad4062_state *st, + enum iio_event_direction dir, int *val) +{ + int ret; + u8 reg; + + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4062_REG_MAX_LIMIT; + else + reg =3D AD4062_REG_MIN_LIMIT; + + ret =3D regmap_bulk_read(st->regmap, reg, &st->raw, 2); + if (ret) + return ret; + + *val =3D sign_extend32(get_unaligned_be16(st->raw), 11); + + return 0; +} + +static int __ad4062_read_event_info_hysteresis(struct ad4062_state *st, + enum iio_event_direction dir, int *val) +{ + u8 reg; + + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4062_REG_MAX_HYST; + else + reg =3D AD4062_REG_MIN_HYST; + return regmap_read(st->regmap, reg, val); +} + +static int ad4062_read_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int *val, + int *val2) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + ad4062_exit_monitor_mode(st); + + switch (info) { + case IIO_EV_INFO_VALUE: + ret =3D __ad4062_read_event_info_value(st, dir, val); + break; + case IIO_EV_INFO_HYSTERESIS: + ret =3D __ad4062_read_event_info_hysteresis(st, dir, val); + break; + default: + ret =3D -EINVAL; + break; + } + + iio_device_release_direct(indio_dev); + return ret ? ret : IIO_VAL_INT; +} + +static int __ad4062_write_event_info_value(struct ad4062_state *st, + enum iio_event_direction dir, int val) +{ + u8 reg; + + if (val > 2047 || val < -2048) + return -EINVAL; + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4062_REG_MAX_LIMIT; + else + reg =3D AD4062_REG_MIN_LIMIT; + put_unaligned_be16(val, &st->raw); + + return regmap_bulk_write(st->regmap, reg, &st->raw, 2); +} + +static int __ad4062_write_event_info_hysteresis(struct ad4062_state *st, + enum iio_event_direction dir, int val) +{ + u8 reg; + + if (val >=3D BIT(7)) + return -EINVAL; + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4062_REG_MAX_HYST; + else + reg =3D AD4062_REG_MIN_HYST; + + return regmap_write(st->regmap, reg, val); +} + +static int ad4062_write_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int val, + int val2) +{ + struct ad4062_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + ad4062_exit_monitor_mode(st); + + switch (type) { + case IIO_EV_TYPE_THRESH: + switch (info) { + case IIO_EV_INFO_VALUE: + ret =3D __ad4062_write_event_info_value(st, dir, val); + break; + case IIO_EV_INFO_HYSTERESIS: + ret =3D __ad4062_write_event_info_hysteresis(st, dir, val); + break; + default: + ret =3D -EINVAL; + break; + } + break; + default: + ret =3D -EINVAL; + break; + } + + iio_device_release_direct(indio_dev); + return ret; +} + static int ad4062_triggered_buffer_postenable(struct iio_dev *indio_dev) { struct ad4062_state *st =3D iio_priv(indio_dev); @@ -788,6 +1122,7 @@ static int ad4062_triggered_buffer_postenable(struct i= io_dev *indio_dev) ret =3D pm_runtime_resume_and_get(&st->i3cdev->dev); if (ret) return ret; + ad4062_exit_monitor_mode(st); =20 ret =3D ad4062_set_operation_mode(st, st->mode); if (ret) @@ -833,6 +1168,7 @@ static int ad4062_debugfs_reg_access(struct iio_dev *i= ndio_dev, unsigned int reg =20 if (!iio_device_claim_direct(indio_dev)) return -EBUSY; + ad4062_exit_monitor_mode(st); =20 if (readval) ret =3D regmap_read(st->regmap, reg, readval); @@ -857,6 +1193,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, }; @@ -932,8 +1273,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 AD4062_FS_OFFSET(st->chip->grade); + st->events_frequency =3D AD4062_FS_OFFSET(st->chip->grade); st->indio_dev =3D indio_dev; =20 indio_dev->modes =3D INDIO_DIRECT_MODE; --=20 2.49.0