From nobody Sun Oct 5 20:44:17 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 9CF7827F73A; Tue, 10 Jun 2025 07:35:28 +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=1749540931; cv=none; b=dCC0Vj4EYXrjxZ7UHqlP0zriFq3/MIucW+U2x0d7e2nDU55nKFFafw70PDMJfwEieH0PpzkBYLBvji1MQf9yOXwNT8fThmSh3DDJW4nx71YxgUCwmyitPQwdNMevamcv+gcTa6OXI3DWaXzp5tssLxZD7h49JPtSXspfJ+/m2aY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749540931; c=relaxed/simple; bh=BStMCOgPLwAcv0102KzdZT2L0QgfKEUgCbYK4hAWzrM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=fT2LUasoVCqtKdMJH9jwnW7RPJoJT0WUATYZ1vW/+F2RyKARYYbdiLNAbOP3eQ8Ofk5uwJv6jiq/7aeXPOJcs3/U3oeaSe6HGhRkkYfflSiQwp35R8desZinHYny/TjLXY8lkXMNf6xrdxSXKvafRX2Gg0gZ6qC5GGFhu2LyNrk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none 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=UOSW/CX4; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none 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="UOSW/CX4" 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 55A62TUC027961; Tue, 10 Jun 2025 03:35:02 -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=nYS8h VWxHnvEOeh9OJgvFtJ0jhBoLhu+GpQOdvI/82o=; b=UOSW/CX4QCL+2irmCI5ig ZlIUbOn96WxY91LYTaizweN5Y+5jhNUhUpzHWn/m+rUI9XQoCRllkW32k5M2Shzx +tXW+nacLSweYW/HxPW1mjvasD4bFNlg6ZljxVbcHzENqS7ds6m6ntwBD5DDg6+h bh9lo56iZBZoILsVA+IM8/sTX6a+xWeEwO7iEA5XAnInBtkLc4Q4a+tuiJ1oLFqa PuLwXcKxXIE/WPMSza/5R4mewBNYfBYU8QD77L8LfSGSbN991/1YvN5LZlJdg9Rv fBTtC692vt6khDlKfGwqPH50fIrGH0jQAO2A3t9IZyc1TF9OufkceWkYkJsOvN27 w== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 475u346cyy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 10 Jun 2025 03:35:02 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 55A7Z1UF056124 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 10 Jun 2025 03:35:01 -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.10; Tue, 10 Jun 2025 03:35:01 -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.10 via Frontend Transport; Tue, 10 Jun 2025 03:35:01 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.51]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 55A7YkMf002608; Tue, 10 Jun 2025 03:34:55 -0400 From: Jorge Marques Date: Tue, 10 Jun 2025 09:34:34 +0200 Subject: [PATCH v3 1/8] Documentation: ABI: add oversampling frequency in sysfs-bus-iio 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: <20250610-iio-driver-ad4052-v3-1-cf1e44c516d4@analog.com> References: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> In-Reply-To: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> To: Jonathan Cameron , Lars-Peter Clausen , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= CC: , , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749540886; l=2299; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=BStMCOgPLwAcv0102KzdZT2L0QgfKEUgCbYK4hAWzrM=; b=SFBpg39X0yjLGyt/eCwcA2RBmfaREh3W1gW6zKTyksHjCCaH7RZr45LuEVmsirZo0JdpODEVX hl/Vxw2rDGlAh7EE212sGr3wi0O/iVCqWmJJXC9tc5ebCNPh3pT0f1P X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=R74DGcRX c=1 sm=1 tr=0 ts=6847e026 cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=6IFa9wvqVegA:10 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=RBIExvWx9eVdLZ2BeXAA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: NMKyQ_A2qgZtDghLkVgYwl1npDCu7nke X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjEwMDA1NiBTYWx0ZWRfX5Ky6/OkSuB4f birNCA5GKcokoo8V6BvTkpo0dkV25mnr+zM3j/vREzlAZejizFP+KMVR/JOQjD2Yl/EuVlE5w7w qulg5lEIYWX62lbO3ttYjqc4eAEyB/aUDigSEt6ViHB/f4VHNaSUHW6ZP2w10d4Sm3t1e1QMCvM Oc8F3OPPra+6yK72vR2MHtl2b1KaGSXkYgRFrjk3icrF1lEeumaS/y0NJ2lZAkPcDXHR7TLuysF nebQRCHWjw00LkEroDeV0cg9sArOVbrQYfUn+6Bgwak7xihIW+OsEGPUJPCfWqTdHRjoq9nLJtc 9A7nM8Ji4voJlfQ7S/srMQuir6CXFvqLv02nTVOnOOuBYKtUuOjRhD0nIVDWkelBI98tZWu3s+C 5UfhO3DHzYijoN8l8kz1vS1Y0DW61wpYdqLxCukIDRt7JWGBdaljhaM+5LrRrLs9oYaRR0CE X-Proofpoint-GUID: NMKyQ_A2qgZtDghLkVgYwl1npDCu7nke X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-10_02,2025-06-09_02,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 impostorscore=0 priorityscore=1501 malwarescore=0 bulkscore=0 lowpriorityscore=0 phishscore=0 mlxscore=0 adultscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2505280000 definitions=main-2506100056 Some devices have an internal clock used to space out the conversion trigger for the oversampling filter, Consider an ADC with conversion and data ready pins topology: Sampling trigger | | | | | ADC conversion ++++ ++++ ++++ ++++ ++++ ADC data ready * * * * * With the oversampling frequency, conversions are spaced: Sampling trigger | | | | | ADC conversion + + + + + + + + + + + + + + + + + + + + ADC data ready * * * * * In some devices and ranges, this internal clock can be used to evenly space the conversions between the sampling edge. In other devices the oversampling frequency is fixed or is computed based on the sampling frequency parameter, and the parameter is read only. Signed-off-by: Jorge Marques --- Documentation/ABI/testing/sysfs-bus-iio | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/te= sting/sysfs-bus-iio index ef52c427a015cf47bb9847782e13afbee01e9f31..e60367255be89a9acc827ec1a74= 9b729735f60e6 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -139,6 +139,23 @@ Contact: linux-iio@vger.kernel.org Description: Hardware dependent values supported by the oversampling filter. =20 +What: /sys/bus/iio/devices/iio:deviceX/oversampling_frequency +KernelVersion: 6.17 +Contact: linux-iio@vger.kernel.org +Description: + Some devices have internal clocks for oversampling. + Sets the resulting frequency in Hz to trigger a conversion used by + the oversampling filter. + If the device has a fixed internal clock or is computed based on + the sampling frequency parameter, the parameter is read only. + +What: /sys/bus/iio/devices/iio:deviceX/oversampling_frequency_available +KernelVersion: 6.17 +Contact: linux-iio@vger.kernel.org +Description: + Hardware dependent values supported by the oversampling + frequency. + What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_raw What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_supply_raw What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_raw --=20 2.49.0 From nobody Sun Oct 5 20:44:17 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 7300C28134F; Tue, 10 Jun 2025 07:35:32 +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=1749540934; cv=none; b=Nbyz/pVgD765Y9z5JWEps/1HHk1R3JbBZeWdM4YsTv+Gxsfy//Y/sGwDB053hPO6UB3eDtxOiAjkT0fJaJI+o0u9iliXj+9bRqtp2xNKFTtSfbGv6Un7YlaosXv3i9r9mvimluw13EbqdONauEiLlbT2Gro7WrGhPUlymLonqEU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749540934; c=relaxed/simple; bh=YGNBbAmxGFyyZoPX38c/y8+uQSUZrM5W1KEjtKOY3G8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=gFXjDEdg8v4TvvJsudC9iN6WalwYyBHVQemXhTJ/83lLsfJsGv28cbRHDzn1KwyXJ+u+wsTnViTJ3bjw9EaWm8G6tlCU2ammFiYl3RiZ306Epk75ZbCMC/IFc4vlHGcR4d7/6BDTuLMScS58wH+WivxbrLf2QWEPdP9PXijk0wk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none 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=CrB2e0zc; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none 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="CrB2e0zc" 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 55A62TUG027961; Tue, 10 Jun 2025 03:35:07 -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=JxEhi YuNWK027Yt40xFcHXX2Aoc+OVtIhuqCOWB0K+w=; b=CrB2e0zcjVlCkpc3yC7Ek MpxNcZrNuXCnOXNPyOj3rV6x9y5Foh314EahIVDpXqJC4RQJayurQPfCkbBOgQAA /hqz5icqkoGiz8pF4nOES7Y2smVH/q5QEF8gaHQ2irtgNjm7CsVFZRIUgeta2qr9 v2Am9mTSH0lCznsTCph59mVEotooGytL7ZwCJfOVLSKmnjFDGk4Xr+HX7otaTONo SFWba/CgS7N0XYAhgtp9JWCPW1HX88/ONgvvueDMrzg/SS+dg9cv+EO3zLWy9kd0 EDRfQ5MWW05MVJSDsjalX54qfJxRlb8ijk/eUu6pO+SzM/LIl6QCjdx9n0PZ14W2 g== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 475u346d0a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 10 Jun 2025 03:35:06 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 55A7Z5Zw056142 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 10 Jun 2025 03:35:05 -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.10; Tue, 10 Jun 2025 03:35:05 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Tue, 10 Jun 2025 03:35:05 -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.10 via Frontend Transport; Tue, 10 Jun 2025 03:35:05 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.51]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 55A7YkMg002608; Tue, 10 Jun 2025 03:34:57 -0400 From: Jorge Marques Date: Tue, 10 Jun 2025 09:34:35 +0200 Subject: [PATCH v3 2/8] dt-bindings: iio: adc: Add adi,ad4052 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: <20250610-iio-driver-ad4052-v3-2-cf1e44c516d4@analog.com> References: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> In-Reply-To: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> To: Jonathan Cameron , Lars-Peter Clausen , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , "Andy Shevchenko" , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= CC: , , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749540886; l=7557; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=YGNBbAmxGFyyZoPX38c/y8+uQSUZrM5W1KEjtKOY3G8=; b=aKrdiDdqVVHWfeJUVEf5ZCLAedHsNREQHvSQJOKbVvwPFa58LS0THfAymaunjxDY83jsmUkJy xWuIvmeoy61BltViWT0vgQ2Y377BJwysziIglIfrMmh/FAh5FX/gza9 X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=R74DGcRX c=1 sm=1 tr=0 ts=6847e02b cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=6IFa9wvqVegA:10 a=gEfo2CItAAAA:8 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=EgBP3gVEkGq-cZKvRrIA:9 a=QEXdDO2ut3YA:10 a=sptkURWiP4Gy88Gu7hUp:22 X-Proofpoint-ORIG-GUID: JH1l5m-eslA2QLcWD3VGlzRUctT3KMg0 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjEwMDA1NiBTYWx0ZWRfXxt/YAPiVab6O vH1rUFw0AzuWuXMk9iYAjvYgIdr+ilmRmqYCnl3MRuT1CKzHL1kbyfzKpnFTcgTTNMSWRVumr+x ezyhxe2u0ybmXB9mqxs2xsVVfL7dHGlHtuSK/1UbdB0qAj4Mexxt3j/0oxxwTANqM/Zlaq606ps RsSWCeh8vD+/ZZ3ypqiv+nFU+sN+CL0T62ZoJ/gxzjNs0s5A5EFkmiGbvsXEHV5/c6v64bCcJBU cJzi/g8C4SHdYQGsg9BHOfcjhWpICFCsuokDlXp4xPofbC3tAnyb/HhgDcAGVYGKEfD1QNaySBs 2SzwA+dYOGerow0xL5DaCf427KmVXUlwsgYBm83xUyqFhH87UBzQSRXSat4G5pqQrG5XctBTAW0 YgAVW7PC1LOkfMypzuq9pfukbr7dGDMs7Wtu12KUszg5L7wTkbUWv2ZnJyntkYi0XC9l+6il X-Proofpoint-GUID: JH1l5m-eslA2QLcWD3VGlzRUctT3KMg0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-10_02,2025-06-09_02,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 impostorscore=0 priorityscore=1501 malwarescore=0 bulkscore=0 lowpriorityscore=0 phishscore=0 mlxscore=0 adultscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2505280000 definitions=main-2506100056 Add dt-bindings for AD4052 family, devices AD4050/AD4052/AD4056/AD4058, low-power with monitor capabilities SAR ADCs. Each variant of the family differs in speed and resolution, resulting in different scan types and spi word sizes, that are matched by the compatible with the chip_info. The device contains one input (cnv) and two outputs (gp0, gp1). The outputs can be configured for range of options, such as threshold and data ready. The spi-max-frequency refers to the configuration mode maximum access speed. The ADC mode speed depends on the vio input voltage. Signed-off-by: Jorge Marques --- .../devicetree/bindings/iio/adc/adi,ad4052.yaml | 167 +++++++++++++++++= ++++ MAINTAINERS | 6 + include/dt-bindings/iio/adc/adi,ad4052.h | 17 +++ 3 files changed, 190 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4052.yaml b/Do= cumentation/devicetree/bindings/iio/adc/adi,ad4052.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2cf197e2d872d9a3d4f7210121a= 1e38f784f92dc --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4052.yaml @@ -0,0 +1,167 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2025 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad4052.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD4052 ADC family device driver + +maintainers: + - Jorge Marques + +description: | + Analog Devices AD4052 Single Channel Precision SAR ADC family + + https://www.analog.com/media/en/technical-documentation/data-sheets/ad40= 50-ad4056.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad40= 52-ad4058.pdf + +properties: + compatible: + enum: + - adi,ad4050 + - adi,ad4052 + - adi,ad4056 + - adi,ad4058 + + reg: + maxItems: 1 + + interrupts: + items: + - description: Signal coming from the GP0 pin. + - description: Signal coming from the GP1 pin. + + interrupt-names: + items: + - const: gp0 + - const: gp1 + + cnv-gpios: + description: The Convert Input (CNV). If omitted, CNV is tied to SPI C= S. + maxItems: 1 + + pwms: + maxItems: 1 + description: PWM connected to the CNV pin. + + trigger-sources: + minItems: 1 + maxItems: 2 + description: + Describes the output pin and event associated. + + "#trigger-source-cells": + const: 2 + description: | + Output pins used as trigger source. + + Cell 0 defines the event: + * 0 =3D Data ready + * 1 =3D Min threshold + * 2 =3D Max threshold + * 3 =3D Either threshold + * 4 =3D CHOP control + * 5 =3D Device enable + * 6 =3D Device ready (only GP1) + + Cell 1 defines which pin: + * 0 =3D GP0 + * 1 =3D GP1 + + For convenience, macros for these values are available in + dt-bindings/iio/adc/adi,ad4052.h. + + spi-max-frequency: + maximum: 83333333 + + 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/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + + spi { + #address-cells =3D <1>; + #size-cells =3D <0>; + + adc@0 { + compatible =3D "adi,ad4052"; + reg =3D <0>; + vdd-supply =3D <&vdd>; + vio-supply =3D <&vio>; + ref-supply =3D <&ref>; + spi-max-frequency =3D <83333333>; + + #trigger-source-cells =3D <2>; + trigger-sources =3D <&adc AD4052_TRIGGER_EVENT_EITHER_THRESH + AD4052_TRIGGER_PIN_GP0 + &adc AD4052_TRIGGER_EVENT_DATA_READY + AD4052_TRIGGER_PIN_GP1>; + interrupt-parent =3D <&gpio>; + interrupts =3D <0 0 IRQ_TYPE_EDGE_RISING>, + <0 1 IRQ_TYPE_EDGE_FALLING>; + interrupt-names =3D "gp0", "gp1"; + cnv-gpios =3D <&gpio 2 GPIO_ACTIVE_HIGH>; + }; + }; + - | + #include + #include + #include + + rx_dma { + #dma-cells =3D <1>; + }; + + spi { + #address-cells =3D <1>; + #size-cells =3D <0>; + + dmas =3D <&rx_dma 0>; + dma-names =3D "offload0-rx"; + trigger-sources =3D <&adc AD4052_TRIGGER_EVENT_DATA_READY + AD4052_TRIGGER_PIN_GP1>; + + adc@0 { + compatible =3D "adi,ad4052"; + reg =3D <0>; + vdd-supply =3D <&vdd>; + vio-supply =3D <&vio>; + spi-max-frequency =3D <83333333>; + pwms =3D <&adc_trigger 0 10000 0>; + + #trigger-source-cells =3D <2>; + trigger-sources =3D <&adc AD4052_TRIGGER_EVENT_EITHER_THRESH + AD4052_TRIGGER_PIN_GP0 + &adc AD4052_TRIGGER_EVENT_DATA_READY + AD4052_TRIGGER_PIN_GP1>; + interrupt-parent =3D <&gpio>; + interrupts =3D <0 0 IRQ_TYPE_EDGE_RISING>, + <0 1 IRQ_TYPE_EDGE_FALLING>; + interrupt-names =3D "gp0", "gp1"; + cnv-gpios =3D <&gpio 2 GPIO_ACTIVE_HIGH>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index c02d83560058f7ea75e24509b4d87ef293df6773..d000c7de7ff9eba390f87593bc2= b1847f966f48b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1337,6 +1337,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 AD4052 DRIVER +M: Jorge Marques +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/adc/adi,ad4052.yaml + ANALOG DEVICES INC AD4080 DRIVER M: Antoniu Miclaus L: linux-iio@vger.kernel.org diff --git a/include/dt-bindings/iio/adc/adi,ad4052.h b/include/dt-bindings= /iio/adc/adi,ad4052.h new file mode 100644 index 0000000000000000000000000000000000000000..37db5d9d10e788d5e7fb715c4ba= 9077e555131d5 --- /dev/null +++ b/include/dt-bindings/iio/adc/adi,ad4052.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_ADI_AD4052_H +#define _DT_BINDINGS_ADI_AD4052_H + +#define AD4052_TRIGGER_EVENT_DATA_READY 0 +#define AD4052_TRIGGER_EVENT_MIN_THRESH 1 +#define AD4052_TRIGGER_EVENT_MAX_THRESH 2 +#define AD4052_TRIGGER_EVENT_EITHER_THRESH 3 +#define AD4052_TRIGGER_EVENT_CHOP 4 +#define AD4052_TRIGGER_EVENT_DEV_ENABLED 5 +#define AD4052_TRIGGER_EVENT_DEV_READY 6 + +#define AD4052_TRIGGER_PIN_GP0 0 +#define AD4052_TRIGGER_PIN_GP1 1 + +#endif /* _DT_BINDINGS_ADI_AD4052_H */ --=20 2.49.0 From nobody Sun Oct 5 20:44:17 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 9CF1027F72E; Tue, 10 Jun 2025 07:35:28 +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=1749540930; cv=none; b=ZTCgyzyRQDyvLMixAcXlU+3KY5Jt1TcjxlXG3zgt6ytxK/nRboWHzyE7m+f19VRjA9YlEiVSqdc0u2BQxT8YJ3siiIa0oJMAd+VScpNuOlI/MHPCaLEmnt17N5xwNduKpNyt5w1I8BSoiV/SbrYUYv2ZUsdzZ7S/xAE59qEgN9A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749540930; c=relaxed/simple; bh=sdFAjldeGCQJJ20ICafL2xOY+VAsXnig4eCBQzH8MzQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=MAQyS6aSLVmvr+7ICybvzpNDtYzsdfUwgegpL1vFOXT8tScyoQCg602wFapeCqJiF5XAcaImJ1Q9QHdmcwIqfdmaloGMaG+QBp1Rz/ZePaFpS11ebZgzDGnVVlDgmF8sDHTAVCLLU3PKLimoS2a7gUp5AAHN4NSiVpDFBPtHxAU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none 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=Y3s0gkXc; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none 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="Y3s0gkXc" 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 55A6g8Bp023177; Tue, 10 Jun 2025 03:35:07 -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=d5ryt 0pI/G+b2LsAq1xg2LHy7S0hE2LV6WmwFRL/qQU=; b=Y3s0gkXcOZsYIfIHascyf TZ4RQ09U8fFOvvTtxJ+2SjBiwYOgTe8Ek4r7XiH9dAns0qn+JlOscAQzNDEkSyAg 1cVA0R75MVRA3bhaPnDFj9bJCOZc8RP/7uEd6a+p/+2ZsZVXg0yMNKom2e7cIzFo KEkxshqwiNoLo6CUAPnbhQXuQImtJ0R4hgINzKVD36+37yAlc0ooFrzfzYEXF3hJ Ce+BNAjHDkciqWgngOm5aLXrReHpw/BnyixzJdxrq+ZJsuiolalt6PqdsgdR8gxd YtNw7jdqVqjww8khFIDErqPAi8HLC8nNJO/WaVYb7+8CofDs0fKKSgVmX+6Kh7gE g== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 476fc30bk3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 10 Jun 2025 03:35:07 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 55A7Z5sN013927 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 10 Jun 2025 03:35:05 -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.10; Tue, 10 Jun 2025 03:35: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.10 via Frontend Transport; Tue, 10 Jun 2025 03:35:05 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.51]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 55A7YkMh002608; Tue, 10 Jun 2025 03:34:59 -0400 From: Jorge Marques Date: Tue, 10 Jun 2025 09:34:36 +0200 Subject: [PATCH v3 3/8] docs: iio: New docs for ad4052 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: <20250610-iio-driver-ad4052-v3-3-cf1e44c516d4@analog.com> References: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> In-Reply-To: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> To: Jonathan Cameron , Lars-Peter Clausen , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= CC: , , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749540886; l=3632; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=sdFAjldeGCQJJ20ICafL2xOY+VAsXnig4eCBQzH8MzQ=; b=TwD251L7wL7SF8OIpJ2r64y34FTdwapbKPHi2dCGNrDcghYCYRc/fG0RwaeIkkiT8bgyDWryr 0N85bXruQTMA8TWp77mZ1z5Z8lu8LFP9SMWNxLs1uxPWTSzFF8l0WTJ X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: j07RvrN39XEziBFan2LZDy1lGuy3Ms2U X-Proofpoint-ORIG-GUID: j07RvrN39XEziBFan2LZDy1lGuy3Ms2U X-Authority-Analysis: v=2.4 cv=LtaSymdc c=1 sm=1 tr=0 ts=6847e02b cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=6IFa9wvqVegA:10 a=gAnH3GRIAAAA:8 a=qLcM2r4-lCJhFG8HUqIA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjEwMDA1NiBTYWx0ZWRfXzpVQ4queZZZy xUGdoSjjhvzWMbfMg34/3+5PNi3TDLkMA3b0cznv/pITyQAuKRPW5iEuD7IsHLMJafUEQ7MVZ5T SKUDqNLXc+Ina0xDs0aHW5y+Xce6K4+9gmdQWN55lk3G7sUcfINjPZk90PnXETSU5eL978nNLmE JxDBSrXJxndNv6vN3m7OiZ5nX4l6EM2ga+mDb6omfDK1RpLrEYgLku1BYQKTiJp3mzpjc6JZVun EKZtDsKImNJZxSTi/FN6Jl/ZAjDZsuCj8O1efZpn9CLLIukBBBc1/oubnJM3HdE8oOIZ7kZkXnw xwSsW0iTmjPKwLXbKpPS3rU5aMl+MfZrZew9iR5LVij+C09RRzrcg62PAY78IsF7uf22Q34yR5R m2wr/AN3euASO0c3AKfHUIg2XceTJow/YBtC5e0E0o5C5AnSsxou4lnUi+65PU8Bsry020Ou X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-10_02,2025-06-09_02,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 malwarescore=0 priorityscore=1501 phishscore=0 lowpriorityscore=0 mlxlogscore=999 impostorscore=0 mlxscore=0 spamscore=0 clxscore=1015 suspectscore=0 bulkscore=0 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2505280000 definitions=main-2506100056 This adds a new page to document how to use the ad4052 ADC driver. Signed-off-by: Jorge Marques --- Documentation/iio/ad4052.rst | 71 ++++++++++++++++++++++++++++++++++++++++= ++++ Documentation/iio/index.rst | 1 + MAINTAINERS | 1 + 3 files changed, 73 insertions(+) diff --git a/Documentation/iio/ad4052.rst b/Documentation/iio/ad4052.rst new file mode 100644 index 0000000000000000000000000000000000000000..25e55eb72e167bd2b2195ba789b= 45ce402869b0f --- /dev/null +++ b/Documentation/iio/ad4052.rst @@ -0,0 +1,71 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +AD4052 driver +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +ADC driver for Analog Devices Inc. AD4052 and similar devices. The module = name +is ``ad4052``. + +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: + +* `AD4050 `_ +* `AD4052 `_ +* `AD4056 `_ +* `AD4058 `_ + +Wiring modes +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The ADC uses SPI 4-wire mode, and contain two programmable GPIOs and a CNV= pin. + +The CNV pin is exposed as the ``cnv-gpios`` and triggers an ADC conversion= . GP1 +is ADC conversion ready signal and GP0 Threshold event interrupt, both exp= osed +as interrupts. + +Omit ``cnv-gpios`` and tie CNV and CS together to use the rising edge of t= he CS +as the CNV 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`` + - Scale factor to multiply the raw value. + * - ``in_voltage_raw`` + - Raw ADC voltage value + * - ``in_voltage_oversampling_ratio`` + - Enable the device's burst averaging mode to over sample using the + internal sample rate. + * - ``in_voltage_oversampling_ratio_available`` + - List of available oversampling values. Value 1 disable the burst + averaging mode. + +Also contain the following device attributes: + +.. list-table:: Device attributes + :header-rows: 1 + + * - Attribute + - Description + * - ``oversamling_frequency`` + - Frequency used in the burst averaging mode, sets the device internal + sample rate when the mode is activated. + * - ``oversampling_frequency_available`` + - List of available sample rates. + +Low-power mode +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The device enters low-power mode on idle to save power. Enabling an event = puts +the device out of the low-power since the ADC autonomously samples to asse= rt +the event condition. diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index 2d6afc5a8ed54a90cd8d5723f0dc5212b8593d16..ef03022b8a6374c14d7b1b2e51e= 5c487e1d37df9 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -22,6 +22,7 @@ Industrial I/O Kernel Drivers ad3552r ad4000 ad4030 + ad4052 ad4695 ad7191 ad7380 diff --git a/MAINTAINERS b/MAINTAINERS index d000c7de7ff9eba390f87593bc2b1847f966f48b..32afd568b68e45616c291d689a3= 5ab905d421cd1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1342,6 +1342,7 @@ M: Jorge Marques S: Supported W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad4052.yaml +F: Documentation/iio/ad4052.rst =20 ANALOG DEVICES INC AD4080 DRIVER M: Antoniu Miclaus --=20 2.49.0 From nobody Sun Oct 5 20:44:17 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 77E5327FD6D; Tue, 10 Jun 2025 07:35:30 +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=1749540933; cv=none; b=q8gG+T3QKhWT0Sa8ssjelCtSYsD6/Y52FAtGw8LwT3TBq2tjl1ezcyz5GtcjBWg2ArGzgFm5vnGDJcJNdnL51XEkWfdpl9Z3nU/y35Xf5kKIwZxPCxQP2W6NcpcW1SB3d/lwnGOUhyQxO8+zp2Dfy4lSWMuH2SAVBEePvN0rlPo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749540933; c=relaxed/simple; bh=nsbwDEaQ87jz0r+Yd4hkac1GFqRNS+p42A3OZyXjPYU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=Z6LoG37Yyoe0GQ3lADNNRN4JxGY9igXScS6M2vwoiGavwoOQPLMb6zNrReT4JrZT/L771Rzn4tHCAM5Zl0eGsOV6niTTZD2Kfx3Ga35votqg0RN6M4qXqR6UtXmkqQPFELkF/Zy5eTIPZONf6SsLRrh2C9L96tTXb/FT4UE6D4A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none 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=GL0D/Cfb; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none 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="GL0D/Cfb" 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 55A6uqt8002452; Tue, 10 Jun 2025 03:35: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=Cae0R Co1qhmFd+xNGtbB8cx0+A7LtIgEx5zWn9pulf4=; b=GL0D/CfbUjzclqp/6OKDN jlu4gliWaz0UeiRMDJ0nDliVEnHiLZ8rMNwgEQa1pvuuRb4Q0u4zjdCZ6g61JkCn /weQLbPiPqm0fRyZ9agL8/kgxZLZUaxyzz5DrNokRoKJcF7K1V8TTm4MBh0Vi/QU D2zUZyF11/gUxPfwNPYizYsorQartbEym/STRUdDiWrGrZkO125X2Vu2dkKUzekW GtYkUufbWBwtG8yRKflxGQ73QTCCl4WZS/CKFjo74+UO7cxUww2fIbZ/X0LJjWY8 bXnMKgte/S/583gEZw04ycOnkJTJvQn5AdMStVcOz0MslXY1K5XK0A5E/JD+w3Ig A== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 476fvkr7ph-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 10 Jun 2025 03:35:08 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 55A7Z7Ri056149 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 10 Jun 2025 03:35:07 -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.10; Tue, 10 Jun 2025 03:35:07 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Tue, 10 Jun 2025 03:35: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.10 via Frontend Transport; Tue, 10 Jun 2025 03:35:07 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.51]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 55A7YkMi002608; Tue, 10 Jun 2025 03:35:01 -0400 From: Jorge Marques Date: Tue, 10 Jun 2025 09:34:37 +0200 Subject: [PATCH v3 4/8] iio: adc: Add support for ad4052 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: <20250610-iio-driver-ad4052-v3-4-cf1e44c516d4@analog.com> References: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> In-Reply-To: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> To: Jonathan Cameron , Lars-Peter Clausen , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , "Andy Shevchenko" , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= CC: , , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749540886; l=34100; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=nsbwDEaQ87jz0r+Yd4hkac1GFqRNS+p42A3OZyXjPYU=; b=qghtBMWbcr9XUWTUcrrrUPv3orUefwP6ZfjTZsyubusQcoUdGW3HvnyZW5zpjuoWIx+L2nWAl aMe0hskF7/KDpQ67z378rrN9hHhnanqLrTVZi4kRD7YN+o8n6xmTDp2 X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjEwMDA1NiBTYWx0ZWRfX51vzcpzv9HKe 9GsHbdCWnkXASPXRq8z8iE5sORGFKmn0PRktSPMhJAiDTBSveVhUG3vYQLCFyKv8Ay1jv7OvfiQ 6Fj+hekMaNu9GIa7porozyBSqgWWD49wnG5uK0IN7sDaUghOz1z6uTenlYnOOHnZMmqXUjBrD/f Fiaur9i5KlfpH4hJGW6hdfKzypb/qC6w+3DTpiOTiMtCCrVwdwa+ej6AkFcr9BBIYlvEWMEu8cY cphmD43W8101yOK2mrpIrc9UCdTKTcTodngWhtqfJCgvU5m9EuJjS0lQynnGnpE8j1FT3JHbKAL cE6lggd7PlddahTd0YU8Ntxwgd7CLLKkMs+8RiUbiKo5UvZEQ59eiMOkvPNsNUaDa/gV83WtjK6 xlXzNcwwPnLAdu60jTqm9DsaTyFhrlbTL0MLRBxD7+pIy9QFkpysPKSq6DEKZ4G3AeycnluN X-Proofpoint-GUID: S2kr9qov3E8EEy0mgpZpfxW6k3MSA5iz X-Authority-Analysis: v=2.4 cv=Coy/cm4D c=1 sm=1 tr=0 ts=6847e02c cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=6IFa9wvqVegA:10 a=gAnH3GRIAAAA:8 a=jXmY7Cu1mi1X9cUNsCcA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: S2kr9qov3E8EEy0mgpZpfxW6k3MSA5iz X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-10_02,2025-06-09_02,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 mlxlogscore=999 spamscore=0 lowpriorityscore=0 impostorscore=0 mlxscore=0 phishscore=0 bulkscore=0 clxscore=1015 suspectscore=0 adultscore=0 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2505280000 definitions=main-2506100056 The AD4052/AD4058/AD4050/AD4056 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 AD4052/AD4058/AD4050/AD4056 are ideal for battery-powered, compact data acquisition and edge sensing applications. Signed-off-by: Jorge Marques --- MAINTAINERS | 1 + drivers/iio/adc/Kconfig | 15 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad4052.c | 1083 ++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 1100 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 32afd568b68e45616c291d689a35ab905d421cd1..d83ac902e515575e1419df7505d= 2e8a96f69244a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1343,6 +1343,7 @@ S: Supported W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad4052.yaml F: Documentation/iio/ad4052.rst +F: drivers/iio/adc/ad4052.c =20 ANALOG DEVICES INC AD4080 DRIVER M: Antoniu Miclaus diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 3bd03df9a9761f20e2b1b71b51ebe43ba7f51b60..1fe14f939a4d9473b697b40f022= 124a2ae0b3245 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -55,6 +55,21 @@ config AD4030 To compile this driver as a module, choose M here: the module will be called ad4030. =20 +config AD4052 + tristate "Analog Devices AD4052 Driver" + depends on SPI + depends on GPIOLIB + select SPI_OFFLOAD + select IIO_BUFFER + select IIO_BUFFER_DMAENGINE + select REGMAP_SPI + help + Say yes here to build support for Analog Devices AD4052 SPI analog + to digital converters (ADC). + + To compile this driver as a module, choose M here: the module will be + called ad4052. + 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 6516ccb4d63bcfe2e2d56c39da7b906fdbe62319..dc3cd61df815fe7a7e77fad8563= 0794b8be11f86 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -10,6 +10,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_AD4052) +=3D ad4052.o obj-$(CONFIG_AD4080) +=3D ad4080.o obj-$(CONFIG_AD4130) +=3D ad4130.o obj-$(CONFIG_AD4695) +=3D ad4695.o diff --git a/drivers/iio/adc/ad4052.c b/drivers/iio/adc/ad4052.c new file mode 100644 index 0000000000000000000000000000000000000000..842f5972a1c58701addf5243e7b= 87da9c26c773f --- /dev/null +++ b/drivers/iio/adc/ad4052.c @@ -0,0 +1,1083 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Analog Devices AD4052 SPI ADC driver + * + * Copyright 2025 Analog Devices Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AD4052_REG_INTERFACE_CONFIG_A 0x00 +#define AD4052_REG_DEVICE_CONFIG 0x02 +#define AD4052_REG_DEVICE_CONFIG_POWER_MODE_MSK GENMASK(1, 0) +#define AD4052_REG_DEVICE_CONFIG_LOW_POWER_MODE 3 +#define AD4052_REG_PROD_ID_1 0x05 +#define AD4052_REG_DEVICE_GRADE 0x06 +#define AD4052_REG_SCRATCH_PAD 0x0A +#define AD4052_REG_VENDOR_H 0x0D +#define AD4052_REG_STREAM_MODE 0x0E +#define AD4052_REG_INTERFACE_STATUS 0x11 +#define AD4052_REG_INTERFACE_STATUS_NOT_RDY BIT(7) +#define AD4052_REG_MODE_SET 0x20 +#define AD4052_REG_MODE_SET_ENTER_ADC BIT(0) +#define AD4052_REG_ADC_MODES 0x21 +#define AD4052_REG_ADC_MODES_MODE_MSK GENMASK(1, 0) +#define AD4052_REG_ADC_MODES_DATA_FORMAT BIT(7) +#define AD4052_REG_ADC_CONFIG 0x22 +#define AD4052_REG_ADC_CONFIG_REF_EN_MSK BIT(5) +#define AD4052_REG_ADC_CONFIG_SCALE_EN_MSK BIT(4) +#define AD4052_REG_AVG_CONFIG 0x23 +#define AD4052_REG_GP_CONF 0x24 +#define AD4052_REG_GP_CONF_MODE_MSK_0 GENMASK(2, 0) +#define AD4052_REG_GP_CONF_MODE_MSK_1 GENMASK(6, 4) +#define AD4052_REG_INTR_CONF 0x25 +#define AD4052_REG_INTR_CONF_EN_MSK_0 GENMASK(1, 0) +#define AD4052_REG_INTR_CONF_EN_MSK_1 GENMASK(5, 4) +#define AD4052_REG_TIMER_CONFIG 0x27 +#define AD4052_REG_TIMER_CONFIG_FS_MASK GENMASK(7, 4) +#define AD4052_REG_TIMER_CONFIG_300KSPS 0x2 +#define AD4052_REG_MAX_LIMIT 0x29 +#define AD4052_REG_MIN_LIMIT 0x2B +#define AD4052_REG_MAX_HYST 0x2C +#define AD4052_REG_MIN_HYST 0x2D +#define AD4052_REG_MON_VAL 0x2F +#define AD4052_REG_FUSE_CRC 0x40 +#define AD4052_REG_DEVICE_STATUS 0x41 +#define AD4052_REG_DEVICE_STATUS_DEVICE_RDY BIT(7) +#define AD4052_REG_DEVICE_STATUS_DEVICE_RESET BIT(6) +#define AD4052_REG_MIN_SAMPLE 0x45 +#define AD4052_MAX_REG 0x45 + +#define AD4052_SPI_VENDOR 0x0456 + +#define AD4050_MAX_AVG 0x7 +#define AD4052_MAX_AVG 0xB +#define AD4052_MAX_RATE(x) ((x) =3D=3D AD4052_500KSPS ? 500000 : 2000000) +#define AD4052_FS_OFFSET(g) ((g) =3D=3D AD4052_500KSPS ? 2 : 0) +#define AD4052_FS(g) (&ad4052_conversion_freqs[AD4052_FS_OFFSET(g)]) +#define AD4052_FS_LEN(g) (ARRAY_SIZE(ad4052_conversion_freqs) - (AD4052_FS= _OFFSET(g))) +#define AD4052_MON_VAL_MAX_GAIN 1999970 +#define AD4052_MON_VAL_MIDDLE_POINT 0x8000 +#define AD4052_T_CNVH_NS 10 +#define AD4052_VIO_3V3 3300000 +#define AD4052_SPI_MAX_ADC_XFER_SPEED(x) ((x) >=3D AD4052_VIO_3V3 ? 833333= 33 : 58823529) +#define AD4052_SPI_MAX_REG_XFER_SPEED 16000000 + +enum ad4052_grade { + AD4052_2MSPS, + AD4052_500KSPS, +}; + +enum ad4052_operation_mode { + AD4052_SAMPLE_MODE =3D 0, + AD4052_BURST_AVERAGING_MODE =3D 1, + AD4052_MONITOR_MODE =3D 3, +}; + +enum ad4052_gp_mode { + AD4052_GP_DISABLED, + AD4052_GP_INTR, + AD4052_GP_DRDY, +}; + +enum ad4052_interrupt_en { + AD4052_INTR_EN_NEITHER, + AD4052_INTR_EN_MIN, + AD4052_INTR_EN_MAX, + AD4052_INTR_EN_EITHER, +}; + +struct ad4052_chip_info { + const struct iio_chan_spec channels[1]; + const char *name; + u16 prod_id; + u8 max_avg; + u8 grade; +}; + +enum { + AD4052_SCAN_TYPE_SAMPLE, + AD4052_SCAN_TYPE_BURST_AVG, +}; + +static const struct iio_scan_type ad4052_scan_type_12_s[] =3D { + [AD4052_SCAN_TYPE_SAMPLE] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, + [AD4052_SCAN_TYPE_BURST_AVG] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, +}; + +static const struct iio_scan_type ad4052_scan_type_16_s[] =3D { + [AD4052_SCAN_TYPE_SAMPLE] =3D { + .sign =3D 's', + .realbits =3D 16, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, + [AD4052_SCAN_TYPE_BURST_AVG] =3D { + .sign =3D 's', + .realbits =3D 24, + .storagebits =3D 32, + .endianness =3D IIO_CPU, + }, +}; + +struct ad4052_state { + const struct ad4052_bus_ops *ops; + const struct ad4052_chip_info *chip; + enum ad4052_operation_mode mode; + struct spi_device *spi; + struct pwm_device *cnv_pwm; + struct pwm_state pwm_st; + struct spi_transfer xfer; + struct gpio_desc *cnv_gp; + struct completion completion; + struct regmap *regmap; + u16 oversampling_frequency; + int gp1_irq; + int vio_uv; + int vref_uv; + u8 reg_tx[3]; + u8 reg_rx[3]; + u8 raw[4] __aligned(IIO_DMA_MINALIGN); + u8 buf_reset_pattern[18]; +}; + +static int ad4052_spi_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + int ret; + struct ad4052_state *st =3D context; + struct spi_transfer xfer =3D { + .tx_buf =3D st->reg_tx, + .rx_buf =3D st->reg_rx, + .len =3D reg_size + val_size, + .speed_hz =3D AD4052_SPI_MAX_REG_XFER_SPEED, + }; + + if (xfer.len > sizeof(st->reg_tx) || + xfer.len > sizeof(st->reg_rx)) + return -EINVAL; + + memset(st->reg_tx, 0, sizeof(st->reg_tx)); + memcpy(st->reg_tx, reg, reg_size); + + ret =3D spi_sync_transfer(st->spi, &xfer, 1); + if (ret) + return ret; + + memcpy(val, &st->reg_rx[reg_size], val_size); + + return 0; +} + +static int ad4052_spi_write(void *context, const void *data, size_t count) +{ + struct ad4052_state *st =3D context; + struct spi_transfer xfer =3D { + .tx_buf =3D st->reg_tx, + .len =3D count, + .speed_hz =3D AD4052_SPI_MAX_REG_XFER_SPEED, + }; + + if (count > sizeof(st->reg_tx)) + return -EINVAL; + + memcpy(st->reg_tx, data, count); + + return spi_sync_transfer(st->spi, &xfer, 1); +} + +/* To limit the configuration mode access speed */ +static const struct regmap_bus ad4052_regmap_bus =3D { + .read =3D ad4052_spi_read, + .write =3D ad4052_spi_write, + .reg_format_endian_default =3D REGMAP_ENDIAN_BIG, +}; + +static const struct regmap_range ad4052_regmap_rd_ranges[] =3D { + regmap_reg_range(AD4052_REG_INTERFACE_CONFIG_A, AD4052_REG_DEVICE_GRADE), + regmap_reg_range(AD4052_REG_SCRATCH_PAD, AD4052_REG_INTERFACE_STATUS), + regmap_reg_range(AD4052_REG_MODE_SET, AD4052_REG_MON_VAL), + regmap_reg_range(AD4052_REG_FUSE_CRC, AD4052_REG_MIN_SAMPLE), +}; + +static const struct regmap_access_table ad4052_regmap_rd_table =3D { + .yes_ranges =3D ad4052_regmap_rd_ranges, + .n_yes_ranges =3D ARRAY_SIZE(ad4052_regmap_rd_ranges), +}; + +static const struct regmap_range ad4052_regmap_wr_ranges[] =3D { + regmap_reg_range(AD4052_REG_INTERFACE_CONFIG_A, AD4052_REG_DEVICE_CONFIG), + regmap_reg_range(AD4052_REG_SCRATCH_PAD, AD4052_REG_SCRATCH_PAD), + regmap_reg_range(AD4052_REG_STREAM_MODE, AD4052_REG_INTERFACE_STATUS), + regmap_reg_range(AD4052_REG_MODE_SET, AD4052_REG_MON_VAL), + regmap_reg_range(AD4052_REG_FUSE_CRC, AD4052_REG_DEVICE_STATUS), +}; + +static const struct regmap_access_table ad4052_regmap_wr_table =3D { + .yes_ranges =3D ad4052_regmap_wr_ranges, + .n_yes_ranges =3D ARRAY_SIZE(ad4052_regmap_wr_ranges), +}; + +static const char *const ad4052_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 ad4052_conversion_frequency_set(struct ad4052_state *st, u8 val) +{ + val +=3D AD4052_FS_OFFSET(st->chip->grade); + return regmap_write(st->regmap, AD4052_REG_TIMER_CONFIG, + FIELD_PREP(AD4052_REG_TIMER_CONFIG_FS_MASK, val)); +} + +static int ad4052_oversampling_frequency_get(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + + return st->oversampling_frequency - AD4052_FS_OFFSET(st->chip->grade); +} + +static int ad4052_oversampling_frequency_set(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int val) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + + val +=3D AD4052_FS_OFFSET(st->chip->grade); + st->oversampling_frequency =3D val; + + return 0; +} + +static const struct iio_enum AD4052_500KSPS_conversion_freq_enum =3D { + .items =3D AD4052_FS(AD4052_500KSPS), + .num_items =3D AD4052_FS_LEN(AD4052_500KSPS), + .set =3D ad4052_oversampling_frequency_set, + .get =3D ad4052_oversampling_frequency_get, +}; + +static const struct iio_enum AD4052_2MSPS_conversion_freq_enum =3D { + .items =3D AD4052_FS(AD4052_2MSPS), + .num_items =3D AD4052_FS_LEN(AD4052_2MSPS), + .set =3D ad4052_oversampling_frequency_set, + .get =3D ad4052_oversampling_frequency_get, +}; + +#define AD4052_EXT_INFO(grade) \ +static struct iio_chan_spec_ext_info grade##_ext_info[] =3D { \ + IIO_ENUM("oversampling_frequency", IIO_SHARED_BY_ALL, \ + &grade##_conversion_freq_enum), \ + IIO_ENUM_AVAILABLE("oversampling_frequency", IIO_SHARED_BY_ALL, \ + &grade##_conversion_freq_enum), \ + { } \ +} + +AD4052_EXT_INFO(AD4052_2MSPS); +AD4052_EXT_INFO(AD4052_500KSPS); + +#define AD4052_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 ad4052_scan_type_##bits##_s, \ + .num_ext_scan_type =3D ARRAY_SIZE(ad4052_scan_type_##bits##_s), \ + .ext_info =3D grade##_ext_info, \ +} + +#define AD4052_OFFLOAD_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) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .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 ad4052_scan_type_##bits##_s, \ + .num_ext_scan_type =3D ARRAY_SIZE(ad4052_scan_type_##bits##_s), \ + .ext_info =3D grade##_ext_info, \ +} + +static const struct ad4052_chip_info ad4050_chip_info =3D { + .name =3D "ad4050", + .channels =3D { AD4052_CHAN(12, AD4052_2MSPS) }, + .prod_id =3D 0x70, + .max_avg =3D AD4050_MAX_AVG, + .grade =3D AD4052_2MSPS, +}; + +static const struct ad4052_chip_info ad4052_chip_info =3D { + .name =3D "ad4052", + .channels =3D { AD4052_CHAN(16, AD4052_2MSPS) }, + .prod_id =3D 0x72, + .max_avg =3D AD4052_MAX_AVG, + .grade =3D AD4052_2MSPS, +}; + +static const struct ad4052_chip_info ad4056_chip_info =3D { + .name =3D "ad4056", + .channels =3D { AD4052_CHAN(12, AD4052_500KSPS) }, + .prod_id =3D 0x76, + .max_avg =3D AD4050_MAX_AVG, + .grade =3D AD4052_500KSPS, +}; + +static const struct ad4052_chip_info ad4058_chip_info =3D { + .name =3D "ad4058", + .channels =3D { AD4052_CHAN(16, AD4052_500KSPS) }, + .prod_id =3D 0x78, + .max_avg =3D AD4052_MAX_AVG, + .grade =3D AD4052_500KSPS, +}; + +static int ad4052_update_xfer_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + const struct iio_scan_type *scan_type; + struct spi_transfer *xfer =3D &st->xfer; + + scan_type =3D iio_get_current_scan_type(indio_dev, chan); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); + + xfer->rx_buf =3D st->raw; + xfer->bits_per_word =3D scan_type->realbits; + xfer->len =3D scan_type->realbits =3D=3D 24 ? 4 : 2; + xfer->speed_hz =3D AD4052_SPI_MAX_ADC_XFER_SPEED(st->vio_uv); + + return 0; +} + +static int ad4052_set_oversampling_ratio(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int val) +{ + struct ad4052_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 AD4052_SAMPLE_MODE; + } else { + val =3D ilog2(val); + st->mode =3D AD4052_BURST_AVERAGING_MODE; + ret =3D regmap_write(st->regmap, AD4052_REG_AVG_CONFIG, val - 1); + if (ret) + return ret; + } + + return ad4052_update_xfer_raw(indio_dev, chan); +} + +static int ad4052_get_oversampling_ratio(struct ad4052_state *st, + unsigned int *val) +{ + int ret, buf; + + if (st->mode =3D=3D AD4052_SAMPLE_MODE) { + *val =3D 1; + return 0; + } + + ret =3D regmap_read(st->regmap, AD4052_REG_AVG_CONFIG, &buf); + if (ret) + return ret; + + *val =3D BIT(buf + 1); + + return 0; +} + +static int ad4052_check_ids(struct ad4052_state *st) +{ + int ret; + u16 val; + + ret =3D regmap_bulk_read(st->regmap, AD4052_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->spi->dev, + "Production ID x%x does not match known values", val); + + ret =3D regmap_bulk_read(st->regmap, AD4052_REG_VENDOR_H, &st->raw, 2); + if (ret) + return ret; + + val =3D get_unaligned_be16(st->raw); + if (val !=3D AD4052_SPI_VENDOR) + return -ENODEV; + + return 0; +} + +static int ad4052_exit_command(struct ad4052_state *st) +{ + struct spi_device *spi =3D st->spi; + const u8 val =3D 0xA8; + + return spi_write(spi, &val, 1); +} + +static int ad4052_set_operation_mode(struct ad4052_state *st, + enum ad4052_operation_mode mode) +{ + int ret; + + if (mode =3D=3D AD4052_BURST_AVERAGING_MODE) { + ret =3D ad4052_conversion_frequency_set(st, st->oversampling_frequency); + if (ret) + return ret; + } + + ret =3D regmap_update_bits(st->regmap, AD4052_REG_ADC_MODES, + AD4052_REG_ADC_MODES_MODE_MSK, mode); + if (ret) + return ret; + + return regmap_write(st->regmap, AD4052_REG_MODE_SET, + AD4052_REG_MODE_SET_ENTER_ADC); +} + +static int ad4052_set_sampling_freq(struct ad4052_state *st, unsigned int = freq) +{ + const u32 start =3D 1; + + if (!in_range(freq, start, AD4052_MAX_RATE(st->chip->grade))) + return -EINVAL; + + st->pwm_st.period =3D DIV_ROUND_UP_ULL(NSEC_PER_SEC, freq); + return pwm_apply_might_sleep(st->cnv_pwm, &st->pwm_st); +} + +static int ad4052_soft_reset(struct ad4052_state *st) +{ + int ret; + + memset(st->buf_reset_pattern, 0xFF, sizeof(st->buf_reset_pattern)); + st->buf_reset_pattern[5] =3D 0xFE; + st->buf_reset_pattern[11] =3D 0xFE; + st->buf_reset_pattern[17] =3D 0xFE; + + ret =3D spi_write(st->spi, st->buf_reset_pattern, + sizeof(st->buf_reset_pattern)); + if (ret) + return ret; + + /* Wait AD4052 reset delay */ + fsleep(5000); + + return 0; +} + +static int ad4052_setup(struct iio_dev *indio_dev, struct iio_chan_spec co= nst *chan, + const bool *ref_sel) +{ + struct ad4052_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(AD4052_REG_GP_CONF_MODE_MSK_0, AD4052_GP_INTR) | + FIELD_PREP(AD4052_REG_GP_CONF_MODE_MSK_1, AD4052_GP_DRDY); + + ret =3D regmap_update_bits(st->regmap, AD4052_REG_GP_CONF, + AD4052_REG_GP_CONF_MODE_MSK_1 | AD4052_REG_GP_CONF_MODE_MSK_0, + val); + if (ret) + return ret; + + val =3D FIELD_PREP(AD4052_REG_INTR_CONF_EN_MSK_0, (AD4052_INTR_EN_EITHER)= ) | + FIELD_PREP(AD4052_REG_INTR_CONF_EN_MSK_1, (AD4052_INTR_EN_NEITHER)); + + if (st->chip->grade =3D=3D AD4052_500KSPS) { + ret =3D regmap_write(st->regmap, AD4052_REG_TIMER_CONFIG, + FIELD_PREP(AD4052_REG_TIMER_CONFIG_FS_MASK, + AD4052_REG_TIMER_CONFIG_300KSPS)); + if (ret) + return ret; + } + + ret =3D regmap_update_bits(st->regmap, AD4052_REG_ADC_MODES, + AD4052_REG_ADC_CONFIG_REF_EN_MSK, + FIELD_PREP(AD4052_REG_ADC_CONFIG_REF_EN_MSK, + *ref_sel)); + if (ret) + return ret; + + ret =3D regmap_write(st->regmap, AD4052_REG_DEVICE_STATUS, + AD4052_REG_DEVICE_STATUS_DEVICE_RESET); + if (ret) + return ret; + + return regmap_update_bits(st->regmap, AD4052_REG_INTR_CONF, + AD4052_REG_INTR_CONF_EN_MSK_0 | AD4052_REG_INTR_CONF_EN_MSK_1, + val); +} + +static irqreturn_t ad4052_irq_handler_drdy(int irq, void *private) +{ + struct ad4052_state *st =3D private; + + complete(&st->completion); + return IRQ_HANDLED; +} + +static int ad4052_request_irq(struct iio_dev *indio_dev) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + struct device *dev =3D &st->spi->dev; + int ret; + + ret =3D fwnode_irq_get_byname(dev_fwnode(&st->spi->dev), "gp1"); + if (ret > 0) { + ret =3D devm_request_threaded_irq(dev, ret, NULL, + ad4052_irq_handler_drdy, + IRQF_ONESHOT, indio_dev->name, + st); + st->gp1_irq =3D ret; + } else if (ret =3D=3D -EPROBE_DEFER) { + return ret; + } + return 0; +} + +static const int ad4052_oversampling_avail[] =3D { + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, +}; + +static int ad4052_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 ad4052_oversampling_avail; + *len =3D ARRAY_SIZE(ad4052_oversampling_avail); + *type =3D IIO_VAL_INT; + + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int ad4052_get_samp_freq(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + + *val =3D DIV_ROUND_UP_ULL(NSEC_PER_SEC, st->pwm_st.period); + return IIO_VAL_INT; +} + +static int ad4052_get_chan_scale(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2) +{ + struct ad4052_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 ad4052_get_chan_calibscale(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + u16 gain; + int ret; + + ret =3D regmap_bulk_read(st->regmap, AD4052_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 / AD4052_MON_VAL_MIDDLE_POINT; + *val2 =3D mul_u64_u32_div(gain % AD4052_MON_VAL_MIDDLE_POINT, NANO, + AD4052_MON_VAL_MIDDLE_POINT); + + return IIO_VAL_INT_PLUS_NANO; +} + +static int ad4052_set_chan_calibscale(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int gain_int, + int gain_frac) +{ + struct ad4052_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 > AD4052_MON_VAL_MAX_GAIN) + return -EINVAL; + + put_unaligned_be16(DIV_ROUND_CLOSEST_ULL(gain * AD4052_MON_VAL_MIDDLE_POI= NT, + MICRO), + &st->raw); + + ret =3D regmap_bulk_write(st->regmap, AD4052_REG_MON_VAL, &st->raw, 2); + if (ret) + return ret; + + return regmap_update_bits(st->regmap, AD4052_REG_ADC_MODES, + AD4052_REG_ADC_CONFIG_SCALE_EN_MSK, + FIELD_PREP(AD4052_REG_ADC_CONFIG_SCALE_EN_MSK, + !(gain_int =3D=3D 1 && gain_frac =3D=3D 0))); +} + +static int __ad4052_read_chan_raw(struct ad4052_state *st, int *val) +{ + struct spi_device *spi =3D st->spi; + struct spi_transfer t_cnv =3D {}; + int ret; + + reinit_completion(&st->completion); + + if (st->cnv_gp) { + gpiod_set_value_cansleep(st->cnv_gp, 1); + gpiod_set_value_cansleep(st->cnv_gp, 0); + } else { + ret =3D spi_sync_transfer(spi, &t_cnv, 1); + if (ret) + return ret; + } + /* + * Single sample read should be used only for oversampling and + * sampling frequency pairs that take less than 1 sec. + */ + if (st->gp1_irq) { + ret =3D wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(1000)); + if (!ret) + return -ETIMEDOUT; + } + + ret =3D spi_sync_transfer(spi, &st->xfer, 1); + if (ret) + return ret; + + if (st->xfer.len =3D=3D 2) + *val =3D sign_extend32(*(u16 *)(st->raw), 15); + else + *val =3D sign_extend32(*(u32 *)(st->raw), 23); + + return ret; +} + +static int ad4052_read_chan_raw(struct iio_dev *indio_dev, int *val) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + int ret; + + ret =3D pm_runtime_resume_and_get(&st->spi->dev); + if (ret) + return ret; + + ret =3D ad4052_set_operation_mode(st, st->mode); + if (ret) + goto out_error; + + ret =3D __ad4052_read_chan_raw(st, val); + if (ret) + goto out_error; + + ret =3D ad4052_exit_command(st); + +out_error: + pm_runtime_mark_last_busy(&st->spi->dev); + pm_runtime_put_autosuspend(&st->spi->dev); + return ret; +} + +static int ad4052_read_raw_dispatch(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long info) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_RAW: + return ad4052_read_chan_raw(indio_dev, val); + + case IIO_CHAN_INFO_CALIBSCALE: + return ad4052_get_chan_calibscale(indio_dev, chan, val, val2); + + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + return ad4052_get_oversampling_ratio(st, val); + + default: + return -EINVAL; + } +} + +static int ad4052_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_SAMP_FREQ) + return ad4052_get_samp_freq(indio_dev, chan, val, val2); + else if (info =3D=3D IIO_CHAN_INFO_SCALE) + return ad4052_get_chan_scale(indio_dev, chan, val, val2); + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret =3D ad4052_read_raw_dispatch(indio_dev, chan, val, val2, info); + iio_device_release_direct(indio_dev); + return ret ? ret : IIO_VAL_INT; +} + +static int ad4052_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 ad4052_set_oversampling_ratio(indio_dev, chan, val); + + case IIO_CHAN_INFO_CALIBSCALE: + return ad4052_set_chan_calibscale(indio_dev, chan, val, val2); + + default: + return -EINVAL; + } +}; + +static int ad4052_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, + int val2, long info) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + int ret; + + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + return ad4052_set_sampling_freq(st, val); + } + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret =3D ad4052_write_raw_dispatch(indio_dev, chan, val, val2, info); + iio_device_release_direct(indio_dev); + return ret; +} + +static int ad4052_debugfs_reg_access(struct iio_dev *indio_dev, unsigned i= nt reg, + unsigned int writeval, unsigned int *readval) +{ + struct ad4052_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 ad4052_get_current_scan_type(const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + + return st->mode =3D=3D AD4052_BURST_AVERAGING_MODE ? + AD4052_SCAN_TYPE_BURST_AVG : + AD4052_SCAN_TYPE_SAMPLE; +} + +static const struct iio_info ad4052_info =3D { + .read_raw =3D ad4052_read_raw, + .write_raw =3D ad4052_write_raw, + .read_avail =3D ad4052_read_avail, + .get_current_scan_type =3D &ad4052_get_current_scan_type, + .debugfs_reg_access =3D &ad4052_debugfs_reg_access, +}; + +static const struct regmap_config ad4052_regmap_config =3D { + .name =3D "ad4052", + .reg_bits =3D 8, + .val_bits =3D 8, + .max_register =3D AD4052_MAX_REG, + .rd_table =3D &ad4052_regmap_rd_table, + .wr_table =3D &ad4052_regmap_wr_table, + .read_flag_mask =3D BIT(7), + .can_sleep =3D true, +}; + +static int __ad4052_validate_trigger_sources(struct of_phandle_args *trigg= er_sources) +{ + switch (trigger_sources->args[1]) { + case AD4052_TRIGGER_PIN_GP1: + return trigger_sources->args[0] =3D=3D AD4052_TRIGGER_EVENT_DATA_READY ? + 0 : -EINVAL; + default: + return -EINVAL; + } +} + +static int ad4052_validate_trigger_sources(struct iio_dev *indio_dev) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + struct of_phandle_args trigger_sources; + struct device_node *np; + int ret; + + np =3D st->spi->dev.of_node; + ret =3D of_parse_phandle_with_args(np, "trigger-sources", + "#trigger-source-cells", 0, + &trigger_sources); + if (ret) + return ret; + + ret =3D __ad4052_validate_trigger_sources(&trigger_sources); + of_node_put(trigger_sources.np); + return ret; +} + +static int ad4052_regulators_get(struct ad4052_state *st, bool *ref_sel) +{ + struct device *dev =3D &st->spi->dev; + int uv; + + st->vio_uv =3D devm_regulator_get_enable_read_voltage(dev, "vio"); + if (st->vio_uv < 0) + return dev_err_probe(dev, st->vio_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 int ad4052_probe(struct spi_device *spi) +{ + const struct ad4052_chip_info *chip; + struct device *dev =3D &spi->dev; + struct iio_dev *indio_dev; + struct ad4052_state *st; + bool ref_sel; + int ret; + + chip =3D spi_get_device_match_data(spi); + if (!chip) + return dev_err_probe(dev, -ENODEV, + "Could not find chip info data\n"); + + indio_dev =3D devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st =3D iio_priv(indio_dev); + st->spi =3D spi; + spi_set_drvdata(spi, st); + init_completion(&st->completion); + + ret =3D ad4052_regulators_get(st, &ref_sel); + if (ret) + return ret; + + st->regmap =3D devm_regmap_init(dev, &ad4052_regmap_bus, st, + &ad4052_regmap_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(dev, PTR_ERR(st->regmap), + "Failed to initialize regmap\n"); + + st->mode =3D AD4052_SAMPLE_MODE; + st->chip =3D chip; + st->oversampling_frequency =3D AD4052_FS_OFFSET(st->chip->grade); + + st->cnv_gp =3D devm_gpiod_get_optional(dev, "cnv", GPIOD_OUT_LOW); + if (IS_ERR(st->cnv_gp)) + return dev_err_probe(dev, PTR_ERR(st->cnv_gp), + "Failed to get cnv gpio\n"); + + indio_dev->modes =3D INDIO_DIRECT_MODE; + indio_dev->num_channels =3D 1; + indio_dev->info =3D &ad4052_info; + indio_dev->name =3D chip->name; + + ret =3D ad4052_validate_trigger_sources(indio_dev); + if (ret) + return dev_err_probe(dev, ret, + "Failed to validate trigger sources\n"); + + ret =3D ad4052_soft_reset(st); + if (ret) + return dev_err_probe(dev, ret, "AD4052 failed to soft reset\n"); + + ret =3D ad4052_check_ids(st); + if (ret) + return dev_err_probe(dev, ret, + "AD4052 fields assertions failed\n"); + + ret =3D ad4052_setup(indio_dev, indio_dev->channels, &ref_sel); + if (ret) + return ret; + + ret =3D ad4052_request_irq(indio_dev); + if (ret) + return ret; + + ret =3D ad4052_update_xfer_raw(indio_dev, indio_dev->channels); + 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); + + return devm_iio_device_register(dev, indio_dev); +} + +static int ad4052_runtime_suspend(struct device *dev) +{ + struct ad4052_state *st =3D dev_get_drvdata(dev); + + return regmap_write(st->regmap, AD4052_REG_DEVICE_CONFIG, + FIELD_PREP(AD4052_REG_DEVICE_CONFIG_POWER_MODE_MSK, + AD4052_REG_DEVICE_CONFIG_LOW_POWER_MODE)); +} + +static int ad4052_runtime_resume(struct device *dev) +{ + struct ad4052_state *st =3D dev_get_drvdata(dev); + int ret; + + ret =3D regmap_clear_bits(st->regmap, AD4052_REG_DEVICE_CONFIG, + AD4052_REG_DEVICE_CONFIG_POWER_MODE_MSK); + + fsleep(4000); + return ret; +} + +static DEFINE_RUNTIME_DEV_PM_OPS(ad4052_pm_ops, ad4052_runtime_suspend, + ad4052_runtime_resume, NULL); + +static const struct spi_device_id ad4052_id_table[] =3D { + {"ad4050", (kernel_ulong_t)&ad4050_chip_info }, + {"ad4052", (kernel_ulong_t)&ad4052_chip_info }, + {"ad4056", (kernel_ulong_t)&ad4056_chip_info }, + {"ad4058", (kernel_ulong_t)&ad4058_chip_info }, + { } +}; +MODULE_DEVICE_TABLE(spi, ad4052_id_table); + +static const struct of_device_id ad4052_of_match[] =3D { + { .compatible =3D "adi,ad4050", .data =3D &ad4050_chip_info }, + { .compatible =3D "adi,ad4052", .data =3D &ad4052_chip_info }, + { .compatible =3D "adi,ad4056", .data =3D &ad4056_chip_info }, + { .compatible =3D "adi,ad4058", .data =3D &ad4058_chip_info }, + { } +}; +MODULE_DEVICE_TABLE(of, ad4052_of_match); + +static struct spi_driver ad4052_driver =3D { + .driver =3D { + .name =3D "ad4052", + .of_match_table =3D ad4052_of_match, + .pm =3D pm_ptr(&ad4052_pm_ops), + }, + .probe =3D ad4052_probe, + .id_table =3D ad4052_id_table, +}; +module_spi_driver(ad4052_driver); + +MODULE_AUTHOR("Jorge Marques "); +MODULE_DESCRIPTION("Analog Devices AD4052"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER"); --=20 2.49.0 From nobody Sun Oct 5 20:44:17 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 77DAE27FD6B; Tue, 10 Jun 2025 07:35:30 +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=1749540932; cv=none; b=N0vibb5nx8ycnsiISxKwKkx6M1YUSeg1/CENw9X7H1kkKLdqEthFk+9K1TvLTxrfYgcb4X2rBrsKnDDw0AqfWhq9gksuwttgjBe36LzD+/aWucO7d+prF4fYSdeVG+/doelnx4V4G7is6ccEi2gKNb7gS06bnck+8DbrP5tTEIk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749540932; c=relaxed/simple; bh=LpB0tn2W8J57FOE/gT31lMBVVdtKo2lsnkxO3IobWoQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=hCmH5nqYmggPw+OM2kQPt5cIz/af/m9PDHi5DtavaaVt3RWZRBjlSEi+ujxC19nDMVB92B4hrU5skagyOv2dw/fZT5al81Fy/VDfFUBso+rJYpE1wcT3xWdeT7zZokANv1+awkjb+xmKhMrutW2JNSELsiluvVxyPpgPTAPNIV8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none 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=SSMIWlDK; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none 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="SSMIWlDK" 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 55A6lCQ8030659; Tue, 10 Jun 2025 03:35:11 -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=adjeN tw0XQXx7CGsSo6c8VElZl2N4SywtE1Yxk4K2KQ=; b=SSMIWlDKKBk8Olhs6chpw 5xp/i+Fne5fp1I3OAjmRUUQsZSORrvQw1+BbQtwmRFN/WfQg4FidSl6FIGLD4Tsz PRwUDfXjjNw5h9iFTRlE3D7dCU1PrZjPvQdaM7SCRBkDMwuLjJuPdJbfAnTv6n+z n6aEq5LEmBo/5mepGSBaGmFTKrvUxQg2KqfojvFBqveq6UGFYPjn66hoMYoeQkM8 lR/PrOMQUgKEtxOYkW6s8Xlj3JNBLeJ8cMHG6+KwYQtc2dxnkjPPB24w0845MQ2N 7dKx/HxtTXPUSgiUiUuwA4FQ9t9s6RraHIqwveVG7MEeY4CRnF3sVv6MIaosyFIa w== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 476fc30bkg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 10 Jun 2025 03:35:10 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 55A7Z91X056157 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 10 Jun 2025 03:35:09 -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.10; Tue, 10 Jun 2025 03:35:09 -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.10 via Frontend Transport; Tue, 10 Jun 2025 03:35:09 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.51]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 55A7YkMj002608; Tue, 10 Jun 2025 03:35:03 -0400 From: Jorge Marques Date: Tue, 10 Jun 2025 09:34:38 +0200 Subject: [PATCH v3 5/8] docs: iio: ad4052: Add offload support documentation 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: <20250610-iio-driver-ad4052-v3-5-cf1e44c516d4@analog.com> References: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> In-Reply-To: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> To: Jonathan Cameron , Lars-Peter Clausen , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= CC: , , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749540886; l=1826; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=LpB0tn2W8J57FOE/gT31lMBVVdtKo2lsnkxO3IobWoQ=; b=gASwBhMMaHdCRv4Vgk2/VpMe65RuPPDsnn+Uyu5xAKCfhzYFNe5zhAftG5PKERUGOlwbJFxro qLHyKV2qP84C2D9gJ++nH7Txq5M7F6b6oi76mFdgRVd3IIaxPxwLSrx X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: EYNPHrycvRh5RSJZAG4llzmJl9D6xp_R X-Proofpoint-ORIG-GUID: EYNPHrycvRh5RSJZAG4llzmJl9D6xp_R X-Authority-Analysis: v=2.4 cv=LtaSymdc c=1 sm=1 tr=0 ts=6847e02e cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=6IFa9wvqVegA:10 a=wI1k2SEZAAAA:8 a=gAnH3GRIAAAA:8 a=d3jCkwYfNc7Hc5xPy-QA:9 a=QEXdDO2ut3YA:10 a=6HWbV-4b7c7AdzY24d_u:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjEwMDA1NiBTYWx0ZWRfX3Lbf+Jp+a27B LIOj4O2rONhlQ2H1Lwr0nGPAotpSdxMN3fdD1UsWWBYUYjAopojWACWGZqYoloOueHOhEFqrHp7 0gXD2JaZwBpnPrFRO2y+jVDamWWaFNHxMATmAuOzmGcykYcPjchBJUulApqKjjzt98xDY9nK1WH U9Ho8nm7LhAnAMdiD3RZRgGn9fzyXabEXdeQ1gMF/AusdiHZo3oVMPfLFmkmQRhTk/1tT6hTbhz Xofp/MRCt8a9kSK5mdPRegzh6OliU6QVa5dwTgdM6JQSEes+sB/kVHAu0dySuFIy0orVTdCCkUx +6oCmfUzm16hFBg9luDgsektuQjeziiBDmnMV83+kfHAzwLypCETfpLFxZPQFugS5D30b14cVZ6 rnpoKAhI5ltL8XfGHBbTXe+vA9LLvjmiQeeqt8N8GdlT8v4HMvMdydyv901CSzkIi28wsosa X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-10_02,2025-06-09_02,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 malwarescore=0 priorityscore=1501 phishscore=0 lowpriorityscore=0 mlxlogscore=906 impostorscore=0 mlxscore=0 spamscore=0 clxscore=1015 suspectscore=0 bulkscore=0 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2505280000 definitions=main-2506100056 Explain the AD4052 support for the SPI Engine Offload. Signed-off-by: Jorge Marques --- Documentation/iio/ad4052.rst | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Documentation/iio/ad4052.rst b/Documentation/iio/ad4052.rst index 25e55eb72e167bd2b2195ba789b45ce402869b0f..2ad1c7712766118b03c48929d1f= 2b7670d5f8d41 100644 --- a/Documentation/iio/ad4052.rst +++ b/Documentation/iio/ad4052.rst @@ -49,6 +49,12 @@ The ADC contains only one channel with following attribu= tes: * - ``in_voltage_oversampling_ratio_available`` - List of available oversampling values. Value 1 disable the burst averaging mode. + * - ``in_voltage_sampling_frequency`` + - Set the sampling frequency, only present if SPI Offload is being us= ed. + +If `gp1` interrupt is not set, the driver will not wait for the data ready +assertion, and will result in reading a sample before it's ready, particul= arly +in oversampling mode. =20 Also contain the following device attributes: =20 @@ -69,3 +75,21 @@ Low-power mode The device enters low-power mode on idle to save power. Enabling an event = puts the device out of the low-power since the ADC autonomously samples to asse= rt the event condition. + +SPI offload support +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +To be able to achieve the maximum sample rate, the driver can be used with= the +`AXI SPI Engine`_ to provide SPI offload support. + +.. _AXI SPI Engine: http://analogdevicesinc.github.io/hdl/projects/ad4052_= ardz/index.html + +When SPI offload is being used, additional attributes are present: + +.. list-table:: Additional attributes + :header-rows: 1 + + * - Attribute + - Description + * - ``in_voltage_sampling_frequency`` + - Set the sampling frequency. --=20 2.49.0 From nobody Sun Oct 5 20:44:17 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 057622206BB; Tue, 10 Jun 2025 07:35:28 +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=1749540931; cv=none; b=nFpzHidTm+E73qO44h9mQvja/g3tqBKzwFEQseDhmMgwexTHsdUNbRNCCoZVf+ePHauU11O7uUNTykRYcCS9Sl8jugZ9lZt1lSi0Gvd6rIuIKszWJhPFagyT/SeYBylNBCrj0z2914RmCJYkEXUk+n+lHG+I1LzH7JELI8y73LA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749540931; c=relaxed/simple; bh=i0pnK2upq34spPsr7tqHTfnCvIIXQXxDLrEbaLwdRIE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=Nm+m/J2pXorpPfl5921gPN9OBoAOaPa5Pgv+Raw0NtBucAiiiyTNK0+h0qnRvW9RsnLMvnJbSBZ4irCbaaW2QecKkU56LpqRWavzr8x5rmQn8ifwVtbI3pcKpZkC/lOcK+AGtebkQecarFnXjglt1upGEQ2aJJ9P0yPnrqYiOg4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none 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=GD7gULYd; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none 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="GD7gULYd" 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 55A7LvV1027953; Tue, 10 Jun 2025 03:35:15 -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=SRXRC CyCRxIiTIx/757L72mrpYSXoLuQlWNEqBlIzYA=; b=GD7gULYdYHwKFRduEbfZ/ zQRZ2kOj0q8WC4059QJQAq6wznJAq6awxyDJYqg8PbzIUrWtPNlK1yJ3ns1Grq22 30z+ac6wly+QwbHTaPDZpy7xpzJWIxF/TCWzcumzwc/h0sAXBTUnKbezWfa46dMb kthuIhmhfE9/Xu4UyMzmHSMn3tp1IznH/+NIjOVfBO5VAZdKerZDRie7EUsXFZU5 gj670gi6fv9kpYt7G/vE5YsiOHwAr66/KuFoq0pKOJS71xgcki98a5XRiDvZZoIL lZDwERl9G+bQdxeq2AASYCEu6bDw5Y7Qyy6IBzPhIzeodJEypslR5Sdqh/s5hgqE g== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 475u346d0r-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 10 Jun 2025 03:35:14 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 55A7ZDRX013965 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 10 Jun 2025 03:35:13 -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.10; Tue, 10 Jun 2025 03:35:13 -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.10 via Frontend Transport; Tue, 10 Jun 2025 03:35:13 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.51]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 55A7YkMk002608; Tue, 10 Jun 2025 03:35:05 -0400 From: Jorge Marques Date: Tue, 10 Jun 2025 09:34:39 +0200 Subject: [PATCH v3 6/8] iio: adc: Add offload support for ad4052 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: <20250610-iio-driver-ad4052-v3-6-cf1e44c516d4@analog.com> References: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> In-Reply-To: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> To: Jonathan Cameron , Lars-Peter Clausen , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= CC: , , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749540886; l=11707; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=i0pnK2upq34spPsr7tqHTfnCvIIXQXxDLrEbaLwdRIE=; b=Rg0itiD/eulVab8Z7Dy2tZi0FJpZ8+Fg5CTIP2NyHh7b1EdqjnPQDEEMQ5jF9kFeCnuy3BW5s wri4VLpF0YbA+JJo1uu7JLyy44ia4T5daC4RjojXRUy7KBqd6m/OkMy X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=R74DGcRX c=1 sm=1 tr=0 ts=6847e032 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=6IFa9wvqVegA:10 a=gAnH3GRIAAAA:8 a=9AuMBu_mA1_DZbfGTuoA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: gJ0fUKD_gIniHevtMjs0MT07qIiyaA2j X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjEwMDA1NiBTYWx0ZWRfX1RcwwynuK/Hr W3ezT/9piSwEeigQxm0FyoJZiuhBl6fyvRuI5jiWPxnPmUtdBOYv2uyh0fPTCC33Fl354617DDs 1rZA5HoOfnwa3tdO3yLCsGaV1XxAHkqlOY1DCWtfOIdvHlFTnKAdREtBvM6Isp+S6hFu2mHjEgV 9GclhgHpGplIa0TsIqCd9xO6U8/YgsVFBgpQhzPYPYBTWTZUqkVaRxkGuG1+ajhqme+fOUiFUk4 2TgpSbFsVHyH51JGIH/X9e7orI+uIpW/rEQl9nyF+ggao2i1iJfeuOD0U/6PvUddEI3V5LfOJ2i 6oZCYYfdXRV+nAWuDNB8Wq0sGsSqtWfC7u8/UDpTgUHjKgSaOLtrBGe3Y1Kxrx6Z7E7VlCn+hFL s4YwOxDkQL5ws20w1PWvdmGvlnZnymrr6O+ro0y55e+507d8TT8FlkvC2XUB3K336SSdng8f X-Proofpoint-GUID: gJ0fUKD_gIniHevtMjs0MT07qIiyaA2j X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-10_02,2025-06-09_02,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 impostorscore=0 priorityscore=1501 malwarescore=0 bulkscore=0 lowpriorityscore=0 phishscore=0 mlxscore=0 adultscore=0 spamscore=0 suspectscore=0 mlxlogscore=999 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2505280000 definitions=main-2506100056 Support SPI offload with appropriate FPGA firmware. Since the SPI-Engine offload module always sends 32-bit data to the DMA engine, the scantype.storagebytes is set to 32-bit and the SPI transfer length is based on the scantype.realbits. This combination allows to optimize the SPI to transfer only 2 or 3 bytes (depending on the granularity and mode), while the number of samples are computed correctly by tools on top of the iio scantype. Signed-off-by: Jorge Marques --- drivers/iio/adc/ad4052.c | 244 +++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 242 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/ad4052.c b/drivers/iio/adc/ad4052.c index 842f5972a1c58701addf5243e7b87da9c26c773f..7d32dc4701ddb0204b5505a650c= e7caafc2cb5ed 100644 --- a/drivers/iio/adc/ad4052.c +++ b/drivers/iio/adc/ad4052.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -23,6 +25,8 @@ #include #include #include +#include +#include #include #include #include @@ -111,6 +115,7 @@ enum ad4052_interrupt_en { =20 struct ad4052_chip_info { const struct iio_chan_spec channels[1]; + const struct iio_chan_spec offload_channels[1]; const char *name; u16 prod_id; u8 max_avg; @@ -156,7 +161,11 @@ struct ad4052_state { const struct ad4052_bus_ops *ops; const struct ad4052_chip_info *chip; enum ad4052_operation_mode mode; + struct spi_offload *offload; + struct spi_offload_trigger *offload_trigger; struct spi_device *spi; + struct spi_transfer offload_xfer; + struct spi_message offload_msg; struct pwm_device *cnv_pwm; struct pwm_state pwm_st; struct spi_transfer xfer; @@ -344,6 +353,7 @@ AD4052_EXT_INFO(AD4052_500KSPS); static const struct ad4052_chip_info ad4050_chip_info =3D { .name =3D "ad4050", .channels =3D { AD4052_CHAN(12, AD4052_2MSPS) }, + .offload_channels =3D { AD4052_OFFLOAD_CHAN(12, AD4052_2MSPS) }, .prod_id =3D 0x70, .max_avg =3D AD4050_MAX_AVG, .grade =3D AD4052_2MSPS, @@ -352,6 +362,7 @@ static const struct ad4052_chip_info ad4050_chip_info = =3D { static const struct ad4052_chip_info ad4052_chip_info =3D { .name =3D "ad4052", .channels =3D { AD4052_CHAN(16, AD4052_2MSPS) }, + .offload_channels =3D { AD4052_OFFLOAD_CHAN(16, AD4052_2MSPS) }, .prod_id =3D 0x72, .max_avg =3D AD4052_MAX_AVG, .grade =3D AD4052_2MSPS, @@ -360,6 +371,7 @@ static const struct ad4052_chip_info ad4052_chip_info = =3D { static const struct ad4052_chip_info ad4056_chip_info =3D { .name =3D "ad4056", .channels =3D { AD4052_CHAN(12, AD4052_500KSPS) }, + .offload_channels =3D { AD4052_OFFLOAD_CHAN(12, AD4052_500KSPS) }, .prod_id =3D 0x76, .max_avg =3D AD4050_MAX_AVG, .grade =3D AD4052_500KSPS, @@ -368,6 +380,7 @@ static const struct ad4052_chip_info ad4056_chip_info = =3D { static const struct ad4052_chip_info ad4058_chip_info =3D { .name =3D "ad4058", .channels =3D { AD4052_CHAN(16, AD4052_500KSPS) }, + .offload_channels =3D { AD4052_OFFLOAD_CHAN(16, AD4052_500KSPS) }, .prod_id =3D 0x78, .max_avg =3D AD4052_MAX_AVG, .grade =3D AD4052_500KSPS, @@ -392,6 +405,28 @@ static int ad4052_update_xfer_raw(struct iio_dev *indi= o_dev, return 0; } =20 +static int ad4052_update_xfer_offload(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + const struct iio_scan_type *scan_type; + struct spi_transfer *xfer =3D &st->offload_xfer; + + scan_type =3D iio_get_current_scan_type(indio_dev, chan); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); + + xfer->bits_per_word =3D scan_type->realbits; + xfer->offload_flags =3D SPI_OFFLOAD_XFER_RX_STREAM; + xfer->len =3D scan_type->realbits =3D=3D 24 ? 4 : 2; + xfer->speed_hz =3D AD4052_SPI_MAX_ADC_XFER_SPEED(st->vio_uv); + + spi_message_init_with_transfers(&st->offload_msg, &st->offload_xfer, 1); + st->offload_msg.offload =3D st->offload; + + return 0; +} + static int ad4052_set_oversampling_ratio(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, unsigned int val) @@ -838,6 +873,87 @@ static int ad4052_write_raw(struct iio_dev *indio_dev, return ret; } =20 +static int ad4052_offload_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + struct spi_offload_trigger_config config =3D { + .type =3D SPI_OFFLOAD_TRIGGER_DATA_READY, + }; + int ret; + + ret =3D pm_runtime_resume_and_get(&st->spi->dev); + if (ret) + return ret; + + ret =3D ad4052_set_operation_mode(st, st->mode); + if (ret) + goto out_mode_error; + + ret =3D ad4052_update_xfer_offload(indio_dev, indio_dev->channels); + if (ret) + goto out_xfer_error; + + ret =3D spi_optimize_message(st->spi, &st->offload_msg); + if (ret) + goto out_xfer_error; + + /* SPI Offload handles the data ready irq */ + if (st->gp1_irq) + disable_irq(st->gp1_irq); + + ret =3D spi_offload_trigger_enable(st->offload, st->offload_trigger, + &config); + if (ret) + goto out_offload_error; + + st->pwm_st.enabled =3D true; + ret =3D pwm_apply_might_sleep(st->cnv_pwm, &st->pwm_st); + if (ret) + goto out_pwm_error; + + return 0; + +out_pwm_error: + spi_offload_trigger_disable(st->offload, st->offload_trigger); +out_offload_error: + if (st->gp1_irq) + enable_irq(st->gp1_irq); + spi_unoptimize_message(&st->offload_msg); +out_xfer_error: + ad4052_exit_command(st); +out_mode_error: + pm_runtime_mark_last_busy(&st->spi->dev); + pm_runtime_put_autosuspend(&st->spi->dev); + + return ret; +} + +static int ad4052_offload_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + int ret; + + st->pwm_st.enabled =3D false; + pwm_apply_might_sleep(st->cnv_pwm, &st->pwm_st); + + spi_offload_trigger_disable(st->offload, st->offload_trigger); + spi_unoptimize_message(&st->offload_msg); + + ret =3D ad4052_exit_command(st); + + if (st->gp1_irq) + enable_irq(st->gp1_irq); + pm_runtime_mark_last_busy(&st->spi->dev); + pm_runtime_put_autosuspend(&st->spi->dev); + + return ret; +} + +static const struct iio_buffer_setup_ops ad4052_buffer_offload_setup_ops = =3D { + .postenable =3D &ad4052_offload_buffer_postenable, + .predisable =3D &ad4052_offload_buffer_predisable, +}; + static int ad4052_debugfs_reg_access(struct iio_dev *indio_dev, unsigned i= nt reg, unsigned int writeval, unsigned int *readval) { @@ -884,9 +1000,82 @@ static const struct regmap_config ad4052_regmap_confi= g =3D { .can_sleep =3D true, }; =20 +static const struct spi_offload_config ad4052_offload_config =3D { + .capability_flags =3D SPI_OFFLOAD_CAP_TRIGGER | + SPI_OFFLOAD_CAP_RX_STREAM_DMA, +}; + +static void ad4052_pwm_disable(void *pwm) +{ + pwm_disable(pwm); +} + +static bool ad4052_offload_trigger_match(struct spi_offload_trigger *trigg= er, + enum spi_offload_trigger_type type, + u64 *args, u32 nargs) +{ + return type =3D=3D SPI_OFFLOAD_TRIGGER_DATA_READY; +} + +static const struct spi_offload_trigger_ops ad4052_offload_trigger_ops =3D= { + .match =3D ad4052_offload_trigger_match, +}; + +static int ad4052_request_offload(struct iio_dev *indio_dev) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + struct device *dev =3D &st->spi->dev; + struct dma_chan *rx_dma; + struct spi_offload_trigger_info trigger_info =3D { + .fwnode =3D dev_fwnode(dev), + .ops =3D &ad4052_offload_trigger_ops, + .priv =3D st, + }; + int ret; + + indio_dev->setup_ops =3D &ad4052_buffer_offload_setup_ops; + + ret =3D devm_spi_offload_trigger_register(dev, &trigger_info); + if (ret) + return dev_err_probe(dev, ret, "failed to register offload trigger\n"); + + st->offload_trigger =3D devm_spi_offload_trigger_get(dev, st->offload, + SPI_OFFLOAD_TRIGGER_DATA_READY); + if (IS_ERR(st->offload_trigger)) + return PTR_ERR(st->offload_trigger); + + st->cnv_pwm =3D devm_pwm_get(dev, NULL); + if (IS_ERR(st->cnv_pwm)) + return dev_err_probe(dev, PTR_ERR(st->cnv_pwm), "failed to get CNV PWM\n= "); + + pwm_init_state(st->cnv_pwm, &st->pwm_st); + + st->pwm_st.enabled =3D false; + st->pwm_st.duty_cycle =3D AD4052_T_CNVH_NS * 2; + st->pwm_st.period =3D DIV_ROUND_UP_ULL(NSEC_PER_SEC, AD4052_MAX_RATE(st->= chip->grade)); + + ret =3D pwm_apply_might_sleep(st->cnv_pwm, &st->pwm_st); + if (ret) + return dev_err_probe(dev, ret, "failed to apply CNV PWM\n"); + + ret =3D devm_add_action_or_reset(dev, ad4052_pwm_disable, st->cnv_pwm); + if (ret) + return ret; + + rx_dma =3D devm_spi_offload_rx_stream_request_dma_chan(dev, st->offload); + if (IS_ERR(rx_dma)) + return PTR_ERR(rx_dma); + + return devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev, rx_dma, + IIO_BUFFER_DIRECTION_IN); +} + static int __ad4052_validate_trigger_sources(struct of_phandle_args *trigg= er_sources) { switch (trigger_sources->args[1]) { + case AD4052_TRIGGER_PIN_GP0: + return trigger_sources->args[0] =3D=3D AD4052_TRIGGER_EVENT_EITHER_THRES= H ? + 0 : -EINVAL; case AD4052_TRIGGER_PIN_GP1: return trigger_sources->args[0] =3D=3D AD4052_TRIGGER_EVENT_DATA_READY ? 0 : -EINVAL; @@ -903,14 +1092,45 @@ static int ad4052_validate_trigger_sources(struct ii= o_dev *indio_dev) int ret; =20 np =3D st->spi->dev.of_node; + for (u8 i =3D 0; i < 2; i++) { + ret =3D of_parse_phandle_with_args(np, "trigger-sources", + "#trigger-source-cells", i, + &trigger_sources); + if (ret) + return ret; + + ret =3D __ad4052_validate_trigger_sources(&trigger_sources); + of_node_put(trigger_sources.np); + if (ret) + return ret; + } + + return ret; +} + +static int ad4052_validate_parent_trigger_sources(struct iio_dev *indio_de= v) +{ + struct ad4052_state *st =3D iio_priv(indio_dev); + struct of_phandle_args trigger_sources; + struct device_node *np; + int ret; + + np =3D of_get_parent(st->spi->dev.of_node); + if (!np) + return -ENODEV; + ret =3D of_parse_phandle_with_args(np, "trigger-sources", "#trigger-source-cells", 0, &trigger_sources); if (ret) - return ret; + goto out_error; =20 - ret =3D __ad4052_validate_trigger_sources(&trigger_sources); + if (trigger_sources.args[0] !=3D AD4052_TRIGGER_EVENT_DATA_READY || + trigger_sources.args[1] !=3D AD4052_TRIGGER_PIN_GP1) + ret =3D -EINVAL; of_node_put(trigger_sources.np); +out_error: + of_node_put(np); return ret; } =20 @@ -986,6 +1206,26 @@ static int ad4052_probe(struct spi_device *spi) indio_dev->info =3D &ad4052_info; indio_dev->name =3D chip->name; =20 + st->offload =3D devm_spi_offload_get(dev, spi, &ad4052_offload_config); + ret =3D PTR_ERR_OR_ZERO(st->offload); + + if (ret =3D=3D -ENODEV) { + st->offload_trigger =3D NULL; + indio_dev->channels =3D chip->channels; + } else if (!ret) { + indio_dev->channels =3D chip->offload_channels; + ret =3D ad4052_request_offload(indio_dev); + if (ret) + return dev_err_probe(dev, ret, + "Failed to configure offload\n"); + ret =3D ad4052_validate_parent_trigger_sources(indio_dev); + if (ret) + return dev_err_probe(dev, ret, + "Failed to validate parent trigger sources\n"); + } else { + return dev_err_probe(dev, ret, "Failed to get offload\n"); + } + ret =3D ad4052_validate_trigger_sources(indio_dev); if (ret) return dev_err_probe(dev, ret, --=20 2.49.0 From nobody Sun Oct 5 20:44:17 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 B22A227F164; Tue, 10 Jun 2025 07:35:29 +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=1749540931; cv=none; b=dbqzuupUoUjw5JC3LZ5l3xTKNxE1LrosftMv2sXMQrQzLjn6GuGCWl8SQxq/8Gb/O79Z0gqEa7K6y1tgQw8X7/GdtNrjTxauHytjOpnAJtWpfD/td9HHe9wsmxG/R3E9nsefFmeFNK1T98CcTSlowZUJm5KmU1gcOG8GHR0PwlU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749540931; c=relaxed/simple; bh=wRpByI1coJpFEIh+zJNKNHgrlO5l0ATlV/vp7byccE0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=kP54xMx7ZjqeVxoo/BQFiKgxJ06v8pDbBdVXe18E/S1K7v1yM5wwYDIjVLCDKNMNTdJePAMwyToXqEERpGXEFAw5AXgN8/F9+f1gJXWNXirk4cKi8T3pNqhtbeXi0ZCXPVm9jyqcS6N8i0W4g1nD3t1OzMCSElq/WsHNZClIwhc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none 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=Vknqc7Fy; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none 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="Vknqc7Fy" 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 55A6uqt9002452; Tue, 10 Jun 2025 03:35:16 -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=b8URu x3k/Kp76Jxq7h6A+CDTnwaDlwXerEzBO9LTHvw=; b=Vknqc7FytR5sBDtm3j283 9QpjvaFRtyLfeqJTEhDHWRHUye8caqEevT/Yzr9wn9Ss0YWbREy/cxV62SLWZ2nQ JfTmY4Fqd4OX2v1Wzen45t7n5y0yrH26nOc+aoN9BWzumT8xHmJZ608sW54Eg6Ap JXG317haEAW4fA2enQl+olRUYLqnM00aTYRD403MiDV41BkuelCzjDf8ivgTKJ2r 3E5+lYJ3GTzg/0GEidr9ZbZ18dMNCU3uMNW82uslXIBmNI5dzf41KkuOAl/S7TGW rzNUk1yxwSw3CqRktpX+tUtiRfQiMYE7xnt0hLNPomN6usLUT0p7qHSgykjqty0d w== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 476fvkr7q1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 10 Jun 2025 03:35:16 -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 55A7ZF1x056174 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 10 Jun 2025 03:35:15 -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.10; Tue, 10 Jun 2025 03:35:15 -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.10 via Frontend Transport; Tue, 10 Jun 2025 03:35:15 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.51]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 55A7YkMl002608; Tue, 10 Jun 2025 03:35:06 -0400 From: Jorge Marques Date: Tue, 10 Jun 2025 09:34:40 +0200 Subject: [PATCH v3 7/8] docs: iio: ad4052: Add event documentation 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: <20250610-iio-driver-ad4052-v3-7-cf1e44c516d4@analog.com> References: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> In-Reply-To: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> To: Jonathan Cameron , Lars-Peter Clausen , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= CC: , , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749540886; l=2133; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=wRpByI1coJpFEIh+zJNKNHgrlO5l0ATlV/vp7byccE0=; b=ji7mAuuU994h1QB4oGT2M8cOkLGrPQA+pJPttJrdTg7uqIFql+lSN97ktdF9TMmyX35e5TF1W wCxz1XXouYqDN23EeV3MGIJmubwfiZVYoFyuNx9a08cfMiOl49vdAvR X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjEwMDA1NiBTYWx0ZWRfX8UhCCaKxg/J6 xkr0upiZcQhcm1MNWm0QnQ0Nq7zsIGTFqnCljeC5mUrSu7RFKRe9w2rmikl2P2A9Zu2vQqjYkyM GJ03wjHPi/2F9Tm62fMJ7YDPsOchwIPo/Pv+Pf0+yd7JZSC+ygt9iCl52yFP8M5uv8nP2jpaj3s dc+mCsu3fMfx98F8rzvxbMkhoVUABV7Ik2IN5j1p6NsG0rdpjMd7gQf0W5xcnZcRmfcNJ1v0/k8 14JXcto58frfYSN7ovXtuZJ77t65vSTuetR5iiQbGJkYg++F+OFkW4G1N4x1OagOdWbQazRaDv0 95rsP65ySxLAsVrGf0d2+YCHJMoAirRXhVnzlZpc9pBoXRyKIqVLgLlmd49/ENhDKwd+sK/+LAY 0ujDnGP8UV7aXRGRiK4jX3m1dfWmOy3Mm0Xdu3z+Fv7jLp5lmBaoIiMX27MLAaEm4EWD9WUS X-Proofpoint-GUID: prhMjQO8IIsya-Yfpp1B43BKxKRaG-jg X-Authority-Analysis: v=2.4 cv=Coy/cm4D c=1 sm=1 tr=0 ts=6847e034 cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=6IFa9wvqVegA:10 a=gAnH3GRIAAAA:8 a=55yT-0NB-ohaRzUcirIA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: prhMjQO8IIsya-Yfpp1B43BKxKRaG-jg X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-10_02,2025-06-09_02,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 mlxlogscore=999 spamscore=0 lowpriorityscore=0 impostorscore=0 mlxscore=0 phishscore=0 bulkscore=0 clxscore=1015 suspectscore=0 adultscore=0 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2505280000 definitions=main-2506100056 Explain the AD4052 monitoring support by exposing as an IIO event. Signed-off-by: Jorge Marques --- Documentation/iio/ad4052.rst | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/Documentation/iio/ad4052.rst b/Documentation/iio/ad4052.rst index 2ad1c7712766118b03c48929d1f2b7670d5f8d41..da9c0481dfcd3b4eecd91280b7f= 259aa9118467c 100644 --- a/Documentation/iio/ad4052.rst +++ b/Documentation/iio/ad4052.rst @@ -93,3 +93,41 @@ When SPI offload is being used, additional attributes ar= e present: - Description * - ``in_voltage_sampling_frequency`` - Set the sampling frequency. + +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 until put back in +configuration mode, due to this, the device returns busy until the feature= is +disabled. + +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. + +If the interrupt ``gp0`` is not provided, the IIO events attributes are st= ill +present, but no IIO Event will ever be triggered. This allows to use ``gp0= `` +output to trigger other resource. --=20 2.49.0 From nobody Sun Oct 5 20:44:17 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 3624128150E; Tue, 10 Jun 2025 07:35:32 +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=1749540935; cv=none; b=R5ioruTWYk97GLMX5Jp/hMat8/sEZyjiehfAhWjUyevgNVd31wz2P9gyb9iJI/Ch/VL3jpksEoQ5xLSUrVTWJup983F6Fg+RKN/EXbp0ym6v4tVb0x1taaxA9DH6BY9qdFksq65NCFCg3vC/4krRmFTT/HJoEsy9cQEDKoc+W1U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749540935; c=relaxed/simple; bh=67vqsQFKrx+1Cvq6u0R9aLnvPfGFMBTPpy5ZRrwcVdo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=Bu5be/pnfVShLhgitLZOLEJI0o2euwDCLs6xTrxy2qQEAZk+8Ig0YIl/cXKJcA0ZiTy0KcrhB61DraOy85CDplJtHiDVuJQlBElzY0DqOnt3naolqUGuOZu2o8qSCivIxhHl/ubMkwTG884nUqwG1eCqcmnweIPTALhugFeNfVo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none 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=WxlO+A3H; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none 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="WxlO+A3H" 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 55A6g8Bw023177; Tue, 10 Jun 2025 03:35:19 -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=PdiwW te0EQfXZhMDSFids8Uilx5wSOu5fIwj73rqFe0=; b=WxlO+A3H5jgXlhLj3K0U3 qYPCp4BDFGXS2m9sVzvI9J+B3qgswO92lA0tDepgr57Lj57vaJdhcdyzAxkrDpMx 0z0Jvq/IXJeqwnOvi48jKqexilMLVAdw4jhHhmkcXLsKerXanQfzPHIJ387VTGMJ cou0mAqx6kcUIscSaa1oC6Z7Nbs71b8hgx+hvi94DSW5iMKOtBS/qtQb2sDNn1Oq jDFBkGkoEPeYRdpRwa4VRTatWkKw/kI+BUpt46bL2hDaj1CqgKTA9xAkV6ARLGKr AVPQTqJPJANWROVh3UrkHSdMWQ1cq3m85szUQ1Ai3yd8ZbXjkN4DOtNU6K+PjhZs A== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 476fc30bm5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 10 Jun 2025 03:35:18 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 55A7ZHeK056193 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 10 Jun 2025 03:35:17 -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.10; Tue, 10 Jun 2025 03:35:17 -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.10 via Frontend Transport; Tue, 10 Jun 2025 03:35:17 -0400 Received: from HYB-DlYm71t3hSl.ad.analog.com (HYB-DlYm71t3hSl.ad.analog.com [10.44.3.51]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 55A7YkMm002608; Tue, 10 Jun 2025 03:35:08 -0400 From: Jorge Marques Date: Tue, 10 Jun 2025 09:34:41 +0200 Subject: [PATCH v3 8/8] iio: adc: Add events support to ad4052 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: <20250610-iio-driver-ad4052-v3-8-cf1e44c516d4@analog.com> References: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> In-Reply-To: <20250610-iio-driver-ad4052-v3-0-cf1e44c516d4@analog.com> To: Jonathan Cameron , Lars-Peter Clausen , Michael Hennerich , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= CC: , , , , , Jorge Marques X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1749540886; l=14324; i=jorge.marques@analog.com; s=20250303; h=from:subject:message-id; bh=67vqsQFKrx+1Cvq6u0R9aLnvPfGFMBTPpy5ZRrwcVdo=; b=r1eUQMrtq0Ig2WfeFCktd3ICTFupK/fokJk7mNgVZmsy4tnRNY5su5brytsanCBUnV+9o3mBu mX35kDrGZ+oAsEHO6Y1U2HFO5RoDBULTIgtZLXOodwRXjyBKqThziIX X-Developer-Key: i=jorge.marques@analog.com; a=ed25519; pk=NUR1IZZMH0Da3QbJ2tBSznSPVfRpuoWdhBzKGSpAdbg= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: Q_qD2OjAl66vdp0xwe2bECq9tlrKjF9d X-Proofpoint-ORIG-GUID: Q_qD2OjAl66vdp0xwe2bECq9tlrKjF9d X-Authority-Analysis: v=2.4 cv=LtaSymdc c=1 sm=1 tr=0 ts=6847e036 cx=c_pps a=PpDZqlmH/M8setHirZLBMw==:117 a=PpDZqlmH/M8setHirZLBMw==:17 a=IkcTkHD0fZMA:10 a=6IFa9wvqVegA:10 a=gAnH3GRIAAAA:8 a=U75sXf5VTUVOPaN5l64A:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjEwMDA1NiBTYWx0ZWRfX9vMwO2rdf8Ij z1a6rGTzhv/VUNDPx0xXecu4//5RNXcSV0ufodU4Vf/uQHCsxoxiKgLaygrPPnWaib4QpNlt86h U0W55rQALaxURNUbTH1rtyg9rM0zr2a+DJ6luIXVYu0NL/uwitq3wEtLYcv427A9g0FHq/4uNrv TaQznLZ3pTlFutmHoD+n0EIhvMt4Zt+9W36UyBnSOAPXQAVP+hnppyuq0AFB66drn3GJrKdaEhR pYvlCAnq46aPI6I0PZY2a7DXQLYAcu/DrtmGHfDkxBKwuLfeTYlLn+tBI/pCGk6Qg8aVSnQg7F+ ICfMVfcqPuOH/mn6IRs4spotaEY0SRu9CBFmnu9R6s2J90QmKfAMcSyrBVWxEpCthz6RU7rByrz hA2nIi2remoAsQcDMPnFlC/J8SbeiNA2YJ/+thT7jWlPPjFS3z2fxDAjzniktP1jqmtWQ2CT X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-10_02,2025-06-09_02,2025-03-28_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 malwarescore=0 priorityscore=1501 phishscore=0 lowpriorityscore=0 mlxlogscore=999 impostorscore=0 mlxscore=0 spamscore=0 clxscore=1015 suspectscore=0 bulkscore=0 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2505280000 definitions=main-2506100056 The AD4052 family supports autonomous monitoring readings for threshold crossings. Add support for catching the GPIO interrupt and expose as an IIO event. The device allows to set either, rising and falling directions. Only either threshold crossing is implemented. Signed-off-by: Jorge Marques --- drivers/iio/adc/ad4052.c | 369 +++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 369 insertions(+) diff --git a/drivers/iio/adc/ad4052.c b/drivers/iio/adc/ad4052.c index 7d32dc4701ddb0204b5505a650ce7caafc2cb5ed..ff52ff002bfe0ee413ae352b0c1= 854798b8e89f8 100644 --- a/drivers/iio/adc/ad4052.c +++ b/drivers/iio/adc/ad4052.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,8 @@ #define AD4052_REG_MON_VAL 0x2F #define AD4052_REG_FUSE_CRC 0x40 #define AD4052_REG_DEVICE_STATUS 0x41 +#define AD4052_REG_DEVICE_STATUS_MIN_FLAG BIT(2) +#define AD4052_REG_DEVICE_STATUS_MAX_FLAG BIT(3) #define AD4052_REG_DEVICE_STATUS_DEVICE_RDY BIT(7) #define AD4052_REG_DEVICE_STATUS_DEVICE_RESET BIT(6) #define AD4052_REG_MIN_SAMPLE 0x45 @@ -173,6 +176,8 @@ struct ad4052_state { struct completion completion; struct regmap *regmap; u16 oversampling_frequency; + u16 events_frequency; + bool wait_event; int gp1_irq; int vio_uv; int vref_uv; @@ -259,6 +264,26 @@ static const struct regmap_access_table ad4052_regmap_= wr_table =3D { .n_yes_ranges =3D ARRAY_SIZE(ad4052_regmap_wr_ranges), }; =20 +static const struct iio_event_spec ad4052_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 ad4052_conversion_freqs[] =3D { "2000000", "1000000", "300000", "100000", /* 0 - 3 */ "33300", "10000", "3000", "500", /* 4 - 7 */ @@ -328,6 +353,8 @@ AD4052_EXT_INFO(AD4052_500KSPS); .info_mask_shared_by_type_available =3D BIT(IIO_CHAN_INFO_OVERSAMPLING_RA= TIO), \ .indexed =3D 1, \ .channel =3D 0, \ + .event_spec =3D ad4052_events, \ + .num_event_specs =3D ARRAY_SIZE(ad4052_events), \ .has_ext_scan_type =3D 1, \ .ext_scan_type =3D ad4052_scan_type_##bits##_s, \ .num_ext_scan_type =3D ARRAY_SIZE(ad4052_scan_type_##bits##_s), \ @@ -344,6 +371,8 @@ AD4052_EXT_INFO(AD4052_500KSPS); .info_mask_shared_by_type_available =3D BIT(IIO_CHAN_INFO_OVERSAMPLING_RA= TIO), \ .indexed =3D 1, \ .channel =3D 0, \ + .event_spec =3D ad4052_events, \ + .num_event_specs =3D ARRAY_SIZE(ad4052_events), \ .has_ext_scan_type =3D 1, \ .ext_scan_type =3D ad4052_scan_type_##bits##_s, \ .num_ext_scan_type =3D ARRAY_SIZE(ad4052_scan_type_##bits##_s), \ @@ -386,6 +415,74 @@ static const struct ad4052_chip_info ad4058_chip_info = =3D { .grade =3D AD4052_500KSPS, }; =20 +static ssize_t ad4052_events_frequency_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ad4052_state *st =3D iio_priv(dev_to_iio_dev(dev)); + + return sysfs_emit(buf, "%s\n", ad4052_conversion_freqs[st->events_frequen= cy]); +} + +static ssize_t ad4052_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 ad4052_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } + + ret =3D __sysfs_match_string(AD4052_FS(st->chip->grade), + AD4052_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, + ad4052_events_frequency_show, + ad4052_events_frequency_store, 0); + +static ssize_t sampling_frequency_available_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ad4052_state *st =3D iio_priv(dev_to_iio_dev(dev)); + int ret =3D 0; + + for (u8 i =3D AD4052_FS_OFFSET(st->chip->grade); + i < AD4052_FS_LEN(st->chip->grade); i++) + ret +=3D sysfs_emit_at(buf, ret, "%s ", ad4052_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 *ad4052_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 ad4052_event_attribute_group =3D { + .attrs =3D ad4052_event_attributes, +}; + static int ad4052_update_xfer_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan) { @@ -602,6 +699,19 @@ static int ad4052_setup(struct iio_dev *indio_dev, str= uct iio_chan_spec const *c val); } =20 +static irqreturn_t ad4052_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 ad4052_irq_handler_drdy(int irq, void *private) { struct ad4052_state *st =3D private; @@ -616,6 +726,18 @@ static int ad4052_request_irq(struct iio_dev *indio_de= v) struct device *dev =3D &st->spi->dev; int ret; =20 + ret =3D fwnode_irq_get_byname(dev_fwnode(&st->spi->dev), "gp0"); + if (ret > 0) { + ret =3D devm_request_threaded_irq(dev, ret, NULL, + ad4052_irq_handler_thresh, + IRQF_ONESHOT, indio_dev->name, + indio_dev); + if (ret) + return ret; + } else if (ret =3D=3D -EPROBE_DEFER) { + return ret; + } + ret =3D fwnode_irq_get_byname(dev_fwnode(&st->spi->dev), "gp1"); if (ret > 0) { ret =3D devm_request_threaded_irq(dev, ret, NULL, @@ -822,6 +944,7 @@ static int ad4052_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long info) { + struct ad4052_state *st =3D iio_priv(indio_dev); int ret; =20 if (info =3D=3D IIO_CHAN_INFO_SAMP_FREQ) @@ -831,8 +954,14 @@ static int ad4052_read_raw(struct iio_dev *indio_dev, =20 if (!iio_device_claim_direct(indio_dev)) return -EBUSY; + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } =20 ret =3D ad4052_read_raw_dispatch(indio_dev, chan, val, val2, info); + +out_release: iio_device_release_direct(indio_dev); return ret ? ret : IIO_VAL_INT; } @@ -867,8 +996,231 @@ static int ad4052_write_raw(struct iio_dev *indio_dev, =20 if (!iio_device_claim_direct(indio_dev)) return -EBUSY; + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } =20 ret =3D ad4052_write_raw_dispatch(indio_dev, chan, val, val2, info); + +out_release: + iio_device_release_direct(indio_dev); + return ret; +} + +static int ad4052_monitor_mode_enable(struct ad4052_state *st) +{ + int ret; + + ret =3D pm_runtime_resume_and_get(&st->spi->dev); + if (ret) + return ret; + + ret =3D ad4052_conversion_frequency_set(st, st->events_frequency); + if (ret) + goto out_error; + + ret =3D ad4052_set_operation_mode(st, AD4052_MONITOR_MODE); + if (ret) + goto out_error; + + return ret; +out_error: + pm_runtime_mark_last_busy(&st->spi->dev); + pm_runtime_put_autosuspend(&st->spi->dev); + return ret; +} + +static int ad4052_monitor_mode_disable(struct ad4052_state *st) +{ + int ret; + + pm_runtime_mark_last_busy(&st->spi->dev); + pm_runtime_put_autosuspend(&st->spi->dev); + + ret =3D ad4052_exit_command(st); + if (ret) + return ret; + return regmap_write(st->regmap, AD4052_REG_DEVICE_STATUS, + AD4052_REG_DEVICE_STATUS_MAX_FLAG | + AD4052_REG_DEVICE_STATUS_MIN_FLAG); +} + +static int ad4052_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 ad4052_state *st =3D iio_priv(indio_dev); + + return st->wait_event; +} + +static int ad4052_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 ad4052_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; + } + + if (state) + ret =3D ad4052_monitor_mode_enable(st); + else + ret =3D ad4052_monitor_mode_disable(st); + + if (!ret) + st->wait_event =3D state; + +out_release: + iio_device_release_direct(indio_dev); + return ret; +} + +static int __ad4052_read_event_info_value(struct ad4052_state *st, + enum iio_event_direction dir, int *val) +{ + int ret; + u8 reg; + + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4052_REG_MAX_LIMIT; + else + reg =3D AD4052_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 __ad4052_read_event_info_hysteresis(struct ad4052_state *st, + enum iio_event_direction dir, int *val) +{ + u8 reg; + + if (dir =3D=3D IIO_EV_DIR_RISING) + reg =3D AD4052_REG_MAX_HYST; + else + reg =3D AD4052_REG_MIN_HYST; + return regmap_read(st->regmap, reg, val); +} + +static int ad4052_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 ad4052_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } + + switch (info) { + case IIO_EV_INFO_VALUE: + ret =3D __ad4052_read_event_info_value(st, dir, val); + break; + case IIO_EV_INFO_HYSTERESIS: + ret =3D __ad4052_read_event_info_hysteresis(st, dir, val); + break; + default: + ret =3D -EINVAL; + break; + } + +out_release: + iio_device_release_direct(indio_dev); + return ret ? ret : IIO_VAL_INT; +} + +static int __ad4052_write_event_info_value(struct ad4052_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 AD4052_REG_MAX_LIMIT; + else + reg =3D AD4052_REG_MIN_LIMIT; + put_unaligned_be16(val, &st->raw); + + return regmap_bulk_write(st->regmap, reg, &st->raw, 2); +} + +static int __ad4052_write_event_info_hysteresis(struct ad4052_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 AD4052_REG_MAX_HYST; + else + reg =3D AD4052_REG_MIN_HYST; + + return regmap_write(st->regmap, reg, val); +} + +static int ad4052_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 ad4052_state *st =3D iio_priv(indio_dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } + + switch (type) { + case IIO_EV_TYPE_THRESH: + switch (info) { + case IIO_EV_INFO_VALUE: + ret =3D __ad4052_write_event_info_value(st, dir, val); + break; + case IIO_EV_INFO_HYSTERESIS: + ret =3D __ad4052_write_event_info_hysteresis(st, dir, val); + break; + default: + ret =3D -EINVAL; + break; + } + break; + default: + ret =3D -EINVAL; + break; + } + +out_release: iio_device_release_direct(indio_dev); return ret; } @@ -881,6 +1233,9 @@ static int ad4052_offload_buffer_postenable(struct iio= _dev *indio_dev) }; int ret; =20 + if (st->wait_event) + return -EBUSY; + ret =3D pm_runtime_resume_and_get(&st->spi->dev); if (ret) return ret; @@ -963,10 +1318,17 @@ static int ad4052_debugfs_reg_access(struct iio_dev = *indio_dev, unsigned int reg if (!iio_device_claim_direct(indio_dev)) return -EBUSY; =20 + if (st->wait_event) { + ret =3D -EBUSY; + goto out_release; + } + if (readval) ret =3D regmap_read(st->regmap, reg, readval); else ret =3D regmap_write(st->regmap, reg, writeval); + +out_release: iio_device_release_direct(indio_dev); return ret; } @@ -985,6 +1347,11 @@ static const struct iio_info ad4052_info =3D { .read_raw =3D ad4052_read_raw, .write_raw =3D ad4052_write_raw, .read_avail =3D ad4052_read_avail, + .read_event_config =3D &ad4052_read_event_config, + .write_event_config =3D &ad4052_write_event_config, + .read_event_value =3D &ad4052_read_event_value, + .write_event_value =3D &ad4052_write_event_value, + .event_attrs =3D &ad4052_event_attribute_group, .get_current_scan_type =3D &ad4052_get_current_scan_type, .debugfs_reg_access =3D &ad4052_debugfs_reg_access, }; @@ -1193,8 +1560,10 @@ static int ad4052_probe(struct spi_device *spi) "Failed to initialize regmap\n"); =20 st->mode =3D AD4052_SAMPLE_MODE; + st->wait_event =3D false; st->chip =3D chip; st->oversampling_frequency =3D AD4052_FS_OFFSET(st->chip->grade); + st->events_frequency =3D AD4052_FS_OFFSET(st->chip->grade); =20 st->cnv_gp =3D devm_gpiod_get_optional(dev, "cnv", GPIOD_OUT_LOW); if (IS_ERR(st->cnv_gp)) --=20 2.49.0