From nobody Mon Sep 28 12:33:38 2026 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 765494BC009; Fri, 21 Aug 2026 14:08:09 +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=1787321290; cv=none; b=X17Nt9nS2or2fj8+Zaf1y1hWj1cPEy2d1pV46zR/U6GQPPZXATUiuxbYRV8qRdW9NZa5j8IMXajpzxcw/VQ4YgL2joiGwusRGB9gcStuA9dZqbcs65DWk9looTJ8/B2hwDmRz1dF/2nxB/mSs3FGSVxtnijb3wtW36/E7PeXTbA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321290; c=relaxed/simple; bh=Ia5cdUwhQp5bspVUqQ3iF/ZRqYMDFIcD31k3fE8TCuc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=Gg9P/QSrsb009AjGQu+o07pzDzGwT0dcAa4H1keyGA/Z5rcJMai0V5Egjsb45yICYisncNu3Yvc8Dm8CFffYfjq/eZpY0SM1hZ9zRoKU/HyuFhAFSlyOnhP5UGfvv4sDmrQESqFg44ZZzA2Fi9mmH7AEPdxJirZ+hyFkZQa8edE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=UCVCgcPb; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="UCVCgcPb" Received: from pps.filterd (m0516787.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpQt03387853; Fri, 21 Aug 2026 10:07:48 -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=isQfr O1kOgift38KlUFUSiekVqhdQPQpvCxC62CsfNk=; b=UCVCgcPbJH3k6LSAPby0f 7lmgWH8bVCfSiDfnsdHDbSf5PeMyv7S409AkzO3d5J8nK5iEbKa/vZ+SKtQlkgFt Cz5xT5EQnfLdCBRPaJiueUGiqdKT8HYnZQGivub8wipQ0UJ/gws95KZ0c2c5glHn ZT3UDIR+JH10J3O8NeYR4TLrOb4uFBZszzbW3Cu1WE/62zPr57DrSZROt8ugdI/f 2hveXrE+mIrJhnjH73qwgUkijeZdgOldlmy4kBMydr1WyKBILp/Gbnsb1CF4Mio6 OFCzLekmIhfs2uMuEYwZAypiATf208UqqU5fmduYU/qaV3IQRVO5LvSRMxZeKUPK g== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g66m6m0dy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:07:48 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 67LE7lt5032862 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:07:47 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:07:47 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:07:47 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkk024319; Fri, 21 Aug 2026 10:07:37 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:06:54 +0200 Subject: [PATCH v4 01/14] iio: adc: adi-axi-adc: Initialize state mutex 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: <20260821-ad7768-driver-v4-1-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=880; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=Ia5cdUwhQp5bspVUqQ3iF/ZRqYMDFIcD31k3fE8TCuc=; b=aBjT0t14v0z9vmtwBEXQjJZhOZY2AOCxddV74l+8kzK3mM0NRoXOSGyHFFgyBLvosOrv5Gej8 fzIwMvwUGoqDOgHpOoKEEgCFUBPwQVNg3A0hiCYKuHEXfGVqRheiWQO X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX3RPIezyF3C+4 ilOJDfRKuyXHTqrOg9VEnMRLVodRmpL4TiCaguiS41Y7P2iFsPzqmUIQ4yKyRQ7J7Kw995q0N4U XWbvSswZbWRdUGBxgZu8HKfQZZhS0bMG2LqUYiwKsi7yg5QD6ZuT X-Proofpoint-ORIG-GUID: 01F9rvbhM1gQiuK_7eHJf9u6r4gT5VuU X-Proofpoint-GUID: 01F9rvbhM1gQiuK_7eHJf9u6r4gT5VuU X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX2PFzXiOhf0+g P2jbTi1IKTn2BuZ+Al6gRw+JpEFmwPMyAaB8qZ2H5LiYXZNpyKrLNc8sHrhP2UVXXQveVCZFX5h udJQNAvJ8u5LN8OcRi6XX4U+/0cOr/iqXUrka6480QZ85mZaJTbKH/i0EXv2hIC9IfOFGBMmh+I HPix3DvTNOBMXImyqaTUYsXlR0P67uUSZBXtUvyJB22iaa8d8zrFJ2ZHrBoeLLMngoB6G7lD8YW 7FjX2ojv5yd4A4hgicDVjXI3zL5faN9UQb5AXg06BDi372nwlJ6v1CwwOyoru7pcebWlfB3/3EQ fq5wEt5NtdBUxLuZXzAJ4BbSRefL6kNSDqGaDlOgrIt68zHcsm8OiJqmNenLcCreFxQKwYiq4w9 QXzdn/Axu54Ow44QQZ1W+JKA7n9ZCu9d5vCSzf2UzUFdHu+avlLhqJ9FrZT1PYDWd5uaBxmSrtj b7iT8X66vl7czuIDi0Q== X-Authority-Analysis: v=2.4 cv=baVbluPB c=1 sm=1 tr=0 ts=6a885bb4 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=OmVn7CZJonkx5R5zMQLL:22 a=gAnH3GRIAAAA:8 a=_ljTvifiVFBlT2kRk7cA:9 a=QEXdDO2ut3YA:10 a=zZCYzV9kfG8A:10 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 phishscore=0 spamscore=0 suspectscore=0 impostorscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 The AXI ADC register access paths serialize transactions with st->lock, but probe does not initialize it. Initialize the mutex before registering the backend. Fixes: 7ecb8ee5c93b ("iio: adc: adi-axi-adc: support digital interface cali= bration") Signed-off-by: Janani Sunil --- drivers/iio/adc/adi-axi-adc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index 26b9c75bd4d8..b5e59b1871b6 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -684,6 +684,10 @@ static int adi_axi_adc_probe(struct platform_device *p= dev) if (!st) return -ENOMEM; =20 + ret =3D devm_mutex_init(dev, &st->lock); + if (ret) + return ret; + base =3D devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 79EA14ADD9E; Fri, 21 Aug 2026 14:08:11 +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=1787321293; cv=none; b=EGG+T/7weWXSnKhWPt1InJUu3xieArHsTTUYULq8cj3oXSMVvxSmx1nNeJygcbVnQ8fFfA0bbzuEUVmv0Nop1XFgMeNnfaa9bFTeMhJxrTm8CCCTwZmJ7rWHnUojSu6LeIl52korve1If9wRAiS1cI8CHlL5qoBoLgmEY1pzRxk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321293; c=relaxed/simple; bh=2Eq2Td2SZLWpVuzyh2LNh8SJ5r8BguipRNSzc7aqqnE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=V7O/K4zhJN1yzcVzQQLG2sEzcAD1VAQUiUa47t56zNgIBBkNzSy9K3W8fTVgXWeD3zHkMEMo9bnuPr5hiqR79nNrR0Ra4cfmIXfhCTQU1qnemKf9ec9mj6g+hLt/N8EMtryFCtfJrDJZXR8YUDTo3/FaiQkgCYoOh2Xqy5SOty0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=oSyd12co; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="oSyd12co" Received: from pps.filterd (m0516787.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpNOF3387730; Fri, 21 Aug 2026 10:07:54 -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=UAZ2J wnrWyDeghbrPuULgP9kgwprXpcxNX/tDesTMKc=; b=oSyd12coe+rvljCtn9+Ft TT79LxyBba/JTmxcOTu6zNapWpRoA2WzWW7qmc22tfEueTyPnwyG4JLfqgbg+qBE BPPDbp0Asi3VJaU2i5s86oLoBYymrdqla1pcQZOCOm8anXb6KE3+/xugudZC0hlG wZLDSbax4W1BNi0HbxPfhWp+XkfC/DL3R3ifh/9zW3i8t+1aSWfVTjdrPVJzsDr3 m8axCvF2+uma+kaEEEXH/R3/sxxfVIAzrBT/8GRe27zp2yR5Ru3rZNithFBSx7Q0 o1Ogjw+p7FRatiXn1SMsZJMmUm7PjpMmML1EXHfnJ29/JMYerdEQW7adk4/fsdCA A== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g66m6m0e9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:07:54 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 67LE7rCs032878 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:07:53 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:07:53 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:07:53 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkl024319; Fri, 21 Aug 2026 10:07:42 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:06:55 +0200 Subject: [PATCH v4 02/14] dt-bindings: iio: adc: Add AD7768 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: <20260821-ad7768-driver-v4-2-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=11566; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=2Eq2Td2SZLWpVuzyh2LNh8SJ5r8BguipRNSzc7aqqnE=; b=XeWsSQIDB4ak6FEhV4b2h/CNQwNfj1904GYGGvywREetF+k0P9575zlvArMZRtgmFu2spP9og sG6oa3mlEAZDTF7W4m9twqocM6KXBdgOzQz1T6gk3OOcj8n4bNHgsIU X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX6+3rtPrtAZZS nx810kRfyahYLnZxCFDze63IRY2G9BqO2MQa2d44dO03MSNW5vfHVVGGEvyN8rfBzfy+d91BEBQ gHkVdU26IxYnOxpDfNnuhoo6WC+8mtebOFF+M/WFcX0rwEErIpk7 X-Proofpoint-ORIG-GUID: 6RRTG6bBHhSXLmrJ_-BRjEJkCbdcKBaC X-Proofpoint-GUID: 6RRTG6bBHhSXLmrJ_-BRjEJkCbdcKBaC X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX6I8ioqC04HQB gZYEPU1Rigg/tiU2eG1R53FeYD2CSDDlQb7UCB31uKyx4hzYBSNWCwgnaZaI9dHE4DMqMiLq0P4 Ti+khDTT7lI3jm1IKGCyH+8wl4hVsKVpXZaKdRFKs44cxedfl/btKEK30D7eNcWpJNBE3N37Om2 kIxlNTIaohzJJ0VZB7d0D43iiB8+nGY8j1bDY/JLMh2keYRB/MlE/K3jK5zi2SS1TpfZrn8Rh9w tK82YbUevW3m8xWGAodHd5BEAPg5K3Dq7VPstnTQkCYluRUBglMLlgR3xwGyYmkRlULLbsY4IR1 KxfqTdRUJHErQGaRUsHKn1YZYiBad21EKxFNSyLTayc7OeohC+ncoJ+QLr7v2hc63Cb8bogB9KN Np4r+lU2QLFGx2wM33AGE1u+j/SlijfcOClJhOEv31yfhVl/63rne9xIi949V/5ntVJ3eTS1x2/ EHafByBx5s8X5nKXbSg== X-Authority-Analysis: v=2.4 cv=baVbluPB c=1 sm=1 tr=0 ts=6a885bba cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=OmVn7CZJonkx5R5zMQLL:22 a=gEfo2CItAAAA:8 a=gAnH3GRIAAAA:8 a=NEAV23lmAAAA:8 a=VwQbUJbxAAAA:8 a=pGLkceISAAAA:8 a=9KVYkBU6uCY3fGsyMq0A:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=sptkURWiP4Gy88Gu7hUp:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 phishscore=0 spamscore=0 suspectscore=0 impostorscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Devicetree Bindings for AD7768-4 (4 channel) and AD7768 (8 channel) simultaneous sampling ADCs. Signed-off-by: Janani Sunil --- .../devicetree/bindings/iio/adc/adi,ad7768.yaml | 314 +++++++++++++++++= ++++ MAINTAINERS | 7 + 2 files changed, 321 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7768.yaml b/Do= cumentation/devicetree/bindings/iio/adc/adi,ad7768.yaml new file mode 100644 index 000000000000..df4b179df988 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7768.yaml @@ -0,0 +1,314 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad7768.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD7768 and AD7768-4 ADC + +maintainers: + - Janani Sunil + +description: | + The AD7768 is an 8-channel, 24-bit simultaneous sampling ADC with config= urable + power and performance modes. The AD7768-4 is a 4-channel version. + + This binding covers SPI mode only (register access via SPI). Pin control= mode, + where configuration is set via hardware pins rather than SPI registers, = is not + supported. + + The io-backend represents the high-speed data output interface, consumin= g the + DOUTx data lines, DCLK (data clock), and DRDY (data ready) signals. + + Datasheet at: + https://www.analog.com/media/en/technical-documentation/data-sheets/ad= 7768-ad7768-4.pdf + + HDL reference design: + https://github.com/analogdevicesinc/hdl/tree/main/projects/ad7768evb + +properties: + compatible: + enum: + - adi,ad7768 + - adi,ad7768-4 + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + description: + Master clock (MCLK). Can be supplied as a CMOS clock on the XTAL2/MC= LK + pin, a crystal oscillator connected between the XTAL1 and XTAL2 pins= , or + an LVDS differential clock on the XTAL1/XTAL2 pin pair. CMOS and LVDS + clocks must operate from 1.15 MHz to 34 MHz. Crystals must operate f= rom + 8 MHz to 34 MHz. + + clock-names: + description: + Identifies the master clock source. + enum: + - mclk + - xtal + - lvds + default: mclk + + avdd1-supply: + description: + Analog supply voltage for the AVDD1A and AVDD1B pins (5V =C2=B1 10% = with + respect to AVSS). Powers the analog front end, reference input, and + common-mode output circuitry. Both pins must be tied to the same + potential. + + avss-supply: + description: + Negative analog supply rail for the AVSS1A, AVSS1B, AVSS2A, AVSS2B, + and AVSS pins. This rail is referenced to DGND and all AVSS pins must + be tied to the same potential. In single-supply operation AVSS is + nominally 0 V; in split-supply operation it can range from 0 V to + -2.75 V with respect to DGND. If omitted, AVSS is assumed to be at + system ground (0 V). + + avdd2-supply: + description: + Analog supply voltage for the AVDD2A and AVDD2B pins (2V to 5.5V with + respect to AVSS). Connects to internal 1.8V analog LDO regulators th= at + power the ADC core. Both pins must be tied to the same potential. + + iovdd-supply: + description: + Digital supply voltage IOVDD (2.25V to 3.6V with respect to DGND). + Sets the logic levels for all interface pins and powers the digital + processing core via an internal LDO. For 1.8V operation (1.72V to + 1.88V), IOVDD must be tied to the DREGCAP pin. + + ref1p-supply: + description: + Positive reference input supply for REF1+. The voltage range is from + (AVSS + 1 V) to AVDD1. Together, REF1+ and REF1- must provide a + differential reference voltage from 1 V to |AVDD1 - AVSS|. This + reference is used by channels 0 to 3 on the AD7768 and channels 0 an= d 1 + on the AD7768-4. + + ref1n-supply: + description: + Negative reference input supply for REF1-. The voltage range is from + AVSS to (AVDD1 - 1 V). + + ref2p-supply: + description: + Positive reference input supply for REF2+. The voltage range is from + (AVSS + 1 V) to AVDD1. Together, REF2+ and REF2- must provide a + differential reference voltage from 1 V to |AVDD1 - AVSS|. This + reference is used by channels 4 to 7 on the AD7768 and channels 2 an= d 3 + on the AD7768-4. + + ref2n-supply: + description: + Negative reference input supply for REF2-. The voltage range is from + AVSS to (AVDD1 - 1 V). + + reset-gpios: + maxItems: 1 + description: GPIO connected to the active-low RESET pin + + start-gpios: + maxItems: 1 + description: + GPIO connected to the START pin. An active-low pulse on this pin + synchronizes the device to other AD7768 devices. When not used, this + pin must be tied to a logic high level through a pull-up resistor. + When used, SYNC_OUT must be wired back to SYNC_IN on all devices in + the synchronization chain. + + sync-in-gpios: + maxItems: 1 + description: + GPIO connected to the SYNC_IN pin. Receives the synchronization pulse + generated on SYNC_OUT in response to a START pulse. Must be synchron= ous + to the MCLK clock domain. In multi-device or daisy-chained systems, + two successive synchronization pulses must be applied to guarantee a= ll + ADCs are synchronized. + + sync-out-gpios: + maxItems: 1 + description: + GPIO connected to the SYNC_OUT pin. Outputs a synchronization pulse + synchronous to MCLK in response to a START pulse or SPI_SYNC command. + In single-device configurations this pin must be wired back to SYNC_= IN. + In multi-device configurations it can be routed to the SYNC_IN pins = of + all devices in the chain. + + gpio-controller: true + + '#gpio-cells': + const: 2 + + adi,data-lines-number: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [1, 2, 4, 8] + description: + Number of DOUTx lines used for the high-speed data output interface + (distinct from the SPI control interface). AD7768 supports 1, 2, or 8 + lines; AD7768-4 supports 1 or 4 lines. Defaults to the maximum number + of lines for the selected variant if omitted. + + regulators: + type: object + description: Container for the on-chip VCM regulator. + additionalProperties: false + + properties: + vcm-output: + type: object + description: + The VCM pin provides a buffered common-mode voltage output used = to + bias the analog inputs. It supports three fixed output levels of + 1650000 uV, 2500000 uV, and 2140000 uV, as well as a + supply-dependent (AVDD1 - AVSS) / 2 output derived from + avdd1-supply. Select the voltage by setting regulator-min-microv= olt + and regulator-max-microvolt to the same value. Use + regulator-always-on when no DT consumer node references the VCM + output. The VCM circuitry is associated with channel 0. When VCM= is + used externally, channel@0 must be present and kept enabled beca= use + placing channel 0 in standby disables the VCM output. + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + + io-backends: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +patternProperties: + "^channel@[0-7]$": + type: object + description: + Represents the external channels which are connected to the device. + AD7768 supports channels 0-7, AD7768-4 supports channels 0-3. + + properties: + reg: + minimum: 0 + maximum: 7 + description: The channel number + + adi,prechargebuf-pos-enable: + type: boolean + description: Enable positive input precharge buffer + + adi,prechargebuf-neg-enable: + type: boolean + description: Enable negative input precharge buffer + + adi,refbuf-pos-enable: + type: boolean + description: Enable positive reference buffer + + adi,refbuf-neg-enable: + type: boolean + description: Enable negative reference buffer + + required: + - reg + + additionalProperties: false + +required: + - compatible + - reg + - clocks + - avdd1-supply + - avdd2-supply + - iovdd-supply + - ref1p-supply + - ref1n-supply + - ref2p-supply + - ref2n-supply + - io-backends + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + - if: + properties: + compatible: + contains: + const: adi,ad7768-4 + then: + properties: + adi,data-lines-number: + enum: [1, 4] + patternProperties: + "^channel@[0-3]$": + properties: + reg: + maximum: 3 + "^channel@[4-7]$": false + else: + properties: + adi,data-lines-number: + enum: [1, 2, 8] + +unevaluatedProperties: false + +examples: + - | + #include + + spi { + #address-cells =3D <1>; + #size-cells =3D <0>; + + adc@0 { + compatible =3D "adi,ad7768"; + reg =3D <0>; + spi-max-frequency =3D <1000000>; + + avdd1-supply =3D <&avdd1_regulator>; + avss-supply =3D <&avss_regulator>; + avdd2-supply =3D <&avdd2_regulator>; + iovdd-supply =3D <&iovdd_regulator>; + ref1p-supply =3D <&ref1p_regulator>; + ref1n-supply =3D <&ref1n_regulator>; + ref2p-supply =3D <&ref2p_regulator>; + ref2n-supply =3D <&ref2n_regulator>; + reset-gpios =3D <&gpio0 86 GPIO_ACTIVE_LOW>; + + clocks =3D <&ad7768_mclk>; + + adi,data-lines-number =3D <8>; + gpio-controller; + #gpio-cells =3D <2>; + + io-backends =3D <&iio_backend>; + + #address-cells =3D <1>; + #size-cells =3D <0>; + + channel@0 { + reg =3D <0>; + adi,prechargebuf-pos-enable; + adi,refbuf-pos-enable; + }; + + channel@1 { + reg =3D <1>; + adi,prechargebuf-pos-enable; + adi,prechargebuf-neg-enable; + adi,refbuf-pos-enable; + adi,refbuf-neg-enable; + }; + + channel@7 { + reg =3D <7>; + adi,prechargebuf-pos-enable; + adi,refbuf-pos-enable; + }; + }; + }; + +... diff --git a/MAINTAINERS b/MAINTAINERS index 2b1ec46c5919..d667a0411f28 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1633,6 +1633,13 @@ F: Documentation/devicetree/bindings/iio/adc/adi,ad7= 768-1.yaml F: drivers/iio/adc/ad7768-1.c F: include/dt-bindings/iio/adc/adi,ad7768-1.h =20 +ANALOG DEVICES INC AD7768 DRIVER +M: Janani Sunil +L: linux-iio@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/adc/adi,ad7768.yaml + ANALOG DEVICES INC AD7780 DRIVER M: Michael Hennerich M: Renato Lui Geh --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 C27E94BC022; Fri, 21 Aug 2026 14:08:10 +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=1787321292; cv=none; b=TWaGz0/hSDkuuhML3wPDOrlnX2gY6WwK1+ayHu05KAgVygi1KedQQPuqzgIhbrCvt/+fK/Xi6758MEF017Zo25ACDM2NjYwv6TxuP28mqu2f+iBkhMCueDwtuzLKYaVBxLHLHjl1BCvcg8gHyeoUXVeesYzGH1rDCXsKy9HzSu8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321292; c=relaxed/simple; bh=jkiscdNM/yjLQE4EVRoyOJE5drR7pDdgq4lSQzZ3UDQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=g3N1k2lPNlqfcgpFgfWrnDZQfH2JP3KppxMH6lXUxhaCdw4vLRo9vf0qOznwLM0WY9I/J/rL7i3/QaJBz/ohk0GVLSaXAfp29p9/cCFqeXGi9LKft3sxlBaay6EC1LqWIyPjKDSi0FWK3QJRshDOI0n+MVZvl4864BwH2LBo+mI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=d5bOzjyS; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="d5bOzjyS" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpO7W3076164; Fri, 21 Aug 2026 10:08:00 -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=sjSCC M8PAvZjvbJQpIZnyOyWSNl4xEiFW92EG7S7YnA=; b=d5bOzjySdTugGQfGlS6FD DnzC8pdDVpU8XX6Iw3DCnsY0mzLEqon+2AfAA/rJn4l9EaXCZXgPR+SL3WW2AHl1 BVWkx9VvcdGElKQkroBaTW+6AB0yLkTWEU/w3pN1BdJRa5PTRBLzXGaQtfziUcp/ X+JDumPTg58YIwO8j6QyRAgdZT9SEAgZv9VdCgi2KGsMoss7WJPTs5oJNSXVuW23 KcA/wtKL/pOBCzQ/dbIjYe3yoRSol/Or2tJ37m4j7VLikyCXbTth3hkP/GMhAM4g KYoY6cG9VcPpx0GMsTk4PhWYg4Os0n1U1EtKiBaD1ap6hMnJT0jIu8vVWPrzY+3b w== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g5rk8ykad-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:08:00 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 67LE7x5F032895 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:07:59 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:07:59 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:07:59 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkm024319; Fri, 21 Aug 2026 10:07:49 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:06:56 +0200 Subject: [PATCH v4 03/14] iio: backend: Add support for CRC 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: <20260821-ad7768-driver-v4-3-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=3769; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=jkiscdNM/yjLQE4EVRoyOJE5drR7pDdgq4lSQzZ3UDQ=; b=aezTpTscLiLA++rvVCm3dtMLbrOYkFO2yE7hBMW01OfyGMkVkqEAYn29xlMLG8IO8O00PxGn1 rGdBVIK5jMpDvJLhAHJaj7kzMC6cQ08aVCPAtAn0n70DLIpK8EopVyi X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX6kjLZp6+Xw4J zQrI51J1XHuDpxeb534ZTZ2cdcIPMgOLQBSGSV/lFTKBsJskgt4A5EzJNkanvFcG8EwFYFHBLy+ ddFC719dsV+JMfwk1vbNSdWqPdx7VtS607i+YVAaeaGgK1Y8gtkP X-Proofpoint-GUID: k4SvG-SFkkr7Eff4OPi5HOLVdoVDHUJb X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX+ueRXr9q6Zd8 PS1kyp6NxQZlAMkn3Aty8ZqUduVi5UnQFQogwwCbJoH2uoemUxLj6awzeu+KwwMtZ6eIUuiw5/i WncO0lOjEDmf3J5SWZczNZRJscKtxm2K51RhdVuaEvKUGYpqedmFNkEaQmF//mxCj+jSmKbkXcg krLzDENNZrDB0IJ1VXwKJ9jdSHhxh5CrAJLmWn9FG/oZhMnIxjb6lLFxxgROrBfkpTq8vd5eTYF K9yBiccCabu36Mvabr7xkq5GnqKzEQV72gy5AK3gD/Cn6LWbYQDEWq5jYBjmUp8CBAwhmIZCCed 3KJ6N3BhCxtrvbpd8ZD/fHGV8syhFIOLwWERRX2mKrKi9zgkDwlfLrOFzkeAZ6w26IhtfVnjBe5 lwBzHDpzIqiADG5bAuTh5NcujW7xP+g/ruVb5Oy0MI6CBhTwb9SdHn5QOiIw0xGpyzacFzuAikA +ZWzW1GTnEi+ln3bRtg== X-Proofpoint-ORIG-GUID: k4SvG-SFkkr7Eff4OPi5HOLVdoVDHUJb X-Authority-Analysis: v=2.4 cv=P+YKQCAu c=1 sm=1 tr=0 ts=6a885bc0 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=Z0pTeXoby7EwIRygza74:22 a=gAnH3GRIAAAA:8 a=O6R5dNVUA00TSld12QQA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 phishscore=0 malwarescore=0 priorityscore=1501 adultscore=0 suspectscore=0 clxscore=1015 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Add a backend operation to enable or disable direction-specific CRC handling. On input data paths, the backend handles CRC data generated by the frontend. On output data paths, the backend generates CRC data for the frontend to verify. Signed-off-by: Janani Sunil Reviewed-by: David Lechner --- drivers/iio/industrialio-backend.c | 33 +++++++++++++++++++++++++++++++++ include/linux/iio/backend.h | 6 ++++++ 2 files changed, 39 insertions(+) diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-= backend.c index f7a4be8ec320..fbf5c39d7655 100644 --- a/drivers/iio/industrialio-backend.c +++ b/drivers/iio/industrialio-backend.c @@ -886,6 +886,39 @@ int iio_backend_num_lanes_set(struct iio_backend *back= , unsigned int num_lanes) } EXPORT_SYMBOL_NS_GPL(iio_backend_num_lanes_set, "IIO_BACKEND"); =20 +/** + * iio_backend_crc_enable - Enable CRC handling + * @back: Backend device + * + * On input data paths, enable backend handling of CRC data generated by t= he + * frontend. On output data paths, enable the backend to generate CRC data= for + * the frontend to verify. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_crc_enable(struct iio_backend *back) +{ + return iio_backend_op_call(back, crc_enable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_crc_enable, "IIO_BACKEND"); + +/** + * iio_backend_crc_disable - Disable CRC handling + * @back: Backend device + * + * On input data paths, disable backend handling of CRC data generated by = the + * frontend. On output data paths, disable CRC generation by the backend. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_crc_disable(struct iio_backend *back) +{ + return iio_backend_op_call(back, crc_disable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_crc_disable, "IIO_BACKEND"); + /** * iio_backend_ddr_enable - Enable interface DDR (Double Data Rate) mode * @back: Backend device diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h index 3f95ed1fdf9e..9c16b695a602 100644 --- a/include/linux/iio/backend.h +++ b/include/linux/iio/backend.h @@ -133,6 +133,8 @@ enum iio_backend_capabilities { * @filter_type_set: Set filter type. * @interface_data_align: Perform the data alignment process. * @num_lanes_set: Set the number of lanes enabled. + * @crc_enable: Enable direction-specific CRC handling. + * @crc_disable: Disable direction-specific CRC handling. * @ddr_enable: Enable interface DDR (Double Data Rate) mode. * @ddr_disable: Disable interface DDR (Double Data Rate) mode. * @data_stream_enable: Enable data stream. @@ -189,6 +191,8 @@ struct iio_backend_ops { enum iio_backend_filter_type type); int (*interface_data_align)(struct iio_backend *back, u32 timeout_us); int (*num_lanes_set)(struct iio_backend *back, unsigned int num_lanes); + int (*crc_enable)(struct iio_backend *back); + int (*crc_disable)(struct iio_backend *back); int (*ddr_enable)(struct iio_backend *back); int (*ddr_disable)(struct iio_backend *back); int (*data_stream_enable)(struct iio_backend *back); @@ -237,6 +241,8 @@ int iio_backend_filter_type_set(struct iio_backend *bac= k, enum iio_backend_filter_type type); int iio_backend_interface_data_align(struct iio_backend *back, u32 timeout= _us); int iio_backend_num_lanes_set(struct iio_backend *back, unsigned int num_l= anes); +int iio_backend_crc_enable(struct iio_backend *back); +int iio_backend_crc_disable(struct iio_backend *back); int iio_backend_ddr_enable(struct iio_backend *back); int iio_backend_ddr_disable(struct iio_backend *back); int iio_backend_data_stream_enable(struct iio_backend *back); --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 B1FE04C77DE; Fri, 21 Aug 2026 14:08:15 +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=1787321297; cv=none; b=kiMG1bKYJTTT3ISDQgQJxILvLypi6DPZdn0+d+wUWTpIUarSXKj6WVjw+Qm6/kySJr3zy8iaLjq+mWvQWA+agA8s4LyZJy/OS3DE1coIb4TxGACWa6oB7OK1e39jwhb18eezefZYEhQ+BPV+JzkqAsB8R6HM6DazgZ1ngoriUhI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321297; c=relaxed/simple; bh=BC3GY2a0PfAaf1anUYAI3VBIwF6NWvD9eEF7jo39oM4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=uG3ihoH6SIfVNW+BqixFxSjjh2KJhauYPF0dhdxowVx0cem2JcK6bKMMg4N+R1OdV8hX0W1aphsZbeSVB/7rtpOdvgHXcHHZ4A4hcc985D/Fx4kiFEngWkzMQLWU2vBs30YGHeMoDJvgoUTvl0Zquy3Mf3pfygw1bFcRfNUcogA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=mnVLxM0i; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="mnVLxM0i" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpGA63677096; Fri, 21 Aug 2026 10:08:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=meDou IdYda+dFUbpyjE577+DP2BMvJelM4xTd/l8MgY=; b=mnVLxM0ixD7QkQNady3Dz 7lMCBv0WmDdqzGpsXs54KyM00srLrvyjwcGZttCl9wTaCBCnZymJGbEdX+/dSdS6 2xhYQfaeGfMyH3CxKbtJulo0uIscZACaPe/xvdcRr9NiMorBXzBHLI9BkVVu0+GW 0oJjUqpL+IfIuCPxX6KJkUM9vj4BQjStTrkmenPuyQEsoN7pknHez5AQqdhRl4PM OFfYlnZj2NwtxE0tlqQSPyVsG3rwuB3e+DiQNwF5yg5ohAhf4MOJhJD6uRwCZ0+a RfB7540ScGNC3ZfwgDI3V8FH86IdE8ghfe2dxzFYsOTx4wCE4AXhuIWL5lhnerv5 w== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g6a27k3xt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:08:06 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 67LE85VI032952 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:08:05 -0400 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:05 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08: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.37 via Frontend Transport; Fri, 21 Aug 2026 10:08:05 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkn024319; Fri, 21 Aug 2026 10:07:55 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:06:57 +0200 Subject: [PATCH v4 04/14] iio: adc: adi-axi-adc: Add support for CRC 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: <20260821-ad7768-driver-v4-4-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , "David Lechner" , Andy Shevchenko , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=2211; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=BC3GY2a0PfAaf1anUYAI3VBIwF6NWvD9eEF7jo39oM4=; b=j6f/8oYRld8ZiXeJUHSER0zlB81tlKyoo6ta3Y2CUH/izU0rR5Cvs/heyLOeyaQbV2PD6SZdj zpRDKZblNV3BYQCiecIxc4Zfs8qI5BKyGCYapyz7dPwRQSsnNhKSqkX X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: MiGLaABGPLw4L2hejH5ZKxkmgzD_1aNT X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX237qJlScs8tT a6HEEWEnECUjJlKvqlVs4kWURkg1VW4IGf6H7TISFWzp6Oq6LjJz9q6uSCAIEytMEzClS72mJuw iEI3gCufoq7cv0OhK2ncw1ETKAKU4VAV6tplDKcntBsBm13ZyOuD X-Authority-Analysis: v=2.4 cv=FeoHAp+6 c=1 sm=1 tr=0 ts=6a885bc6 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=uXIjobp8t2wMuQ0fPvqm:22 a=gAnH3GRIAAAA:8 a=xcMXqGzQfnDy9uQaBxsA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: MiGLaABGPLw4L2hejH5ZKxkmgzD_1aNT X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX9QFhI02AaUmd goUJSUA8h2XLGAzX9YgDFO7aYRRCdzPOWTvTChoHFcPFjQ3MJo1NHhEGW8aUwzzHpON9KG7Cvuk 9XR1IQ4Tc8Vq/L3Ev5iYdKjooJYZvLfjx29Unof3XgzFU2wROLQ4sSYTOXZIJArVzgdjCeHQqEd 4UFwnWIczBdXH2rwBy1yXhgD0wsv2TXp/pIVn1zXWWIV8iJtSMiXN+Hm5VIX+9kwOfoo5xgpbOS 0k3r8FUfEjByBku2yowG8VXp2PlZhQywwScnAViqb/3MStHdkhk0V05EqKRuR2EhoclnOLgLFJ6 CRyplwLjzfX2NEvurWuhvYW5R5DcV8OBF2UMgztfR7uXubhQ8b4uidhRdW4ZDuQXLl26GWiJ1b7 p9h+yYs4MAf4StnOmA4fBSBdEYQsA7snCeH6rIJoexO8rCpeMsef22IXSRKh5uMc+vi8kDu8zyr v80KVnTEUsnEBHD9ARA== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 malwarescore=0 adultscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 priorityscore=1501 bulkscore=0 phishscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Add support for enabling and disabling Cyclic Redundancy Check (CRC) processing in the AXI ADC backend. CRC provides data integrity verification for high-speed ADC data streams, ensuring reliable data transfer between the ADC frontend and backend processing systems. Signed-off-by: Janani Sunil Reviewed-by: David Lechner --- drivers/iio/adc/adi-axi-adc.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index b5e59b1871b6..e8f149e230e7 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -47,6 +47,9 @@ #define ADI_AXI_ADC_CTRL_DDR_EDGESEL_MASK BIT(1) =20 #define ADI_AXI_ADC_REG_CNTRL_3 0x004c +/* Bit 8 is common to all AXI ADC cores; bits 7-0 are per-HDL-project. */ +#define ADI_AXI_ADC_CNTRL_3_CRC_EN_MASK BIT(8) + #define AXI_AD485X_CNTRL_3_OS_EN_MSK BIT(2) #define AXI_AD485X_CNTRL_3_PACKET_FORMAT_MSK GENMASK(1, 0) #define AXI_AD485X_PACKET_FORMAT_20BIT 0x0 @@ -567,6 +570,22 @@ static int axi_adc_reg_access(struct iio_backend *back= , unsigned int reg, return regmap_write(st->regmap, reg, writeval); } =20 +static int axi_adc_crc_enable(struct iio_backend *back) +{ + struct adi_axi_adc_state *st =3D iio_backend_get_priv(back); + + return regmap_set_bits(st->regmap, ADI_AXI_ADC_REG_CNTRL_3, + ADI_AXI_ADC_CNTRL_3_CRC_EN_MASK); +} + +static int axi_adc_crc_disable(struct iio_backend *back) +{ + struct adi_axi_adc_state *st =3D iio_backend_get_priv(back); + + return regmap_clear_bits(st->regmap, ADI_AXI_ADC_REG_CNTRL_3, + ADI_AXI_ADC_CNTRL_3_CRC_EN_MASK); +} + static const struct regmap_config axi_adc_regmap_config =3D { .val_bits =3D 32, .reg_bits =3D 32, @@ -615,6 +634,8 @@ static const struct iio_backend_ops adi_axi_adc_ops =3D= { .num_lanes_set =3D axi_adc_num_lanes_set, .debugfs_reg_access =3D iio_backend_debugfs_ptr(axi_adc_reg_access), .debugfs_print_chan_status =3D iio_backend_debugfs_ptr(axi_adc_debugfs_pr= int_chan_status), + .crc_enable =3D axi_adc_crc_enable, + .crc_disable =3D axi_adc_crc_disable, }; =20 static const struct iio_backend_info adi_axi_adc_generic =3D { --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 3FD0433D6D6; Fri, 21 Aug 2026 14:08:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321306; cv=none; b=VMwJiWkidvngFLqjyOJ0XWbZABOfhru23414mARPKPBg/ofW5sQgdj8BRBXwrhl68UkgeAXw4sFIxAEYbgAOJbHOHpDpW2LQX/EwZuO9h3N71Tkyk3NAVYu+tj71oDqgYyzWxV6skvXpvTNwLLWQxxSm0Z+472jz2cZizRuSTGQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321306; c=relaxed/simple; bh=3+uLqrvsHoR9upQ+lrN4MctXntXHxH7wckZc1bdDKHc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=ijtRH9MvM7amrU/+C1Q/wkEHSz+nj2huEqmVg40E41I6CY1j6tggzZxhD4btGC23lg2tBRma8N2UJ4mIhlJ6QqiVWaP1tix5iW3K3o/kvvRpz6/QALDpDUVlOIsU/i2cP9x6MosXK2NED2XT8H/CaZidgUCPhHH2pkifLwA0ZMw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=dgF5psUa; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="dgF5psUa" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpQKK3076187; Fri, 21 Aug 2026 10:08:13 -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=AcYmj PBa5/eggKNHSAJPUdrbtq5xrKPKO61yofNE30k=; b=dgF5psUazoBh2rXr5Z1HD Hr3uZE6mWd3fAwa4iN39+BY4h2gxRcT3BPjT0yNuYthJVpY3Rl2stvb0/ILERyTg g0kGIxsRddAvt3vY9x0+Pr+8EDuegcA5adrECHuheCm4yUNRfo57P6zYKveLz/DG GbW8oy51l6X9t53z9Thx8VvPQPwP+mxr4u8Ol2hsOeOSXXq4LwGgVWnEUUaDURTG eExjHMdjA1y+D9EjSujaTUVCFOlqhseriQwLFpzv8U8kGxPm66xWVWCcGH7TU4Ux a5uwUmTJUz7q/yBylsn90uT3y0tf2Kp2sYzPkEKYUlD0MkB49JVIXBV82x2+wFkn Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g5rk8ykbg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:08:12 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 67LE8B03032984 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:08:11 -0400 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:11 -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.37; Fri, 21 Aug 2026 10:08:11 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:08:11 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kko024319; Fri, 21 Aug 2026 10:08:00 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:06:58 +0200 Subject: [PATCH v4 05/14] iio: adc: Add AD7768 and AD7768-4 core support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20260821-ad7768-driver-v4-5-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , "David Lechner" , Andy Shevchenko , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=28863; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=3+uLqrvsHoR9upQ+lrN4MctXntXHxH7wckZc1bdDKHc=; b=pWqsr5uvdJORQjpxwv9WsUIbqYUzz/lc4NTLafuurtiZgCiI0fWRcik5FUbSh+Lrtf4ftOqRc ZwBdpGbij+sAq0qbBiwbT6qiHG/SmnWaak7tJz6mhgfIzpsfYeTEAAZ X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX2OPP8vMsA2Vk Ad/dxcKgx+qN/tWiJqHuNpHJ9RG3vMed3lcCH17ms2EvXgxv6IjxrAX/21ivpA2JFYw2vE9xC8x 22nuK65WykloiTV59cg0+BDocqY1wEEqP0hC+P5sZtaVxaREgBKE X-Proofpoint-GUID: x1D05TxUVd0TxgHzxs8o2B9P0Cd4Jgoz X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX7sDIRQi+Hi9e Vk2fRNWizmbyJuUrcdjReEWR5X5AosV9Ph2Wq1nU6iQw/EXVyT4T8g7rFdZn7ftrgycOyNnu57X fV8T07EzmwngcHGPiBcDXC5JsFUhwdGs6AsRkoSBXykXbZihyNoXdcg6W5WZCLv3MffM+MJqx/k +gvGVdi0q8Cqz4x+fSfqNe4e3mdGwXgLiZVWVzkN3kMpD4bVVOkDEhNj3rcX23udRkkkXntMQw7 1+kPgTHwrufVJSawR+DmiPGQwm3aA3mZbXtqAs2tt98EuPptSPCCmkQdNGEJejQgtb6NfQZM8yC b5O+o5eRbKQH+IPiVqMBb6E9UlnbyAcpbdp01EmdIEdhzI5+gETP49qdbo7KN2tDBQ8zAT9mEMk mEVr/C1v9xQ6Jk9WFpoq3FzJqmHUuszc0WT5S9qxDCcxEby0N6W4kNToi6/2LLbcTPe094YVdjj 4/faOPT2eY3UNvlWfOw== X-Proofpoint-ORIG-GUID: x1D05TxUVd0TxgHzxs8o2B9P0Cd4Jgoz X-Authority-Analysis: v=2.4 cv=P+YKQCAu c=1 sm=1 tr=0 ts=6a885bcc cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=Z0pTeXoby7EwIRygza74:22 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=D3CSPCWpKpZ9qul4N3QA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 phishscore=0 malwarescore=0 priorityscore=1501 adultscore=0 suspectscore=0 clxscore=1015 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Add core support for the AD7768 and AD7768-4 simultaneous sampling ADCs. Configure supplies, clock and reset, use a custom regmap bus for the SPI protocol, and parse the enabled channels and input buffer settings from devicetree. Connect the converter to an IIO backend for buffered capture with CRC, provide a fixed safe wideband sampling configuration and add runtime power management. Signed-off-by: Janani Sunil --- MAINTAINERS | 1 + drivers/iio/adc/Kconfig | 14 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad7768.c | 920 +++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 936 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index d667a0411f28..dc94e7803a7c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1639,6 +1639,7 @@ L: linux-iio@vger.kernel.org S: Supported W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad7768.yaml +F: drivers/iio/adc/ad7768.c =20 ANALOG DEVICES INC AD7780 DRIVER M: Michael Hennerich diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index d1b198cb8a80..48bb108382b5 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -429,6 +429,20 @@ config AD7766 To compile this driver as a module, choose M here: the module will be called ad7766. =20 +config AD7768 + tristate "Analog Devices AD7768/AD7768-4 ADC driver" + depends on SPI + depends on REGULATOR || COMPILE_TEST + select IIO_BUFFER + select IIO_BACKEND + select REGMAP + help + Say yes here to build support for Analog Devices AD7768 and AD7768-4 + SPI analog to digital converters. + + To compile this driver as a module, choose M here: the module will be + called ad7768. + config AD7768_1 tristate "Analog Devices AD7768-1 ADC driver" depends on SPI diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 0f90b75577ff..3e896c8aa7c3 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_AD7606_IFACE_SPI) +=3D ad7606_spi.o obj-$(CONFIG_AD7606) +=3D ad7606.o obj-$(CONFIG_AD7625) +=3D ad7625.o obj-$(CONFIG_AD7766) +=3D ad7766.o +obj-$(CONFIG_AD7768) +=3D ad7768.o obj-$(CONFIG_AD7768_1) +=3D ad7768-1.o obj-$(CONFIG_AD7779) +=3D ad7779.o obj-$(CONFIG_AD7780) +=3D ad7780.o diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c new file mode 100644 index 000000000000..34233ad6cfca --- /dev/null +++ b/drivers/iio/adc/ad7768.c @@ -0,0 +1,920 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Analog Devices AD7768 ADC driver + * + * Copyright 2018-2026 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define AD7768_REG_CH_STANDBY 0x00 + +#define AD7768_REG_CH_MODE(x) (0x01 + (x)) +#define AD7768_CH_MODE_FILTER_TYPE_MSK BIT(3) +#define AD7768_CH_MODE_FILTER_TYPE_WIDEBAND 0x0 +#define AD7768_CH_MODE_DEC_RATE_MSK GENMASK(2, 0) +#define AD7768_CH_MODE_DEC_RATE_64 0x1 + +#define AD7768_REG_CH_MODE_SEL 0x03 + +#define AD7768_REG_POWER_MODE 0x04 +#define AD7768_SLEEP_MODE_MSK BIT(7) +#define AD7768_POWER_MODE_POWER_MODE_MSK GENMASK(5, 4) +#define AD7768_POWER_MODE_POWER_MODE_LOW 0x0 +#define AD7768_POWER_MODE_POWER_MODE_MEDIAN 0x2 +#define AD7768_POWER_MODE_POWER_MODE_FAST 0x3 +#define AD7768_POWER_MODE_LVDS_ENABLE BIT(3) +#define AD7768_POWER_MODE_MCLK_DIV_MSK GENMASK(1, 0) + +#define AD7768_REG_GENERAL_CONFIG 0x05 + +#define AD7768_REG_DATA_CONTROL 0x06 +#define AD7768_DATA_CONTROL_SPI_RESET_1 0x03 +#define AD7768_DATA_CONTROL_SPI_RESET_2 0x02 +#define AD7768_DATA_CONTROL_SPI_SYNC BIT(7) + +#define AD7768_REG_INTERFACE_CFG 0x07 +#define AD7768_INTERFACE_CFG_CRC_SELECT_MSK GENMASK(3, 2) +/* + * Hardware supports CRC every 4 or 16 samples; the backend supports only + * 4-sample CRC. + */ +#define AD7768_INTERFACE_CFG_CRC_SELECT_4 0x1 +#define AD7768_INTERFACE_CFG_DCLK_DIV_MSK GENMASK(1, 0) +#define AD7768_INTERFACE_CFG_DCLK_DIV(x) (4 - ffs(x)) + +#define AD7768_REG_REV_ID 0x0A +#define AD7768_REV_ID_VAL 0x06 + +#define AD7768_REG_GPIO_CONTROL 0x0E +#define AD7768_GPIO_UGPIO_ENABLE BIT(7) +#define AD7768_GPIO4_OUTPUT_ENABLE BIT(4) + +#define AD7768_REG_GPIO_WRITE 0x0F + +#define AD7768_REG_PRECHARGE_BUF1 0x11 +#define AD7768_REG_PRECHARGE_BUF2 0x12 +#define AD7768_PREBUF_POS_EN(ch) BIT((ch) * 2) +#define AD7768_PREBUF_NEG_EN(ch) BIT(((ch) * 2) + 1) + +#define AD7768_REG_REFP_BUF 0x13 +#define AD7768_REG_REFN_BUF 0x14 + +#define AD7768_REG_OFFSET_BASE 0x1E +#define AD7768_REG_GAIN_BASE 0x36 +#define AD7768_REG_PHASE_BASE 0x4E +#define AD7768_REG_OFFSET(ch) \ + (AD7768_REG_OFFSET_BASE + (3 * (ch))) +#define AD7768_REG_GAIN(ch) \ + (AD7768_REG_GAIN_BASE + (3 * (ch))) +#define AD7768_REG_PHASE(ch) ((AD7768_REG_PHASE_BASE + (ch))) +#define __AD7768_4_REG_MAP(ch) ((ch) < 2 ? (ch) : ((ch) + 2)) +#define AD7768_4_REG_OFFSET(ch) \ + (AD7768_REG_OFFSET_BASE + (3 * __AD7768_4_REG_MAP(ch))) +#define AD7768_4_REG_GAIN(ch) \ + (AD7768_REG_GAIN_BASE + (3 * __AD7768_4_REG_MAP(ch))) +#define AD7768_4_REG_PHASE(ch) \ + (AD7768_REG_PHASE_BASE + __AD7768_4_REG_MAP(ch)) + +#define AD7768_REG_DIAGNOSTIC_RX 0x56 + +#define AD7768_REG_CHOP_CTRL 0x59 + +#define AD7768_SPI_READ_CMD BIT(15) +#define AD7768_SPI_REG_MASK GENMASK(14, 8) +#define AD7768_SPI_DATA_MASK GENMASK(7, 0) + +#define AD7768_SAMPLE_SIZE 32 +#define AD7768_MAX_DCLK_DIV 8 +#define AD7768_MAX_CHANNEL 8 + +enum ad7768_clock_source { + AD7768_CLOCK_SOURCE_MCLK, + AD7768_CLOCK_SOURCE_XTAL, + AD7768_CLOCK_SOURCE_LVDS, +}; + +struct ad7768_precharge_config { + bool prebufp_en; + bool prebufn_en; + bool refbufp; + bool refbufn; +}; + +struct ad7768_chip_info { + const char *name; + unsigned int num_channels; + const struct regmap_config *regmap_config; + const unsigned int *available_datalines; + unsigned int num_datalines; + const u8 *chan_map; + u8 prebuf_split; +}; + +struct ad7768_state { + struct regmap *regmap; + /* Protects device register access and configuration. */ + struct mutex lock; + struct clk *mclk; + unsigned int datalines; + enum ad7768_clock_source clock_source; + const struct ad7768_chip_info *chip_info; + struct iio_backend *back; + + __be16 d16 __aligned(IIO_DMA_MINALIGN); +}; + +static const unsigned int ad7768_available_datalines[] =3D { + 1, 2, 8, +}; + +static const unsigned int ad7768_4_available_datalines[] =3D { + 1, 4, +}; + +static const u8 ad7768_chan_map[] =3D { + 0, 1, 2, 3, 4, 5, 6, 7, +}; + +static const u8 ad7768_4_chan_map[] =3D { + 0, 1, 4, 5, +}; + +static const char * const ad7768_supply_names[] =3D { + "avdd2", "iovdd", "ref1p", "ref1n", "ref2p", "ref2n", +}; + +static const char * const ad7768_clock_names[] =3D { + [AD7768_CLOCK_SOURCE_MCLK] =3D "mclk", + [AD7768_CLOCK_SOURCE_XTAL] =3D "xtal", + [AD7768_CLOCK_SOURCE_LVDS] =3D "lvds", +}; + +static u8 ad7768_channel_mask(const struct ad7768_state *st, u8 ch) +{ + return BIT(st->chip_info->chan_map[ch]); +} + +static u8 ad7768_all_standby_mask(const struct ad7768_state *st) +{ + return GENMASK(st->chip_info->num_channels - 1, 0); +} + +static u8 ad7768_precharge_buf1_mask(const struct ad7768_state *st, u16 va= l) +{ + return val & GENMASK(st->chip_info->prebuf_split - 1, 0); +} + +static u8 ad7768_precharge_buf2_mask(const struct ad7768_state *st, u16 va= l) +{ + return (val >> st->chip_info->prebuf_split) & + GENMASK(st->chip_info->prebuf_split - 1, 0); +} + +static int ad7768_regmap_read(void *context, const void *reg_buf, + size_t reg_size, void *val_buf, size_t val_size) +{ + struct ad7768_state *st =3D spi_get_drvdata(context); + struct spi_device *spi =3D context; + struct spi_transfer t[] =3D { + { + .tx_buf =3D &st->d16, + .len =3D sizeof(st->d16), + .cs_change =3D 1, + }, { + /* + * Register responses are delayed by one CS frame. While + * receiving the response to this read, the device also + * decodes another command on SDI. Repeat the read + * command to avoid sending an unspecified dummy + * command. + */ + .tx_buf =3D &st->d16, + .rx_buf =3D &st->d16, + .len =3D sizeof(st->d16), + }, + }; + u8 *data_val =3D val_buf; + unsigned int reg; + int ret; + + reg =3D *(const u8 *)reg_buf; + + st->d16 =3D be16_replace_bits(cpu_to_be16(AD7768_SPI_READ_CMD), reg, + AD7768_SPI_REG_MASK); + + ret =3D spi_sync_transfer(spi, t, ARRAY_SIZE(t)); + if (ret) + return ret; + + *data_val =3D be16_get_bits(st->d16, AD7768_SPI_DATA_MASK); + + return 0; +} + +static int ad7768_regmap_write(void *context, const void *data, size_t cou= nt) +{ + struct spi_device *spi =3D context; + + return spi_write(spi, data, count); +} + +static const struct regmap_bus ad7768_regmap_bus =3D { + .read =3D ad7768_regmap_read, + .write =3D ad7768_regmap_write, + .reg_format_endian_default =3D REGMAP_ENDIAN_BIG, + .val_format_endian_default =3D REGMAP_ENDIAN_BIG, +}; + +static bool ad7768_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case AD7768_REG_CH_STANDBY ... AD7768_REG_REV_ID: + case AD7768_REG_GPIO_CONTROL ... AD7768_REG_REFN_BUF: + return true; + case AD7768_REG_OFFSET(0) ... AD7768_REG_OFFSET(7) + 2: + case AD7768_REG_GAIN(0) ... AD7768_REG_GAIN(7) + 2: + case AD7768_REG_PHASE(0) ... AD7768_REG_PHASE(7): + case AD7768_REG_DIAGNOSTIC_RX ... AD7768_REG_CHOP_CTRL: + return true; + default: + return false; + } +} + +static bool ad7768_4_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case AD7768_REG_CH_STANDBY ... AD7768_REG_REV_ID: + case AD7768_REG_GPIO_CONTROL ... AD7768_REG_REFN_BUF: + return true; + case AD7768_4_REG_OFFSET(0) ... AD7768_4_REG_OFFSET(1) + 2: + case AD7768_4_REG_OFFSET(2) ... AD7768_4_REG_OFFSET(3) + 2: + case AD7768_4_REG_GAIN(0) ... AD7768_4_REG_GAIN(1) + 2: + case AD7768_4_REG_GAIN(2) ... AD7768_4_REG_GAIN(3) + 2: + case AD7768_4_REG_PHASE(0) ... AD7768_4_REG_PHASE(1): + case AD7768_4_REG_PHASE(2) ... AD7768_4_REG_PHASE(3): + case AD7768_REG_DIAGNOSTIC_RX ... AD7768_REG_CHOP_CTRL: + return true; + default: + return false; + } +} + +static const struct regmap_config ad7768_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .max_register =3D AD7768_REG_CHOP_CTRL, + .use_single_read =3D true, + .use_single_write =3D true, + .readable_reg =3D ad7768_readable_reg, +}; + +static const struct regmap_config ad7768_4_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .max_register =3D AD7768_REG_CHOP_CTRL, + .use_single_read =3D true, + .use_single_write =3D true, + .readable_reg =3D ad7768_4_readable_reg, +}; + +static int ad7768_reg_access(struct iio_dev *indio_dev, + unsigned int reg, + unsigned int writeval, + unsigned int *readval) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + int ret; + + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(regmap_get_device(st->regmap), pm); + ret =3D PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + if (readval) + return regmap_read(st->regmap, reg, readval); + + return regmap_write(st->regmap, reg, writeval); +} + +static int ad7768_sync(struct ad7768_state *st) +{ + int ret; + + ret =3D regmap_clear_bits(st->regmap, AD7768_REG_DATA_CONTROL, + AD7768_DATA_CONTROL_SPI_SYNC); + if (ret) + return ret; + + return regmap_set_bits(st->regmap, AD7768_REG_DATA_CONTROL, + AD7768_DATA_CONTROL_SPI_SYNC); +} + +static int ad7768_configure_capture(struct ad7768_state *st) +{ + unsigned int dclk_div_reg; + unsigned int mode_config; + unsigned int dclk_div; + int ret; + + ret =3D regmap_update_bits(st->regmap, AD7768_REG_POWER_MODE, + AD7768_POWER_MODE_POWER_MODE_MSK | + AD7768_POWER_MODE_MCLK_DIV_MSK, + FIELD_PREP(AD7768_POWER_MODE_POWER_MODE_MSK, + AD7768_POWER_MODE_POWER_MODE_FAST) | + FIELD_PREP(AD7768_POWER_MODE_MCLK_DIV_MSK, + AD7768_POWER_MODE_POWER_MODE_FAST)); + if (ret) + return ret; + + /* + * Start with the wideband filter and a decimation rate of 64. This + * supports every valid data-line configuration at the maximum MCLK. + */ + mode_config =3D FIELD_PREP(AD7768_CH_MODE_FILTER_TYPE_MSK, + AD7768_CH_MODE_FILTER_TYPE_WIDEBAND); + mode_config |=3D FIELD_PREP(AD7768_CH_MODE_DEC_RATE_MSK, + AD7768_CH_MODE_DEC_RATE_64); + ret =3D regmap_update_bits(st->regmap, AD7768_REG_CH_MODE(0), + AD7768_CH_MODE_FILTER_TYPE_MSK | + AD7768_CH_MODE_DEC_RATE_MSK, + mode_config); + if (ret) + return ret; + + ret =3D regmap_write(st->regmap, AD7768_REG_CH_MODE_SEL, 0); + if (ret) + return ret; + + dclk_div =3D 8 * st->datalines / st->chip_info->num_channels; + dclk_div_reg =3D AD7768_INTERFACE_CFG_DCLK_DIV(dclk_div); + ret =3D regmap_update_bits(st->regmap, AD7768_REG_INTERFACE_CFG, + AD7768_INTERFACE_CFG_DCLK_DIV_MSK, + FIELD_PREP(AD7768_INTERFACE_CFG_DCLK_DIV_MSK, + dclk_div_reg)); + if (ret) + return ret; + + return ad7768_sync(st); +} + +static int ad7768_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + unsigned int channel_mask; + unsigned int standby_mask; + int ret; + + channel_mask =3D ad7768_all_standby_mask(st); + standby_mask =3D channel_mask; + if (st->clock_source =3D=3D AD7768_CLOCK_SOURCE_XTAL) + standby_mask &=3D ~BIT(st->chip_info->num_channels / 2); + + for (unsigned int c =3D 0; c < st->chip_info->num_channels; c++) { + if (test_bit(c, scan_mask)) + standby_mask &=3D ~BIT(c); + } + + ret =3D regmap_update_bits(st->regmap, AD7768_REG_CH_STANDBY, + channel_mask, standby_mask); + if (ret) + return ret; + + for (unsigned int c =3D 0; c < st->chip_info->num_channels; c++) { + if (test_bit(c, scan_mask)) + ret =3D iio_backend_chan_enable(st->back, c); + else + ret =3D iio_backend_chan_disable(st->back, c); + if (ret) + return ret; + } + + return 0; +} + +static const struct ad7768_chip_info ad7768_chip_info =3D { + .name =3D "ad7768", + .num_channels =3D 8, + .regmap_config =3D &ad7768_regmap_config, + .available_datalines =3D ad7768_available_datalines, + .num_datalines =3D ARRAY_SIZE(ad7768_available_datalines), + .chan_map =3D ad7768_chan_map, + .prebuf_split =3D 8, +}; + +static const struct ad7768_chip_info ad7768_4_chip_info =3D { + .name =3D "ad7768-4", + .num_channels =3D 4, + .regmap_config =3D &ad7768_4_regmap_config, + .available_datalines =3D ad7768_4_available_datalines, + .num_datalines =3D ARRAY_SIZE(ad7768_4_available_datalines), + .chan_map =3D ad7768_4_chan_map, + .prebuf_split =3D 4, +}; + +static int ad7768_buffer_preenable(struct iio_dev *indio_dev) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + + return pm_runtime_resume_and_get(regmap_get_device(st->regmap)); +} + +static int ad7768_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + + pm_runtime_put_autosuspend(regmap_get_device(st->regmap)); + return 0; +} + +static const struct iio_buffer_setup_ops ad7768_buffer_ops =3D { + .preenable =3D ad7768_buffer_preenable, + .postdisable =3D ad7768_buffer_postdisable, +}; + +static const struct iio_info ad7768_info =3D { + .debugfs_reg_access =3D ad7768_reg_access, + .update_scan_mode =3D ad7768_update_scan_mode, +}; + +static int ad7768_configure_precharge_buffers(struct iio_dev *indio_dev, + struct ad7768_precharge_config *precharge_cfg) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + u8 prebuf1_val, prebuf2_val; + u16 prebuf_mask =3D 0; + u8 refbufp_val =3D 0; + u8 refbufn_val =3D 0; + int ret; + + for (u8 ch =3D 0; ch < indio_dev->num_channels; ch++) { + u8 channel =3D indio_dev->channels[ch].channel; + + if (precharge_cfg[channel].prebufp_en) + prebuf_mask |=3D AD7768_PREBUF_POS_EN(channel); + + if (precharge_cfg[channel].prebufn_en) + prebuf_mask |=3D AD7768_PREBUF_NEG_EN(channel); + + if (precharge_cfg[channel].refbufp) + refbufp_val |=3D ad7768_channel_mask(st, channel); + + if (precharge_cfg[channel].refbufn) + refbufn_val |=3D ad7768_channel_mask(st, channel); + } + + prebuf1_val =3D ad7768_precharge_buf1_mask(st, ~prebuf_mask); + prebuf2_val =3D ad7768_precharge_buf2_mask(st, ~prebuf_mask); + + ret =3D regmap_write(st->regmap, AD7768_REG_PRECHARGE_BUF1, prebuf1_val); + if (ret) + return ret; + + ret =3D regmap_write(st->regmap, AD7768_REG_PRECHARGE_BUF2, prebuf2_val); + if (ret) + return ret; + + ret =3D regmap_write(st->regmap, AD7768_REG_REFP_BUF, refbufp_val); + if (ret) + return ret; + + return regmap_write(st->regmap, AD7768_REG_REFN_BUF, refbufn_val); +} + +static int ad7768_parse_config(struct iio_dev *indio_dev, + struct device *dev) +{ + struct ad7768_precharge_config precharge_cfg[AD7768_MAX_CHANNEL] =3D { }; + struct ad7768_state *st =3D iio_priv(indio_dev); + const unsigned int *available_datalines; + struct iio_chan_spec *chan; + unsigned int num_channels; + unsigned int standby_mask; + unsigned int i, len; + int chan_idx =3D 0; + int ret; + + num_channels =3D 0; + device_for_each_named_child_node_scoped(dev, child, "channel") + num_channels++; + + if (!num_channels || num_channels > st->chip_info->num_channels) + return dev_err_probe(dev, -EINVAL, + "Invalid number of channels\n"); + + chan =3D devm_kcalloc(indio_dev->dev.parent, num_channels, + sizeof(*chan), GFP_KERNEL); + if (!chan) + return -ENOMEM; + + indio_dev->channels =3D chan; + indio_dev->num_channels =3D num_channels; + + standby_mask =3D ad7768_all_standby_mask(st); + if (st->clock_source =3D=3D AD7768_CLOCK_SOURCE_XTAL) + standby_mask &=3D ~BIT(st->chip_info->num_channels / 2); + + ret =3D regmap_write(st->regmap, AD7768_REG_CH_STANDBY, standby_mask); + if (ret) + return ret; + + device_for_each_named_child_node_scoped(dev, child, "channel") { + unsigned int channel; + + ret =3D fwnode_property_read_u32(child, "reg", &channel); + if (ret) + return dev_err_probe(dev, ret, + "Failed to parse reg of %pfwP\n", + child); + + if (channel >=3D st->chip_info->num_channels) + return dev_err_probe(dev, -EINVAL, + "Invalid channel %u in firmware\n", + channel); + + ret =3D regmap_clear_bits(st->regmap, AD7768_REG_CH_STANDBY, + BIT(channel)); + if (ret) + return ret; + + precharge_cfg[channel].prebufp_en =3D + fwnode_property_read_bool(child, + "adi,prechargebuf-pos-enable"); + precharge_cfg[channel].prebufn_en =3D + fwnode_property_read_bool(child, + "adi,prechargebuf-neg-enable"); + precharge_cfg[channel].refbufp =3D + fwnode_property_read_bool(child, + "adi,refbuf-pos-enable"); + precharge_cfg[channel].refbufn =3D + fwnode_property_read_bool(child, + "adi,refbuf-neg-enable"); + + chan[chan_idx] =3D (struct iio_chan_spec) { + .type =3D IIO_VOLTAGE, + .indexed =3D 1, + .address =3D channel, + .channel =3D channel, + .scan_index =3D channel, + .scan_type =3D { + .sign =3D 's', + .realbits =3D 24, + .storagebits =3D 32, + }, + }; + chan_idx++; + } + + ret =3D ad7768_configure_precharge_buffers(indio_dev, precharge_cfg); + if (ret) + return ret; + + available_datalines =3D st->chip_info->available_datalines; + len =3D st->chip_info->num_datalines; + st->datalines =3D available_datalines[len - 1]; + ret =3D device_property_read_u32(dev, "adi,data-lines-number", + &st->datalines); + if (ret && ret !=3D -EINVAL) + return dev_err_probe(dev, ret, + "Invalid %s property\n", + "adi,data-lines-number"); + + for (i =3D 0; i < len; i++) { + if (available_datalines[i] =3D=3D st->datalines) + break; + } + + if (i =3D=3D len) + return dev_err_probe(dev, -EINVAL, + "Invalid data-lines-number %d for %s\n", + st->datalines, st->chip_info->name); + + return ad7768_configure_capture(st); +} + +static int ad7768_reset(struct ad7768_state *st) +{ + struct device *dev =3D regmap_get_device(st->regmap); + struct reset_control *reset_ctrl; + unsigned long reset_low_us; + unsigned long mclk; + int ret; + + reset_ctrl =3D devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(reset_ctrl)) + return PTR_ERR(reset_ctrl); + + if (reset_ctrl) { + mclk =3D clk_get_rate(st->mclk); + if (!mclk) + return -EINVAL; + + /* + * Minimum RESET low pulse width: 2 x tMCLK + * (datasheet Table 1). + */ + reset_low_us =3D DIV_ROUND_UP_ULL(2ULL * USEC_PER_SEC, mclk); + + ret =3D reset_control_assert(reset_ctrl); + if (ret) + return ret; + + fsleep(max_t(unsigned long, 1, reset_low_us)); + + ret =3D reset_control_deassert(reset_ctrl); + if (ret) + return ret; + } else { + ret =3D regmap_write(st->regmap, AD7768_REG_DATA_CONTROL, + AD7768_DATA_CONTROL_SPI_RESET_1); + if (ret) + return ret; + + ret =3D regmap_write(st->regmap, AD7768_REG_DATA_CONTROL, + AD7768_DATA_CONTROL_SPI_RESET_2); + if (ret) + return ret; + } + + /* ADC start-up time after reset: 1.66 ms max (datasheet Table 1) */ + fsleep(2000); + + return 0; +} + +static void ad7768_disable_clk(void *clk) +{ + clk_disable_unprepare(clk); +} + +static int ad7768_configure_xtal_clock(struct ad7768_state *st) +{ + int ret; + + ret =3D regmap_set_bits(st->regmap, AD7768_REG_GPIO_WRITE, BIT(4)); + if (ret) + return ret; + + return regmap_set_bits(st->regmap, AD7768_REG_GPIO_CONTROL, + AD7768_GPIO_UGPIO_ENABLE | + AD7768_GPIO4_OUTPUT_ENABLE); +} + +static int ad7768_enable_lvds_clock(struct ad7768_state *st) +{ + struct device *dev =3D regmap_get_device(st->regmap); + int ret; + + ret =3D regmap_clear_bits(st->regmap, AD7768_REG_GPIO_WRITE, BIT(4)); + if (ret) + return ret; + + ret =3D regmap_set_bits(st->regmap, AD7768_REG_GPIO_CONTROL, + AD7768_GPIO_UGPIO_ENABLE | + AD7768_GPIO4_OUTPUT_ENABLE); + if (ret) + return ret; + + ret =3D regmap_set_bits(st->regmap, AD7768_REG_POWER_MODE, + AD7768_POWER_MODE_LVDS_ENABLE); + if (ret) + return ret; + + ret =3D clk_prepare_enable(st->mclk); + if (ret) + return ret; + + return devm_add_action_or_reset(dev, ad7768_disable_clk, st->mclk); +} + +static int ad7768_probe(struct spi_device *spi) +{ + unsigned int spi_readback, rev_id; + struct device *dev =3D &spi->dev; + struct iio_dev *indio_dev; + struct ad7768_state *st; + unsigned int num_clocks; + const char *clock_name; + int ret; + + indio_dev =3D devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st =3D iio_priv(indio_dev); + spi_set_drvdata(spi, st); + + ret =3D devm_mutex_init(dev, &st->lock); + if (ret) + return ret; + + st->chip_info =3D spi_get_device_match_data(spi); + if (!st->chip_info) + return dev_err_probe(dev, -ENODEV, + "Failed to get match data\n"); + + ret =3D devm_regulator_get_enable_optional(dev, "avss"); + if (ret < 0 && ret !=3D -ENODEV) + return dev_err_probe(dev, ret, + "Failed to enable AVSS supply\n"); + + ret =3D devm_regulator_get_enable(dev, "avdd1"); + if (ret) + return dev_err_probe(dev, ret, + "Failed to enable AVDD1 supply\n"); + + ret =3D devm_regulator_bulk_get_enable(dev, + ARRAY_SIZE(ad7768_supply_names), + ad7768_supply_names); + if (ret) + return ret; + + if (device_property_present(dev, "clock-names")) { + num_clocks =3D ARRAY_SIZE(ad7768_clock_names); + ret =3D device_property_match_property_string(dev, "clock-names", + ad7768_clock_names, + num_clocks); + if (ret < 0) + return dev_err_probe(dev, ret, + "Invalid clock source\n"); + + st->clock_source =3D ret; + } + + clock_name =3D ad7768_clock_names[st->clock_source]; + if (st->clock_source =3D=3D AD7768_CLOCK_SOURCE_LVDS) + st->mclk =3D devm_clk_get(dev, clock_name); + else if (device_property_present(dev, "clock-names")) + st->mclk =3D devm_clk_get_enabled(dev, clock_name); + else + st->mclk =3D devm_clk_get_enabled(dev, NULL); + if (IS_ERR(st->mclk)) + return dev_err_probe(dev, PTR_ERR(st->mclk), + "Failed to get master clock\n"); + + st->regmap =3D devm_regmap_init(dev, &ad7768_regmap_bus, spi, + st->chip_info->regmap_config); + if (IS_ERR(st->regmap)) + return PTR_ERR(st->regmap); + + ret =3D ad7768_reset(st); + if (ret) + return ret; + + /* Discard the reset response with a dummy SPI register read. */ + ret =3D regmap_read(st->regmap, AD7768_REG_REV_ID, &spi_readback); + if (ret) + return ret; + + ret =3D regmap_read(st->regmap, AD7768_REG_REV_ID, &rev_id); + if (ret) + return ret; + + if (rev_id !=3D AD7768_REV_ID_VAL) + dev_info(dev, "Unexpected revision ID 0x%02x\n", rev_id); + + if (st->clock_source =3D=3D AD7768_CLOCK_SOURCE_XTAL) { + ret =3D ad7768_configure_xtal_clock(st); + if (ret) + return dev_err_probe(dev, ret, + "Failed to configure crystal clock\n"); + } else if (st->clock_source =3D=3D AD7768_CLOCK_SOURCE_LVDS) { + ret =3D ad7768_enable_lvds_clock(st); + if (ret) + return dev_err_probe(dev, ret, + "Failed to enable LVDS clock\n"); + } + + ret =3D ad7768_parse_config(indio_dev, dev); + if (ret) + return ret; + + ret =3D regmap_update_bits(st->regmap, AD7768_REG_INTERFACE_CFG, + AD7768_INTERFACE_CFG_CRC_SELECT_MSK, + FIELD_PREP(AD7768_INTERFACE_CFG_CRC_SELECT_MSK, + AD7768_INTERFACE_CFG_CRC_SELECT_4)); + if (ret) + return ret; + + indio_dev->name =3D st->chip_info->name; + indio_dev->info =3D &ad7768_info; + + st->back =3D devm_iio_backend_get(dev, NULL); + if (IS_ERR(st->back)) + return PTR_ERR(st->back); + + ret =3D devm_iio_backend_request_buffer(dev, st->back, indio_dev); + if (ret) + return ret; + + ret =3D iio_backend_num_lanes_set(st->back, st->datalines); + if (ret) + return ret; + + ret =3D iio_backend_crc_enable(st->back); + if (ret) + return ret; + + ret =3D devm_iio_backend_enable(dev, st->back); + if (ret) + return ret; + + pm_runtime_set_autosuspend_delay(dev, 2000); + pm_runtime_use_autosuspend(dev); + ret =3D devm_pm_runtime_set_active_enabled(dev); + if (ret) + return ret; + + indio_dev->setup_ops =3D &ad7768_buffer_ops; + + ret =3D devm_iio_device_register(dev, indio_dev); + if (ret) + return ret; + + return 0; +} + +static int ad7768_runtime_suspend(struct device *dev) +{ + struct ad7768_state *st =3D dev_get_drvdata(dev); + + return regmap_set_bits(st->regmap, AD7768_REG_POWER_MODE, + AD7768_SLEEP_MODE_MSK); +} + +static int ad7768_runtime_resume(struct device *dev) +{ + struct ad7768_state *st =3D dev_get_drvdata(dev); + int ret; + + ret =3D regmap_clear_bits(st->regmap, AD7768_REG_POWER_MODE, + AD7768_SLEEP_MODE_MSK); + if (ret) + return ret; + + /* + * The datasheet does not specify a wake-up time. Allow 20 ms for the + * ADC and digital clocks to restart. + */ + fsleep(20000); + + return 0; +} + +static DEFINE_RUNTIME_DEV_PM_OPS(ad7768_pm_ops, ad7768_runtime_suspend, + ad7768_runtime_resume, NULL); + +static const struct of_device_id ad7768_of_match[] =3D { + { .compatible =3D "adi,ad7768", .data =3D &ad7768_chip_info }, + { .compatible =3D "adi,ad7768-4", .data =3D &ad7768_4_chip_info }, + { } +}; +MODULE_DEVICE_TABLE(of, ad7768_of_match); + +static const struct spi_device_id ad7768_spi_id[] =3D { + { "ad7768", (kernel_ulong_t)&ad7768_chip_info }, + { "ad7768-4", (kernel_ulong_t)&ad7768_4_chip_info }, + { } +}; +MODULE_DEVICE_TABLE(spi, ad7768_spi_id); + +static struct spi_driver ad7768_driver =3D { + .probe =3D ad7768_probe, + .driver =3D { + .name =3D "ad7768", + .of_match_table =3D ad7768_of_match, + .pm =3D pm_ptr(&ad7768_pm_ops), + }, + .id_table =3D ad7768_spi_id, +}; +module_spi_driver(ad7768_driver); + +MODULE_AUTHOR("Stefan Popa "); +MODULE_AUTHOR("Janani Sunil "); +MODULE_DESCRIPTION("Analog Devices AD7768 ADC driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_BACKEND"); --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 18A1E4CA261; Fri, 21 Aug 2026 14:08:27 +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=1787321310; cv=none; b=ucjDO8w4Okk5odvprJU5Xen8xxM/QwwhwSJeBlcdhRbLc7nZYqhff5v8kb1G8Tm3FxJ4KDRjJv9TSZlImfaMoOrlGMviZbI6DO7SHuMSWTa/N8uXUwnJpZSvpU+hfbzepQvv9aYuCOK3uxuvwy8PnCEwhKO9d/0LbNEADNzRjpA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321310; c=relaxed/simple; bh=/XRRCGpT9KMiA8oa1wpQhEpWRlHiEYU6iGJKhvbqo0g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=tQzLvP8AQuyvhG+XLW6gPo5uGkKcnpZCImbCU6v7tYxPSwA3y/F323XTV9ZVEAHP195MI7jV5a8erl4cO1e9taz1OwM/PFnuS1BD0C9pqqfHduufKIiTwHIvLVrl+Oo4f4+wVEUyEKuAm+kRFinz825FPQ6Au9Yy9GEPS17VsMI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=BIOHi9JH; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="BIOHi9JH" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpPbJ3076179; Fri, 21 Aug 2026 10:08:18 -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=7EDhd wQMMa34JHtRTEYKeBjBpOdBMsfw5qNSJJbiw2s=; b=BIOHi9JHlbKCC45mDNQRL f6rrJLpT+4P3cirQmqU7e8hVLU2lK6tr9mh3ihYwNKDD2avyTcT8EVEv02jLRVTA GxrfNQO1jNhKLT4lbnqa+7mOhjAEi2XBkQuTEG3oN8bgLDIgrnqpNzKFHQHZi22X vCdx8iYUGyAiMkgGEeLIk3l+CqcCNVZPBcKP7i3WDFNw54mo32lSE1VmQhL5NEcx 0bT+y0gPHfl1d4Gf0v6MtQqYRbLdvpt7J+l6BNB7LJdgWHmO6HsRCRpKKp+oPpGD datn6s00ZoO7F7D13RrKMolEslzrFMmLEX5jd2v52MQecWfWs6LQBOBN/4yjYBjK Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g5rk8ykbv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:08:17 -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 67LE8GPm032987 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:08:16 -0400 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:16 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:16 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:08:16 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkp024319; Fri, 21 Aug 2026 10:08:06 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:06:59 +0200 Subject: [PATCH v4 06/14] iio: adc: ad7768: Add configurable sampling modes 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: <20260821-ad7768-driver-v4-6-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , "David Lechner" , Andy Shevchenko , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=22763; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=/XRRCGpT9KMiA8oa1wpQhEpWRlHiEYU6iGJKhvbqo0g=; b=D4sNnZS0kCOIuPVeM4E6dyixtcf07PFU5foIrgIljQQY7drtMQ0icLY23l3Me4h3jJHZs6dYk C1O2tZofS6XAaFuZ55z+kKVXlflVLQYqc4RPUe3avw00htiEhZbuAdp X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfXzv+WljkjHmqV zIIHWErCBHIL3QDDplgTGi1fuDGatqFokH5UUE1Gh7JMCwZFgwd9UIByWPO7HH/qf+4uGbFP5ho lsDPetIOwaQoyOVz0ILWbmFTJVejgU5xrGb8VyCh/oOrnUvHhOTC X-Proofpoint-GUID: 8MK-KzSTGuCzN1oW4MItgOlb-gqHZIz8 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX7FGa/gJPWbYB o3KcsAoLylREm876oIhaYMOtNTynKzgvDGLRZ8pnZuYLB+oQ6Ds0KoeRwoFD1+2WPpWYlwuuVZ8 fNdsmxWkGJUgdIcQ1J9x2/7emGbh/37N1iOI8jgGN1md8cOc1mfg6swycivgaw5uXCNkov3te2v 8cDiKg9WqJkNcRUu0FrntbE0bg7YovOFg+23dJHJ81gXnUbPTvb0x1/BVNqcXJt6wjJtYV8Tpaw 9KzqKdw9tS2o+QAdXQ+GPc6D6sa4qwZkfEfjXOj0HqMOmxCUt3nU2pAsYzM/oE1pNH27gj//23X 6Q9EA28B9BJA8Ln0JpCGM4b0YIsSA7VhCVstU+95NtWv4ofbN/mYMFT1ft0c89SWdeN7dZ/mi1k Gxcjj3RNCc5WT5NybLB/5IUWGyxfInyz7JmaTKhlUUwvKTsbI4TdtwIZuwJebhiaH8/sEOZvaEO D5nbQ8HgGUsO/DNtOAQ== X-Proofpoint-ORIG-GUID: 8MK-KzSTGuCzN1oW4MItgOlb-gqHZIz8 X-Authority-Analysis: v=2.4 cv=P+YKQCAu c=1 sm=1 tr=0 ts=6a885bd1 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=Z0pTeXoby7EwIRygza74:22 a=gAnH3GRIAAAA:8 a=DHFYRi2-UijItfTWdScA:9 a=QEXdDO2ut3YA:10 a=br55WurUj89AL1qEz8Q6:22 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 lowpriorityscore=0 phishscore=0 malwarescore=0 priorityscore=1501 adultscore=0 suspectscore=0 clxscore=1015 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Derive the available output data rates from MCLK and expose per-channel sampling frequency and filter controls. Select the fastest compatible power mode for the enabled channels and map matching sampling frequency and filter combinations onto the two hardware channel profiles. Configure the data clock divider and wait for the selected filters to settle before capture. Signed-off-by: Janani Sunil --- drivers/iio/adc/ad7768.c | 580 +++++++++++++++++++++++++++++++++++++++++++= +--- 1 file changed, 543 insertions(+), 37 deletions(-) diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c index 34233ad6cfca..08d8e97d58fc 100644 --- a/drivers/iio/adc/ad7768.c +++ b/drivers/iio/adc/ad7768.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include =20 #include #include @@ -108,7 +110,19 @@ =20 #define AD7768_SAMPLE_SIZE 32 #define AD7768_MAX_DCLK_DIV 8 +#define AD7768_MIN_MCLK_FREQ_HZ (1150 * HZ_PER_KHZ) +#define AD7768_MIN_XTAL_FREQ_HZ (8 * HZ_PER_MHZ) +#define AD7768_MAX_MCLK_FREQ_HZ (34 * HZ_PER_MHZ) +#define MAX_FREQ_PER_MODE 6 #define AD7768_MAX_CHANNEL 8 +#define AD7768_NUM_CHANNEL_MODES 2 +#define AD7768_WIDEBAND_SETTLING_SAMPLES 68 +#define AD7768_SINC5_SETTLING_SAMPLES 7 + +enum ad7768_filter_type { + AD7768_FILTER_TYPE_WIDEBAND, + AD7768_FILTER_TYPE_SINC5, +}; =20 enum ad7768_clock_source { AD7768_CLOCK_SOURCE_MCLK, @@ -116,6 +130,20 @@ enum ad7768_clock_source { AD7768_CLOCK_SOURCE_LVDS, }; =20 +struct ad7768_power_mode_info { + unsigned int mode; + unsigned int mclk_div; +}; + +static const struct ad7768_power_mode_info ad7768_power_modes[] =3D { + { .mode =3D AD7768_POWER_MODE_POWER_MODE_LOW, .mclk_div =3D 32 }, + { .mode =3D AD7768_POWER_MODE_POWER_MODE_MEDIAN, .mclk_div =3D 8 }, + { .mode =3D AD7768_POWER_MODE_POWER_MODE_FAST, .mclk_div =3D 4 }, +}; + +#define AD7768_MAX_FREQS \ + (MAX_FREQ_PER_MODE + ARRAY_SIZE(ad7768_power_modes)) + struct ad7768_precharge_config { bool prebufp_en; bool prebufn_en; @@ -123,6 +151,17 @@ struct ad7768_precharge_config { bool refbufn; }; =20 +struct ad7768_freq_config { + unsigned int freq_hz; + unsigned int dec_rate; +}; + +struct ad7768_avail_freq { + unsigned int n_freqs; + unsigned int freqs[MAX_FREQ_PER_MODE]; + struct ad7768_freq_config freq_cfg[MAX_FREQ_PER_MODE]; +}; + struct ad7768_chip_info { const char *name; unsigned int num_channels; @@ -140,12 +179,22 @@ struct ad7768_state { struct clk *mclk; unsigned int datalines; enum ad7768_clock_source clock_source; + unsigned int power_mode_idx; const struct ad7768_chip_info *chip_info; + struct ad7768_avail_freq avail_freq[ARRAY_SIZE(ad7768_power_modes)]; + unsigned int n_freqs; + int freqs[AD7768_MAX_FREQS]; + unsigned int ch_freq[AD7768_MAX_CHANNEL]; + enum ad7768_filter_type ch_filter[AD7768_MAX_CHANNEL]; struct iio_backend *back; =20 __be16 d16 __aligned(IIO_DMA_MINALIGN); }; =20 +static const int ad7768_dec_rate[MAX_FREQ_PER_MODE] =3D { + 32, 64, 128, 256, 512, 1024, +}; + static const unsigned int ad7768_available_datalines[] =3D { 1, 2, 8, }; @@ -177,6 +226,11 @@ static u8 ad7768_channel_mask(const struct ad7768_stat= e *st, u8 ch) return BIT(st->chip_info->chan_map[ch]); } =20 +static u8 ad7768_channel_mode_mask(const struct ad7768_state *st, u8 ch) +{ + return BIT(ch) | ad7768_channel_mask(st, ch); +} + static u8 ad7768_all_standby_mask(const struct ad7768_state *st) { return GENMASK(st->chip_info->num_channels - 1, 0); @@ -333,70 +387,272 @@ static int ad7768_sync(struct ad7768_state *st) AD7768_DATA_CONTROL_SPI_SYNC); } =20 -static int ad7768_configure_capture(struct ad7768_state *st) +static int ad7768_set_power_mode(struct ad7768_state *st, unsigned int mod= e) { - unsigned int dclk_div_reg; - unsigned int mode_config; - unsigned int dclk_div; + unsigned int mode_idx; int ret; =20 + for (mode_idx =3D 0; mode_idx < ARRAY_SIZE(ad7768_power_modes); + mode_idx++) { + if (ad7768_power_modes[mode_idx].mode =3D=3D mode) + break; + } + + if (mode_idx =3D=3D ARRAY_SIZE(ad7768_power_modes)) + return -EINVAL; + ret =3D regmap_update_bits(st->regmap, AD7768_REG_POWER_MODE, - AD7768_POWER_MODE_POWER_MODE_MSK | - AD7768_POWER_MODE_MCLK_DIV_MSK, + AD7768_POWER_MODE_POWER_MODE_MSK, FIELD_PREP(AD7768_POWER_MODE_POWER_MODE_MSK, - AD7768_POWER_MODE_POWER_MODE_FAST) | - FIELD_PREP(AD7768_POWER_MODE_MCLK_DIV_MSK, - AD7768_POWER_MODE_POWER_MODE_FAST)); + mode)); if (ret) return ret; =20 - /* - * Start with the wideband filter and a decimation rate of 64. This - * supports every valid data-line configuration at the maximum MCLK. - */ - mode_config =3D FIELD_PREP(AD7768_CH_MODE_FILTER_TYPE_MSK, - AD7768_CH_MODE_FILTER_TYPE_WIDEBAND); - mode_config |=3D FIELD_PREP(AD7768_CH_MODE_DEC_RATE_MSK, - AD7768_CH_MODE_DEC_RATE_64); - ret =3D regmap_update_bits(st->regmap, AD7768_REG_CH_MODE(0), - AD7768_CH_MODE_FILTER_TYPE_MSK | - AD7768_CH_MODE_DEC_RATE_MSK, - mode_config); + ret =3D regmap_update_bits(st->regmap, AD7768_REG_POWER_MODE, + AD7768_POWER_MODE_MCLK_DIV_MSK, + FIELD_PREP(AD7768_POWER_MODE_MCLK_DIV_MSK, + mode)); if (ret) return ret; - - ret =3D regmap_write(st->regmap, AD7768_REG_CH_MODE_SEL, 0); + ret =3D ad7768_sync(st); if (ret) return ret; =20 - dclk_div =3D 8 * st->datalines / st->chip_info->num_channels; + st->power_mode_idx =3D mode_idx; + + return 0; +} + +static int ad7768_set_clk_divs(struct ad7768_state *st, + unsigned int freq) +{ + struct ad7768_freq_config f_cfg =3D { }; + unsigned int mclk, dclk, dclk_div, i; + unsigned int chan_per_doutx; + unsigned int dclk_div_reg; + + mclk =3D clk_get_rate(st->mclk); + + chan_per_doutx =3D st->chip_info->num_channels / st->datalines; + if (!chan_per_doutx) + return -EINVAL; + + for (i =3D 0; i < st->avail_freq[st->power_mode_idx].n_freqs; i++) { + f_cfg =3D st->avail_freq[st->power_mode_idx].freq_cfg[i]; + if (freq =3D=3D f_cfg.freq_hz) + break; + } + + if (i =3D=3D st->avail_freq[st->power_mode_idx].n_freqs) + return -EINVAL; + + dclk =3D f_cfg.freq_hz * AD7768_SAMPLE_SIZE * chan_per_doutx; + if (!dclk || dclk > mclk) + return -EINVAL; + + /* + * Set dclk_div to the nearest power of 2 less than the + * original value. + */ + dclk_div =3D DIV_ROUND_CLOSEST(mclk, dclk); + if (dclk_div > AD7768_MAX_DCLK_DIV) + dclk_div =3D AD7768_MAX_DCLK_DIV; + else + dclk_div =3D rounddown_pow_of_two(dclk_div); + dclk_div_reg =3D AD7768_INTERFACE_CFG_DCLK_DIV(dclk_div); - ret =3D regmap_update_bits(st->regmap, AD7768_REG_INTERFACE_CFG, - AD7768_INTERFACE_CFG_DCLK_DIV_MSK, - FIELD_PREP(AD7768_INTERFACE_CFG_DCLK_DIV_MSK, - dclk_div_reg)); - if (ret) - return ret; =20 - return ad7768_sync(st); + return regmap_update_bits(st->regmap, AD7768_REG_INTERFACE_CFG, + AD7768_INTERFACE_CFG_DCLK_DIV_MSK, + FIELD_PREP(AD7768_INTERFACE_CFG_DCLK_DIV_MSK, + dclk_div_reg)); } =20 -static int ad7768_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *scan_mask) +static bool ad7768_freq_supported(const struct ad7768_state *st, + unsigned int mode_idx, unsigned int freq) +{ + for (unsigned int i =3D 0; + i < st->avail_freq[mode_idx].n_freqs; i++) { + if (freq =3D=3D st->avail_freq[mode_idx].freq_cfg[i].freq_hz) + return true; + } + + return false; +} + +static bool ad7768_freq_supported_in_any_mode(const struct ad7768_state *s= t, + unsigned int freq) +{ + for (unsigned int mode_idx =3D 0; + mode_idx < ARRAY_SIZE(ad7768_power_modes); mode_idx++) { + if (ad7768_freq_supported(st, mode_idx, freq)) + return true; + } + + return false; +} + +static int ad7768_set_lowest_noise_mode(struct ad7768_state *st, + const unsigned long *scan_mask) +{ + unsigned int mode_idx =3D ARRAY_SIZE(ad7768_power_modes); + unsigned int channel; + + /* + * The output data rate ranges overlap between the power modes. At a + * common ODR, the faster mode has lower noise, so prefer the fastest + * mode that supports every enabled channel. + */ + while (mode_idx--) { + for (channel =3D 0; + channel < st->chip_info->num_channels; channel++) { + if (test_bit(channel, scan_mask) && + !ad7768_freq_supported(st, mode_idx, + st->ch_freq[channel])) + break; + } + + if (channel =3D=3D st->chip_info->num_channels) + return ad7768_set_power_mode(st, + ad7768_power_modes[mode_idx].mode); + } + + return -EINVAL; +} + +static int ad7768_set_mode_decimation(struct ad7768_state *st, + unsigned int freq, unsigned int mode) +{ + struct ad7768_freq_config f_cfg =3D { }; + unsigned int i; + + for (i =3D 0; i < st->avail_freq[st->power_mode_idx].n_freqs; i++) { + f_cfg =3D st->avail_freq[st->power_mode_idx].freq_cfg[i]; + if (freq =3D=3D f_cfg.freq_hz) + break; + } + + if (i =3D=3D st->avail_freq[st->power_mode_idx].n_freqs) + return -EINVAL; + + return regmap_update_bits(st->regmap, AD7768_REG_CH_MODE(mode), + AD7768_CH_MODE_DEC_RATE_MSK, + FIELD_PREP(AD7768_CH_MODE_DEC_RATE_MSK, + f_cfg.dec_rate)); +} + +static int ad7768_set_sampling_freq(struct iio_dev *indio_dev, + unsigned int freq, unsigned int ch) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + + if (!freq) + return -EINVAL; + + if (!ad7768_freq_supported_in_any_mode(st, freq)) + return -EINVAL; + + guard(mutex)(&st->lock); + + st->ch_freq[ch] =3D freq; + + return 0; +} + +static void ad7768_filter_wait(const unsigned int *mode_freq, + const enum ad7768_filter_type *mode_filter, + const bool *mode_used) { + unsigned int t_settle_us =3D 0; + + for (unsigned int mode =3D 0; mode < AD7768_NUM_CHANNEL_MODES; mode++) { + unsigned int settling_samples; + unsigned int t_mode_us; + + if (!mode_used[mode] || !mode_freq[mode]) + continue; + + if (mode_filter[mode] =3D=3D AD7768_FILTER_TYPE_SINC5) + settling_samples =3D AD7768_SINC5_SETTLING_SAMPLES; + else + settling_samples =3D AD7768_WIDEBAND_SETTLING_SAMPLES; + + t_mode_us =3D DIV_ROUND_UP(settling_samples * USEC_PER_SEC, + mode_freq[mode]); + t_settle_us =3D max(t_settle_us, t_mode_us); + } + + if (t_settle_us) + fsleep(t_settle_us); +} + +static int ad7768_find_matching_mode(const bool *mode_used, + const unsigned int *mode_freq, + const enum ad7768_filter_type *mode_filter, + unsigned int freq, + enum ad7768_filter_type filter) +{ + for (unsigned int mode =3D 0; mode < AD7768_NUM_CHANNEL_MODES; mode++) { + if (!mode_used[mode] || + (mode_freq[mode] =3D=3D freq && mode_filter[mode] =3D=3D filter)) + return mode; + } + + return -EINVAL; +} + +static int ad7768_apply_channel_modes(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + enum ad7768_filter_type mode_filter[AD7768_NUM_CHANNEL_MODES]; + unsigned int mode_freq[AD7768_NUM_CHANNEL_MODES]; + bool mode_used[AD7768_NUM_CHANNEL_MODES] =3D { }; struct ad7768_state *st =3D iio_priv(indio_dev); unsigned int channel_mask; unsigned int standby_mask; + unsigned int max_freq =3D 0; + struct device *dev; + unsigned int c; int ret; =20 + guard(mutex)(&st->lock); + dev =3D regmap_get_device(st->regmap); + + ret =3D ad7768_set_lowest_noise_mode(st, scan_mask); + if (ret =3D=3D -EINVAL) + return dev_err_probe(dev, ret, + "No power mode supports all ODRs\n"); + if (ret) + return ret; + channel_mask =3D ad7768_all_standby_mask(st); standby_mask =3D channel_mask; if (st->clock_source =3D=3D AD7768_CLOCK_SOURCE_XTAL) standby_mask &=3D ~BIT(st->chip_info->num_channels / 2); =20 - for (unsigned int c =3D 0; c < st->chip_info->num_channels; c++) { - if (test_bit(c, scan_mask)) - standby_mask &=3D ~BIT(c); + for_each_set_bit(c, scan_mask, st->chip_info->num_channels) { + unsigned int mask; + int mode; + + standby_mask &=3D ~BIT(c); + + mode =3D ad7768_find_matching_mode(mode_used, mode_freq, + mode_filter, st->ch_freq[c], + st->ch_filter[c]); + if (mode < 0) + return dev_err_probe(dev, -EINVAL, + "Over %d channel modes required\n", + AD7768_NUM_CHANNEL_MODES); + + mode_freq[mode] =3D st->ch_freq[c]; + mode_filter[mode] =3D st->ch_filter[c]; + mode_used[mode] =3D true; + + mask =3D ad7768_channel_mode_mask(st, c); + ret =3D regmap_update_bits(st->regmap, AD7768_REG_CH_MODE_SEL, + mask, mode ? mask : 0); + if (ret) + return ret; } =20 ret =3D regmap_update_bits(st->regmap, AD7768_REG_CH_STANDBY, @@ -404,6 +660,121 @@ static int ad7768_update_scan_mode(struct iio_dev *in= dio_dev, if (ret) return ret; =20 + for (unsigned int mode =3D 0; mode < AD7768_NUM_CHANNEL_MODES; + mode++) { + unsigned int filter_config; + + if (!mode_used[mode]) + continue; + + ret =3D ad7768_set_mode_decimation(st, mode_freq[mode], mode); + if (ret) + return ret; + + filter_config =3D FIELD_PREP(AD7768_CH_MODE_FILTER_TYPE_MSK, + mode_filter[mode]); + ret =3D regmap_update_bits(st->regmap, AD7768_REG_CH_MODE(mode), + AD7768_CH_MODE_FILTER_TYPE_MSK, + filter_config); + if (ret) + return ret; + + max_freq =3D max(max_freq, mode_freq[mode]); + } + + ret =3D ad7768_set_clk_divs(st, max_freq); + if (ret) + return ret; + + ret =3D ad7768_sync(st); + if (ret) + return ret; + + /* Apply a filter settling time (datasheet Tables 28 and 29) */ + ad7768_filter_wait(mode_freq, mode_filter, mode_used); + + return 0; +} + +static int ad7768_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long info) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + int ret; + + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(regmap_get_device(st->regmap), pm); + ret =3D PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + if (info !=3D IIO_CHAN_INFO_SAMP_FREQ) + return -EINVAL; + + guard(mutex)(&st->lock); + *val =3D st->ch_freq[chan->channel]; + + return IIO_VAL_INT; +} + +static int ad7768_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, long info) +{ + if (info =3D=3D IIO_CHAN_INFO_SAMP_FREQ) + return IIO_VAL_INT; + + return -EINVAL; +} + +static int ad7768_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long info) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + int ret; + + IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); + if (IIO_DEV_ACQUIRE_FAILED(claim)) + return -EBUSY; + + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(regmap_get_device(st->regmap), pm); + ret =3D PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + if (info =3D=3D IIO_CHAN_INFO_SAMP_FREQ) + return ad7768_set_sampling_freq(indio_dev, val, chan->channel); + + return -EINVAL; +} + +static int ad7768_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long info) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + + if (info !=3D IIO_CHAN_INFO_SAMP_FREQ) + return -EINVAL; + + *vals =3D st->freqs; + *type =3D IIO_VAL_INT; + *length =3D st->n_freqs; + + return IIO_AVAIL_LIST; +} + +static int ad7768_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + int ret; + + ret =3D ad7768_apply_channel_modes(indio_dev, scan_mask); + if (ret) + return ret; + for (unsigned int c =3D 0; c < st->chip_info->num_channels; c++) { if (test_bit(c, scan_mask)) ret =3D iio_backend_chan_enable(st->back, c); @@ -458,9 +829,76 @@ static const struct iio_buffer_setup_ops ad7768_buffer= _ops =3D { =20 static const struct iio_info ad7768_info =3D { .debugfs_reg_access =3D ad7768_reg_access, + .read_raw =3D ad7768_read_raw, + .write_raw_get_fmt =3D ad7768_write_raw_get_fmt, + .write_raw =3D ad7768_write_raw, + .read_avail =3D ad7768_read_avail, .update_scan_mode =3D ad7768_update_scan_mode, }; =20 +static void ad7768_set_available_sampl_freq(struct ad7768_state *st) +{ + unsigned int mclk =3D clk_get_rate(st->mclk); + struct ad7768_avail_freq *avail_freq; + + for (unsigned int mode_idx =3D 0; + mode_idx < ARRAY_SIZE(ad7768_power_modes); mode_idx++) { + avail_freq =3D &st->avail_freq[mode_idx]; + for (unsigned int dec =3D ARRAY_SIZE(ad7768_dec_rate); + dec > 0; dec--) { + struct ad7768_freq_config freq_cfg; + + freq_cfg.dec_rate =3D dec - 1; + freq_cfg.freq_hz =3D mclk / (ad7768_dec_rate[dec - 1] * + ad7768_power_modes[mode_idx].mclk_div); + avail_freq->freqs[avail_freq->n_freqs] =3D + freq_cfg.freq_hz; + avail_freq->freq_cfg[avail_freq->n_freqs++] =3D freq_cfg; + } + } + + if (st->datalines =3D=3D 1 && + st->chip_info->num_channels =3D=3D AD7768_MAX_CHANNEL) + st->avail_freq[ARRAY_SIZE(ad7768_power_modes) - 1].n_freqs--; + + for (unsigned int mode_idx =3D 0; + mode_idx < ARRAY_SIZE(ad7768_power_modes); mode_idx++) { + avail_freq =3D &st->avail_freq[mode_idx]; + for (unsigned int i =3D 0; i < avail_freq->n_freqs; i++) { + unsigned int freq =3D avail_freq->freqs[i]; + + if (st->n_freqs && st->freqs[st->n_freqs - 1] >=3D freq) + continue; + + st->freqs[st->n_freqs++] =3D freq; + } + } +} + +static int ad7768_set_filter_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int mode) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + + IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); + if (IIO_DEV_ACQUIRE_FAILED(claim)) + return -EBUSY; + + guard(mutex)(&st->lock); + st->ch_filter[chan->channel] =3D mode; + return 0; +} + +static int ad7768_get_filter_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ad7768_state *st =3D iio_priv(indio_dev); + + guard(mutex)(&st->lock); + return st->ch_filter[chan->channel]; +} + static int ad7768_configure_precharge_buffers(struct iio_dev *indio_dev, struct ad7768_precharge_config *precharge_cfg) { @@ -505,14 +943,36 @@ static int ad7768_configure_precharge_buffers(struct = iio_dev *indio_dev, return regmap_write(st->regmap, AD7768_REG_REFN_BUF, refbufn_val); } =20 +static const char *const ad7768_filter_types[] =3D { + [AD7768_FILTER_TYPE_WIDEBAND] =3D "wideband", + [AD7768_FILTER_TYPE_SINC5] =3D "sinc5", +}; + +static const struct iio_enum ad7768_filter_types_enum =3D { + .items =3D ad7768_filter_types, + .num_items =3D ARRAY_SIZE(ad7768_filter_types), + .set =3D ad7768_set_filter_mode, + .get =3D ad7768_get_filter_mode, +}; + +static struct iio_chan_spec_ext_info ad7768_ext_info[] =3D { + IIO_ENUM("filter_type", IIO_SEPARATE, + &ad7768_filter_types_enum), + IIO_ENUM_AVAILABLE("filter_type", IIO_SEPARATE, + &ad7768_filter_types_enum), + { } +}; + static int ad7768_parse_config(struct iio_dev *indio_dev, struct device *dev) { struct ad7768_precharge_config precharge_cfg[AD7768_MAX_CHANNEL] =3D { }; struct ad7768_state *st =3D iio_priv(indio_dev); + const struct ad7768_avail_freq *avail_freq; const unsigned int *available_datalines; struct iio_chan_spec *chan; unsigned int num_channels; + unsigned int default_freq; unsigned int standby_mask; unsigned int i, len; int chan_idx =3D 0; @@ -576,6 +1036,9 @@ static int ad7768_parse_config(struct iio_dev *indio_d= ev, =20 chan[chan_idx] =3D (struct iio_chan_spec) { .type =3D IIO_VOLTAGE, + .info_mask_separate =3D BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_separate_available =3D + BIT(IIO_CHAN_INFO_SAMP_FREQ), .indexed =3D 1, .address =3D channel, .channel =3D channel, @@ -585,6 +1048,7 @@ static int ad7768_parse_config(struct iio_dev *indio_d= ev, .realbits =3D 24, .storagebits =3D 32, }, + .ext_info =3D ad7768_ext_info, }; chan_idx++; } @@ -603,6 +1067,27 @@ static int ad7768_parse_config(struct iio_dev *indio_= dev, "Invalid %s property\n", "adi,data-lines-number"); =20 + ad7768_set_available_sampl_freq(st); + + /* + * Start in fast mode; capture setup may select another + * compatible mode. + */ + scoped_guard(mutex, &st->lock) { + ret =3D ad7768_set_power_mode(st, + AD7768_POWER_MODE_POWER_MODE_FAST); + } + if (ret) + return dev_err_probe(dev, ret, "Failed to set power mode\n"); + + avail_freq =3D &st->avail_freq[st->power_mode_idx]; + default_freq =3D avail_freq->freq_cfg[avail_freq->n_freqs - 1].freq_hz; + for (unsigned int channel =3D 0; + channel < st->chip_info->num_channels; channel++) { + st->ch_freq[channel] =3D default_freq; + st->ch_filter[channel] =3D AD7768_FILTER_TYPE_WIDEBAND; + } + for (i =3D 0; i < len; i++) { if (available_datalines[i] =3D=3D st->datalines) break; @@ -613,7 +1098,7 @@ static int ad7768_parse_config(struct iio_dev *indio_d= ev, "Invalid data-lines-number %d for %s\n", st->datalines, st->chip_info->name); =20 - return ad7768_configure_capture(st); + return 0; } =20 static int ad7768_reset(struct ad7768_state *st) @@ -711,6 +1196,23 @@ static int ad7768_enable_lvds_clock(struct ad7768_sta= te *st) return devm_add_action_or_reset(dev, ad7768_disable_clk, st->mclk); } =20 +static int ad7768_validate_mclk_rate(struct device *dev, + const struct ad7768_state *st) +{ + unsigned long min_rate =3D AD7768_MIN_MCLK_FREQ_HZ; + unsigned long rate =3D clk_get_rate(st->mclk); + + if (st->clock_source =3D=3D AD7768_CLOCK_SOURCE_XTAL) + min_rate =3D AD7768_MIN_XTAL_FREQ_HZ; + + if (rate < min_rate || rate > AD7768_MAX_MCLK_FREQ_HZ) + return dev_err_probe(dev, -EINVAL, + "MCLK rate %lu Hz outside %lu-%lu Hz\n", + rate, min_rate, AD7768_MAX_MCLK_FREQ_HZ); + + return 0; +} + static int ad7768_probe(struct spi_device *spi) { unsigned int spi_readback, rev_id; @@ -776,6 +1278,10 @@ static int ad7768_probe(struct spi_device *spi) return dev_err_probe(dev, PTR_ERR(st->mclk), "Failed to get master clock\n"); =20 + ret =3D ad7768_validate_mclk_rate(dev, st); + if (ret) + return ret; + st->regmap =3D devm_regmap_init(dev, &ad7768_regmap_bus, spi, st->chip_info->regmap_config); if (IS_ERR(st->regmap)) --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 9FD934C6EFF; Fri, 21 Aug 2026 14:08: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=1787321314; cv=none; b=ghLmlWyIc6uY/5oa+wwJntdewo7gzP3JmHrxlHPJNi9rFrhpb3n9/MCzpjM0O3KSA/vrX/hkkUxYhhqAl0dTdx92eFGOuPmABVYiC6TphkAbkrSg70FNJ2PT0u6F14IG/N3VMGEhgy61HSJQWkVZpxDSwCzrLCfwADG4ApOgH30= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321314; c=relaxed/simple; bh=sJaBzRymvE52VIqthqRK7e91z/tu/Vm0dy5m6HwqVOg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=eApaqF/3JCFnObWNGF/gO7rNFSpTjRXmRFw8qmKSqUwKblsmI8LnmqjaBaXzl891DtUcOG7FXx5ZEN+st9OUvAhFGNIW/W2VVDvY1KKePTBGduAntlzrJ5N7b3G+70q4Y37vfFv0vCZJvlCmPWOkhLDZsuZ0iQyLQndyoNdkITs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=z/z7a1rY; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="z/z7a1rY" Received: from pps.filterd (m0516787.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpcLu3388116; Fri, 21 Aug 2026 10:08:23 -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=o84ae LP8Ti4e004fMuS5tSXCV08GQ06uX1A5bVW/iAk=; b=z/z7a1rYQ8dSOdvWAxbae RciBJ+8FXcXoWSeTeBhQic8Xa+pmkTxK+jPF+WKq7sAmXpV+ihWeVh9PbPsN/9to cg0OUyFRl4J9fN8Zf/Vlp5mCZUt4k+0PDMAQgCl2pcJk4XsUK1yUiwkOoy4yjGvs FODfuzXuFvS1Z+mowJtXEwHVVxa5PYxEq/YsFbyPH0cZMr38YNi7omg7lbGEbnnD OBw4pfb76DTa2QSjXMGgCjOJXA7LFhWXzL1tEWU64yTL+C/ZHG538XC5pRL+nKyT oodPuHPOoAVqg+srx41hT6WdRtwCLddjGmtylC3Q+VydWf30QFU+unvCatseVYTb A== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g66m6m0gm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:08:23 -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 67LE8M1F033005 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:08:22 -0400 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:21 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:21 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:08:21 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkq024319; Fri, 21 Aug 2026 10:08:12 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:07:00 +0200 Subject: [PATCH v4 07/14] iio: adc: ad7768: Add calibration controls 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: <20260821-ad7768-driver-v4-7-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , "David Lechner" , Andy Shevchenko , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=5966; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=sJaBzRymvE52VIqthqRK7e91z/tu/Vm0dy5m6HwqVOg=; b=uP220UAQE8HJYv1kf5GraNvNbzxgzJ+G5BJU2urXWRt9MjXCtcgMnKPxwohNgRXm7P2r8Z7dJ 8tb+LfxslbDBwVUCwU0u4fKj3+yFsqlnJ8pwo6KZ2mnGeXgNLAA1Ro/ X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX6DVHj6iC0G0j SH90ANiD2WPXUjmLQTu3ai8tpbM+npWJfTZ7QWBgjIFF1ugJDcHbO5wsAO5JkxnPzq/02NygakX 5p+LCoue/AWPekeB1QFuG0BdSQusTaKzOp5WYZdEHYItlbsJBknb X-Proofpoint-ORIG-GUID: RXcABJ2oOyMEvONhKqZ7fyv2x5KE2-Mv X-Proofpoint-GUID: RXcABJ2oOyMEvONhKqZ7fyv2x5KE2-Mv X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfXzi+hn2eORPyI rZUrORnCnLHfJ9FDnkqmOwbRIpuJIAjnnq1oZu0jX3i031ZC1epTp/SvVued4/1KsvWZIE6xkU2 qhZKrRe6+Pe8Ilvnx522Ky9VWUm9Pt0cTImUzlPLtxQHWyQ8GkavPceyctd2wCthoCbuFGhXWn7 Dxp+CKYM4mzGHmJW1HhUAR4nNnjpIGPptShJjsvhvq0ILHtZj1e8HZ7JTBe1kUsOJXVFMFQ5n6J buMDRYLvmBKufUieoAOwsvfoR/Bxa0do1QQJODNWbPnX/XjUyBTlEZJH1keOmBvDV4edk6A4c1B CCLwOK36BKyl9/0EHHmGAi80RcdVGVqUAejgClFRx+25ehBJC4fqdci7Fdy9GxGRJhr69V5tTzM 6OTPPXqzMAYT58o8BF+pEKBTqXL3sy+SwnOsFBcRpQoUxz/4MrjRwjhdYC0cKZrVJiwou7xBVaW 5GZbvjcNWI2CxyHaSjQ== X-Authority-Analysis: v=2.4 cv=baVbluPB c=1 sm=1 tr=0 ts=6a885bd7 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=OmVn7CZJonkx5R5zMQLL:22 a=gAnH3GRIAAAA:8 a=2R_6Ol2CWV77H6UbNhkA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 phishscore=0 spamscore=0 suspectscore=0 impostorscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Expose the per-channel offset and gain calibration registers through the IIO calibbias and calibscale attributes. Signed-off-by: Janani Sunil --- drivers/iio/adc/ad7768.c | 119 ++++++++++++++++++++++++++++++++++++++++++-= ---- 1 file changed, 108 insertions(+), 11 deletions(-) diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c index 08d8e97d58fc..289f3fa3142e 100644 --- a/drivers/iio/adc/ad7768.c +++ b/drivers/iio/adc/ad7768.c @@ -25,6 +25,7 @@ #include #include #include +#include #include =20 #include @@ -116,6 +117,7 @@ #define MAX_FREQ_PER_MODE 6 #define AD7768_MAX_CHANNEL 8 #define AD7768_NUM_CHANNEL_MODES 2 +#define AD7768_CALIB_REG_MSK GENMASK(23, 0) #define AD7768_WIDEBAND_SETTLING_SAMPLES 68 #define AD7768_SINC5_SETTLING_SAMPLES 7 =20 @@ -236,6 +238,18 @@ static u8 ad7768_all_standby_mask(const struct ad7768_= state *st) return GENMASK(st->chip_info->num_channels - 1, 0); } =20 +static unsigned int ad7768_offset_reg(const struct ad7768_state *st, + unsigned int ch) +{ + return AD7768_REG_OFFSET(st->chip_info->chan_map[ch]); +} + +static unsigned int ad7768_gain_reg(const struct ad7768_state *st, + unsigned int ch) +{ + return AD7768_REG_GAIN(st->chip_info->chan_map[ch]); +} + static u8 ad7768_precharge_buf1_mask(const struct ad7768_state *st, u16 va= l) { return val & GENMASK(st->chip_info->prebuf_split - 1, 0); @@ -355,6 +369,48 @@ static const struct regmap_config ad7768_4_regmap_conf= ig =3D { .readable_reg =3D ad7768_4_readable_reg, }; =20 +static unsigned int ad7768_get_calib_reg_base(struct ad7768_state *st, + const struct iio_chan_spec *chan, + bool is_gain) +{ + if (is_gain) + return ad7768_gain_reg(st, chan->address); + + return ad7768_offset_reg(st, chan->address); +} + +static int ad7768_read_calib_value(struct ad7768_state *st, + unsigned int base_reg, unsigned int *val) +{ + u8 data[3]; + int ret; + + guard(mutex)(&st->lock); + + ret =3D regmap_bulk_read(st->regmap, base_reg, data, ARRAY_SIZE(data)); + if (ret) + return ret; + + *val =3D get_unaligned_be24(data); + + return 0; +} + +static int ad7768_write_calib_value(struct ad7768_state *st, + unsigned int base_reg, unsigned int val) +{ + u8 data[3]; + + if (val > AD7768_CALIB_REG_MSK) + return -EINVAL; + + put_unaligned_be24(val, data); + + guard(mutex)(&st->lock); + + return regmap_bulk_write(st->regmap, base_reg, data, ARRAY_SIZE(data)); +} + static int ad7768_reg_access(struct iio_dev *indio_dev, unsigned int reg, unsigned int writeval, @@ -701,6 +757,8 @@ static int ad7768_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long info) { struct ad7768_state *st =3D iio_priv(indio_dev); + unsigned int base_reg; + unsigned int calib; int ret; =20 PM_RUNTIME_ACQUIRE_AUTOSUSPEND(regmap_get_device(st->regmap), pm); @@ -708,22 +766,44 @@ static int ad7768_read_raw(struct iio_dev *indio_dev, if (ret) return ret; =20 - if (info !=3D IIO_CHAN_INFO_SAMP_FREQ) - return -EINVAL; + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: { + guard(mutex)(&st->lock); + *val =3D st->ch_freq[chan->channel]; + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_CALIBBIAS: + base_reg =3D ad7768_get_calib_reg_base(st, chan, false); + ret =3D ad7768_read_calib_value(st, base_reg, &calib); + if (ret) + return ret; =20 - guard(mutex)(&st->lock); - *val =3D st->ch_freq[chan->channel]; + *val =3D calib; + return IIO_VAL_INT; + case IIO_CHAN_INFO_CALIBSCALE: + base_reg =3D ad7768_get_calib_reg_base(st, chan, true); + ret =3D ad7768_read_calib_value(st, base_reg, &calib); + if (ret) + return ret; =20 - return IIO_VAL_INT; + *val =3D calib; + return IIO_VAL_INT; + default: + return -EINVAL; + } } =20 static int ad7768_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, long info) { - if (info =3D=3D IIO_CHAN_INFO_SAMP_FREQ) + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + case IIO_CHAN_INFO_CALIBBIAS: + case IIO_CHAN_INFO_CALIBSCALE: return IIO_VAL_INT; - - return -EINVAL; + default: + return -EINVAL; + } } =20 static int ad7768_write_raw(struct iio_dev *indio_dev, @@ -731,6 +811,7 @@ static int ad7768_write_raw(struct iio_dev *indio_dev, int val, int val2, long info) { struct ad7768_state *st =3D iio_priv(indio_dev); + unsigned int base_reg; int ret; =20 IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); @@ -742,10 +823,24 @@ static int ad7768_write_raw(struct iio_dev *indio_dev, if (ret) return ret; =20 - if (info =3D=3D IIO_CHAN_INFO_SAMP_FREQ) + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: return ad7768_set_sampling_freq(indio_dev, val, chan->channel); + case IIO_CHAN_INFO_CALIBBIAS: + if (val < 0 || val > AD7768_CALIB_REG_MSK) + return -EINVAL; =20 - return -EINVAL; + base_reg =3D ad7768_get_calib_reg_base(st, chan, false); + return ad7768_write_calib_value(st, base_reg, val); + case IIO_CHAN_INFO_CALIBSCALE: + if (val < 0 || val > AD7768_CALIB_REG_MSK) + return -EINVAL; + + base_reg =3D ad7768_get_calib_reg_base(st, chan, true); + return ad7768_write_calib_value(st, base_reg, val); + default: + return -EINVAL; + } } =20 static int ad7768_read_avail(struct iio_dev *indio_dev, @@ -1036,7 +1131,9 @@ static int ad7768_parse_config(struct iio_dev *indio_= dev, =20 chan[chan_idx] =3D (struct iio_chan_spec) { .type =3D IIO_VOLTAGE, - .info_mask_separate =3D BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_separate =3D BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), .info_mask_separate_available =3D BIT(IIO_CHAN_INFO_SAMP_FREQ), .indexed =3D 1, --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 E1B8F4C77AA; Fri, 21 Aug 2026 14:08:40 +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=1787321322; cv=none; b=paPS9m3J4AOBdbpI4qsubylTbFHb++KWCDo3RhGlA+xMKu4pkd+pi5jWCRUfe5frvVe8yGxCEzz7nAx8lHuHz2kTk8+DT1et5SALlQDsBZGcN0dU7K7X2LyaEcS3BuR3KkEp3xKNeCbti0I2NW5TNZwPmcWyhK9RUFVYep3Cgsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321322; c=relaxed/simple; bh=CARzdsTcg5q47aobGrotmIqT738dJfNyAFz3iOVaszo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=V/40EZM75qwZIJjbOfFYxZ0nYfonW5V1JWZli7fi9+EbXhE9Dl2EbGoarUcs8b9xmMoaLoQA/x/1m2H+MxuXoTAGAMTQrc0MGt2GiZdp0VO5rfWgouzOXmeK5VQNXbWP4k25jBNUuhhO+Bgk2ybyGZLedbVbp357ylUV8bwgpY8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=naLKK23g; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="naLKK23g" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpb5C3677854; Fri, 21 Aug 2026 10:08:31 -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=ZDcBb qJFqYyAkk5t4m1+gc6kyIV4HFBDP5L9b5548WM=; b=naLKK23g6c596r6CvpD2a cRywhd5W2hyzcKYEgdzHaZ9qz5pCHbLfF30zj7lrZwrGBAKvNMFXEgJvavYnKlDk VywXi2O35Oabjg/NDrbrwxPQ3526I3y4dOgrol/m7ekEuji8mNvN92kJuKGn2YWA lkAPXMSYSNTwJIShiHJ8zt3SYY5sxaZ6bZViTtb9plVRliAqOkR0QeJz51OLI93t RN8C6N1MRgm6cYHFZln4uGbJjCfLe1dlMTnUy0ym3UQe5ueR1L5rLWSFfkWmHenc u9pgDtJsEIPRScQIEtfybuNUDHxPGTThifOonscLjutfUpjFa+zAHBuCulPsnjET w== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g6a27k401-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:08:31 -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 67LE8T8A033029 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:08:29 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:29 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:08:29 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkr024319; Fri, 21 Aug 2026 10:08:18 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:07:01 +0200 Subject: [PATCH v4 08/14] iio: adc: ad7768: Add per-channel conversion delay 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: <20260821-ad7768-driver-v4-8-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=6649; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=CARzdsTcg5q47aobGrotmIqT738dJfNyAFz3iOVaszo=; b=fe+XUTZv68UXI0cOiNVCVIgSgVl8SwmT5wl8M+7O9uY/GcfeNbaHn14uhVDOdODiXQdC+q0ZR //Oogj8fx7MAVYZ3hczxb0y0o10XKsBexkSNGgYRzYCqqLibdhyyloj X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: HYpPAXB9yM-6kXLt5RVit9Elg_-9nrtM X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX7q8ukF1lJVIA 50D4ba86ODhDUCJQNN+n3zGJGGA+vTHH/RSoYLyqFXpNd8M1ZeH8DIpj3Ps8wUT2ZLC+nfkwe2D xDW/fFceQFQ03h+E2PtcP8mweV0fUfV5ALsh+w9DUxLB+Q+xvmCX X-Authority-Analysis: v=2.4 cv=FeoHAp+6 c=1 sm=1 tr=0 ts=6a885bdf cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=uXIjobp8t2wMuQ0fPvqm:22 a=gAnH3GRIAAAA:8 a=QS77uNcazL5vWiXudcsA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: HYpPAXB9yM-6kXLt5RVit9Elg_-9nrtM X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX619twwc6PVLx xEm1UvtqmYowbLqDsHjohTFepzI0m6krzUEnqyDBCLB22jiJqqyQswgcZo3HYV8rA9MozIab+Bq tcWjO1MyB1+hOxb3YYG3U1FCsVCQm7jemVp8KUz59kwnr7UX0s+cpcKeCGcDTTndqQz9KFF9m4S VUWjPzXb6Sw2Eb1HUH3LqW8vSaJqs73Bcrh8hZ+URXO4U/ysZO3WG3vwfym5+enz8+WJcn+VSmA uBBsLi9j604qndLoZdwpaFnSBLkmOmXLVS/lv/F4MSVeUW1GWAzGKR2f/KKBXXOrk+W2jFp9uKW 3UYNVKU9kY6kOwCqktQ5rypgvA1jhmi6ifHvrjd1yXqRuSpqe6xPhFvyqZx9J0qR6sVoC/lpwvx VYscmJeG8IfwxdM27Lf63yr1tLqIRawo5dmKSBEkSZJtq4n6QSexXWyc4Lwj/9qSt4kYu8DuvTc EcT4XPbTPhvygMnEjiw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 malwarescore=0 adultscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 priorityscore=1501 bulkscore=0 phishscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Expose the per-channel synchronization phase offset through the IIO conversion-delay attribute. Derive the delay resolution from MCLK, power mode and decimation rate. Validate the requested delay and program the corresponding phase register when applying the active channel configuration. Signed-off-by: Janani Sunil --- drivers/iio/adc/ad7768.c | 143 +++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 143 insertions(+) diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c index 289f3fa3142e..12370139d03f 100644 --- a/drivers/iio/adc/ad7768.c +++ b/drivers/iio/adc/ad7768.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -158,6 +159,12 @@ struct ad7768_freq_config { unsigned int dec_rate; }; =20 +struct ad7768_convdelay_params { + unsigned int shift; + unsigned int max_raw; + u64 step_ps; +}; + struct ad7768_avail_freq { unsigned int n_freqs; unsigned int freqs[MAX_FREQ_PER_MODE]; @@ -187,6 +194,7 @@ struct ad7768_state { unsigned int n_freqs; int freqs[AD7768_MAX_FREQS]; unsigned int ch_freq[AD7768_MAX_CHANNEL]; + u64 ch_convdelay_ps[AD7768_MAX_CHANNEL]; enum ad7768_filter_type ch_filter[AD7768_MAX_CHANNEL]; struct iio_backend *back; =20 @@ -250,6 +258,12 @@ static unsigned int ad7768_gain_reg(const struct ad776= 8_state *st, return AD7768_REG_GAIN(st->chip_info->chan_map[ch]); } =20 +static unsigned int ad7768_phase_reg(const struct ad7768_state *st, + unsigned int ch) +{ + return AD7768_REG_PHASE(st->chip_info->chan_map[ch]); +} + static u8 ad7768_precharge_buf1_mask(const struct ad7768_state *st, u16 va= l) { return val & GENMASK(st->chip_info->prebuf_split - 1, 0); @@ -615,6 +629,105 @@ static int ad7768_set_sampling_freq(struct iio_dev *i= ndio_dev, return 0; } =20 +static int ad7768_get_freq_cfg(struct ad7768_state *st, unsigned int freq, + struct ad7768_freq_config *f_cfg) +{ + for (unsigned int i =3D 0; + i < st->avail_freq[st->power_mode_idx].n_freqs; i++) { + *f_cfg =3D st->avail_freq[st->power_mode_idx].freq_cfg[i]; + if (freq =3D=3D f_cfg->freq_hz) + return 0; + } + + return -EINVAL; +} + +static int ad7768_get_convdelay_params(struct ad7768_state *st, unsigned i= nt ch, + struct ad7768_convdelay_params *params) +{ + struct ad7768_freq_config f_cfg; + unsigned int dec_rate; + unsigned int mclk_div; + unsigned int mult; + u64 mclk; + int ret; + + ret =3D ad7768_get_freq_cfg(st, st->ch_freq[ch], &f_cfg); + if (ret) + return ret; + + dec_rate =3D ad7768_dec_rate[f_cfg.dec_rate]; + switch (dec_rate) { + case 32: + params->shift =3D 3; + params->max_raw =3D 31; + mult =3D 1; + break; + case 64: + params->shift =3D 2; + params->max_raw =3D 63; + mult =3D 1; + break; + case 128: + params->shift =3D 1; + params->max_raw =3D 127; + mult =3D 1; + break; + case 256: + params->shift =3D 0; + params->max_raw =3D 255; + mult =3D 1; + break; + case 512: + params->shift =3D 0; + params->max_raw =3D 255; + mult =3D 2; + break; + case 1024: + params->shift =3D 0; + params->max_raw =3D 255; + mult =3D 4; + break; + default: + return -EINVAL; + } + + mclk =3D clk_get_rate(st->mclk); + if (!mclk) + return -EINVAL; + + mclk_div =3D ad7768_power_modes[st->power_mode_idx].mclk_div; + params->step_ps =3D DIV_ROUND_CLOSEST_ULL((u64)mult * PSEC_PER_SEC * + mclk_div, mclk); + + return 0; +} + +static int ad7768_set_channel_convdelay(struct ad7768_state *st, + unsigned int ch) +{ + u64 delay_ps =3D st->ch_convdelay_ps[ch]; + struct ad7768_convdelay_params params; + u64 max_delay_ps; + u64 raw; + int ret; + + ret =3D ad7768_get_convdelay_params(st, ch, ¶ms); + if (ret) + return ret; + + max_delay_ps =3D (u64)params.max_raw * params.step_ps; + if (delay_ps > max_delay_ps) + return -EINVAL; + + raw =3D DIV_ROUND_CLOSEST_ULL(delay_ps, params.step_ps); + if (raw > params.max_raw) + return -EINVAL; + + return regmap_write(st->regmap, ad7768_phase_reg(st, ch), + raw << params.shift); +} + static void ad7768_filter_wait(const unsigned int *mode_freq, const enum ad7768_filter_type *mode_filter, const bool *mode_used) @@ -738,6 +851,16 @@ static int ad7768_apply_channel_modes(struct iio_dev *= indio_dev, max_freq =3D max(max_freq, mode_freq[mode]); } =20 + for_each_set_bit(c, scan_mask, st->chip_info->num_channels) { + ret =3D ad7768_set_channel_convdelay(st, c); + if (ret =3D=3D -EINVAL) + return dev_err_probe(regmap_get_device(st->regmap), ret, + "Invalid conversion delay for channel %u\n", + c); + if (ret) + return ret; + } + ret =3D ad7768_set_clk_divs(st, max_freq); if (ret) return ret; @@ -788,6 +911,13 @@ static int ad7768_read_raw(struct iio_dev *indio_dev, =20 *val =3D calib; return IIO_VAL_INT; + case IIO_CHAN_INFO_CONVDELAY: { + guard(mutex)(&st->lock); + iio_val_s64_decompose(st->ch_convdelay_ps[chan->channel], + val, val2); + + return IIO_VAL_DECIMAL64_PICO; + } default: return -EINVAL; } @@ -801,6 +931,8 @@ static int ad7768_write_raw_get_fmt(struct iio_dev *ind= io_dev, case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBSCALE: return IIO_VAL_INT; + case IIO_CHAN_INFO_CONVDELAY: + return IIO_VAL_DECIMAL64_PICO; default: return -EINVAL; } @@ -812,6 +944,7 @@ static int ad7768_write_raw(struct iio_dev *indio_dev, { struct ad7768_state *st =3D iio_priv(indio_dev); unsigned int base_reg; + s64 delay_ps; int ret; =20 IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); @@ -838,6 +971,15 @@ static int ad7768_write_raw(struct iio_dev *indio_dev, =20 base_reg =3D ad7768_get_calib_reg_base(st, chan, true); return ad7768_write_calib_value(st, base_reg, val); + case IIO_CHAN_INFO_CONVDELAY: { + delay_ps =3D iio_val_s64_compose(val, val2); + if (delay_ps < 0) + return -EINVAL; + + guard(mutex)(&st->lock); + st->ch_convdelay_ps[chan->channel] =3D delay_ps; + return 0; + } default: return -EINVAL; } @@ -1133,6 +1275,7 @@ static int ad7768_parse_config(struct iio_dev *indio_= dev, .type =3D IIO_VOLTAGE, .info_mask_separate =3D BIT(IIO_CHAN_INFO_CALIBBIAS) | BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CONVDELAY) | BIT(IIO_CHAN_INFO_SAMP_FREQ), .info_mask_separate_available =3D BIT(IIO_CHAN_INFO_SAMP_FREQ), --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 068AF4B8DE6; Fri, 21 Aug 2026 14:08:47 +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=1787321329; cv=none; b=fO9CmqyC6HBekxEKsEn6U28eKpimnfSn6JaIu4E1y19koMbgx+qXvhP+9X9m+y36yG3AfOJTz/rA6r9JLShT6GCOAnx/EI+TLO/gPknC+UzXXAydIIbDHxQNlsyWqnTblOQbSGRb5ZbBAKDgJyLYunJ7a+aozlvGW47Bemh01K8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321329; c=relaxed/simple; bh=AifmB2G01YuHbrZ/VCISIzsFDixJ2lc7TLl+pAbOcZg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=cpwEtsJ/EP/mFII9aLocrHfYT/2/3IGBrLNa/J0Hxx7xZ+ffvcHhOUGFzN2KSCqgThwyhrxKbwI5k9E7vQ5WFBrDTUttck0UNSTqNfKVVYY27e/lroP2Odd8gd8cJ4+qG2clN2BZB2GBSapqO1WwmmI4v4QnlXBe5/DQN15atG0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=wVQ4ubv2; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="wVQ4ubv2" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpIwT3677118; Fri, 21 Aug 2026 10:08:36 -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=ctXKK SqdYp1H827suGBvnUi0zcup9pqq/XGe2hYuRpM=; b=wVQ4ubv2EoKYl3daoPoiX Mz5wX/q3ZVvWyePzklT6hnr1WzAZS5QgTO6EpM7vPUigA3yw+bvBSoiU6toX3oXV C1ZwImwJTmOm5qdAK7tNrXi5WwZJ9pTDAl+aYdsHG3WejzJkIUi9WesKyPS5OjY8 QT6L2BMdVvVEBwj4s5rXhvyIrgagWgTYNhkTiOL9rbQjLpCQ87GCn9jMPv8GDmdn 4PNEiXkcHBB5+TCY2rdg38oDhYC7v98jNTibIhMGSd/+AHOFdd9cjMx53yfBPf0X YxRz2KLt+1UR35io0Dpr2QShDG6nwVaIecin8QW66iVvTr/HM9lgaaL/2gEIB5vs g== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g6a27k40b-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:08:36 -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 67LE8Zpc033049 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:08:35 -0400 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:35 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:35 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:08:34 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kks024319; Fri, 21 Aug 2026 10:08:25 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:07:02 +0200 Subject: [PATCH v4 09/14] iio: adc: ad7768: Add VCM regulator support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20260821-ad7768-driver-v4-9-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , "David Lechner" , Andy Shevchenko , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=6931; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=AifmB2G01YuHbrZ/VCISIzsFDixJ2lc7TLl+pAbOcZg=; b=u+mbP8eWUt2pTq935o0TWuE/srFLQg/+bvjlvqrmDfkDLEl31GuqMiEwEd8qlhqe38av+sEyR IV0DCq3dVk4D+yTcBwcMEa8Iq+vRTUfojpKgY9MFtQbs8MgBVjupZOp X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: nbn87fw-9abNDJ_buyTBBzCjJUDQm4bF X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfXyMIqSwP+6y++ 1Hi9akI8Q/iRNnjhav6sX18Z8RyCNT+2HM6ccV8dTM7F4S5cMoZVSWQcRC8zJmP8QQf+Rn2ZH2D Xfzso8SeSVoUs4rNU1A7xb/osGZaz4IgmvfLDApkDNHxDCIwRJQo X-Authority-Analysis: v=2.4 cv=FeoHAp+6 c=1 sm=1 tr=0 ts=6a885be4 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=uXIjobp8t2wMuQ0fPvqm:22 a=gAnH3GRIAAAA:8 a=-yOam_tWmGQwaYRI1VcA:9 a=QEXdDO2ut3YA:10 a=br55WurUj89AL1qEz8Q6:22 X-Proofpoint-GUID: nbn87fw-9abNDJ_buyTBBzCjJUDQm4bF X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX/dUnDKVoNozi WIOBP2ukzWDQ4jbvpwcjiNo3KTbQUSc8XjbhMLotrVK8QVmMZ19RICF8TXkij3S1DZo+NUt3B2i SvmBQ+omC24hZrotXu9y2A4mbzZLzUx1edThcmgCCOBtkIb79HPzeXUc/kB+x6sDlQ9rMfcVIoR OBODKbKeu9Eqi+jMhljHwzIIOhnNLz2IFAsjY+hZ23CpHP3NDcOQZVD3Luj9bxBKgueeirC0ot6 5xyCocPnqlUbjz3UlqSFZN0xefZVnqJWvEp9zuiza6d0R+EeBAUhljrjjn6xT3YHPrTB2L+jbwn KpSdUnujb/icfCj3wWLeaGMw3N6x9KRNl0Kwq2N6qG44ILiU+R1PEqlHd5DuoYMfBUwyY/GyiYt 3hnSEoWGop3Vb7VK0q2dNzgP5dqyUPxD+ihZ+wUlJ8N+3VAwxVqVZFSgKJcAeCRDW/q0UQrbQWo qB/k+iHtOxLhxi/HlQw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 malwarescore=0 adultscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 priorityscore=1501 bulkscore=0 phishscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Expose the on-chip common mode voltage output through the regulator framework. Support the three fixed output levels and the supply-dependent AVDD1/2 setting. Keep the ADC runtime active while VCM is enabled and release the runtime PM reference when the output is disabled. Signed-off-by: Janani Sunil --- drivers/iio/adc/Kconfig | 2 +- drivers/iio/adc/ad7768.c | 161 +++++++++++++++++++++++++++++++++++++++++++= +++- 2 files changed, 160 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 48bb108382b5..a16f36f9502c 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -432,7 +432,7 @@ config AD7766 config AD7768 tristate "Analog Devices AD7768/AD7768-4 ADC driver" depends on SPI - depends on REGULATOR || COMPILE_TEST + select REGULATOR select IIO_BUFFER select IIO_BACKEND select REGMAP diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c index 12370139d03f..97f84a6da63e 100644 --- a/drivers/iio/adc/ad7768.c +++ b/drivers/iio/adc/ad7768.c @@ -18,10 +18,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -53,6 +55,8 @@ #define AD7768_POWER_MODE_MCLK_DIV_MSK GENMASK(1, 0) =20 #define AD7768_REG_GENERAL_CONFIG 0x05 +#define AD7768_GEN_CONFIG_VCM_SEL_MSK GENMASK(1, 0) +#define AD7768_GEN_CONFIG_VCM_PD BIT(4) =20 #define AD7768_REG_DATA_CONTROL 0x06 #define AD7768_DATA_CONTROL_SPI_RESET_1 0x03 @@ -197,10 +201,156 @@ struct ad7768_state { u64 ch_convdelay_ps[AD7768_MAX_CHANNEL]; enum ad7768_filter_type ch_filter[AD7768_MAX_CHANNEL]; struct iio_backend *back; + struct regulator_dev *vcm_rdev; + unsigned int avdd1_uV; =20 __be16 d16 __aligned(IIO_DMA_MINALIGN); }; =20 +static const unsigned int ad7768_vcm_voltage_table[] =3D { + 0, 1650000, 2500000, 2140000, +}; + +static int ad7768_vcm_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + struct ad7768_state *st =3D rdev_get_drvdata(rdev); + + if (selector >=3D ARRAY_SIZE(ad7768_vcm_voltage_table)) + return -EINVAL; + + if (!selector) + return DIV_ROUND_CLOSEST(st->avdd1_uV, 2); + + return ad7768_vcm_voltage_table[selector]; +} + +static int ad7768_vcm_enable(struct regulator_dev *rdev) +{ + struct ad7768_state *st =3D rdev_get_drvdata(rdev); + int ret; + + ret =3D pm_runtime_resume_and_get(regmap_get_device(st->regmap)); + if (ret < 0) + return ret; + + ret =3D regmap_clear_bits(st->regmap, AD7768_REG_GENERAL_CONFIG, + AD7768_GEN_CONFIG_VCM_PD); + if (ret) + pm_runtime_put_autosuspend(regmap_get_device(st->regmap)); + + return ret; +} + +static int ad7768_vcm_disable(struct regulator_dev *rdev) +{ + struct ad7768_state *st =3D rdev_get_drvdata(rdev); + int ret; + + ret =3D regmap_set_bits(st->regmap, AD7768_REG_GENERAL_CONFIG, + AD7768_GEN_CONFIG_VCM_PD); + if (ret) + return ret; + + pm_runtime_put_autosuspend(regmap_get_device(st->regmap)); + + return 0; +} + +static int ad7768_vcm_is_enabled(struct regulator_dev *rdev) +{ + struct ad7768_state *st =3D rdev_get_drvdata(rdev); + int ret; + + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(regmap_get_device(st->regmap), pm); + ret =3D PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + ret =3D regmap_test_bits(st->regmap, AD7768_REG_GENERAL_CONFIG, + AD7768_GEN_CONFIG_VCM_PD); + if (ret < 0) + return ret; + + return !ret; +} + +static int ad7768_vcm_set_voltage_sel(struct regulator_dev *rdev, + unsigned int selector) +{ + struct ad7768_state *st =3D rdev_get_drvdata(rdev); + int ret; + + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(regmap_get_device(st->regmap), pm); + ret =3D PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + return regmap_update_bits(st->regmap, AD7768_REG_GENERAL_CONFIG, + AD7768_GEN_CONFIG_VCM_SEL_MSK, + FIELD_PREP(AD7768_GEN_CONFIG_VCM_SEL_MSK, + selector)); +} + +static int ad7768_vcm_get_voltage_sel(struct regulator_dev *rdev) +{ + struct ad7768_state *st =3D rdev_get_drvdata(rdev); + unsigned int val; + int ret; + + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(regmap_get_device(st->regmap), pm); + ret =3D PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + ret =3D regmap_read(st->regmap, AD7768_REG_GENERAL_CONFIG, &val); + if (ret) + return ret; + + return FIELD_GET(AD7768_GEN_CONFIG_VCM_SEL_MSK, val); +} + +static const struct regulator_ops ad7768_vcm_ops =3D { + .enable =3D ad7768_vcm_enable, + .disable =3D ad7768_vcm_disable, + .is_enabled =3D ad7768_vcm_is_enabled, + .list_voltage =3D ad7768_vcm_list_voltage, + .set_voltage_sel =3D ad7768_vcm_set_voltage_sel, + .get_voltage_sel =3D ad7768_vcm_get_voltage_sel, +}; + +static const struct regulator_desc ad7768_vcm_desc =3D { + .name =3D "vcm", + .of_match =3D of_match_ptr("vcm-output"), + .regulators_node =3D "regulators", + .n_voltages =3D ARRAY_SIZE(ad7768_vcm_voltage_table), + .ops =3D &ad7768_vcm_ops, + .type =3D REGULATOR_VOLTAGE, + .owner =3D THIS_MODULE, +}; + +static int ad7768_register_vcm_regulator(struct device *dev, + struct ad7768_state *st) +{ + struct regulator_config config =3D { + .dev =3D dev, + .driver_data =3D st, + }; + int ret; + + /* + * Start with VCM disabled so each enabled state is paired with the + * runtime PM reference acquired by ad7768_vcm_enable(). + */ + ret =3D regmap_set_bits(st->regmap, AD7768_REG_GENERAL_CONFIG, + AD7768_GEN_CONFIG_VCM_PD); + if (ret) + return ret; + + st->vcm_rdev =3D devm_regulator_register(dev, &ad7768_vcm_desc, &config); + return PTR_ERR_OR_ZERO(st->vcm_rdev); +} + static const int ad7768_dec_rate[MAX_FREQ_PER_MODE] =3D { 32, 64, 128, 256, 512, 1024, }; @@ -1484,11 +1634,13 @@ static int ad7768_probe(struct spi_device *spi) return dev_err_probe(dev, ret, "Failed to enable AVSS supply\n"); =20 - ret =3D devm_regulator_get_enable(dev, "avdd1"); - if (ret) + ret =3D devm_regulator_get_enable_read_voltage(dev, "avdd1"); + if (ret < 0) return dev_err_probe(dev, ret, "Failed to enable AVDD1 supply\n"); =20 + st->avdd1_uV =3D ret; + ret =3D devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(ad7768_supply_names), ad7768_supply_names); @@ -1595,6 +1747,11 @@ static int ad7768_probe(struct spi_device *spi) if (ret) return ret; =20 + ret =3D ad7768_register_vcm_regulator(dev, st); + if (ret) + return dev_err_probe(dev, ret, + "Failed to register VCM regulator\n"); + indio_dev->setup_ops =3D &ad7768_buffer_ops; =20 ret =3D devm_iio_device_register(dev, indio_dev); --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 32B954D2EFE; Fri, 21 Aug 2026 14:08:53 +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=1787321334; cv=none; b=nW4C/rqAkPbrdzo6VYdS3GBWcOr993j30+IYsd1wrtfV3DA+MlT+M1rKKDjUiIlTD3eHTd2MuChsz0bny931wsbZ1O+emibctxhdWTIZLkB5utdPXfunU4FAX/D8AXeXwGY2JHylUGVPZaoJwyMKp9VeyKZW4gPHhE6yZzdgjLQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321334; c=relaxed/simple; bh=ZymO/Vtz6KLtQ+shBQPjosSDpjpie2N3ZyEUGaNPxTE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=GegVwNWUyvy3rx1wITYS8972V89/+R9QTdzHKoNKYygUlOeL5ZexaG2F3FWHR7dozogL38ijDvSGw0zzgPPrdbm/kq3e8gVCtViFt6uC7+gtBbboot/Cm1J6Bs+ECDHsoUXK7QWZBbDR9w5mHa65q1UZ/PLg21Sys+Vp2NEaDGo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=BJcinRr2; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="BJcinRr2" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpfK82651167; Fri, 21 Aug 2026 10:08:42 -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=edjnW tKvzqrrryFgvFS7J1KBqVvFFCoIk7Gq871BrjM=; b=BJcinRr2RvQl9OlM9mT8u qXn2ENkjf1aEh/JuTWDJp/HUY/UfgtXkEjA0bRW93UwZivP5hdsLjVGX1VQOf9J9 aZP4bwMJrUnOqH+Iorb4zE8sW3ew7C9+D+8jHZuh6FSJ/Ht2bPojJ8I6xlXhCmym r65DfCYoSj/4t3rBN51by4CHSYdl59DZawT7AsJDECR0SZF06y6g9LtGbekJX2yy av4y6xxNCchs0YjQxoyUmNWyK8ytM/5IlXc/6wJpJZiKZOEGs9qDWfwxEHv72sEa V7lsSg5ICLusdsmaMa+DUxBvvfHeHQg5RsmecNb43ATVN4IC7We1hCeq7v57kM8v A== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 4g4yepyvkt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:08:42 -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 67LE8fol033055 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:08:41 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:40 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:08:40 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkt024319; Fri, 21 Aug 2026 10:08:30 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:07:03 +0200 Subject: [PATCH v4 10/14] iio: adc: ad7768: Register GPIO auxiliary device 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: <20260821-ad7768-driver-v4-10-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=3031; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=ZymO/Vtz6KLtQ+shBQPjosSDpjpie2N3ZyEUGaNPxTE=; b=t/NJuMiQwlaBj2qlLvZ2d8fM5evyZrTSRNkbtLCZiTOHmmihe98QZMCiJJJecO7T+Ura5KlrD h3WZg+s5XIxC2RBF+1r3BfzXpnHqbQQEq5v0kgPiybsEuCdSauf53kW X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: 4fZ_EQ2bpmwlXuTSOw-9bM4P-5DDGJYk X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX8sseZGDOYHKX 7huSX2GJQhxpOdBtELSd23fJAWPt4gbryyFEW32UdJKnlB14NAh+kI4COqjZOifrhI2rS7pFkf9 cgyW0INe6r406m1s+hWAkKBM/54X8+pbnSlh388l4N7yl2lIU9Ls X-Authority-Analysis: v=2.4 cv=NLHlPU6g c=1 sm=1 tr=0 ts=6a885bea cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=N--XFCr6TIEc_64PeIT2:22 a=gAnH3GRIAAAA:8 a=kQnUbRfMuyK_Mtn_XBwA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX+5a6z23Pyslh sCf18i/5BhLUWiwLHJT1+ztlPAbpzTc6cVTYheUlCZIGMr3++sGReorhwip0l3LDFODPB6Sj+eH xKh3WKKs5vRfOKDIOwLNCGxFmCTg892QR23mghm1cylWLjGZhNBugtI/4Kxs/u6cW6KhBvOouEx /LXQZaubgyY/MOPd7Kq9mYd54pDKI2k4h8xlN3iYIomaOytoXw3pyV440vIboI7sLawAC0p+/pj vwyrWDL34iVm+IXqi4iRF3QjKh6LbdfkxGX9M6p1tiCYAuyXnUvJz8GftbqpKhGOsDA6GiZrc1y whnYkaWgVsePEI8T9QSixESe/OD7i4rMK23TV7E17UpamNfK1KHq8AmeHa5t1dHxG5FUA+CGgV9 mEtznFLFhrbz8syefEF8clLWCPqQofmPdZo8HMvC52T6R/srgnxAkGQJV6V7ulfnEwCwb7SQsv+ /taL+U3FQWZYkg/ZXZw== X-Proofpoint-GUID: 4fZ_EQ2bpmwlXuTSOw-9bM4P-5DDGJYk X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 adultscore=0 suspectscore=0 clxscore=1015 phishscore=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 malwarescore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Register an auxiliary device when the AD7768 is described as a GPIO controller. This allows the GPIO driver to share the parent regmap and runtime power-management state. Signed-off-by: Janani Sunil --- drivers/iio/adc/Kconfig | 1 + drivers/iio/adc/ad7768.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index a16f36f9502c..68334793c9ba 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -433,6 +433,7 @@ config AD7768 tristate "Analog Devices AD7768/AD7768-4 ADC driver" depends on SPI select REGULATOR + select AUXILIARY_BUS select IIO_BUFFER select IIO_BACKEND select REGMAP diff --git a/drivers/iio/adc/ad7768.c b/drivers/iio/adc/ad7768.c index 97f84a6da63e..3f9306d54952 100644 --- a/drivers/iio/adc/ad7768.c +++ b/drivers/iio/adc/ad7768.c @@ -6,6 +6,7 @@ */ =20 #include +#include #include #include #include @@ -121,6 +122,7 @@ #define AD7768_MAX_MCLK_FREQ_HZ (34 * HZ_PER_MHZ) #define MAX_FREQ_PER_MODE 6 #define AD7768_MAX_CHANNEL 8 +#define AD7768_NUM_GPIOS 5 #define AD7768_NUM_CHANNEL_MODES 2 #define AD7768_CALIB_REG_MSK GENMASK(23, 0) #define AD7768_WIDEBAND_SETTLING_SAMPLES 68 @@ -191,6 +193,7 @@ struct ad7768_state { struct mutex lock; struct clk *mclk; unsigned int datalines; + unsigned long gpio_valid_mask; enum ad7768_clock_source clock_source; unsigned int power_mode_idx; const struct ad7768_chip_info *chip_info; @@ -1262,6 +1265,31 @@ static void ad7768_set_available_sampl_freq(struct a= d7768_state *st) } } =20 +static int ad7768_gpio_adev_init(struct ad7768_state *st) +{ + struct device *dev =3D regmap_get_device(st->regmap); + struct spi_device *spi =3D to_spi_device(dev); + struct auxiliary_device *adev; + int id; + + if (!device_property_read_bool(dev, "gpio-controller")) + return 0; + + st->gpio_valid_mask =3D GENMASK(AD7768_NUM_GPIOS - 1, 0); + if (st->clock_source !=3D AD7768_CLOCK_SOURCE_MCLK) + st->gpio_valid_mask &=3D ~BIT(4); + + /* Use the SPI bus number and chip select to derive a stable per-device I= D. */ + id =3D (spi->controller->bus_num << 8) | spi_get_chipselect(spi, 0); + adev =3D __devm_auxiliary_device_create(dev, KBUILD_MODNAME, "gpio", + &st->gpio_valid_mask, id); + if (!adev) + return dev_err_probe(dev, -ENODEV, + "Failed to create GPIO auxiliary device\n"); + + return 0; +} + static int ad7768_set_filter_mode(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, unsigned int mode) @@ -1754,6 +1782,10 @@ static int ad7768_probe(struct spi_device *spi) =20 indio_dev->setup_ops =3D &ad7768_buffer_ops; =20 + ret =3D ad7768_gpio_adev_init(st); + if (ret) + return ret; + ret =3D devm_iio_device_register(dev, indio_dev); if (ret) return ret; --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 160C14C8FE9; Fri, 21 Aug 2026 14:08:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321339; cv=none; b=Pb3j0iH/zqLh9lel0ruiyNuDkFv9PniB5n5cdIMFRgdEnFOZUmac9+OGnMswVHvqrdYWELMMdtzTGJ/lANdomst/7UvOcI+yfOhO6aZmo4Bq6nOqFZMx45mBZ3JZrNVevIgFLeDwOkwFzHoNYo1LlrKNuCH3y71ihvve/EUPNGg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321339; c=relaxed/simple; bh=avB1555kJ+GOyyc5fE8p1FrcUXTJvMXpwCTIYWQx1Us=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=eLALCt1w3+2KbpG1rG7YLWV3BBeqDPJGz3BRj5ym0gkB/P3vOwgNKP1lR2/e5/Dt3q7NwZJAq3K2ajBjGn7vh8F5yhsBNsiNQEOT5viiMnb61be3uWhb87wvT1WpXKsiRip5VsAb0ajghp4OJCqig6PGdapQK02ghNJMGxAJxpY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=MJi93s6A; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="MJi93s6A" Received: from pps.filterd (m0516787.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpc7x3388113; Fri, 21 Aug 2026 10:08:48 -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=xLiYf B9zUEHmd49UdNRGkukLG5fLQRmFBLhph/BOetk=; b=MJi93s6Av5BYIpWYI3avZ PORzWJbhueCsNWrRjXLG2wfttSDUSgIi5C/dXDDceTlEmAr9uEmnoqGoCjhtjV/N vnoK4aauIoPkCToV29xHEFK6fgRsb88lv8bgk+d7C4DgzidbE5H6Kgj/3hHkmup2 D3ID4U0ySnI7fQKY0Zu9xpRTILF8X9lxXLNdlr6cki/XTzOwiWxOULKzuHPlGd09 0eWbgzviLCLxR8gRFnsXdrE6eZdND2nmaxEnMZBC1sYeFqmv9lgNMRO/X7dXX7pu rZ7Oq0mJXpOb3jasGW+CzMOaeyxMC5nxLvCwYcEAcYb7r+WyQ8pwsoLs5+15ApcJ A== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g66m6m0j9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:08:48 -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 67LE8lRl033064 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:08:47 -0400 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:47 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:47 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:08:46 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kku024319; Fri, 21 Aug 2026 10:08:36 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:07:04 +0200 Subject: [PATCH v4 11/14] gpio: regmap: Use regmap_test_bits() for single bit reads 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: <20260821-ad7768-driver-v4-11-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , "David Lechner" , Andy Shevchenko , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=1956; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=avB1555kJ+GOyyc5fE8p1FrcUXTJvMXpwCTIYWQx1Us=; b=px09P536CdmoNMnc0EWL7n0PznSoXteiD/EmLD3RGCIq3pmB2iZiH9HqEmyw1exftszD3EIiS +REIkZX6imBAVUL7Im1DxtzeLcmwmIEVJEB3ugpNWPIHzI5BLH9BF5T X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX6DZYg6vfVImr vTts7Q6xfIBvfoQFatcmuLG5SO7EwBOtjunVMckTf4RzGkkejH2FhD770vi1FvLNyaGz1krdtDr 91Mch9bF0pco4t/+Ui5WxVR7mhtfD/Mw3Ca89FAoU4vRefNk15Vb X-Proofpoint-ORIG-GUID: MAcbq0XjZLO1lBWw4BpBsmLV4VKW5iAS X-Proofpoint-GUID: MAcbq0XjZLO1lBWw4BpBsmLV4VKW5iAS X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfXz35uYJfJ0lxf RTl5D/O0VFXND5fPPVQ1wuHtKdYcJPm1iWIEmLE2EEdK0QVPyj5j72ea9dCHBjESHyuUzttsuGu JTDRWMf4Tki3tzr3nwaIRebeSIFyIYBsB34sU0fjkwIZyLB0SF/qZaPrPLT9d2qntxsFPW4kJQa 5mh2bCUYW7S/DHvnDlBtaK7QJ2UEaHtZcPfksxkmLTcXU1Wd8axUIXoVhVYBKM9HYJAZiKYNyop g3oO9xspLVFB0LPiXqEAv1duhVEctuWozHUJ0VQdgx0JrxEp2i4+G5iSChVckaYm8WQqlOhKCWX +A+TS/txmO523GvWBBcHZm+lTWBZK0QQ0BtiT2/fdGrXyM2zKXShFWWhtrOkjzC5stc26I83emQ lZLD+R62GUnrFvFC4aORVwnvCNLPAHufCzIDG5UA9JbAP57L20uYT+Lrrze+qZr7jOJodLChdkP x8v1pSgxPoO0C07LJCg== X-Authority-Analysis: v=2.4 cv=baVbluPB c=1 sm=1 tr=0 ts=6a885bf0 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=OmVn7CZJonkx5R5zMQLL:22 a=VwQbUJbxAAAA:8 a=gAnH3GRIAAAA:8 a=D1cL9gYDKEHF3ZsCBWwA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 phishscore=0 spamscore=0 suspectscore=0 impostorscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Use regmap_test_bits() when reading a single GPIO value from a normal register and when reading the direction bit. Reviewed-by: Linus Walleij Reviewed-by: Michael Walle Signed-off-by: Janani Sunil Reviewed-by: Andy Shevchenko --- drivers/gpio/gpio-regmap.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index 51b4d69b8740..0012e03d0d4e 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c @@ -83,11 +83,11 @@ static int gpio_regmap_get(struct gpio_chip *chip, unsi= gned int offset) if (ret) return ret; =20 + if (gpio->reg_dat_base !=3D gpio->reg_set_base) + return regmap_test_bits(gpio->regmap, reg, mask); + /* ensure we don't spoil any register cache with pin input values */ - if (gpio->reg_dat_base =3D=3D gpio->reg_set_base) - ret =3D regmap_read_bypassed(gpio->regmap, reg, &val); - else - ret =3D regmap_read(gpio->regmap, reg, &val); + ret =3D regmap_read_bypassed(gpio->regmap, reg, &val); if (ret) return ret; =20 @@ -157,7 +157,7 @@ static int gpio_regmap_get_direction(struct gpio_chip *= chip, unsigned int offset) { struct gpio_regmap *gpio =3D gpiochip_get_data(chip); - unsigned int base, val, reg, mask; + unsigned int base, reg, mask; int invert, ret; =20 if (gpio_regmap_fixed_direction(gpio, offset)) { @@ -186,14 +186,14 @@ static int gpio_regmap_get_direction(struct gpio_chip= *chip, if (ret) return ret; =20 - ret =3D regmap_read(gpio->regmap, reg, &val); - if (ret) + ret =3D regmap_test_bits(gpio->regmap, reg, mask); + if (ret < 0) return ret; =20 - if (!!(val & mask) ^ invert) + if (ret ^ invert) return GPIO_LINE_DIRECTION_OUT; - else - return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_IN; } =20 static int gpio_regmap_try_direction_fixed(struct gpio_regmap *gpio, --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 EE4994C8FEF; Fri, 21 Aug 2026 14:09:03 +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=1787321345; cv=none; b=MuPFuwoBQVZ05KMOKL8plQSiT9S/Z2XaYCiZrh4zu2/K8/jBudvmqd/51Ru3iUriAhOSwEQhs50VbMBvnlpRejC28OfNQXIT1KsAIa0fNnRtrDqf0h4V7IpUbOvjqIs5lOnjq5rATSPODx+rK91nwwMI09iUtH8CHpr2Ddb+HfI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321345; c=relaxed/simple; bh=qAtdMDKoQuyTDGwsahfpRL/dgFjrGIYhZrr36H8o6lY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=DWZxPjNwVvrMDp4C+a6ul+CNt8yQ6v4glaK3LKkjSlWVdCc6lGnN8mV0UIu31RlSHZfbmBqC9a6/xM0v3r++ZZbRRPzg19OzHFUsvjCsbMn7pTCzXxc0DdjK1GWouhjTE5W16dyLDVeRhAlgLE1Qi9vTDuRYEKNkzdmHnkqMGII= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=xEKxJUaq; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="xEKxJUaq" Received: from pps.filterd (m0516787.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpTMm3387957; Fri, 21 Aug 2026 10:08:55 -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=R46s5 fxfiAUeWw76ISw/2grT3/yXiC0NWLVsFCoQ7TQ=; b=xEKxJUaqWRTJ3ay1mulrJ 3JmD8NVo6/FzPOhQkz1FWRR+esnHs25AmXT/JJaavF/2Nxb4/vH/YXIdZTZywXll Jx0Zw/BGYXR3e/RiLXFitnoC30Md6NCWFHk8scJnyFgGNuzZlU9FXC1Shn9qC2kO wV6rGlvUfM8bTw+XkCUOAZ9LAWsQAerWVWRatNj8hO3F4YweEBZ1V66vixa96bpx HOV4eTmo3BbCiP5XMm4ixqVmCoiSZIfbX7XxL7Ql/kg5fXRfNqcEIZ2T3mpqpwmp e+9Hqc9zn3EsDg+RXmfQ3ojJJvr/aXfitFkmDsWgXFODqwYh4gjEF+K6uf75IUB1 Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g66m6m0jn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:08:54 -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 67LE8rVD033076 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:08:53 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:53 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:08:53 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkv024319; Fri, 21 Aug 2026 10:08:42 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:07:05 +0200 Subject: [PATCH v4 12/14] gpio: regmap: Add optional runtime PM support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-ID: <20260821-ad7768-driver-v4-12-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=6305; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=qAtdMDKoQuyTDGwsahfpRL/dgFjrGIYhZrr36H8o6lY=; b=PHxPyBfSZbyXwfiaodJzgSw4+bVxOn//gShAPWNu1tdG0kSqVsDtD3/+FMHahzPj2VPElB0oO sLjvpDDwsn9AFHnmpIDFtOc42kQajGUFXvYdsj13nfeeKy0aA7d0+az X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX9+zIqF6yBG6w 5YMMBjZ5aLYY3OuUDril8UDdzYWOnYTueDXnr+OCbK6Eem2itCPo9k+iFWRbgFGqKssbf06lBG/ xamK09ulQGK/DeQU3cfDgnelpwXTRIoADzrY5a6cyfxkJ0gAe/Si X-Proofpoint-ORIG-GUID: CTpP0wPXLqnwS2Rk2PjxM3mkjYiIyBYo X-Proofpoint-GUID: CTpP0wPXLqnwS2Rk2PjxM3mkjYiIyBYo X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX2AQeqmM+9vqs 4Id3PlUGacjU0BlewgscSDDU5q8KN9eJ5I72uLEXdyqiv9QQPXTiXvB/PAtI9YrdEpUzsPruT3+ fjxtpXXvNkKjqdWA89FmSA17vp68xClR6DtwqVr6pcYn9J2eB810HtZ7165pP2+Cg18UB1K+UFr WvIXk8yhyh8GNWrdM2fwOAuscCqCxdSPlK1icI3gpKFCj2nCjmN+55TtWotKBjlIphcdw4BzcDp jubOb6Zzq5zKnSWgveRDdwkZzXUHwwTjFhZs9o3l9Wp2g61KA1I1vVzUhVngWXHlL6D24c52JmX EXfWRUa6JpPudAln3MGGiZ4gCH1xL4YKmfhsl0kFxHSnXGeI1xsAe9qTWad48Sk70vRHAZ6MCEB jtw6DEu+Op8EzFgPs+hBi2CafKlVP2Y0fm0gjyjCvT1CBuGnB+wrpXZYKpFJJjHo2ZWBNqgbo5l W4aTSpSgC/4uNvaDdZw== X-Authority-Analysis: v=2.4 cv=baVbluPB c=1 sm=1 tr=0 ts=6a885bf6 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=OmVn7CZJonkx5R5zMQLL:22 a=gAnH3GRIAAAA:8 a=3fJ8ZLtifNgCll64qzMA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 phishscore=0 spamscore=0 suspectscore=0 impostorscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Some gpio-regmap consumers share their regmap with a parent device that may be runtime suspended. GPIO register accesses must resume that device first. Add an optional pm_dev field and acquire it before register translation or access. Release it using runtime autosuspend after each operation. Keep the device active across the complete direction-output sequence and propagate failure when setting the initial output value. Signed-off-by: Janani Sunil --- drivers/gpio/gpio-regmap.c | 62 +++++++++++++++++++++++++++++++++++++++++= ++-- include/linux/gpio/regmap.h | 2 ++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index 0012e03d0d4e..3e7030e47483 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c @@ -6,10 +6,12 @@ */ =20 #include +#include #include #include #include #include +#include #include #include #include @@ -31,6 +33,7 @@ struct gpio_regmap { unsigned int reg_clr_base; unsigned int reg_dir_in_base; unsigned int reg_dir_out_base; + struct device *pm_dev; unsigned long *fixed_direction_mask; unsigned long *fixed_direction_output; =20 @@ -67,6 +70,27 @@ static int gpio_regmap_simple_xlate(struct gpio_regmap *= gpio, return 0; } =20 +static int gpio_regmap_runtime_get(struct gpio_regmap *gpio) +{ + if (!gpio->pm_dev) + return 0; + + return pm_runtime_get_active(gpio->pm_dev, RPM_TRANSPARENT); +} + +static void gpio_regmap_runtime_put(struct gpio_regmap *gpio) +{ + if (!gpio->pm_dev) + return; + + pm_runtime_put_autosuspend(gpio->pm_dev); +} + +DEFINE_GUARD(gpio_regmap_runtime, struct gpio_regmap *, + gpio_regmap_runtime_get(_T), gpio_regmap_runtime_put(_T)) +DEFINE_GUARD_COND(gpio_regmap_runtime, _try, + gpio_regmap_runtime_get(_T), _RET =3D=3D 0) + static int gpio_regmap_get(struct gpio_chip *chip, unsigned int offset) { struct gpio_regmap *gpio =3D gpiochip_get_data(chip); @@ -79,6 +103,11 @@ static int gpio_regmap_get(struct gpio_chip *chip, unsi= gned int offset) else base =3D gpio_regmap_addr(gpio->reg_set_base); =20 + ACQUIRE(gpio_regmap_runtime_try, pm)(gpio); + ret =3D ACQUIRE_ERR(gpio_regmap_runtime_try, &pm); + if (ret) + return ret; + ret =3D gpio->reg_mask_xlate(gpio, base, offset, ®, &mask); if (ret) return ret; @@ -102,6 +131,11 @@ static int gpio_regmap_set(struct gpio_chip *chip, uns= igned int offset, unsigned int reg, mask, mask_val; int ret; =20 + ACQUIRE(gpio_regmap_runtime_try, pm)(gpio); + ret =3D ACQUIRE_ERR(gpio_regmap_runtime_try, &pm); + if (ret) + return ret; + ret =3D gpio->reg_mask_xlate(gpio, base, offset, ®, &mask); if (ret) return ret; @@ -127,6 +161,11 @@ static int gpio_regmap_set_with_clear(struct gpio_chip= *chip, unsigned int base, reg, mask; int ret; =20 + ACQUIRE(gpio_regmap_runtime_try, pm)(gpio); + ret =3D ACQUIRE_ERR(gpio_regmap_runtime_try, &pm); + if (ret) + return ret; + if (val) base =3D gpio_regmap_addr(gpio->reg_set_base); else @@ -182,6 +221,11 @@ static int gpio_regmap_get_direction(struct gpio_chip = *chip, return -ENOTSUPP; } =20 + ACQUIRE(gpio_regmap_runtime_try, pm)(gpio); + ret =3D ACQUIRE_ERR(gpio_regmap_runtime_try, &pm); + if (ret) + return ret; + ret =3D gpio->reg_mask_xlate(gpio, base, offset, ®, &mask); if (ret) return ret; @@ -236,6 +280,11 @@ static int gpio_regmap_set_direction(struct gpio_chip = *chip, return -ENOTSUPP; } =20 + ACQUIRE(gpio_regmap_runtime_try, pm)(gpio); + ret =3D ACQUIRE_ERR(gpio_regmap_runtime_try, &pm); + if (ret) + return ret; + ret =3D gpio->reg_mask_xlate(gpio, base, offset, ®, &mask); if (ret) return ret; @@ -260,6 +309,11 @@ static int gpio_regmap_direction_output(struct gpio_ch= ip *chip, struct gpio_regmap *gpio =3D gpiochip_get_data(chip); int ret; =20 + ACQUIRE(gpio_regmap_runtime_try, pm)(gpio); + ret =3D ACQUIRE_ERR(gpio_regmap_runtime_try, &pm); + if (ret) + return ret; + /* * First check if this is gonna work on a fixed direction line, * if it doesn't (i.e. this is a fixed input line), then do not @@ -271,7 +325,9 @@ static int gpio_regmap_direction_output(struct gpio_chi= p *chip, return ret; } =20 - gpio_regmap_set(chip, offset, value); + ret =3D gpio_regmap_set(chip, offset, value); + if (ret) + return ret; =20 return gpio_regmap_set_direction(chip, offset, true); } @@ -323,6 +379,7 @@ struct gpio_regmap *gpio_regmap_register(const struct g= pio_regmap_config *config gpio->reg_clr_base =3D config->reg_clr_base; gpio->reg_dir_in_base =3D config->reg_dir_in_base; gpio->reg_dir_out_base =3D config->reg_dir_out_base; + gpio->pm_dev =3D config->pm_dev; =20 chip =3D &gpio->gpio_chip; chip->parent =3D config->parent; @@ -330,7 +387,8 @@ struct gpio_regmap *gpio_regmap_register(const struct g= pio_regmap_config *config chip->base =3D -1; chip->names =3D config->names; chip->label =3D config->label ?: dev_name(config->parent); - chip->can_sleep =3D regmap_might_sleep(config->regmap); + chip->can_sleep =3D config->pm_dev || + regmap_might_sleep(config->regmap); chip->init_valid_mask =3D config->init_valid_mask; =20 chip->request =3D gpiochip_generic_request; diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h index 06255756710d..eceb31b89f50 100644 --- a/include/linux/gpio/regmap.h +++ b/include/linux/gpio/regmap.h @@ -34,6 +34,7 @@ struct regmap; * @ngpio_per_reg: (Optional) Number of GPIOs per register * @irq_domain: (Optional) IRQ domain if the controller is * interrupt-capable + * @pm_dev: (Optional) Device to use for runtime power management. * @reg_mask_xlate: (Optional) Translates base address and GPIO * offset to a register/bitmask pair. If not * given the default gpio_regmap_simple_xlate() @@ -95,6 +96,7 @@ struct gpio_regmap_config { int reg_stride; int ngpio_per_reg; struct irq_domain *irq_domain; + struct device *pm_dev; unsigned long *fixed_direction_mask; unsigned long *fixed_direction_output; =20 --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 BE7F34C9012; Fri, 21 Aug 2026 14:09:09 +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=1787321351; cv=none; b=OfQWpbjt9aV4qiK58vfgJN9ySXmNHwdiidmQeMNG+hsp2T504Ap9o0RWKhk1F3B+HjrU9ZtfE3akb6XGvg9zmoq9W7PSvIzYnYr+CnYnh7yY/FTGFauW3NOqDC1Syw/+suQ/OVTuindFs5jIK3abqh1WEehR/S/BDiL3Ly0wt/U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321351; c=relaxed/simple; bh=q/TL1NVykNjMWtW8Lil45SStrRj/mHgaltCNPIn4ZwY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=WSErvYV1p8xu/gG80NkoBvNvZmHjMLtl5xBH+omwSFuZVhps38K5IqV+b8H//OKdFh0tTubUUBz/n1MPjjsfz/R0aijxn2lpyJQGtP5nByP/OXl8Kth1eiipmH2w5cehpkLp8fMaitQIpBRa//Ziz6O8JS5A0uE6Ff0mluperYc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=YnG81hS1; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="YnG81hS1" Received: from pps.filterd (m0516787.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpc803388113; Fri, 21 Aug 2026 10:09:00 -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=Qpx3q YvaMm1KudADebGzqocYcokF+jNaFsu81vWJCR8=; b=YnG81hS1Wk2Pzdc8/adCy W59dtn81jBxqRTkMCZj1RZKDEtXBB9M8pqXj1Cgzvuq3Sg8eBueXCiHEAz1d/w9G pIOhCEDP9JAYvtmnwZ7ACdnQEaOFv5hV9XBL0V/JvXPfairkQi3XExaM7OK+bDyy p9cqAhP8MnxA81f6pfA/VJqGWvMg59Xy9KkMjAsSxvvybSUpG1mm1va6fZwDRsG0 P6Nr0iGY6ym7Z78nYn+Hj/iC6IgQHTunIdvo8enFwGUZ0laVy3MzeDBwMRw9Hket fKLbLPgu8+iWrATAGNrP/qpOBY+j8U5ydOXxGt4QNAOBYU/hgnacnhsICJvkHbXt A== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g66m6m0jy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:09:00 -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 67LE8xDm033079 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:08:59 -0400 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:58 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.37; Fri, 21 Aug 2026 10:08:59 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:08:58 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkw024319; Fri, 21 Aug 2026 10:08:49 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:07:06 +0200 Subject: [PATCH v4 13/14] gpio: ad7768: Add AD7768 GPIO auxiliary 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: <20260821-ad7768-driver-v4-13-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , "David Lechner" , Andy Shevchenko , "Rob Herring" , Krzysztof Kozlowski , "Conor Dooley" , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=5816; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=q/TL1NVykNjMWtW8Lil45SStrRj/mHgaltCNPIn4ZwY=; b=5AXU9WabCGasZuJk6dmDzqrw96Q0IOwIIkctTJ5Sc950hIHI5mxoRIix7ubgm8UkG1ud3xOwf PtPU35YgE+WAMpRzBq4eaEHAuyFh5nuMGhwHgEO1x1WuRRYOM3w2BCt X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX6anSvWIlT5Fz QDI57XWUW8GMmFHjePx18AkGRd2lyEOBfkzhDCfXX/SVBRX1lir6YqvY9WfdaNgAZ3W7DIVcf/D QEmtMi3fHXPkg8VUn9u7E10rr3kUOQoDrpwKsNKf2sJmmieEZCrA X-Proofpoint-ORIG-GUID: x8QRgIsPt2eDyWCFGqJ1XNwxpX88OiAG X-Proofpoint-GUID: x8QRgIsPt2eDyWCFGqJ1XNwxpX88OiAG X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfXwlQWt5hRHH6d 1sawBqx9MS9hTtziPDfboHcThKmRyOtXW69PZ3nXLeExdVTbb2MTN8iI+jR5g4ysz2sP2phey2q h6zJJslEFglv6M08hBIrAKTLuXewA647i8CSB8yuNfbYUwxpuIrb4cQcFMm8QUPea4Ho4F/QcFV rPW7qLXQSrDNVoV08FtPQN8KP2yZc2hqvWYidaO/Fye9dXSBrEYdMfW43wOadm0XnyTTBGSy4+2 6JRA3wdY2gDkxy1eNwalLM1+4tSFvrJwx7hoQIvGMwosqbmzUQWJjVT9D5aHq4ChrnnRoJbq5GE /gQtSApPXZJqkjn7aKu0uQ1HKnUeA/3rH+S8yJvKKnZIYN4w9qaz/+f228u+mraBwUbp7FSQdQ+ nMK+BPZrQb+pDmKsjdJvqsFjxSOE05MXr+Ru0vpW0BKDggl/gwqC/xYCYYrriNyuEKaPBZNnhpR HOPQL5RuE9vk6J5e6Rg== X-Authority-Analysis: v=2.4 cv=baVbluPB c=1 sm=1 tr=0 ts=6a885bfc cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=OmVn7CZJonkx5R5zMQLL:22 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=DyYY1DdFIiypQHwlAEwA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 phishscore=0 spamscore=0 suspectscore=0 impostorscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 The AD7768 provides five GPIOs controlled through registers shared with the parent IIO device. Register an auxiliary gpio-regmap driver and use the parent device for runtime PM. The device has separate input-state and output-latch registers. Add a reg_mask_xlate() callback that checks the line direction and reads the programmed output latch for output lines while retaining input-state reads for input lines. Signed-off-by: Janani Sunil Reviewed-by: Andy Shevchenko Reviewed-by: Linus Walleij --- MAINTAINERS | 1 + drivers/gpio/Kconfig | 12 +++++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-ad7768.c | 118 +++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 132 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index dc94e7803a7c..3de7ebcc4ee7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1639,6 +1639,7 @@ L: linux-iio@vger.kernel.org S: Supported W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad7768.yaml +F: drivers/gpio/gpio-ad7768.c F: drivers/iio/adc/ad7768.c =20 ANALOG DEVICES INC AD7780 DRIVER diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 28cf6d2e83c2..85cb0c82a823 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1796,6 +1796,18 @@ endmenu menu "Auxiliary Bus GPIO drivers" depends on AUXILIARY_BUS =20 +config GPIO_AD7768 + tristate "Analog Devices AD7768 GPIO support" + depends on AD7768 + depends on GPIOLIB + select GPIO_REGMAP + help + Say yes here to expose the AD7768 utility pins as GPIOs when the + device tree node is marked as a GPIO controller. + + To compile this driver as a module, choose M here: the module will be + called gpio-ad7768. + config GPIO_LTC4283 tristate "Analog Devices LTC4283 GPIO support" depends on SENSORS_LTC4283 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 4d0e900402fc..d2921963efc7 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_GPIO_104_IDI_48) +=3D gpio-104-idi-48.o obj-$(CONFIG_GPIO_104_IDIO_16) +=3D gpio-104-idio-16.o obj-$(CONFIG_GPIO_74X164) +=3D gpio-74x164.o obj-$(CONFIG_GPIO_74XX_MMIO) +=3D gpio-74xx-mmio.o +obj-$(CONFIG_GPIO_AD7768) +=3D gpio-ad7768.o obj-$(CONFIG_GPIO_ADNP) +=3D gpio-adnp.o obj-$(CONFIG_GPIO_ADP5520) +=3D gpio-adp5520.o obj-$(CONFIG_GPIO_ADP5585) +=3D gpio-adp5585.o diff --git a/drivers/gpio/gpio-ad7768.c b/drivers/gpio/gpio-ad7768.c new file mode 100644 index 000000000000..710739e33dff --- /dev/null +++ b/drivers/gpio/gpio-ad7768.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Analog Devices AD7768 GPIO auxiliary driver + * + * Copyright 2026 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AD7768_REG_GPIO_CONTROL 0x0E +#define AD7768_GPIO_UGPIO_ENABLE BIT(7) + +#define AD7768_REG_GPIO_WRITE 0x0F +#define AD7768_REG_GPIO_READ 0x10 + +#define AD7768_NUM_GPIOS 5 + +static int ad7768_gpio_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + unsigned long *mask =3D dev_get_platdata(gc->parent); + + bitmap_copy(valid_mask, mask, ngpios); + + return 0; +} + +static int ad7768_gpio_reg_mask_xlate(struct gpio_regmap *gpio, + unsigned int base, unsigned int offset, + unsigned int *reg, unsigned int *mask) +{ + struct regmap *regmap =3D gpio_regmap_get_drvdata(gpio); + int ret; + + *reg =3D base; + *mask =3D BIT(offset); + + if (base !=3D AD7768_REG_GPIO_READ) + return 0; + + /* + * AD7768 has separate input-state and output-latch registers. For an + * output line, report the programmed value from the output latch; + * input lines continue to use the input-state register. + */ + ret =3D regmap_test_bits(regmap, AD7768_REG_GPIO_CONTROL, *mask); + if (ret < 0) + return ret; + if (ret) + *reg =3D AD7768_REG_GPIO_WRITE; + + return 0; +} + +static int ad7768_gpio_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct device *parent =3D adev->dev.parent; + struct gpio_regmap_config config =3D { + .parent =3D &adev->dev, + .label =3D dev_name(parent), + .ngpio =3D AD7768_NUM_GPIOS, + .reg_dat_base =3D AD7768_REG_GPIO_READ, + .reg_set_base =3D AD7768_REG_GPIO_WRITE, + .reg_dir_out_base =3D AD7768_REG_GPIO_CONTROL, + .pm_dev =3D parent, + .reg_mask_xlate =3D ad7768_gpio_reg_mask_xlate, + .init_valid_mask =3D ad7768_gpio_init_valid_mask, + }; + struct gpio_regmap *gpio; + struct regmap *map; + int ret; + + map =3D dev_get_regmap(parent, NULL); + if (!map) + return -ENODEV; + + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(parent, pm); + ret =3D PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + ret =3D regmap_set_bits(map, AD7768_REG_GPIO_CONTROL, AD7768_GPIO_UGPIO_E= NABLE); + if (ret) + return ret; + + config.regmap =3D map; + config.drvdata =3D map; + + gpio =3D devm_gpio_regmap_register(&adev->dev, &config); + return PTR_ERR_OR_ZERO(gpio); +} + +static const struct auxiliary_device_id ad7768_gpio_ids[] =3D { + { .name =3D "ad7768.gpio" }, + { } +}; +MODULE_DEVICE_TABLE(auxiliary, ad7768_gpio_ids); + +static struct auxiliary_driver ad7768_gpio_driver =3D { + .probe =3D ad7768_gpio_probe, + .id_table =3D ad7768_gpio_ids, +}; +module_auxiliary_driver(ad7768_gpio_driver); + +MODULE_AUTHOR("Janani Sunil "); +MODULE_DESCRIPTION("Analog Devices AD7768 GPIO auxiliary driver"); +MODULE_LICENSE("GPL"); --=20 2.43.0 From nobody Mon Sep 28 12:33:38 2026 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 6E5374C9012; Fri, 21 Aug 2026 14:09:15 +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=1787321357; cv=none; b=HalqWWpQCsAQhcT4L69+NtKHRKmpyo6cSiirT1Broz479C+8UoOTVLdjEbQByqetQ4g4hdmYEUxSputGS715sJ7QmS7HTBI5vceeJyynURkpHEB/dQHWO0zJsffvNMw0CCBxHyOjPy1r21CSK9k43vHQgRzi5QXyk6TvYJqu4s4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787321357; c=relaxed/simple; bh=UWjfRpF9pXaGZ5ZOGZnipUeHQFkQthkgUSV1eOik/cA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=NAdZZZQaROfVqAbd0ZEjHgnnW1BpWhKIRgBYsbKaTCK+a07Mncz83cZpv/+Y5yWyrOYB9jTjVUZb7Hvf2llUdgqGoq1NdqUXm0kbGvbWwHv69VoE91mwLrci+VdeFLJ0n5BdUAlbP3oLMdY1hyXgeNPWsbXy9cFXGsiZ2TJXBiI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=pAXRlz42; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="pAXRlz42" Received: from pps.filterd (m0516787.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67LCpcM83388116; Fri, 21 Aug 2026 10:09:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=DGdKt Lv2P/QbCjQmq0w/yz5ydx2HCpxArBzmoGDstjk=; b=pAXRlz42dBzBxEUz6Nwdz NiHCrXIXPl69vYvauTmCqCanse7euLuc284Zz2BrWgYUROm9eBSZF8zqQ0bv43Mb b9FW4t78GiXmMhmjbmzoQbiDRHD/TczDeVjFWKGHKXVxxXHobZMKGYv8wMfKcXe3 DDSKfAP4OzR6jdMl4FRwioHCoj0ntN1JHn+/+QdgTsqevVmmOE7+hZVna5HjfME+ SALcLnPptSoip7WbTqV1KHdKCaFME68iaG9lcgPYe30qXSQTxUrsb0P+960xLluQ xyEwyXVtDQCpHR6ZOnpcaMvqeZ5lJoAuPOcuywdkT9XdlUN1Kgw0zCGaZTeuno8A w== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 4g66m6m0kp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 21 Aug 2026 10:09:06 -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 67LE95Xf033152 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 21 Aug 2026 10:09: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.37; Fri, 21 Aug 2026 10:09:05 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.1748.37 via Frontend Transport; Fri, 21 Aug 2026 10:09:05 -0400 Received: from HYB-e1y2fvUQ3cx.ad.analog.com ([10.32.223.174]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 67LE7Kkx024319; Fri, 21 Aug 2026 10:08:55 -0400 From: Janani Sunil Date: Fri, 21 Aug 2026 16:07:07 +0200 Subject: [PATCH v4 14/14] Documentation: iio: Add AD7768 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: <20260821-ad7768-driver-v4-14-bb8fbd06d4eb@analog.com> References: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> In-Reply-To: <20260821-ad7768-driver-v4-0-bb8fbd06d4eb@analog.com> To: =?utf-8?q?Nuno_S=C3=A1?= , Michael Hennerich , Jonathan Cameron , David Lechner , Andy Shevchenko , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan , Philipp Zabel , Linus Walleij , Bartosz Golaszewski , Jonathan Corbet , Shuah Khan , Michael Walle CC: , , , , , , , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , Janani Sunil X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1787321240; l=10333; i=janani.sunil@analog.com; s=20260507; h=from:subject:message-id; bh=UWjfRpF9pXaGZ5ZOGZnipUeHQFkQthkgUSV1eOik/cA=; b=SnDLuTOK4xlUNsW+sJNFzjHbdpsSHDakMm1Oo7JdsuNAGaW89Id2orweSpkx27Hee5lAPIdkI F2L2fCdtN8oBSagnY5kYZ4MIzp59wXs4Z7TY3A3UQmMY9icxK2KKyCU X-Developer-Key: i=janani.sunil@analog.com; a=ed25519; pk=e25MyjRLPY3RWrYm/LrJ+/+t1MZJUbkgIW5CZg+g+hA= X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-Spam-Info: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX2vdvXazeoaGT 13pAmNfDPIHV5Gvr5ytnYLM9tFPQrS8DicOityka0JhUShSI5dVqErK9BKbQLa7XHNrVVfuPndx t8yapOHjgfte90tLsa6GEj+0FF6LnYbip3jnO6Uf9NGFAOb+fH8d X-Proofpoint-ORIG-GUID: zqLqgun-JFtkTkpM4g1dQILhd1u_NCKI X-Proofpoint-GUID: zqLqgun-JFtkTkpM4g1dQILhd1u_NCKI X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODIxMDEwOSBTYWx0ZWRfX/JRioZMkpgVx BSrin99DSsii0A5x3wzKP+rqH51NyUaU4HyVvFETb3BUNxTaaFb3uo7T+/86dM7A0XsI9RsiUOf 6p/rJwx21gfzzBRLdM2NHJF9jbS0oXU7Y/17I3Tx1WR/Ra4z8bw7Ws8jIqGID0YXARK/JNowIiM qnqjheqVmQj29qFiQSJ+sP3l2rCVOnBACyvTLyMQm0+8LeZVqDvM17siBxlUkOFCGHE6lItXzjE U80+nTupAd7n1qS3f6rFkM7rPaeMiNBpzqJAyaJUtGtJOAAmXVIzcEKc67xGn5j0CMzWxdrdw3w vbgkVwIUCSqLaPWJraXf0fZse+WvLi8eApjR1U4/MPDNI8Uaw3VmL+Tt8orImYl5uGf4xXBxU5z cTA3eKVooJiQnT1tSh1Xtcc6z9Ym/qO0XB+vo6ybaIHQcDtKGyueJa7cqLWdfCAeY9v1vTTgE6Q PS86bSqUMlTRLoFQmWA== X-Authority-Analysis: v=2.4 cv=baVbluPB c=1 sm=1 tr=0 ts=6a885c02 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=0sLvza09kfJOxVLZPwjg:22 a=OmVn7CZJonkx5R5zMQLL:22 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=zZ-fWJg24byqPpz8oLwA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-21_04,2026-08-21_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 adultscore=0 phishscore=0 spamscore=0 suspectscore=0 impostorscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608210109 Add driver documentation for AD7768. Signed-off-by: Janani Sunil --- Documentation/iio/ad7768.rst | 259 +++++++++++++++++++++++++++++++++++++++= ++++ Documentation/iio/index.rst | 1 + MAINTAINERS | 1 + 3 files changed, 261 insertions(+) diff --git a/Documentation/iio/ad7768.rst b/Documentation/iio/ad7768.rst new file mode 100644 index 000000000000..a5d7daf37b7d --- /dev/null +++ b/Documentation/iio/ad7768.rst @@ -0,0 +1,259 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +AD7768 driver +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +ADC driver for Analog Devices Inc. AD7768 and AD7768-4 devices. The module= name +is ``ad7768``. + +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: + +* `AD7768 `_ - + 8-channel, 24-bit simultaneous sampling ADC +* `AD7768-4 `_ - + 4-channel, 24-bit simultaneous sampling ADC + +Supported features +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Clock sources +------------- + +The master clock source is selected using the ``clock-names`` device tree +property: + +* ``mclk`` selects a CMOS clock on XTAL2/MCLK. CLK_SEL must be low and XTA= L1 + must be connected to DGND. +* ``xtal`` selects a crystal connected between XTAL1 and XTAL2. CLK_SEL mu= st + be high. The driver drives FILTER/GPIO4 high and keeps channel 4 on the + AD7768 or channel 2 on the AD7768-4 enabled to maintain crystal excitati= on. +* ``lvds`` selects a differential clock on XTAL1 and XTAL2. CLK_SEL must be + high. The driver drives FILTER/GPIO4 low before enabling the LVDS input. + +GPIO4 is reserved when ``xtal`` or ``lvds`` is selected. + +Power modes +----------- + +The AD7768 family supports three power and performance modes: + +* **Low power mode** - Optimized for lowest power consumption +* **Median mode** - Balanced power and performance +* **Fast mode** - Highest performance with maximum sampling rates + +The driver initializes the device in fast mode and uses the maximum fast-m= ode +output data rate as the default sampling frequency. + +When buffered capture starts, the driver selects the lowest-noise mode tha= t can +produce the requested output data rates for all enabled channels. Where ou= tput +data rates overlap, fast mode is preferred over median mode, and median mo= de is +preferred over low power mode. This prioritizes the lower RMS noise and hi= gher +dynamic range offered by a faster mode at the same output data rate. + +Data output configuration +------------------------- + +The devices support flexible serial data output configurations: + +AD7768 data lines +^^^^^^^^^^^^^^^^^ + +* 1 data line (DOUT0) - Standard single-lane output +* 2 data lines (DOUT0, DOUT1) - Dual-lane output for higher throughput +* 8 data lines (DOUT0-DOUT7) - Maximum throughput, one line per channel + +AD7768-4 data lines +^^^^^^^^^^^^^^^^^^^ + +* 1 data line (DOUT0) - Standard single-lane output +* 4 data lines (DOUT0-DOUT3) - Maximum throughput, one line per channel + +The number of data lines can be configured via the ``adi,data-lines-number= `` +device tree property. If omitted, the driver uses the maximum supported by= the +selected variant: eight lines for AD7768 and four lines for AD7768-4. + +Channel configuration +--------------------- + +Each channel can be individually configured with: + +Channel modes +^^^^^^^^^^^^^ + +* **Mode A** - First set of filter and decimation settings +* **Mode B** - Second set of filter and decimation settings + +The hardware provides two mode profiles (A and B), each holding one +(frequency, filter) combination. When buffered capture is started, +enabled channels are grouped by their configured (frequency, filter) +pair. Up to two distinct groups are supported; the driver automatically +assigns each group to a mode slot and programs the hardware accordingly. + +Precharge and reference buffers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Per-channel buffer control for optimal signal integrity: + +* Positive input precharge buffer (``adi,prechargebuf-pos-enable``) +* Negative input precharge buffer (``adi,prechargebuf-neg-enable``) +* Positive reference buffer (``adi,refbuf-pos-enable``) +* Negative reference buffer (``adi,refbuf-neg-enable``) + +Common mode voltage +------------------- + +The VCM pin provides a buffered common-mode voltage output used to bias +the analog inputs. The driver exposes this as a standard voltage regulator +provider under a ``regulators`` subnode in the device tree. Supported +output voltage levels are: + +* (AVDD1 - AVSS) / 2 - Mid-supply (hardware default), reported as half the + voltage provided by ``avdd1-supply`` +* 1,650,000 =C2=B5V - 1.65V +* 2,500,000 =C2=B5V - 2.5V +* 2,140,000 =C2=B5V - 2.14V + +The regulator can be enabled and disabled at runtime using the standard +regulator framework interfaces. + +The VCM circuitry is associated with channel 0. When VCM is used externall= y, +``channel@0`` must be present in the device tree and channel 0 must remain +enabled in the active scan mask. Placing channel 0 in standby disables the= VCM +output. + +Filter types +------------ + +Two digital filter types are available: + +* **Wideband** - Optimized for wide bandwidth applications +* **Sinc5** - Fifth-order sinc filter for high rejection of out-of-band no= ise + +IIO backend support +------------------- + +The driver integrates with IIO backends (e.g., AXI ADC) for high-speed data +capture and DMA operations. Features include: + +* Automatic channel enable/disable based on scan mask +* CRC on data interface. CRC replaces the header every 4th output sample. +* High-throughput buffered data acquisition + +GPIO controller +--------------- + +The AD7768 includes a 5-pin GPIO controller for auxiliary digital I/O +operations. The GPIO pins can be configured as inputs or outputs. + +GPIO4 is reserved when a crystal or LVDS master clock is used. GPIO0 throu= gh +GPIO3 remain available in these configurations. + +Device attributes +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The following IIO attributes are available for each enabled channel: + +Sampling frequency +------------------ + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Attribute + - Description + * - ``in_voltage_sampling_frequency`` + - Requested sampling frequency in Hz for channel N. Enabled channels = are + grouped into up to two profiles at capture time. + * - ``in_voltage_sampling_frequency_available`` + - Available sampling frequencies in Hz for channel N across all power + modes, based on the master clock frequency. Buffer setup fails if no + single power mode supports the frequencies requested by all enabled + channels. + +Filter configuration +--------------------- + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Attribute + - Description + * - ``in_voltage_filter_type`` + - Requested filter type for channel N: "wideband" or "sinc5". It is + grouped with sampling frequency at capture time. + * - ``in_voltage_filter_type_available`` + - Available filter types for channel N: "wideband sinc5". + +Per-channel calibration +----------------------- + +.. list-table:: + :header-rows: 1 + :widths: 40 60 + + * - Attribute + - Description + * - ``in_voltage_calibbias`` + - Raw unsigned 24-bit channel offset register value. + * - ``in_voltage_calibscale`` + - Raw unsigned 24-bit channel gain register value. + * - ``in_voltage_convdelay`` + - Per-channel conversion delay. The driver exposes the sync phase off= set + value in seconds with picosecond precision. Resolution and valid ra= nge + depend on the decimation ratio in use (see datasheet + Table 32). + +Device buffers +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +This driver supports IIO buffered data acquisition through IIO backends. +When used with compatible backends like the AXI ADC, it provides: + +* High-speed simultaneous sampling across all enabled channels +* Hardware-driven data capture +* DMA-based data transfer for minimal CPU overhead +* CRC error detection + +See :doc:`iio_devbuf` for more information about IIO device buffers. + +Example usage +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +.. code-block:: bash + + # Read current sampling frequency for channel 0 + cat /sys/bus/iio/devices/iio:device0/in_voltage0_sampling_frequency + + # Update sampling frequency for channel 0 + echo 8000 > /sys/bus/iio/devices/iio:device0/in_voltage0_sampling_frequen= cy + + # Read current filter type for channel 0 + cat /sys/bus/iio/devices/iio:device0/in_voltage0_filter_type + + # List available filter types for channel 0 + cat /sys/bus/iio/devices/iio:device0/in_voltage0_filter_type_available + + # Update filter type for channel 0 to wideband + echo wideband > /sys/bus/iio/devices/iio:device0/in_voltage0_filter_type + + # Buffer setup fails if enabled channels request more than two distinct + # (sampling frequency, filter type) combinations. + + # Read calibration scale for channel 0 + cat /sys/bus/iio/devices/iio:device0/in_voltage0_calibscale + + # Read conversion delay for channel 0 + cat /sys/bus/iio/devices/iio:device0/in_voltage0_convdelay + + +Unimplemented features +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +* CRC message every 16 samples (CRC_SEL configuration) - currently only + supports CRC every 4 samples diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index b02b879b053a..73c58cec7620 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -29,6 +29,7 @@ Industrial I/O Kernel Drivers ad7380 ad7606 ad7625 + ad7768 ad7944 ade9000 adf41513 diff --git a/MAINTAINERS b/MAINTAINERS index 3de7ebcc4ee7..b93c77d3a4c3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1639,6 +1639,7 @@ L: linux-iio@vger.kernel.org S: Supported W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad7768.yaml +F: Documentation/iio/ad7768.rst F: drivers/gpio/gpio-ad7768.c F: drivers/iio/adc/ad7768.c =20 --=20 2.43.0