From nobody Wed Dec 17 23:27:15 2025 Received: from mail-lj1-f179.google.com (mail-lj1-f179.google.com [209.85.208.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF28912F36F for ; Wed, 1 May 2024 14:55:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575353; cv=none; b=aw/DsvYAXqzM9w4Lp05K40sjKAGxbAbuMwxc537Xc89EywXcurGPaQ2xqAyVoMgx6ElTcSTNXDRjulz4FLDpS694J8Hl0k2tCa7GuK1Kw2ia13GSk/h6JSMvWpxF/ET9Y8aK1wChL3AoZKrcny1CxLZgpMIFZgDlaBPt3BoD424= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575353; c=relaxed/simple; bh=IDhrjIJtC1G3o2fCZqsHvxz7NEDrI0F5jKU0EEQs398=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SZACBklns6WIKrHnG1O1+wPinNAhjuDUoyOIm7ly/EqLdIbNjOqn+zVoMgmiiehNuLj+E4ulNSqboQ9SrGoCu3GzRZcXfpcD7Okyjb0owXs2f/aQkupLpxh3v5B45Wpq1kuZ8dqzCLmZEh/qmYIpc+zQauGlmml2re1NErMW+bY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=HZWK5idm; arc=none smtp.client-ip=209.85.208.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="HZWK5idm" Received: by mail-lj1-f179.google.com with SMTP id 38308e7fff4ca-2dfb4ea2bbfso53046981fa.2 for ; Wed, 01 May 2024 07:55:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714575349; x=1715180149; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Fhz/hQk8RD1tt0hu/cR4amFoB9mWCchFbN+TxPow/AQ=; b=HZWK5idmP6QILE3q3N3KEcFMgKf6S+NSTqRhw5tSLPSieMEYngUugUXemk6LlhS8Wg hQSkXexZpa8QZiDpL8c0M0QFL7rncNPbbQCmtZQQUq0ou1Lm+e0NrVwVHmgawXzBCWyI hgFNVHVva4xsacW+JUqAtmDKxzAR0EtdTXx83v5ct9TxbEJ5piXUTfNYLlYbeCAV5qn1 OlfD/GT79UAZ9AUBZnNfxahAzN+YaDIFDDUF4e1Zzf6bzzLz3TrNijo+PO1qqxkoHpXD pnSCKiL9/JJ1IAGekKlcwv25fqE19dDWd6GACM6jRN+IYoFydQgUcfZt2GspX20kuS/6 7pFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714575349; x=1715180149; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Fhz/hQk8RD1tt0hu/cR4amFoB9mWCchFbN+TxPow/AQ=; b=W/iTxLEvZ5f8gJSGgqeg14Gl0MdrNNyQx5sA3qsfhCnJ8iigf8iyccc5GTBiY/9I4/ Gb2Stu4Dwnz4So/BU2OLYddwrt4LqUKMqAtKd4g9lydAR+iu2CmSKRAkyECXsMko2asc AMVXPTBPVhADFmU7q5GvXEsBYvIUnzKLOv83qD78UwRp9hF+2p24D3SpLl8chhWCNsDi va/cmNv9+7gvO7ckp5dLD3jq0qH4HX/pc4BJ3B/OsjvyYLzr2jKqkKYulFVL4h7oeJzL jb7h5MV9c3yxgsnHf3g5thDKtuSGoWd7SoRmC2XsyLGq8gG34yANBYyvap48yOQFsMXe kgRw== X-Forwarded-Encrypted: i=1; AJvYcCV1QbyEco5HRufNCkpmgnb6SLNVr+nyk2NjQV+k4L8g9x/xuWlJrr8r2fjrK2bbCrnBX8OzhILPrSOPy2DfRRS4OIccvYj75O/mqrJJ X-Gm-Message-State: AOJu0Yzb/onx5p5nvKCCgs8WzIYZgxpLnHlypuGeDawwzflCvFBURbh7 WgYOWUnM6jeaPNLJrXoqf2zhzzKefwwDn1RFzL0F5W63eAK3qfAYUGaGI43VHRA= X-Google-Smtp-Source: AGHT+IExWbzFu/y+P/BHymNniS1NWoawv6PjReU8jo15sbOyMVB1Zznn6zp0RVZFa5o0QkTLX+GZDA== X-Received: by 2002:a05:651c:222:b0:2d8:930c:bbfa with SMTP id z2-20020a05651c022200b002d8930cbbfamr1798566ljn.5.1714575348754; Wed, 01 May 2024 07:55:48 -0700 (PDT) Received: from [192.168.1.61] ([2a02:842a:d52e:6101:6fd0:6c4:5d68:f0a5]) by smtp.gmail.com with ESMTPSA id o27-20020a05600c511b00b00418a386c17bsm2422999wms.12.2024.05.01.07.55.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 07:55:48 -0700 (PDT) From: Julien Stephan Date: Wed, 01 May 2024 16:55:34 +0200 Subject: [PATCH RFC v6 01/10] dt-bindings: iio: adc: Add binding for AD7380 ADCs 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: <20240501-adding-new-ad738x-driver-v6-1-3c0741154728@baylibre.com> References: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> In-Reply-To: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Liam Girdwood , Mark Brown Cc: kernel test robot , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Stephan , Conor Dooley X-Mailer: b4 0.13.0 From: David Lechner This adds a binding specification for the Analog Devices Inc. AD7380 family of ADCs. Signed-off-by: David Lechner Signed-off-by: Julien Stephan Reviewed-by: Conor Dooley --- .../devicetree/bindings/iio/adc/adi,ad7380.yaml | 82 ++++++++++++++++++= ++++ MAINTAINERS | 9 +++ 2 files changed, 91 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml b/Do= cumentation/devicetree/bindings/iio/adc/adi,ad7380.yaml new file mode 100644 index 000000000000..5e1ee0ebe0a2 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml @@ -0,0 +1,82 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad7380.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices Simultaneous Sampling Analog to Digital Converters + +maintainers: + - Michael Hennerich + - Nuno S=C3=A1 + +description: | + * https://www.analog.com/en/products/ad7380.html + * https://www.analog.com/en/products/ad7381.html + +$ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + enum: + - adi,ad7380 + - adi,ad7381 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 80000000 + spi-cpol: true + spi-cpha: true + + vcc-supply: + description: A 3V to 3.6V supply that powers the chip. + + vlogic-supply: + description: + A 1.65V to 3.6V supply for the logic pins. + + refio-supply: + description: + A 2.5V to 3.3V supply for the external reference voltage. When omitt= ed, + the internal 2.5V reference is used. + + interrupts: + description: + When the device is using 1-wire mode, this property is used to optio= nally + specify the ALERT interrupt. + maxItems: 1 + +required: + - compatible + - reg + - vcc-supply + - vlogic-supply + +unevaluatedProperties: false + +examples: + - | + #include + + spi { + #address-cells =3D <1>; + #size-cells =3D <0>; + + adc@0 { + compatible =3D "adi,ad7380"; + reg =3D <0>; + + spi-cpol; + spi-cpha; + spi-max-frequency =3D <80000000>; + + interrupts =3D <27 IRQ_TYPE_EDGE_FALLING>; + interrupt-parent =3D <&gpio0>; + + vcc-supply =3D <&supply_3_3V>; + vlogic-supply =3D <&supply_3_3V>; + refio-supply =3D <&supply_2_5V>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 8ad79cf70552..5bb168937853 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -427,6 +427,15 @@ W: http://wiki.analog.com/AD7142 W: https://ez.analog.com/linux-software-drivers F: drivers/input/misc/ad714x.c =20 +AD738X ADC DRIVER (AD7380/1/2/4) +M: Michael Hennerich +M: Nuno S=C3=A1 +R: David Lechner +S: Supported +W: https://wiki.analog.com/resources/tools-software/linux-drivers/iio-adc/= ad738x +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml + AD7877 TOUCHSCREEN DRIVER M: Michael Hennerich S: Supported --=20 2.44.0 From nobody Wed Dec 17 23:27:15 2025 Received: from mail-lj1-f179.google.com (mail-lj1-f179.google.com [209.85.208.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4D42912DD93 for ; Wed, 1 May 2024 14:55:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575355; cv=none; b=AAecJYFw3qB/e42OaSZWKdCVg3KEzsvxrKmDuY+jzC578r/LolScXVj6+CNhDQJL1Y7mSpiRiZ0RGmRXS9G+UaIi1rZsbh8iEBJBIXsrGAX454BZ34khukpYVpkw2nyEXqwp5fPIZkDrwK1VpT3EZ/jioDK02mwLijibNNfY7aE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575355; c=relaxed/simple; bh=MBENGPPqyNcE3f0Eq4rYojKREBiI6HECbglfQTnhvc8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oMcYT725HN3hLuv6QuTnHOfJYvcphYoem0huKkvilNIH+54E4y7r19p8RF60B8WDVa8rvKFGlzvUbFeUQlCCFDzxd5Lrwnw38bqY2tvbAxDYn3llqjEf9Tj5eETf+rrC19eDgnHSy6x3qAGYssJgKC/5Z8a853EboSol9pDHMQQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=m8r06lJ1; arc=none smtp.client-ip=209.85.208.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="m8r06lJ1" Received: by mail-lj1-f179.google.com with SMTP id 38308e7fff4ca-2db6f5977e1so80711051fa.2 for ; Wed, 01 May 2024 07:55:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714575351; x=1715180151; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=SqLntdBdXYRYi9ks5TlMm8Ua5AzpqigLpD/dxKZjzhw=; b=m8r06lJ1Pdwirv47bz5DXUdVlZIJXpUDCxe+JN5JPcbRTIOhsGJyZe/UYWp30oHBII /mj2VkMxzbYHy72WojL0GlrZ1N7iX0P6hB7Vfms/Uln4oVbXyuEAXlcVkIfViQp7f03f KCgXgD/zC4XSQ3fvCbGYLxFeLRgACOoGL4zXnQZ/jv3AK/8fsxSexfrXaeqmgBdqJ7NM yVTopOsq6+TagqYknckuviDXyoOSI7D9NuTii20K3RTY2o9JcWEZANWcxs8z3EHoiLMv h/bxKgNhvwcsl+KitTliUJcFd/QFBRxggn38738Di3xAF8rb9WUngzHplXWHGhl8Zfcx Us6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714575351; x=1715180151; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SqLntdBdXYRYi9ks5TlMm8Ua5AzpqigLpD/dxKZjzhw=; b=pFoTUIk/kCe83gR8/N1qgIwqDR821cjI2vPztWxemgIlAJj/DBj6tCFM5LsRftAlpF /hAiZIGbCbchaUkhOIWgGe4RHaeScjtEandwU752K78Tk/bTdHEw9r12j0cUaf0I3qSP ko1AXxdivdFMUII4XpBNdtSOypfiNfhkV6yNkhjcSlcMuen2LfXpK7th8NBtuIQ/n9Jy POAChp7SxQfZVvIWjHgMQu/28+eI8dboFjYZ4TGDZYYQyGeS7BPQMrEB3u+mx0228RRh RgvBwbG+Ns3aKRMSUmO2XHlEU2sBPGEb87tCYbt9uPYtR2iavareqdawjd0DYLewFn4r iEGQ== X-Forwarded-Encrypted: i=1; AJvYcCUjsFEEEzInTp1b0pK2EjNShnOIh2Q48q5Sh+LRw4QGlI6kRyt3we0JfNj4nz9zywiQUqFTHT3+n5naM6ckWJfb4iaZb0BebODJGuT9 X-Gm-Message-State: AOJu0YxulTTA+nECUYnpRE25RIJEPW45SkN1RUCyziIj0YWnXhFON+l3 btDiaDyjD27QD+syD0sVu5wYgGUO4CmKBiPAuc1YrxhZH01bbAUVx1LzWamMCpM= X-Google-Smtp-Source: AGHT+IE6UO6JMlz9VaZ800sjdNTf6JrX3yjaN+lK78tNrDPOCk5/mp2t3euxDsuNDdBChbGeER9y1Q== X-Received: by 2002:a2e:a7c5:0:b0:2de:7046:b8f8 with SMTP id x5-20020a2ea7c5000000b002de7046b8f8mr2195990ljp.5.1714575349559; Wed, 01 May 2024 07:55:49 -0700 (PDT) Received: from [192.168.1.61] ([2a02:842a:d52e:6101:6fd0:6c4:5d68:f0a5]) by smtp.gmail.com with ESMTPSA id o27-20020a05600c511b00b00418a386c17bsm2422999wms.12.2024.05.01.07.55.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 07:55:49 -0700 (PDT) From: Julien Stephan Date: Wed, 01 May 2024 16:55:35 +0200 Subject: [PATCH RFC v6 02/10] iio: adc: ad7380: new driver for AD7380 ADCs 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: <20240501-adding-new-ad738x-driver-v6-2-3c0741154728@baylibre.com> References: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> In-Reply-To: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Liam Girdwood , Mark Brown Cc: kernel test robot , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Stephan , Stefan Popa X-Mailer: b4 0.13.0 From: David Lechner This adds a new driver for the AD7380 family ADCs. The driver currently implements basic support for the AD7380, AD7381, 2-channel differential ADCs. Support for additional single-ended, pseudo-differential and 4-channel chips that use the same register map as well as additional features of the chip will be added in future patches. Co-developed-by: Stefan Popa Signed-off-by: Stefan Popa Reviewed-by: Nuno Sa Signed-off-by: David Lechner [Julien Stephan: add datasheet links of supported parts] [Julien Stephan: fix rx/tx buffer for regmap access] [Julien Stephan: fix scale issue] [Julien Stephan: use the new iio_device_claim_direct_scoped instead of iio_device_claim_direct_mode] Signed-off-by: Julien Stephan --- MAINTAINERS | 1 + drivers/iio/adc/Kconfig | 16 ++ drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad7380.c | 443 +++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 461 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 5bb168937853..87724a9e9f9f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -435,6 +435,7 @@ S: Supported W: https://wiki.analog.com/resources/tools-software/linux-drivers/iio-adc/= ad738x W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml +F: drivers/iio/adc/ad7380.c =20 AD7877 TOUCHSCREEN DRIVER M: Michael Hennerich diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 8db68b80b391..631386b037ae 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -155,6 +155,22 @@ config AD7298 To compile this driver as a module, choose M here: the module will be called ad7298. =20 +config AD7380 + tristate "Analog Devices AD7380 ADC driver" + depends on SPI_MASTER + select IIO_BUFFER + select IIO_TRIGGER + select IIO_TRIGGERED_BUFFER + help + AD7380 is a family of simultaneous sampling ADCs that share the same + SPI register map and have similar pinouts. + + Say yes here to build support for Analog Devices AD7380 ADC and + similar chips. + + To compile this driver as a module, choose M here: the module will be + called ad7380. + config AD7476 tristate "Analog Devices AD7476 1-channel ADCs driver and other similar d= evices from AD and TI" depends on SPI diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index edb32ce2af02..bd3cbbb178fa 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_AD7291) +=3D ad7291.o obj-$(CONFIG_AD7292) +=3D ad7292.o obj-$(CONFIG_AD7298) +=3D ad7298.o obj-$(CONFIG_AD7923) +=3D ad7923.o +obj-$(CONFIG_AD7380) +=3D ad7380.o obj-$(CONFIG_AD7476) +=3D ad7476.o obj-$(CONFIG_AD7606_IFACE_PARALLEL) +=3D ad7606_par.o obj-$(CONFIG_AD7606_IFACE_SPI) +=3D ad7606_spi.o diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c new file mode 100644 index 000000000000..a218f59c276e --- /dev/null +++ b/drivers/iio/adc/ad7380.c @@ -0,0 +1,443 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Analog Devices AD738x Simultaneous Sampling SAR ADCs + * + * Copyright 2017 Analog Devices Inc. + * Copyright 2024 BayLibre, SAS + * + * Datasheets of supported parts: + * ad7380/1 : https://www.analog.com/media/en/technical-documentation/data= -sheets/AD7380-7381.pdf + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* 2.5V internal reference voltage */ +#define AD7380_INTERNAL_REF_MV 2500 + +/* reading and writing registers is more reliable at lower than max speed = */ +#define AD7380_REG_WR_SPEED_HZ 10000000 + +#define AD7380_REG_WR BIT(15) +#define AD7380_REG_REGADDR GENMASK(14, 12) +#define AD7380_REG_DATA GENMASK(11, 0) + +#define AD7380_REG_ADDR_NOP 0x0 +#define AD7380_REG_ADDR_CONFIG1 0x1 +#define AD7380_REG_ADDR_CONFIG2 0x2 +#define AD7380_REG_ADDR_ALERT 0x3 +#define AD7380_REG_ADDR_ALERT_LOW_TH 0x4 +#define AD7380_REG_ADDR_ALERT_HIGH_TH 0x5 + +#define AD7380_CONFIG1_OS_MODE BIT(9) +#define AD7380_CONFIG1_OSR GENMASK(8, 6) +#define AD7380_CONFIG1_CRC_W BIT(5) +#define AD7380_CONFIG1_CRC_R BIT(4) +#define AD7380_CONFIG1_ALERTEN BIT(3) +#define AD7380_CONFIG1_RES BIT(2) +#define AD7380_CONFIG1_REFSEL BIT(1) +#define AD7380_CONFIG1_PMODE BIT(0) + +#define AD7380_CONFIG2_SDO2 GENMASK(9, 8) +#define AD7380_CONFIG2_SDO BIT(8) +#define AD7380_CONFIG2_RESET GENMASK(7, 0) + +#define AD7380_CONFIG2_RESET_SOFT 0x3C +#define AD7380_CONFIG2_RESET_HARD 0xFF + +#define AD7380_ALERT_LOW_TH GENMASK(11, 0) +#define AD7380_ALERT_HIGH_TH GENMASK(11, 0) + +struct ad7380_chip_info { + const char *name; + const struct iio_chan_spec *channels; + unsigned int num_channels; +}; + +#define AD7380_CHANNEL(index, bits) { \ + .type =3D IIO_VOLTAGE, \ + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE), \ + .indexed =3D 1, \ + .differential =3D 1, \ + .channel =3D 2 * (index), \ + .channel2 =3D 2 * (index) + 1, \ + .scan_index =3D (index), \ + .scan_type =3D { \ + .sign =3D 's', \ + .realbits =3D (bits), \ + .storagebits =3D 16, \ + .endianness =3D IIO_CPU, \ + }, \ +} + +#define DEFINE_AD7380_2_CHANNEL(name, bits) \ +static const struct iio_chan_spec name[] =3D { \ + AD7380_CHANNEL(0, bits), \ + AD7380_CHANNEL(1, bits), \ + IIO_CHAN_SOFT_TIMESTAMP(2), \ +} + +DEFINE_AD7380_2_CHANNEL(ad7380_channels, 16); +DEFINE_AD7380_2_CHANNEL(ad7381_channels, 14); + +/* Since this is simultaneous sampling, we don't allow individual channels= . */ +static const unsigned long ad7380_2_channel_scan_masks[] =3D { + GENMASK(1, 0), + 0 +}; + +static const struct ad7380_chip_info ad7380_chip_info =3D { + .name =3D "ad7380", + .channels =3D ad7380_channels, + .num_channels =3D ARRAY_SIZE(ad7380_channels), +}; + +static const struct ad7380_chip_info ad7381_chip_info =3D { + .name =3D "ad7381", + .channels =3D ad7381_channels, + .num_channels =3D ARRAY_SIZE(ad7381_channels), +}; + +struct ad7380_state { + const struct ad7380_chip_info *chip_info; + struct spi_device *spi; + struct regmap *regmap; + unsigned int vref_mv; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + * Make the buffer large enough for 2 16-bit samples and one 64-bit + * aligned 64 bit timestamp. + */ + struct { + u16 raw[2]; + + s64 ts __aligned(8); + } scan_data __aligned(IIO_DMA_MINALIGN); + u16 tx; + u16 rx; +}; + +static int ad7380_regmap_reg_write(void *context, unsigned int reg, + unsigned int val) +{ + struct ad7380_state *st =3D context; + struct spi_transfer xfer =3D { + .speed_hz =3D AD7380_REG_WR_SPEED_HZ, + .bits_per_word =3D 16, + .len =3D 2, + .tx_buf =3D &st->tx, + }; + + st->tx =3D FIELD_PREP(AD7380_REG_WR, 1) | + FIELD_PREP(AD7380_REG_REGADDR, reg) | + FIELD_PREP(AD7380_REG_DATA, val); + + return spi_sync_transfer(st->spi, &xfer, 1); +} + +static int ad7380_regmap_reg_read(void *context, unsigned int reg, + unsigned int *val) +{ + struct ad7380_state *st =3D context; + struct spi_transfer xfers[] =3D { + { + .speed_hz =3D AD7380_REG_WR_SPEED_HZ, + .bits_per_word =3D 16, + .len =3D 2, + .tx_buf =3D &st->tx, + .cs_change =3D 1, + .cs_change_delay =3D { + .value =3D 10, /* t[CSH] */ + .unit =3D SPI_DELAY_UNIT_NSECS, + }, + }, { + .speed_hz =3D AD7380_REG_WR_SPEED_HZ, + .bits_per_word =3D 16, + .len =3D 2, + .rx_buf =3D &st->rx, + }, + }; + int ret; + + st->tx =3D FIELD_PREP(AD7380_REG_WR, 0) | + FIELD_PREP(AD7380_REG_REGADDR, reg) | + FIELD_PREP(AD7380_REG_DATA, 0); + + ret =3D spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); + if (ret < 0) + return ret; + + *val =3D FIELD_GET(AD7380_REG_DATA, st->rx); + + return 0; +} + +static const struct regmap_config ad7380_regmap_config =3D { + .reg_bits =3D 3, + .val_bits =3D 12, + .reg_read =3D ad7380_regmap_reg_read, + .reg_write =3D ad7380_regmap_reg_write, + .max_register =3D AD7380_REG_ADDR_ALERT_HIGH_TH, + .can_sleep =3D true, +}; + +static int ad7380_debugfs_reg_access(struct iio_dev *indio_dev, u32 reg, + u32 writeval, u32 *readval) +{ + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + struct ad7380_state *st =3D iio_priv(indio_dev); + int ret; + + if (readval) + ret =3D regmap_read(st->regmap, reg, readval); + else + ret =3D regmap_write(st->regmap, reg, writeval); + + return ret; + } + unreachable(); +} + +static irqreturn_t ad7380_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf =3D p; + struct iio_dev *indio_dev =3D pf->indio_dev; + struct ad7380_state *st =3D iio_priv(indio_dev); + struct spi_transfer xfer =3D { + .bits_per_word =3D st->chip_info->channels[0].scan_type.realbits, + .len =3D 4, + .rx_buf =3D st->scan_data.raw, + }; + int ret; + + ret =3D spi_sync_transfer(st->spi, &xfer, 1); + if (ret) + goto out; + + iio_push_to_buffers_with_timestamp(indio_dev, &st->scan_data, + pf->timestamp); + +out: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int ad7380_read_direct(struct ad7380_state *st, + struct iio_chan_spec const *chan, int *val) +{ + struct spi_transfer xfers[] =3D { + /* toggle CS (no data xfer) to trigger a conversion */ + { + .speed_hz =3D AD7380_REG_WR_SPEED_HZ, + .bits_per_word =3D chan->scan_type.realbits, + .delay =3D { + .value =3D 190, /* t[CONVERT] */ + .unit =3D SPI_DELAY_UNIT_NSECS, + }, + .cs_change =3D 1, + .cs_change_delay =3D { + .value =3D 10, /* t[CSH] */ + .unit =3D SPI_DELAY_UNIT_NSECS, + }, + }, + /* then read both channels */ + { + .speed_hz =3D AD7380_REG_WR_SPEED_HZ, + .bits_per_word =3D chan->scan_type.realbits, + .rx_buf =3D st->scan_data.raw, + .len =3D 4, + }, + }; + int ret; + + ret =3D spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); + if (ret < 0) + return ret; + + *val =3D sign_extend32(st->scan_data.raw[chan->scan_index], + chan->scan_type.realbits - 1); + + return IIO_VAL_INT; +} + +static int ad7380_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct ad7380_state *st =3D iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_RAW: + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + return ad7380_read_direct(st, chan, val); + } + unreachable(); + case IIO_CHAN_INFO_SCALE: + /* + * According to the datasheet, the LSB size for fully differential ADC is + * (2 =C3=97 VREF) / 2^N, where N is the ADC resolution (i.e realbits) + */ + *val =3D st->vref_mv; + *val2 =3D chan->scan_type.realbits - 1; + + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; + } +} + +static const struct iio_info ad7380_info =3D { + .read_raw =3D &ad7380_read_raw, + .debugfs_reg_access =3D &ad7380_debugfs_reg_access, +}; + +static int ad7380_init(struct ad7380_state *st, struct regulator *vref) +{ + int ret; + + /* perform hard reset */ + ret =3D regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2, + AD7380_CONFIG2_RESET, + FIELD_PREP(AD7380_CONFIG2_RESET, + AD7380_CONFIG2_RESET_HARD)); + if (ret < 0) + return ret; + + /* select internal or external reference voltage */ + ret =3D regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, + AD7380_CONFIG1_REFSEL, + FIELD_PREP(AD7380_CONFIG1_REFSEL, + vref ? 1 : 0)); + if (ret < 0) + return ret; + + /* SPI 1-wire mode */ + return regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2, + AD7380_CONFIG2_SDO, + FIELD_PREP(AD7380_CONFIG2_SDO, 1)); +} + +static void ad7380_regulator_disable(void *p) +{ + regulator_disable(p); +} + +static int ad7380_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct ad7380_state *st; + struct regulator *vref; + int ret; + + indio_dev =3D devm_iio_device_alloc(&spi->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st =3D iio_priv(indio_dev); + st->spi =3D spi; + st->chip_info =3D spi_get_device_match_data(spi); + if (!st->chip_info) + return dev_err_probe(&spi->dev, -EINVAL, "missing match data\n"); + + vref =3D devm_regulator_get_optional(&spi->dev, "refio"); + if (IS_ERR(vref)) { + if (PTR_ERR(vref) !=3D -ENODEV) + return dev_err_probe(&spi->dev, PTR_ERR(vref), + "Failed to get refio regulator\n"); + + vref =3D NULL; + } + + /* + * If there is no REFIO supply, then it means that we are using + * the internal 2.5V reference, otherwise REFIO is reference voltage. + */ + if (vref) { + ret =3D regulator_enable(vref); + if (ret) + return ret; + + ret =3D devm_add_action_or_reset(&spi->dev, + ad7380_regulator_disable, vref); + if (ret) + return ret; + + ret =3D regulator_get_voltage(vref); + if (ret < 0) + return ret; + + st->vref_mv =3D ret / 1000; + } else { + st->vref_mv =3D AD7380_INTERNAL_REF_MV; + } + + st->regmap =3D devm_regmap_init(&spi->dev, NULL, st, &ad7380_regmap_confi= g); + if (IS_ERR(st->regmap)) + return dev_err_probe(&spi->dev, PTR_ERR(st->regmap), + "failed to allocate register map\n"); + + indio_dev->channels =3D st->chip_info->channels; + indio_dev->num_channels =3D st->chip_info->num_channels; + indio_dev->name =3D st->chip_info->name; + indio_dev->info =3D &ad7380_info; + indio_dev->modes =3D INDIO_DIRECT_MODE; + indio_dev->available_scan_masks =3D ad7380_2_channel_scan_masks; + + ret =3D devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, + iio_pollfunc_store_time, + ad7380_trigger_handler, NULL); + if (ret) + return ret; + + ret =3D ad7380_init(st, vref); + if (ret) + return ret; + + return devm_iio_device_register(&spi->dev, indio_dev); +} + +static const struct of_device_id ad7380_of_match_table[] =3D { + { .compatible =3D "adi,ad7380", .data =3D &ad7380_chip_info }, + { .compatible =3D "adi,ad7381", .data =3D &ad7381_chip_info }, + { } +}; + +static const struct spi_device_id ad7380_id_table[] =3D { + { "ad7380", (kernel_ulong_t)&ad7380_chip_info }, + { "ad7381", (kernel_ulong_t)&ad7381_chip_info }, + { } +}; +MODULE_DEVICE_TABLE(spi, ad7380_id_table); + +static struct spi_driver ad7380_driver =3D { + .driver =3D { + .name =3D "ad7380", + .of_match_table =3D ad7380_of_match_table, + }, + .probe =3D ad7380_probe, + .id_table =3D ad7380_id_table, +}; +module_spi_driver(ad7380_driver); + +MODULE_AUTHOR("Stefan Popa "); +MODULE_DESCRIPTION("Analog Devices AD738x ADC driver"); +MODULE_LICENSE("GPL"); --=20 2.44.0 From nobody Wed Dec 17 23:27:15 2025 Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B4D4512F588 for ; Wed, 1 May 2024 14:55:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575355; cv=none; b=jdFf+yHm6eO6dpi4ikv/O4/T9aUOnNbqRU1y1OXSl2G7fY8VryyKdoGqSWXChmyVdTbcN8885MelhEE5eRyW65602PZ6wMJGMrZmMi+0RjN7lUuL99agWDAIDT1lWKgvnL1HeWXaexZyYtdNoU2jTdgGSq2XVLbv8SzAv7wqVqI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575355; c=relaxed/simple; bh=OB8tgBWPkNRhkYwIg+R2Ji0Wb3SGKEyVa27sOqMTYcs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Yb2RFVmtHk+oR+z454CMXgtkQ14Bg320gQI/FJKVz5z/oNBSCGKxuUvbvmEjnHN3P5VmRYacd7kvL/j29Nncvm1WyXmd/9ka4HtP7xa0PZemSEKRWbLoK2Jp9zHj/tylzCgQ7xV2VkizAu0aE3EruSjmwtLP8LTYjuVdL8oC8f0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=Ihh5VOAF; arc=none smtp.client-ip=209.85.221.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="Ihh5VOAF" Received: by mail-wr1-f42.google.com with SMTP id ffacd0b85a97d-34dc9065606so384991f8f.1 for ; Wed, 01 May 2024 07:55:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714575352; x=1715180152; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=kJ8CU1KsZdsOI/zOnwTeILM7ZuUE9hyEpMnwtAluPZE=; b=Ihh5VOAF5kqM+khFfNVYVVEgLvdamwx3Rx+OxH6lfnPkr7UyIN8KTqfLhn2LDuHj+X H3NK7Xd1xKAC8uei6tASU3u40u/FOqIVRSm9AFAbhu0Iuqcd8dNeyJXVnuIIYv4IMzgI T6ZXiHbvlAkwr6+f84ODRkH9F30WAucHK09QlEv5E2EqUs+fpSll9/N99RK5gt+8hc+i mQJas8mxfCfCzKzviAbThhJA63v4GbT1vsu1SCae7fc/QpN4FgYe2eq1e9Rqk6GJAt2P gcs7E6PEeXljlbkmrAaLQXzcH4oCnTHQV0h7rKYs1sEDM/S8x8rc+GLvwzfnyY9t1D6z BJeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714575352; x=1715180152; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kJ8CU1KsZdsOI/zOnwTeILM7ZuUE9hyEpMnwtAluPZE=; b=gn5nAfDYvmwGkE6nBFpzVtLKtfsMpxY4HDDZSeAHp7rA01ka3MFKyOiaPeFqfd4mFL AGnjZgVPUuRMAAryq5AJBV6AhBMUhX/sWjSKSyddXbp2QKDLaeD4ozX3r1LB1SfFZKv8 DjUCZsMtaAFOioWfG2M8qds0dbisX0UwjXH53p29ghhmcKvarZKnqhro4qsC2kLAwEOc 04mzcNgT2jYwub+d3HrTSI0GUGWiu33jpeY1Q4ypmRKvxz2Mkn7lpkgBMDm9BfQU8lvI LVzcfCR8nLXPwYOptZXIUtm0kf6irAk+tgfjdxhnlJemmaiY+kIMWfhMkTX1WAv0tBNN o5FQ== X-Forwarded-Encrypted: i=1; AJvYcCXwUiDPzhuiVbBGaCACiGZTCNUL61GunI+J9Z5cuJfGWCXCLqAeROnG05McPlEyp9EvYhaa6FEUJUbOSfTBm6WcPlXJ6Rr2sPX/ZGGe X-Gm-Message-State: AOJu0YwLzAiwpIS8DRpBEBXcqKcrf0GMYk8M5xpo0F/PX0YzMw5eIAzK GemRFEgRppL07jOgYxnLLbm5nhzBn+GP112dYlU1cFKglaZzGh9rTAsC9XqRUY8= X-Google-Smtp-Source: AGHT+IEbjszfmVkTzjjE49mNkp1RDoY6WJdm5Dh/H6CEyFull2eOfXFaa255+mdEhVRdivb1lKxn4A== X-Received: by 2002:adf:e708:0:b0:34d:a37d:d383 with SMTP id c8-20020adfe708000000b0034da37dd383mr3329382wrm.22.1714575352183; Wed, 01 May 2024 07:55:52 -0700 (PDT) Received: from [192.168.1.61] ([2a02:842a:d52e:6101:6fd0:6c4:5d68:f0a5]) by smtp.gmail.com with ESMTPSA id o27-20020a05600c511b00b00418a386c17bsm2422999wms.12.2024.05.01.07.55.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 07:55:52 -0700 (PDT) From: Julien Stephan Date: Wed, 01 May 2024 16:55:36 +0200 Subject: [PATCH RFC v6 03/10] dt-bindings: iio: adc: ad7380: add pseudo-differential parts 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: <20240501-adding-new-ad738x-driver-v6-3-3c0741154728@baylibre.com> References: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> In-Reply-To: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Liam Girdwood , Mark Brown Cc: kernel test robot , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Stephan , Conor Dooley X-Mailer: b4 0.13.0 From: David Lechner Adding AD7383 and AD7384 compatible parts that are pseudo-differential. Pseudo-differential require common mode voltage supplies, so add them conditionally Signed-off-by: David Lechner Signed-off-by: Julien Stephan Acked-by: Conor Dooley --- .../devicetree/bindings/iio/adc/adi,ad7380.yaml | 32 ++++++++++++++++++= ++++ 1 file changed, 32 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml b/Do= cumentation/devicetree/bindings/iio/adc/adi,ad7380.yaml index 5e1ee0ebe0a2..de3d28a021ae 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml @@ -13,6 +13,8 @@ maintainers: description: | * https://www.analog.com/en/products/ad7380.html * https://www.analog.com/en/products/ad7381.html + * https://www.analog.com/en/products/ad7383.html + * https://www.analog.com/en/products/ad7384.html =20 $ref: /schemas/spi/spi-peripheral-props.yaml# =20 @@ -21,6 +23,8 @@ properties: enum: - adi,ad7380 - adi,ad7381 + - adi,ad7383 + - adi,ad7384 =20 reg: maxItems: 1 @@ -42,6 +46,16 @@ properties: A 2.5V to 3.3V supply for the external reference voltage. When omitt= ed, the internal 2.5V reference is used. =20 + aina-supply: + description: + The common mode voltage supply for the AINA- pin on pseudo-different= ial + chips. + + ainb-supply: + description: + The common mode voltage supply for the AINB- pin on pseudo-different= ial + chips. + interrupts: description: When the device is using 1-wire mode, this property is used to optio= nally @@ -56,6 +70,24 @@ required: =20 unevaluatedProperties: false =20 +allOf: + # pseudo-differential chips require common mode voltage supplies, + # true differential chips don't use them + - if: + properties: + compatible: + enum: + - adi,ad7383 + - adi,ad7384 + then: + required: + - aina-supply + - ainb-supply + else: + properties: + aina-supply: false + ainb-supply: false + examples: - | #include --=20 2.44.0 From nobody Wed Dec 17 23:27:15 2025 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80DBB12F59E for ; Wed, 1 May 2024 14:55:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575356; cv=none; b=uKGmV/+vOATSx846xlm7eMmaplpFo2Gs2iQT0e21pN2HPcfCmj6ZI4HPUX7NFkh0+ajlmMAYiHAncAbA8LqsVVLriZZCWYF5RZa1wcgLirHSuRN2wEscDzUVIT9zOrW/HllxZjJgsnYmSKBuphGUTaYkaETCjWZMkp5g76sD4xk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575356; c=relaxed/simple; bh=pkf8/LBRCf3QFRHG5cHQzVuVo0laS5hX0xG0KSpAu9o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=akIQTrviaruZeADooOehqaUsyglzYKzbnKl9mGzFGa8epcAnxZ8KRg8e3m7pt1VTAE+ORNXGdN9gjEaTM7mxAga44gcBlzpzLYF56XcrgNoOE+ocMpL1I3GwzvO/qc6QBt52uyWb9ZPHj4a3wKmPCMnn6DpLeEslWToeNXhi5TM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=nc3mPf9I; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="nc3mPf9I" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-418e4cd2196so53313155e9.1 for ; Wed, 01 May 2024 07:55:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714575353; x=1715180153; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=z2zQ8GQKC8PPzpOVhoeg1QxOlQu6eFpvStLY4dMmkvU=; b=nc3mPf9ItVYKwtVIu3v3fQyya0674yswZqYmKkLoaVQxydT4DakF08WBDLjkfc2dKo yrTr2bOEUAJYKJnaBuDi9QRjax6/2hLcjJV6vJShOS+DTKz2jR8qMprpo76loPyA5v0a Uxl6F7YtIQMhehrqI73ovXndnKG17AmQA2NZ/SAg4dAuHkjqNjjqOCIcK9iSLsO7qYGq wZJd3d9MODW+nkls9x50IHtYwD76WnGat5ysVJqkOWtV9zVP96qJO4LV1Z1C4X7JgnYD D6OL4LhIFTfiixlXFLd28PlVRAfU4/6BXxcPcMIhKk6raJvfZ/rzbJgPlIgYWcMBM6m0 pV+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714575353; x=1715180153; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=z2zQ8GQKC8PPzpOVhoeg1QxOlQu6eFpvStLY4dMmkvU=; b=cZygCo/rKDTZmAsmH59UrNPQapQkdjAr2dPsRJNoNbXQ1uqxrH7ezvSbGzYP8b19Iy IENLs+pSId4GsHRK7OnPwYmz2mBdDirnWlG2aaVSdsyL8LGKKU/aNsK3jrODVbKBhbpY SCuWzRlhBJ/dE1NXcvY4OnDwhxHv6PErDKIZ9GqmDr5c0arM6kDEK8NZkqeJENRUwqwJ F3x7K1QXiAskMgPtYk9pXGsj7dlDaJyMvXiRq2jfjns/UIOVPiGyl5Ugm0ZvdRb8Lzw1 e8pjBqGuxzdYw4JgNTT0+E9h8CFwg0UdXVPzx8Cc/KsTyPrjTVgUk85tdbY308AwzsdH eLeg== X-Forwarded-Encrypted: i=1; AJvYcCWaEVv519vCqZ5Jv0rtRi9LB0b4Z+/gaitHU9uGgewNIg3bj07RhvbGbArzHOiJynTEuarSqnBhZH/vjFkONJB1zESXnHWPIbgQgksA X-Gm-Message-State: AOJu0Yy1SwufMixUiWbcVxYupcwasxdiHa/KRyy3SW3pRVsR/7cSBmGH R2GSQ4vh+On3Doj/uuJFUz/B+QcWdcirRGnLYsH1EeQwNCq268dTf9WXMJvDKZY= X-Google-Smtp-Source: AGHT+IGBz8W9nhzACKGWf4RlR4Hiqj1BQdAdiHE4fm1+pfhBTIRnjURKhxDOzFO2p/pjRMJ/UFm4bA== X-Received: by 2002:a05:600c:4fd3:b0:41c:9155:fbe6 with SMTP id o19-20020a05600c4fd300b0041c9155fbe6mr1791507wmq.17.1714575352879; Wed, 01 May 2024 07:55:52 -0700 (PDT) Received: from [192.168.1.61] ([2a02:842a:d52e:6101:6fd0:6c4:5d68:f0a5]) by smtp.gmail.com with ESMTPSA id o27-20020a05600c511b00b00418a386c17bsm2422999wms.12.2024.05.01.07.55.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 07:55:52 -0700 (PDT) From: Julien Stephan Date: Wed, 01 May 2024 16:55:37 +0200 Subject: [PATCH RFC v6 04/10] iio: adc: ad7380: add support for pseudo-differential parts 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: <20240501-adding-new-ad738x-driver-v6-4-3c0741154728@baylibre.com> References: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> In-Reply-To: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Liam Girdwood , Mark Brown Cc: kernel test robot , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Stephan X-Mailer: b4 0.13.0 From: David Lechner Add support for AD7383, AD7384 pseudo-differential compatible parts. Pseudo differential parts require common mode voltage supplies so add the support for them and add the support of IIO_CHAN_INFO_OFFSET to retrieve the offset Signed-off-by: David Lechner Signed-off-by: Julien Stephan --- drivers/iio/adc/ad7380.c | 110 ++++++++++++++++++++++++++++++++++++++++---= ---- 1 file changed, 94 insertions(+), 16 deletions(-) diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index a218f59c276e..d6abce6d45d3 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -7,6 +7,7 @@ * * Datasheets of supported parts: * ad7380/1 : https://www.analog.com/media/en/technical-documentation/data= -sheets/AD7380-7381.pdf + * ad7383/4 : https://www.analog.com/media/en/technical-documentation/data= -sheets/ad7383-7384.pdf */ =20 #include @@ -68,16 +69,19 @@ struct ad7380_chip_info { const char *name; const struct iio_chan_spec *channels; unsigned int num_channels; + const char * const *vcm_supplies; + unsigned int num_vcm_supplies; }; =20 -#define AD7380_CHANNEL(index, bits) { \ +#define AD7380_CHANNEL(index, bits, diff) { \ .type =3D IIO_VOLTAGE, \ - .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | \ + ((diff) ? 0 : BIT(IIO_CHAN_INFO_OFFSET)), \ .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE), \ .indexed =3D 1, \ - .differential =3D 1, \ - .channel =3D 2 * (index), \ - .channel2 =3D 2 * (index) + 1, \ + .differential =3D (diff), \ + .channel =3D (diff) ? (2 * (index)) : (index), \ + .channel2 =3D (diff) ? (2 * (index) + 1) : 0, \ .scan_index =3D (index), \ .scan_type =3D { \ .sign =3D 's', \ @@ -87,15 +91,23 @@ struct ad7380_chip_info { }, \ } =20 -#define DEFINE_AD7380_2_CHANNEL(name, bits) \ -static const struct iio_chan_spec name[] =3D { \ - AD7380_CHANNEL(0, bits), \ - AD7380_CHANNEL(1, bits), \ - IIO_CHAN_SOFT_TIMESTAMP(2), \ +#define DEFINE_AD7380_2_CHANNEL(name, bits, diff) \ +static const struct iio_chan_spec name[] =3D { \ + AD7380_CHANNEL(0, bits, diff), \ + AD7380_CHANNEL(1, bits, diff), \ + IIO_CHAN_SOFT_TIMESTAMP(2), \ } =20 -DEFINE_AD7380_2_CHANNEL(ad7380_channels, 16); -DEFINE_AD7380_2_CHANNEL(ad7381_channels, 14); +/* fully differential */ +DEFINE_AD7380_2_CHANNEL(ad7380_channels, 16, 1); +DEFINE_AD7380_2_CHANNEL(ad7381_channels, 14, 1); +/* pseudo differential */ +DEFINE_AD7380_2_CHANNEL(ad7383_channels, 16, 0); +DEFINE_AD7380_2_CHANNEL(ad7384_channels, 14, 0); + +static const char * const ad7380_2_channel_vcm_supplies[] =3D { + "aina", "ainb", +}; =20 /* Since this is simultaneous sampling, we don't allow individual channels= . */ static const unsigned long ad7380_2_channel_scan_masks[] =3D { @@ -115,11 +127,28 @@ static const struct ad7380_chip_info ad7381_chip_info= =3D { .num_channels =3D ARRAY_SIZE(ad7381_channels), }; =20 +static const struct ad7380_chip_info ad7383_chip_info =3D { + .name =3D "ad7383", + .channels =3D ad7383_channels, + .num_channels =3D ARRAY_SIZE(ad7383_channels), + .vcm_supplies =3D ad7380_2_channel_vcm_supplies, + .num_vcm_supplies =3D ARRAY_SIZE(ad7380_2_channel_vcm_supplies), +}; + +static const struct ad7380_chip_info ad7384_chip_info =3D { + .name =3D "ad7384", + .channels =3D ad7384_channels, + .num_channels =3D ARRAY_SIZE(ad7384_channels), + .vcm_supplies =3D ad7380_2_channel_vcm_supplies, + .num_vcm_supplies =3D ARRAY_SIZE(ad7380_2_channel_vcm_supplies), +}; + struct ad7380_state { const struct ad7380_chip_info *chip_info; struct spi_device *spi; struct regmap *regmap; unsigned int vref_mv; + unsigned int vcm_mv[2]; /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. @@ -293,13 +322,24 @@ static int ad7380_read_raw(struct iio_dev *indio_dev, unreachable(); case IIO_CHAN_INFO_SCALE: /* - * According to the datasheet, the LSB size for fully differential ADC is - * (2 =C3=97 VREF) / 2^N, where N is the ADC resolution (i.e realbits) + * According to the datasheet, the LSB size is: + * * (2 =C3=97 VREF) / 2^N, for differential chips + * * VREF / 2^N, for pseudo-differential chips + * where N is the ADC resolution (i.e realbits) */ *val =3D st->vref_mv; - *val2 =3D chan->scan_type.realbits - 1; + *val2 =3D chan->scan_type.realbits - chan->differential; =20 return IIO_VAL_FRACTIONAL_LOG2; + case IIO_CHAN_INFO_OFFSET: + /* + * According to IIO ABI, offset is applied before scale, + * so offset is: vcm_mv / scale + */ + *val =3D st->vcm_mv[chan->channel] * (1 << chan->scan_type.realbits) + / st->vref_mv; + + return IIO_VAL_INT; default: return -EINVAL; } @@ -346,7 +386,7 @@ static int ad7380_probe(struct spi_device *spi) struct iio_dev *indio_dev; struct ad7380_state *st; struct regulator *vref; - int ret; + int ret, i; =20 indio_dev =3D devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (!indio_dev) @@ -390,6 +430,40 @@ static int ad7380_probe(struct spi_device *spi) st->vref_mv =3D AD7380_INTERNAL_REF_MV; } =20 + if (st->chip_info->num_vcm_supplies > ARRAY_SIZE(st->vcm_mv)) + return dev_err_probe(&spi->dev, -EINVAL, + "invalid number of VCM supplies\n"); + + /* + * pseudo-differential chips have common mode supplies for the negative + * input pin. + */ + for (i =3D 0; i < st->chip_info->num_vcm_supplies; i++) { + struct regulator *vcm; + + vcm =3D devm_regulator_get(&spi->dev, + st->chip_info->vcm_supplies[i]); + if (IS_ERR(vcm)) + return dev_err_probe(&spi->dev, PTR_ERR(vcm), + "Failed to get %s regulator\n", + st->chip_info->vcm_supplies[i]); + + ret =3D regulator_enable(vcm); + if (ret) + return ret; + + ret =3D devm_add_action_or_reset(&spi->dev, + ad7380_regulator_disable, vcm); + if (ret) + return ret; + + ret =3D regulator_get_voltage(vcm); + if (ret < 0) + return ret; + + st->vcm_mv[i] =3D ret / 1000; + } + st->regmap =3D devm_regmap_init(&spi->dev, NULL, st, &ad7380_regmap_confi= g); if (IS_ERR(st->regmap)) return dev_err_probe(&spi->dev, PTR_ERR(st->regmap), @@ -418,12 +492,16 @@ static int ad7380_probe(struct spi_device *spi) static const struct of_device_id ad7380_of_match_table[] =3D { { .compatible =3D "adi,ad7380", .data =3D &ad7380_chip_info }, { .compatible =3D "adi,ad7381", .data =3D &ad7381_chip_info }, + { .compatible =3D "adi,ad7383", .data =3D &ad7383_chip_info }, + { .compatible =3D "adi,ad7384", .data =3D &ad7384_chip_info }, { } }; =20 static const struct spi_device_id ad7380_id_table[] =3D { { "ad7380", (kernel_ulong_t)&ad7380_chip_info }, { "ad7381", (kernel_ulong_t)&ad7381_chip_info }, + { "ad7383", (kernel_ulong_t)&ad7383_chip_info }, + { "ad7384", (kernel_ulong_t)&ad7384_chip_info }, { } }; MODULE_DEVICE_TABLE(spi, ad7380_id_table); --=20 2.44.0 From nobody Wed Dec 17 23:27:15 2025 Received: from mail-lj1-f181.google.com (mail-lj1-f181.google.com [209.85.208.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 66B3812FF7C for ; Wed, 1 May 2024 14:55:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575359; cv=none; b=LsbrpeAdXEv+gkKhKARHTZlRzOrrjw5GGccIyIZvFwLnr4/1Ro1GtNoM4DFb5MGJir2LaTTCst8WqUnyViPiW7meqcctUny07EmBGvGBIrKUfKsUJlRw3Poxbb4yU3y4HI11rqPiZDvhH86nUde5IsapLPqpMa4qUBEjSA0vQSM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575359; c=relaxed/simple; bh=PlVN8xXeJpQxRFCg/Zbc/zFXTyCgg9A5cV1m+rK2HuU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QYE6UNbYCqUqYfBs+FCTc5+4N67qG9SaQbrW+t87mMNOx5EmmqRpRbGNdLa1WNPyBR2yhwlzhYLzMoWV8gdZXVUj0UBIXXT+J6EF/TG4TIr1MeLZKPfxBWChB8CJCOPyFfR1bHp+J0W5/OTYXuX9cVvQnhgDYLgbeb8QnNh/5TE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=3Je228iL; arc=none smtp.client-ip=209.85.208.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="3Je228iL" Received: by mail-lj1-f181.google.com with SMTP id 38308e7fff4ca-2d858501412so88263171fa.0 for ; Wed, 01 May 2024 07:55:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714575355; x=1715180155; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=jAPd7+I9U5+1I8Z6YQiXd//LKxCaLInr9ip5Pmkk0XE=; b=3Je228iL7Mk2LUzdz6SM9FguE3nmTT0wxhTQCPrYrWycUUeTssu+km+wPpPFnNATkA +Cl3TFOFjD5n7MlCKB7ccQ2+XRb+yLETHGdTr4nhrhHpM3CdQZTo/lxerlY0NjgSaxZ2 Q40bgK++cKLVx1LttwDI1jK2PXPNWZqsaQRFxmS3ol9a82ka4ppBRHq6cO8uG2/cEkMW asMLLrHX4BxnVraBv95VUQ1d0T1A1WrwS02BsRaOcxmRewVZBqfjVUti7E2vvsGYfvyF nNe2+8r8yXb1HRlg6OMGfI9Sad38FUut3/ig1t/RD/Zg5MIUeY8u1c6t//2Ak2uvbUZ4 Hezg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714575355; x=1715180155; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jAPd7+I9U5+1I8Z6YQiXd//LKxCaLInr9ip5Pmkk0XE=; b=Fc8MKQTMS04TxF1hG+JjbB9C8rbmA0f+4TBNoMdubZzCjDHDILMtGwhpL3o5gLJzJA Bv8lTVor0Kqk75hEmo9soVeGCYxrEfUNBwuw3PxqRyf8qd6gbhXUr+2U3JiRSPYvpvxS 8tuO8nMX6SB0KL74E/AG5ne563zq7g6+g+Uo1+UNOVibb2DFzL3CmS/EJNzMAaAoHph6 QNTpIpfyyTpz/P2LIHl1G+/1um0HYRBlHbLueDQloS+L+03kfJtZ7roIY8Aj7DaOC4M4 KYY776UGL/PRM/5X3a5fWZ0huwlBdzi/J06uFMrtnrP7RoEer7ndiC4GInNqSk7+Goil ioIA== X-Forwarded-Encrypted: i=1; AJvYcCX5IHsbLleQ7D/oLTtUGJEq9suqCxjkwYwQPH1uF/5HM7RnaHuBaH25NVLMCaiHPtONK5AON34o+MitU86JVAolpEmu/LyJHxgqHi0v X-Gm-Message-State: AOJu0Yy8FktQ+RcUl04EtetZUsZdxKy4NiqJtIB25CbmRZtnVIcV6Ybl wI0p61AZLD5b9oOsI/0NtWGsDDs1dFZqORx9LAofI6O2BxKYa4fylklWkSp2SMI= X-Google-Smtp-Source: AGHT+IETnXzT+yQs6Yj2CWqIQQetQPoDaLRkkWGMsrtIM9SAobTswOR6AFvtKqMV9AqyM9AlDvmm6w== X-Received: by 2002:a2e:a7d1:0:b0:2e0:4a32:1f41 with SMTP id x17-20020a2ea7d1000000b002e04a321f41mr2092149ljp.19.1714575353548; Wed, 01 May 2024 07:55:53 -0700 (PDT) Received: from [192.168.1.61] ([2a02:842a:d52e:6101:6fd0:6c4:5d68:f0a5]) by smtp.gmail.com with ESMTPSA id o27-20020a05600c511b00b00418a386c17bsm2422999wms.12.2024.05.01.07.55.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 07:55:53 -0700 (PDT) From: Julien Stephan Date: Wed, 01 May 2024 16:55:38 +0200 Subject: [PATCH RFC v6 05/10] iio: adc: ad7380: prepare for parts with more channels 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: <20240501-adding-new-ad738x-driver-v6-5-3c0741154728@baylibre.com> References: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> In-Reply-To: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Liam Girdwood , Mark Brown Cc: kernel test robot , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Stephan X-Mailer: b4 0.13.0 The current driver supports only parts with 2 channels. In order to prepare the support of new compatible ADCs with more channels, this commit: - defines MAX_NUM_CHANNEL to specify the maximum number of channels currently supported by the driver - adds available_scan_mask member in ad7380_chip_info structure - fixes spi xfer struct len depending on number of channels - fixes scan_data.raw buffer size to handle more channels - adds a timing specifications structure in ad7380_chip_info structure Signed-off-by: Julien Stephan --- drivers/iio/adc/ad7380.c | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index d6abce6d45d3..201006d878f1 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -29,6 +29,7 @@ #include #include =20 +#define MAX_NUM_CHANNELS 2 /* 2.5V internal reference voltage */ #define AD7380_INTERNAL_REF_MV 2500 =20 @@ -65,12 +66,19 @@ #define AD7380_ALERT_LOW_TH GENMASK(11, 0) #define AD7380_ALERT_HIGH_TH GENMASK(11, 0) =20 +#define T_CONVERT_NS 190 /* conversion time */ +struct ad7380_timing_specs { + const unsigned int t_csh_ns; /* CS minimum high time */ +}; + struct ad7380_chip_info { const char *name; const struct iio_chan_spec *channels; unsigned int num_channels; const char * const *vcm_supplies; unsigned int num_vcm_supplies; + const unsigned long *available_scan_masks; + const struct ad7380_timing_specs *timing_specs; }; =20 #define AD7380_CHANNEL(index, bits, diff) { \ @@ -115,16 +123,24 @@ static const unsigned long ad7380_2_channel_scan_mask= s[] =3D { 0 }; =20 +static const struct ad7380_timing_specs ad7380_timing =3D { + .t_csh_ns =3D 10, +}; + static const struct ad7380_chip_info ad7380_chip_info =3D { .name =3D "ad7380", .channels =3D ad7380_channels, .num_channels =3D ARRAY_SIZE(ad7380_channels), + .available_scan_masks =3D ad7380_2_channel_scan_masks, + .timing_specs =3D &ad7380_timing, }; =20 static const struct ad7380_chip_info ad7381_chip_info =3D { .name =3D "ad7381", .channels =3D ad7381_channels, .num_channels =3D ARRAY_SIZE(ad7381_channels), + .available_scan_masks =3D ad7380_2_channel_scan_masks, + .timing_specs =3D &ad7380_timing, }; =20 static const struct ad7380_chip_info ad7383_chip_info =3D { @@ -133,6 +149,8 @@ static const struct ad7380_chip_info ad7383_chip_info = =3D { .num_channels =3D ARRAY_SIZE(ad7383_channels), .vcm_supplies =3D ad7380_2_channel_vcm_supplies, .num_vcm_supplies =3D ARRAY_SIZE(ad7380_2_channel_vcm_supplies), + .available_scan_masks =3D ad7380_2_channel_scan_masks, + .timing_specs =3D &ad7380_timing, }; =20 static const struct ad7380_chip_info ad7384_chip_info =3D { @@ -141,6 +159,8 @@ static const struct ad7380_chip_info ad7384_chip_info = =3D { .num_channels =3D ARRAY_SIZE(ad7384_channels), .vcm_supplies =3D ad7380_2_channel_vcm_supplies, .num_vcm_supplies =3D ARRAY_SIZE(ad7380_2_channel_vcm_supplies), + .available_scan_masks =3D ad7380_2_channel_scan_masks, + .timing_specs =3D &ad7380_timing, }; =20 struct ad7380_state { @@ -148,15 +168,16 @@ struct ad7380_state { struct spi_device *spi; struct regmap *regmap; unsigned int vref_mv; - unsigned int vcm_mv[2]; + unsigned int vcm_mv[MAX_NUM_CHANNELS]; /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. - * Make the buffer large enough for 2 16-bit samples and one 64-bit + * Make the buffer large enough for MAX_NUM_CHANNELS 16-bit samples and o= ne 64-bit * aligned 64 bit timestamp. + * As MAX_NUM_CHANNELS is 2 the layout of the structure is the same for a= ll parts */ struct { - u16 raw[2]; + u16 raw[MAX_NUM_CHANNELS]; =20 s64 ts __aligned(8); } scan_data __aligned(IIO_DMA_MINALIGN); @@ -194,7 +215,7 @@ static int ad7380_regmap_reg_read(void *context, unsign= ed int reg, .tx_buf =3D &st->tx, .cs_change =3D 1, .cs_change_delay =3D { - .value =3D 10, /* t[CSH] */ + .value =3D st->chip_info->timing_specs->t_csh_ns, .unit =3D SPI_DELAY_UNIT_NSECS, }, }, { @@ -252,7 +273,8 @@ static irqreturn_t ad7380_trigger_handler(int irq, void= *p) struct ad7380_state *st =3D iio_priv(indio_dev); struct spi_transfer xfer =3D { .bits_per_word =3D st->chip_info->channels[0].scan_type.realbits, - .len =3D 4, + .len =3D (st->chip_info->num_channels - 1) * + BITS_TO_BYTES(st->chip_info->channels->scan_type.storagebits), .rx_buf =3D st->scan_data.raw, }; int ret; @@ -279,21 +301,22 @@ static int ad7380_read_direct(struct ad7380_state *st, .speed_hz =3D AD7380_REG_WR_SPEED_HZ, .bits_per_word =3D chan->scan_type.realbits, .delay =3D { - .value =3D 190, /* t[CONVERT] */ + .value =3D T_CONVERT_NS, .unit =3D SPI_DELAY_UNIT_NSECS, }, .cs_change =3D 1, .cs_change_delay =3D { - .value =3D 10, /* t[CSH] */ + .value =3D st->chip_info->timing_specs->t_csh_ns, .unit =3D SPI_DELAY_UNIT_NSECS, }, }, - /* then read both channels */ + /* then read all channels */ { .speed_hz =3D AD7380_REG_WR_SPEED_HZ, .bits_per_word =3D chan->scan_type.realbits, .rx_buf =3D st->scan_data.raw, - .len =3D 4, + .len =3D (st->chip_info->num_channels - 1) * + ((chan->scan_type.storagebits > 16) ? 4 : 2), }, }; int ret; @@ -474,7 +497,7 @@ static int ad7380_probe(struct spi_device *spi) indio_dev->name =3D st->chip_info->name; indio_dev->info =3D &ad7380_info; indio_dev->modes =3D INDIO_DIRECT_MODE; - indio_dev->available_scan_masks =3D ad7380_2_channel_scan_masks; + indio_dev->available_scan_masks =3D st->chip_info->available_scan_masks; =20 ret =3D devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, iio_pollfunc_store_time, --=20 2.44.0 From nobody Wed Dec 17 23:27:15 2025 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5E48412FF98 for ; Wed, 1 May 2024 14:55:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575360; cv=none; b=KqnIazbrOKsiAQTgKB+uRxEIbUOJ/pkTkn+EjDqKVv3QRcNR+ChNAfcwFPnh8fM6IDLrK6lqf5ESbYs+AdtBcDMV6MMZOZjroMLT+JAz1rgaP3DuxX5oBQKsCfGopCuZPCbvhWANgO7SO5QFyX0XG/JofaDpIG0GubcXdaNIV+Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575360; c=relaxed/simple; bh=VQ4RPFjraeg9QG+WtxUK0LxObNrAlrRgeIFZywlwUq0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=bQ/nUSuSsxs8NT6NaEjxl1oQcc2xL1sAZ+xpTg9oZddtI+Rv+Dfin/ASh++uSStnOO0IoSXI4xZVa1kTM1rXeAdAA7jQZYO1HyKARKaFPNJiDG/GBhhN/xcr/JPhYilyXzzunhLiWsK5Ye0N168IPyMlF3ZGUAGyvIV2Ay97DOM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=Z5a/zJlt; arc=none smtp.client-ip=209.85.128.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="Z5a/zJlt" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-41a1d2a7b81so4729255e9.0 for ; Wed, 01 May 2024 07:55:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714575357; x=1715180157; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=7kVmMiAww/1MNzSxxAk2mzn+IJ9yIpCfeirFaQBWWao=; b=Z5a/zJltr1B/SgV2vz/KZYVsn526i3YYhIjB6xlRCKu2SdmzFSGSwuuCRv0Hb1aPO4 kX7xjjCnzrtmezVJ7Dg8vkSV0Aqo9lbTpIGMVitVJq0DnKJjV3YB6s3oKp7ZSJPlVyvJ MxSJsuXYdWjSFmhof7eD///F6dR0CKPwH1n/74O1oQey0w9zAOuLwF8xHdNKuWxqF9eA 2eqMRRCqGYBuwwwO7r9J4bjPZEs5rI4mDKgtNMQA9Wu0nZ/Jz+bIUHOdCourH6A/udKo oLj6NQhC9kZySaDsz7UFeXpzX1+SN4z+pXt+DqJskGT4x62dCMWrnwPHIc3Ni05DyU3k Htzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714575357; x=1715180157; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7kVmMiAww/1MNzSxxAk2mzn+IJ9yIpCfeirFaQBWWao=; b=VLi4PJX004Y7mlmranZEnZLrQw02KCqCcKu0imItyHeFVsTjUa4o6K4KWKmBtuKWHY Z3eyVsW7p41UCH3lvH1q339z81qGaosBdRgci7jAyvID0dtycnzNSVRM8QsutUNwxfuS 247ZDTDuYrENJzAZw9maZAa7fbwwASROAcWxXeMeCSXcJtYapNMEZPzwH6nHPYML3QH2 Nc+Q0rllNInF3uiwEZBXj4htfyaRjurnCki4bnSs7HCd/FdotO6gnM8mikurVSyIwYBf //Yl+gDf4pEhl5ssEiY/Y6eaMo/3gEdZCUhX8nMLEjWKxEphdn87QAMDfV0noWzRqMz9 +8dQ== X-Forwarded-Encrypted: i=1; AJvYcCX4BPIbevWYJK784D5xmbVkDIoxT1MlzQ83huYmeiOcttMRwlu+9cR05+KrM+DbY+9XRnkcCdZbpKZWhbE0Qb55bxKk4Ds3Kwpe8lJQ X-Gm-Message-State: AOJu0YzksAq+vdnpC/GDH3qbA8QJekf+VHdwQZsZN99sFg0Y5/+k/TzE LMfs6HxaI6piWNuDfGmJnrDaaIkHN9uD9p5ZF6rvw3csxNZXiUyXxBtTYuILTbo= X-Google-Smtp-Source: AGHT+IEANloY5ykx9Y8v3SvYudon/zDa72AUor3FRJRdAs2hAmb12iii9rrqR7zhQBrbVBg7l3dLXg== X-Received: by 2002:a05:600c:3b10:b0:419:c9e1:70b8 with SMTP id m16-20020a05600c3b1000b00419c9e170b8mr2540608wms.13.1714575356686; Wed, 01 May 2024 07:55:56 -0700 (PDT) Received: from [192.168.1.61] ([2a02:842a:d52e:6101:6fd0:6c4:5d68:f0a5]) by smtp.gmail.com with ESMTPSA id o27-20020a05600c511b00b00418a386c17bsm2422999wms.12.2024.05.01.07.55.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 07:55:55 -0700 (PDT) From: Julien Stephan Date: Wed, 01 May 2024 16:55:39 +0200 Subject: [PATCH RFC v6 06/10] dt-bindings: iio: adc: ad7380: add support for ad738x-4 4 channels variants 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: <20240501-adding-new-ad738x-driver-v6-6-3c0741154728@baylibre.com> References: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> In-Reply-To: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Liam Girdwood , Mark Brown Cc: kernel test robot , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Stephan , Conor Dooley X-Mailer: b4 0.13.0 Add compatible support for ad7380/1/3/4-4 parts which are 4 channels variants from ad7380/1/3/4 Signed-off-by: Julien Stephan Acked-by: Conor Dooley --- .../devicetree/bindings/iio/adc/adi,ad7380.yaml | 34 ++++++++++++++++++= ++++ 1 file changed, 34 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml b/Do= cumentation/devicetree/bindings/iio/adc/adi,ad7380.yaml index de3d28a021ae..899b777017ce 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml @@ -15,6 +15,10 @@ description: | * https://www.analog.com/en/products/ad7381.html * https://www.analog.com/en/products/ad7383.html * https://www.analog.com/en/products/ad7384.html + * https://www.analog.com/en/products/ad7380-4.html + * https://www.analog.com/en/products/ad7381-4.html + * https://www.analog.com/en/products/ad7383-4.html + * https://www.analog.com/en/products/ad7384-4.html =20 $ref: /schemas/spi/spi-peripheral-props.yaml# =20 @@ -25,6 +29,10 @@ properties: - adi,ad7381 - adi,ad7383 - adi,ad7384 + - adi,ad7380-4 + - adi,ad7381-4 + - adi,ad7383-4 + - adi,ad7384-4 =20 reg: maxItems: 1 @@ -56,6 +64,16 @@ properties: The common mode voltage supply for the AINB- pin on pseudo-different= ial chips. =20 + ainc-supply: + description: + The common mode voltage supply for the AINC- pin on pseudo-different= ial + chips. + + aind-supply: + description: + The common mode voltage supply for the AIND- pin on pseudo-different= ial + chips. + interrupts: description: When the device is using 1-wire mode, this property is used to optio= nally @@ -79,6 +97,8 @@ allOf: enum: - adi,ad7383 - adi,ad7384 + - adi,ad7383-4 + - adi,ad7384-4 then: required: - aina-supply @@ -87,6 +107,20 @@ allOf: properties: aina-supply: false ainb-supply: false + - if: + properties: + compatible: + enum: + - adi,ad7383-4 + - adi,ad7384-4 + then: + required: + - ainc-supply + - aind-supply + else: + properties: + ainc-supply: false + aind-supply: false =20 examples: - | --=20 2.44.0 From nobody Wed Dec 17 23:27:15 2025 Received: from mail-lj1-f169.google.com (mail-lj1-f169.google.com [209.85.208.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1037813048B for ; Wed, 1 May 2024 14:55:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575362; cv=none; b=c9vN8h0oi0w2xNVeab14SN1uY4774oT+NaYeSfIBmOuzXitJ3IklbLpH5QSt1xRVBpcb8fYd10yY9Ovkf2yUWny7X6kLbUmf4U4L39yewJX81IK31GMlrD3BXaIuXbDAFVkKdVknp5sWwT+tanYZIzMBm0vmXpXfBuHcgS8xggE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575362; c=relaxed/simple; bh=ZNQE99beBwoRSVRXgPiuYKEUKZPVmY+MpjIBueQJo5Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ExfJ58xslkJJph0Cx/WRUUWipRLEdSuSfJ+Y+qhIm8IpXq08tpMcJ6V0UOxp4zKaHueh00vDRWll7pkMID1ZB01PCgSTZCwccc0chRuou3xLXlnAjIkSsL9EQXI2skKOHeeouMnF5hGsRj19sPqIWK4R1BqJjrNX+cvYIHkYJac= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=VxX37z4q; arc=none smtp.client-ip=209.85.208.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="VxX37z4q" Received: by mail-lj1-f169.google.com with SMTP id 38308e7fff4ca-2e0933d3b5fso37318921fa.2 for ; Wed, 01 May 2024 07:55:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714575357; x=1715180157; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=2SUrAQZGAtrStLGSV72n9ZrFrH3z0Vq+Ea2QpVZsYzA=; b=VxX37z4qwmlW0BReVaadVBfJJ0+OGctDYzNwUb/v5Yjo8yHQxYwE7VQFDbfFyHFrGL FlfxGZVYibs6P5pVpOm09fh2nTC7uAZwzdodfGec4CR97iAQHgPCB/gW9N0IRileSOSS WfpeVX6KhIlpdk8YHROcOmR9/JlKpRKz5uKTK2QsvBCh0F0gwXGHxZoAarksXj1HpP7q 9I+Igh2zEQR1+0HmLDOhNA3oDukZRX7UR8kjkmtJ0G8BI1bm5TlWOPrq2Rq0R5X5dPnN px9ZC3lmD2+ik3kqgonjoDH0MJS4BKqpyRjAum5LHENxwGPMjOblqJGWQ2vdDW1pS8jb 96zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714575357; x=1715180157; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2SUrAQZGAtrStLGSV72n9ZrFrH3z0Vq+Ea2QpVZsYzA=; b=TSARyZOMfEs9QmzGhIpcOBIH3IQzfdM4Xoa4dYyiRPALMx19ZuoDxx5jW/qXx07Dfm OTUQJ5JThSKUxQRHKfP18lU2ZEoNkW9R2F1gmsPTbtaY+W3qvEVTb9tUft8Rmsog2wbp LWQ5LukLs/+2SjOaL/gOKDoY+c7b1fJ8IVxzp/oXqN6UrcD6MR3JuoJOPSKbzgPyEZyU x9cNOYkLxgfUHeBB6FetQwjrcblvuWBl3KwhIUljlmUTbHQ231ZTc41iAFhp2ZGHfmkA q9FxqXuJ2fcFwfgy8BTT285j3BSJmQNQX9R6t3HdVEqu1VSjKtHx8Zi8DX21tkUftab3 eNBQ== X-Forwarded-Encrypted: i=1; AJvYcCW142w8MGfeCJUSjBHXBpgP3dpOfOFs9IFfmeXqiBIy5By3eqFMC+n0jJJbz2lp4Y/ZaCmNd45ipB5u95YP98ePULjZPO8ttBQZemJS X-Gm-Message-State: AOJu0YyBdwTBwWFn4zYLEJ9g3l7P4kbN7/zi/dS8ltl/mBuMqBnB1iDn +lFkYvFOVN0sBml2tDTEVfvJiHuYfvky0a+WBWALeBc9NISB4RP9eiULDegWmn+eq3DyapfqqnX 4 X-Google-Smtp-Source: AGHT+IEv9sPD9F1hPTXXzQtVy0YeCQSCcJgq28A1F/hSj8DUSPiVAnVdblnxCwk7HLdQcWPj9V/HWQ== X-Received: by 2002:a05:651c:2110:b0:2e1:b0e3:21f with SMTP id a16-20020a05651c211000b002e1b0e3021fmr183264ljq.40.1714575357402; Wed, 01 May 2024 07:55:57 -0700 (PDT) Received: from [192.168.1.61] ([2a02:842a:d52e:6101:6fd0:6c4:5d68:f0a5]) by smtp.gmail.com with ESMTPSA id o27-20020a05600c511b00b00418a386c17bsm2422999wms.12.2024.05.01.07.55.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 07:55:57 -0700 (PDT) From: Julien Stephan Date: Wed, 01 May 2024 16:55:40 +0200 Subject: [PATCH RFC v6 07/10] iio: adc: ad7380: add support for ad738x-4 4 channels variants 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: <20240501-adding-new-ad738x-driver-v6-7-3c0741154728@baylibre.com> References: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> In-Reply-To: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Liam Girdwood , Mark Brown Cc: kernel test robot , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Stephan X-Mailer: b4 0.13.0 Add support for ad7380/1/2/3-4 parts which are 4 channels variants from ad7380/1/2/3 Signed-off-by: Julien Stephan --- drivers/iio/adc/ad7380.c | 77 ++++++++++++++++++++++++++++++++++++++++++++= ++-- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index 201006d878f1..020959759170 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -8,6 +8,9 @@ * Datasheets of supported parts: * ad7380/1 : https://www.analog.com/media/en/technical-documentation/data= -sheets/AD7380-7381.pdf * ad7383/4 : https://www.analog.com/media/en/technical-documentation/data= -sheets/ad7383-7384.pdf + * ad7380-4 : https://www.analog.com/media/en/technical-documentation/data= -sheets/ad7380-4.pdf + * ad7381-4 : https://www.analog.com/media/en/technical-documentation/data= -sheets/ad7381-4.pdf + * ad7383/4-4 : https://www.analog.com/media/en/technical-documentation/da= ta-sheets/ad7383-4-ad7384-4.pdf */ =20 #include @@ -29,7 +32,7 @@ #include #include =20 -#define MAX_NUM_CHANNELS 2 +#define MAX_NUM_CHANNELS 4 /* 2.5V internal reference voltage */ #define AD7380_INTERNAL_REF_MV 2500 =20 @@ -106,27 +109,53 @@ static const struct iio_chan_spec name[] =3D { \ IIO_CHAN_SOFT_TIMESTAMP(2), \ } =20 +#define DEFINE_AD7380_4_CHANNEL(name, bits, diff) \ +static const struct iio_chan_spec name[] =3D { \ + AD7380_CHANNEL(0, bits, diff), \ + AD7380_CHANNEL(1, bits, diff), \ + AD7380_CHANNEL(2, bits, diff), \ + AD7380_CHANNEL(3, bits, diff), \ + IIO_CHAN_SOFT_TIMESTAMP(4), \ +} + /* fully differential */ DEFINE_AD7380_2_CHANNEL(ad7380_channels, 16, 1); DEFINE_AD7380_2_CHANNEL(ad7381_channels, 14, 1); +DEFINE_AD7380_4_CHANNEL(ad7380_4_channels, 16, 1); +DEFINE_AD7380_4_CHANNEL(ad7381_4_channels, 14, 1); /* pseudo differential */ DEFINE_AD7380_2_CHANNEL(ad7383_channels, 16, 0); DEFINE_AD7380_2_CHANNEL(ad7384_channels, 14, 0); +DEFINE_AD7380_4_CHANNEL(ad7383_4_channels, 16, 0); +DEFINE_AD7380_4_CHANNEL(ad7384_4_channels, 14, 0); =20 static const char * const ad7380_2_channel_vcm_supplies[] =3D { "aina", "ainb", }; =20 +static const char * const ad7380_4_channel_vcm_supplies[] =3D { + "aina", "ainb", "ainc", "aind", +}; + /* Since this is simultaneous sampling, we don't allow individual channels= . */ static const unsigned long ad7380_2_channel_scan_masks[] =3D { GENMASK(1, 0), 0 }; =20 +static const unsigned long ad7380_4_channel_scan_masks[] =3D { + GENMASK(3, 0), + 0 +}; + static const struct ad7380_timing_specs ad7380_timing =3D { .t_csh_ns =3D 10, }; =20 +static const struct ad7380_timing_specs ad7380_4_timing =3D { + .t_csh_ns =3D 20, +}; + static const struct ad7380_chip_info ad7380_chip_info =3D { .name =3D "ad7380", .channels =3D ad7380_channels, @@ -163,6 +192,42 @@ static const struct ad7380_chip_info ad7384_chip_info = =3D { .timing_specs =3D &ad7380_timing, }; =20 +static const struct ad7380_chip_info ad7380_4_chip_info =3D { + .name =3D "ad7380-4", + .channels =3D ad7380_4_channels, + .num_channels =3D ARRAY_SIZE(ad7380_4_channels), + .available_scan_masks =3D ad7380_4_channel_scan_masks, + .timing_specs =3D &ad7380_4_timing, +}; + +static const struct ad7380_chip_info ad7381_4_chip_info =3D { + .name =3D "ad7381-4", + .channels =3D ad7381_4_channels, + .num_channels =3D ARRAY_SIZE(ad7381_4_channels), + .available_scan_masks =3D ad7380_4_channel_scan_masks, + .timing_specs =3D &ad7380_4_timing, +}; + +static const struct ad7380_chip_info ad7383_4_chip_info =3D { + .name =3D "ad7383-4", + .channels =3D ad7383_4_channels, + .num_channels =3D ARRAY_SIZE(ad7383_4_channels), + .vcm_supplies =3D ad7380_4_channel_vcm_supplies, + .num_vcm_supplies =3D ARRAY_SIZE(ad7380_4_channel_vcm_supplies), + .available_scan_masks =3D ad7380_4_channel_scan_masks, + .timing_specs =3D &ad7380_4_timing, +}; + +static const struct ad7380_chip_info ad7384_4_chip_info =3D { + .name =3D "ad7384-4", + .channels =3D ad7384_4_channels, + .num_channels =3D ARRAY_SIZE(ad7384_4_channels), + .vcm_supplies =3D ad7380_4_channel_vcm_supplies, + .num_vcm_supplies =3D ARRAY_SIZE(ad7380_4_channel_vcm_supplies), + .available_scan_masks =3D ad7380_4_channel_scan_masks, + .timing_specs =3D &ad7380_4_timing, +}; + struct ad7380_state { const struct ad7380_chip_info *chip_info; struct spi_device *spi; @@ -174,7 +239,7 @@ struct ad7380_state { * transfer buffers to live in their own cache lines. * Make the buffer large enough for MAX_NUM_CHANNELS 16-bit samples and o= ne 64-bit * aligned 64 bit timestamp. - * As MAX_NUM_CHANNELS is 2 the layout of the structure is the same for a= ll parts + * As MAX_NUM_CHANNELS is 4 the layout of the structure is the same for a= ll parts */ struct { u16 raw[MAX_NUM_CHANNELS]; @@ -517,6 +582,10 @@ static const struct of_device_id ad7380_of_match_table= [] =3D { { .compatible =3D "adi,ad7381", .data =3D &ad7381_chip_info }, { .compatible =3D "adi,ad7383", .data =3D &ad7383_chip_info }, { .compatible =3D "adi,ad7384", .data =3D &ad7384_chip_info }, + { .compatible =3D "adi,ad7380-4", .data =3D &ad7380_4_chip_info }, + { .compatible =3D "adi,ad7381-4", .data =3D &ad7381_4_chip_info }, + { .compatible =3D "adi,ad7383-4", .data =3D &ad7383_4_chip_info }, + { .compatible =3D "adi,ad7384-4", .data =3D &ad7384_4_chip_info }, { } }; =20 @@ -525,6 +594,10 @@ static const struct spi_device_id ad7380_id_table[] = =3D { { "ad7381", (kernel_ulong_t)&ad7381_chip_info }, { "ad7383", (kernel_ulong_t)&ad7383_chip_info }, { "ad7384", (kernel_ulong_t)&ad7384_chip_info }, + { "ad7380-4", (kernel_ulong_t)&ad7380_4_chip_info }, + { "ad7381-4", (kernel_ulong_t)&ad7381_4_chip_info }, + { "ad7383-4", (kernel_ulong_t)&ad7383_4_chip_info }, + { "ad7384-4", (kernel_ulong_t)&ad7384_4_chip_info }, { } }; MODULE_DEVICE_TABLE(spi, ad7380_id_table); --=20 2.44.0 From nobody Wed Dec 17 23:27:15 2025 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFFB81304A2 for ; Wed, 1 May 2024 14:55:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575362; cv=none; b=j2tMWnxWmUgZdBquDGRw1GHeOJSUa7RXABdK2Xv2VrKB6odI0evVrdIZd8jKOe8xcGvcA4MKySu0sVQvXv6jJfzL9jVPgfnATfUgdoRLXy/jaWtzel06eFbK/6sfLFjd7oA61xGilkqW8OYfasI0IZnHQ8eM1BwSvyUYg3Vq8fE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575362; c=relaxed/simple; bh=qpYpssS45nruTsiAVK4hIr/DfAzCuG8bb/CkuI//dIU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eLXkGAVeUtC0qHZP3MzHZPIwFna0PjpG6sNQcjIwrUcOv7Qygylk6S5qerxmqdMdWGeZozvJpK/Zm5+7ucD8qt5pd+OQu2sAQZbPivoc/eMnVzoxDlgcYq14X5qMBYDwnz3VNQNdAXnGFsJ6sjz03Lpm7VzZVIp9VDSsC4dD6/0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=PH+W5njQ; arc=none smtp.client-ip=209.85.128.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="PH+W5njQ" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-41b79450f8cso43698915e9.3 for ; Wed, 01 May 2024 07:55:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714575358; x=1715180158; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=IikJd/LplXd0GAQdyekbojR8JRFhxUeGGR+Ui18yUXw=; b=PH+W5njQ+qduIHHTNik2dCCqKLDxCkqQYhfvagpK+2baB2vmBR85h3ZjuAg1N4cawV 83h+y3Y/48x1ShyzWC4qin/25cBked63oKulrHDmcLu/Qy/eADlZCiB+n6qnlCDIb+Zn I5TIdjIBv4tTKc5YdiF3ToVS8QToHz/4YZh5deJ2iBzWOuvuXxsCsHzh34cQDjqa0ptZ s25FIxXkBnMx2wFn111MMIRxBOfRvvmEdZEAyXVa0uY5LDx9ycq5NWLEmxz8uvfh1kcx M34bRrCejopZdNb2wVLCwPYJ/7UZvYj09Q2vbyccLdQRQybnTUa2bdVTdZowfv1Oad8y KGUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714575358; x=1715180158; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IikJd/LplXd0GAQdyekbojR8JRFhxUeGGR+Ui18yUXw=; b=H7YTY9WxojiX/K5mrA44HzMROqz02VjRh+tN5CPKOaCKr5S1Qmc664foPoz3UT+8GP LqvTbpT2Kyvx5foCUV9W8W8RJyXZcEWLLFVxK51erK44X8/jwl7prBXIVM7K4Zz/YHEM 5lbVrGayhIRPE8L4c2KFjEe26wOl3m7o0c9ZbLGnZHVS5dJciutR7mN+Gs9oOmaEZRok +823Qy+ihHsk2LruVelABVrnfop6YoUgeFQGuB3nSGp8U3vJS/Sybbv2AzyCdaOPE0Rm v3CTDyj3etoIG4bv8L1nXd2ArZWzCRLqSk3OTj1klaI3nXd0AC1roJBigzwngh9GU97c iOZg== X-Forwarded-Encrypted: i=1; AJvYcCXPpoCVSTsoXaYPims+XbnTago4GEhfteod24I6rules/TqsGSDGh3RVZgxtqTqwyym+xLpHOqckrg4G/OzryAOakrcZioJ2OPPLljS X-Gm-Message-State: AOJu0YzVLqRvMUfPqBHNnjEbsVJ/VmZHI8etbULTqjSc46Ccp1VF/xXU Kb/4l7qglTAynI7/kJnaUEOZNoUHy8yP0jFIGFOxhINj3VXXIj06AZteESpI/cI= X-Google-Smtp-Source: AGHT+IF4RI3DWH3O6s2iqU3cnNMEynbpVDI4WzhAtH0r6Hgxn6Ww74V8vUuYJ4goPrb2+hzQO9Uhhw== X-Received: by 2002:a05:600c:4751:b0:41b:4443:9e10 with SMTP id w17-20020a05600c475100b0041b44439e10mr1954285wmo.29.1714575358123; Wed, 01 May 2024 07:55:58 -0700 (PDT) Received: from [192.168.1.61] ([2a02:842a:d52e:6101:6fd0:6c4:5d68:f0a5]) by smtp.gmail.com with ESMTPSA id o27-20020a05600c511b00b00418a386c17bsm2422999wms.12.2024.05.01.07.55.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 07:55:57 -0700 (PDT) From: Julien Stephan Date: Wed, 01 May 2024 16:55:41 +0200 Subject: [PATCH RFC v6 08/10] iio: adc: ad7380: add oversampling 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: <20240501-adding-new-ad738x-driver-v6-8-3c0741154728@baylibre.com> References: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> In-Reply-To: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Liam Girdwood , Mark Brown Cc: kernel test robot , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Stephan X-Mailer: b4 0.13.0 ad7380x(-4) parts are able to do oversampling to increase accuracy. They support 2 average modes: normal average and rolling overage. This commits focus on enabling normal average oversampling, which is the default one. Normal averaging involves taking a number of samples, adding them together, and dividing the result by the number of samples taken. This result is then output from the device. The sample data is cleared when the process completes. Because we need more samples to output a value, the data output rate decrease with the oversampling ratio. Signed-off-by: Julien Stephan --- drivers/iio/adc/ad7380.c | 115 +++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index 020959759170..1e3869f5e48c 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -88,7 +88,10 @@ struct ad7380_chip_info { .type =3D IIO_VOLTAGE, \ .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | \ ((diff) ? 0 : BIT(IIO_CHAN_INFO_OFFSET)), \ - .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .info_mask_shared_by_type_available =3D \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ .indexed =3D 1, \ .differential =3D (diff), \ .channel =3D (diff) ? (2 * (index)) : (index), \ @@ -156,6 +159,16 @@ static const struct ad7380_timing_specs ad7380_4_timin= g =3D { .t_csh_ns =3D 20, }; =20 +/* + * Available oversampling ratios. The indices correspond + * with the bit value expected by the chip. + * The available ratios depend on the averaging mode, + * only normal averaging is supported for now + */ +static const int ad7380_normal_average_oversampling_ratios[] =3D { + 1, 2, 4, 8, 16, 32, +}; + static const struct ad7380_chip_info ad7380_chip_info =3D { .name =3D "ad7380", .channels =3D ad7380_channels, @@ -231,6 +244,7 @@ static const struct ad7380_chip_info ad7384_4_chip_info= =3D { struct ad7380_state { const struct ad7380_chip_info *chip_info; struct spi_device *spi; + unsigned int oversampling_ratio; struct regmap *regmap; unsigned int vref_mv; unsigned int vcm_mv[MAX_NUM_CHANNELS]; @@ -386,6 +400,12 @@ static int ad7380_read_direct(struct ad7380_state *st, }; int ret; =20 + /* + * In normal average oversampling we need to wait for multiple conversion= s to be done + */ + if (st->oversampling_ratio > 1) + xfers[0].delay.value =3D T_CONVERT_NS + 500 * st->oversampling_ratio; + ret =3D spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); if (ret < 0) return ret; @@ -428,6 +448,91 @@ static int ad7380_read_raw(struct iio_dev *indio_dev, / st->vref_mv; =20 return IIO_VAL_INT; + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + *val =3D st->oversampling_ratio; + + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int ad7380_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + *vals =3D ad7380_normal_average_oversampling_ratios; + *length =3D ARRAY_SIZE(ad7380_normal_average_oversampling_ratios); + *type =3D IIO_VAL_INT; + + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +/** + * check_osr - Check the oversampling ratio + * @available_ratio: available ratios's array + * @size: size of the available_ratio array + * ratio: ratio to check + * + * Check if ratio is present in @available_ratio. Check for exact match. + * @available_ratio is an array of the available ratios (depending on the = oversampling mode). + * The indices must correspond with the bit value expected by the chip. + */ +static inline int check_osr(const int *available_ratio, int size, int rati= o) +{ + int i; + + for (i =3D 0; i < size; i++) { + if (ratio =3D=3D available_ratio[i]) + return i; + } + + return -EINVAL; +} + +static int ad7380_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, + int val2, long mask) +{ + struct ad7380_state *st =3D iio_priv(indio_dev); + int ret, osr; + + switch (mask) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + osr =3D check_osr(ad7380_normal_average_oversampling_ratios, + ARRAY_SIZE(ad7380_normal_average_oversampling_ratios), + val); + + if (osr < 0) + return osr; + + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + ret =3D regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, + AD7380_CONFIG1_OSR, + FIELD_PREP(AD7380_CONFIG1_OSR, osr)); + + if (ret) + return ret; + + st->oversampling_ratio =3D val; + + /* + * Perform a soft reset. + * This will flush the oversampling block and FIFO but will + * maintain the content of the configurable registers. + */ + ret =3D regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2, + AD7380_CONFIG2_RESET, + FIELD_PREP(AD7380_CONFIG2_RESET, + AD7380_CONFIG2_RESET_SOFT)); + } + return 0; default: return -EINVAL; } @@ -435,6 +540,8 @@ static int ad7380_read_raw(struct iio_dev *indio_dev, =20 static const struct iio_info ad7380_info =3D { .read_raw =3D &ad7380_read_raw, + .read_avail =3D &ad7380_read_avail, + .write_raw =3D &ad7380_write_raw, .debugfs_reg_access =3D &ad7380_debugfs_reg_access, }; =20 @@ -458,6 +565,12 @@ static int ad7380_init(struct ad7380_state *st, struct= regulator *vref) if (ret < 0) return ret; =20 + /* Disable oversampling by default. + * This is the default value after reset, + * so just initialize internal data + */ + st->oversampling_ratio =3D 1; + /* SPI 1-wire mode */ return regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2, AD7380_CONFIG2_SDO, --=20 2.44.0 From nobody Wed Dec 17 23:27:15 2025 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B6601304B1 for ; Wed, 1 May 2024 14:56:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575362; cv=none; b=CSFGhaEPK7/KIfuqAjvl3GuaO2wcSOZ7iGNefElzkV9g+u2Wr+xHssSCKhKewsZC2JxTN4qXxJn/nxoOOCKngHopsPFoeCewEtzOCrg/N4K2TPFh2dDOrEWVFNp18oXZHCqUwflKDJYBGIbT2BLMsF9LOxOEQeHsPY3Z2lnzCOk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575362; c=relaxed/simple; bh=du2kLMCRp5o4P3dsqZNBM0LPI3ROwsmwvCGStfPCr9g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZdsQ1fiUwj1cmbVXNUVeg0uBe+FJbKk+QBGRWvUA9c45M9yb/MZG+WqqUwj32k4rQb+/zcXtPcX0/1HUPpHs93DSK0srQHyT8Tnv3NhonfBJ+Bl7ssxLaPrhy//vp9NjO4pBSJdtY5DJZVnjWEIKoOVo7Kr2AbhZ8ECFmJE+kHM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=poCE+KvX; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="poCE+KvX" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-41c7ac73fddso27494365e9.3 for ; Wed, 01 May 2024 07:56:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714575358; x=1715180158; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=i7y0HuhKkWvqsIGNuF6QczDFqnvdiHcoO8fQ4/iNtzs=; b=poCE+KvXhN7uuuX0pL6L7JRYd9h9vqK1UHnrTDzk++aiDicsWFywc7ez/GkXK4ZUjL 1AyVEDpt1a4+dBFv1ZjrX2BEqjFK307WOHsa/uwIramawIeevpY/qtvAt2X0CiHg3gaf XLV06rcITfHvxHe6XY0ayB2SlGXw0KgTixAbDmiH1Po+15FKlVTpmWlGPBc7sdN7EpzV bRntg2hag9F9ny6KmdI6ZM566SO7O2thZMHlWME5G/7bRj4HxonC3hT0HQQhZARw58OP RjTRynWtIbIYjWJVRSXAqoaXbuv8Inx4zgdIMimR/9KbayEgrJ+aHr9JkVmv5KWbu6os PWXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714575358; x=1715180158; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=i7y0HuhKkWvqsIGNuF6QczDFqnvdiHcoO8fQ4/iNtzs=; b=vKSLOXNw0efepsYmB8nC1kgDgnRCw/xzuaEzaqhjTkSJhZQS3eP4BY/9RatAtp/Jyp l3wU8Wunm7I0LsJPuYGCMwEB1TgSSqeYGr/ob9Cg5vb7yNtAVY89nHQFF4SkikRLYF+K Pehlb9Nq7aEGtq8ttZwtwL81Tu8qaqwI0Mu0xlmmSb9yuRawQ5ZRQrKstigsRDuMwSeN uE8/l9TfUTdpOBlggBscHcw/YdpBmCDMY95fktxBD5ARhS6g2dQN8O4AEt4PFz/dRODf SzduXqq0jWm//QvDxspDKoldpZCK6Y1i3bYQHb8N7PfdX2p/EwUQKVUEhYLns8APOgoj xLeg== X-Forwarded-Encrypted: i=1; AJvYcCVm8yJ+hXX2ekzAo60NdhqpRg8Zy7nDizVJvc3Vi16/8bf3j0BghLaMhD4igivjfZJvf2GeNFGmTOpflsQw+0LvSeOg5aokBBDVkWpy X-Gm-Message-State: AOJu0Yz7+1GPFfvevCeaol8fy5FNkFeALcWS6sgXewFMHIZd+lfRlPmb vg+lU/bN2pK0ASm+NavB9osXfImrHia+TGbMJu4c9SttopGSecrYJxHC4+4Tt5c= X-Google-Smtp-Source: AGHT+IFb+S1JZu/pjS1R0VAFDljvVUvKkc6fdJz5V7dgS2gKjVI2x4U7x6KqVf5Hme/wx0vVVUAkjg== X-Received: by 2002:a05:600c:5250:b0:41c:b44:f917 with SMTP id fc16-20020a05600c525000b0041c0b44f917mr2595394wmb.22.1714575358698; Wed, 01 May 2024 07:55:58 -0700 (PDT) Received: from [192.168.1.61] ([2a02:842a:d52e:6101:6fd0:6c4:5d68:f0a5]) by smtp.gmail.com with ESMTPSA id o27-20020a05600c511b00b00418a386c17bsm2422999wms.12.2024.05.01.07.55.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 07:55:58 -0700 (PDT) From: Julien Stephan Date: Wed, 01 May 2024 16:55:42 +0200 Subject: [PATCH RFC v6 09/10] iio: adc: ad7380: add support for rolling average oversampling mode 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: <20240501-adding-new-ad738x-driver-v6-9-3c0741154728@baylibre.com> References: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> In-Reply-To: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Liam Girdwood , Mark Brown Cc: kernel test robot , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Stephan X-Mailer: b4 0.13.0 Adds support for rolling average oversampling mode. Rolling oversampling mode uses a first in, first out (FIFO) buffer of the most recent samples in the averaging calculation, allowing the ADC throughput rate and output data rate to stay the same, since we only need to take only one sample for each new conversion. The FIFO length is 8, thus the available oversampling ratios are 1, 2, 4, 8 in this mode (vs 1, 2, 4, 8, 16, 32 for the normal average) In order to be able to change the averaging mode, this commit also adds the new "oversampling_mode" and "oversampling_mode_available" custom attributes along with the according documentation file in Documentation/ABI/testing/sysfs-bus-iio-adc-ad7380 since no standard attributes correspond to this use case. Signed-off-by: Julien Stephan --- Documentation/ABI/testing/sysfs-bus-iio-adc-ad7380 | 38 ++++++ MAINTAINERS | 1 + drivers/iio/adc/ad7380.c | 143 +++++++++++++++++= ++-- 3 files changed, 174 insertions(+), 8 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-bus-iio-adc-ad7380 b/Documenta= tion/ABI/testing/sysfs-bus-iio-adc-ad7380 new file mode 100644 index 000000000000..0a560ef3e32a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-adc-ad7380 @@ -0,0 +1,38 @@ +What: /sys/bus/iio/devices/iio:deviceX/oversampling_mode +KernelVersion: 6.9 +Contact: Michael Hennerich +Description: + Writing this attribute sets the oversampling average mode. + Reading it, shows the configured mode. + Available modes can be displayed using the oversampling_mode_available + attribute. + When writing this attribute to change the oversampling mode, this will + have the following side effects: + + - soft reset the ADC to flush the oversampling block and FIFO + + - the available oversampling ratios depend on the oversampling mode + configured so to avoid misconfiguration, changing the mode will di= sable + the oversampling by setting the ratio to 1. + + - the list of available ratios (displayed by reading the + oversampling_ratio_available attribute) will be updated when chang= ing + the oversampling mode. + +What: /sys/bus/iio/devices/iio:deviceX/oversampling_mode_available +KernelVersion: 6.9 +Contact: Michael Hennerich +Description: + Display the available oversampling average modes. The two available mo= des + are "normal" and "rolling" where "normal" average mode is the default = one. + + - normal averaging involves taking a number of samples, adding them + together, and dividing the result by the number of samples taken. + This result is then output from the device. The sample data is cle= ared + when the process completes. Because we need more samples to output= a + value, the data output rate decrease with the oversampling ratio. + + - rolling oversampling mode uses a first in, first out (FIFO) buffer= of + the most recent samples in the averaging calculation, allowing the= ADC + throughput rate and output data rate to stay the same, since we on= ly need + to take only one sample for each new conversion. diff --git a/MAINTAINERS b/MAINTAINERS index 87724a9e9f9f..ca1e115f2aff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -434,6 +434,7 @@ R: David Lechner S: Supported W: https://wiki.analog.com/resources/tools-software/linux-drivers/iio-adc/= ad738x W: https://ez.analog.com/linux-software-drivers +F: Documentation/ABI/testing/sysfs-bus-iio-adc-ad7380 F: Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml F: drivers/iio/adc/ad7380.c =20 diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index 1e3869f5e48c..7b021bb9cf87 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -51,6 +51,8 @@ #define AD7380_REG_ADDR_ALERT_HIGH_TH 0x5 =20 #define AD7380_CONFIG1_OS_MODE BIT(9) +#define OS_MODE_NORMAL_AVERAGE 0 +#define OS_MODE_ROLLING_AVERAGE 1 #define AD7380_CONFIG1_OSR GENMASK(8, 6) #define AD7380_CONFIG1_CRC_W BIT(5) #define AD7380_CONFIG1_CRC_R BIT(4) @@ -159,16 +161,27 @@ static const struct ad7380_timing_specs ad7380_4_timi= ng =3D { .t_csh_ns =3D 20, }; =20 +/* + * Available oversampling modes. + */ +static const char * const ad7380_oversampling_average_modes[] =3D { + [OS_MODE_NORMAL_AVERAGE] =3D "normal", + [OS_MODE_ROLLING_AVERAGE] =3D "rolling", +}; + /* * Available oversampling ratios. The indices correspond * with the bit value expected by the chip. - * The available ratios depend on the averaging mode, - * only normal averaging is supported for now + * The available ratios depend on the averaging mode. */ static const int ad7380_normal_average_oversampling_ratios[] =3D { 1, 2, 4, 8, 16, 32, }; =20 +static const int ad7380_rolling_average_oversampling_ratios[] =3D { + 1, 2, 4, 8, +}; + static const struct ad7380_chip_info ad7380_chip_info =3D { .name =3D "ad7380", .channels =3D ad7380_channels, @@ -244,6 +257,7 @@ static const struct ad7380_chip_info ad7384_4_chip_info= =3D { struct ad7380_state { const struct ad7380_chip_info *chip_info; struct spi_device *spi; + unsigned int oversampling_mode; unsigned int oversampling_ratio; struct regmap *regmap; unsigned int vref_mv; @@ -403,7 +417,7 @@ static int ad7380_read_direct(struct ad7380_state *st, /* * In normal average oversampling we need to wait for multiple conversion= s to be done */ - if (st->oversampling_ratio > 1) + if (st->oversampling_mode =3D=3D OS_MODE_NORMAL_AVERAGE && st->oversampli= ng_ratio > 1) xfers[0].delay.value =3D T_CONVERT_NS + 500 * st->oversampling_ratio; =20 ret =3D spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); @@ -462,10 +476,22 @@ static int ad7380_read_avail(struct iio_dev *indio_de= v, const int **vals, int *type, int *length, long mask) { + struct ad7380_state *st =3D iio_priv(indio_dev); + switch (mask) { case IIO_CHAN_INFO_OVERSAMPLING_RATIO: - *vals =3D ad7380_normal_average_oversampling_ratios; - *length =3D ARRAY_SIZE(ad7380_normal_average_oversampling_ratios); + switch (st->oversampling_mode) { + case OS_MODE_NORMAL_AVERAGE: + *vals =3D ad7380_normal_average_oversampling_ratios; + *length =3D ARRAY_SIZE(ad7380_normal_average_oversampling_ratios); + break; + case OS_MODE_ROLLING_AVERAGE: + *vals =3D ad7380_rolling_average_oversampling_ratios; + *length =3D ARRAY_SIZE(ad7380_rolling_average_oversampling_ratios); + break; + default: + return -EINVAL; + } *type =3D IIO_VAL_INT; =20 return IIO_AVAIL_LIST; @@ -505,9 +531,20 @@ static int ad7380_write_raw(struct iio_dev *indio_dev, =20 switch (mask) { case IIO_CHAN_INFO_OVERSAMPLING_RATIO: - osr =3D check_osr(ad7380_normal_average_oversampling_ratios, - ARRAY_SIZE(ad7380_normal_average_oversampling_ratios), - val); + switch (st->oversampling_mode) { + case OS_MODE_NORMAL_AVERAGE: + osr =3D check_osr(ad7380_normal_average_oversampling_ratios, + ARRAY_SIZE(ad7380_normal_average_oversampling_ratios), + val); + break; + case OS_MODE_ROLLING_AVERAGE: + osr =3D check_osr(ad7380_rolling_average_oversampling_ratios, + ARRAY_SIZE(ad7380_rolling_average_oversampling_ratios), + val); + break; + default: + return -EINVAL; + } =20 if (osr < 0) return osr; @@ -538,7 +575,96 @@ static int ad7380_write_raw(struct iio_dev *indio_dev, } } =20 +static ssize_t oversampling_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ad7380_state *st =3D iio_priv(dev_to_iio_dev(dev)); + unsigned int os_mode; + + os_mode =3D st->oversampling_mode; + + return sysfs_emit(buf, "%s\n", ad7380_oversampling_average_modes[os_mode]= ); +} + +static ssize_t oversampling_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev =3D dev_to_iio_dev(dev); + struct ad7380_state *st =3D iio_priv(indio_dev); + int os_mode, ret; + + ret =3D sysfs_match_string(ad7380_oversampling_average_modes, buf); + if (ret < 0) + return ret; + + os_mode =3D ret; + + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + ret =3D regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, + AD7380_CONFIG1_OS_MODE, + FIELD_PREP(AD7380_CONFIG1_OS_MODE, os_mode)); + + if (ret) + return ret; + + st->oversampling_mode =3D os_mode; + + /* + * Oversampling ratio depends on oversampling mode, to avoid + * misconfiguration when changing oversampling mode, + * disable oversampling by setting OSR to 0. + */ + ret =3D regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, + AD7380_CONFIG1_OSR, FIELD_PREP(AD7380_CONFIG1_OSR, 0)); + + if (ret) + return ret; + + st->oversampling_ratio =3D 1; + + /* + * Perform a soft reset. + * This will flush the oversampling block and FIFO but will + * maintain the content of the configurable registers. + */ + ret =3D regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2, + AD7380_CONFIG2_RESET, + FIELD_PREP(AD7380_CONFIG2_RESET, + AD7380_CONFIG2_RESET_SOFT)); + } + return ret ?: len; +} + +static ssize_t oversampling_mode_available_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i; + size_t len =3D 0; + + for (i =3D 0; i < ARRAY_SIZE(ad7380_oversampling_average_modes); i++) + len +=3D sysfs_emit_at(buf, len, "%s ", ad7380_oversampling_average_mode= s[i]); + + buf[len - 1] =3D '\n'; + + return len; +} + +static IIO_DEVICE_ATTR_RW(oversampling_mode, 0); +static IIO_DEVICE_ATTR_RO(oversampling_mode_available, 0); + +static struct attribute *ad7380_attributes[] =3D { + &iio_dev_attr_oversampling_mode.dev_attr.attr, + &iio_dev_attr_oversampling_mode_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group ad7380_attribute_group =3D { + .attrs =3D ad7380_attributes, +}; + static const struct iio_info ad7380_info =3D { + .attrs =3D &ad7380_attribute_group, .read_raw =3D &ad7380_read_raw, .read_avail =3D &ad7380_read_avail, .write_raw =3D &ad7380_write_raw, @@ -569,6 +695,7 @@ static int ad7380_init(struct ad7380_state *st, struct = regulator *vref) * This is the default value after reset, * so just initialize internal data */ + st->oversampling_mode =3D OS_MODE_NORMAL_AVERAGE; st->oversampling_ratio =3D 1; =20 /* SPI 1-wire mode */ --=20 2.44.0 From nobody Wed Dec 17 23:27:15 2025 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA912130A65 for ; Wed, 1 May 2024 14:56:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575364; cv=none; b=GK6gbA8TA0OVKqZctyo4pAaSPdX7mEq+IAfW6z47V2gwmiicvt7EZRW7Hf+/pMiLlMW74+95qHD/lcl6D4/ymBA7OPcVaOlRKg1LAxlJvhjH4dqdrtn3x+ReLv8sdexl8LysEnb00p4uV1GA7tzh2CkNiS8ZXvEU7Y90AbTsVLA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714575364; c=relaxed/simple; bh=fPiWODpLyIpk8mbW8S6s/JMkotwnMO8eXB66C821A4Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fmXXh4Yg+ccMNZXef8rcWDWglAZY6nxr51hKp9uc2hEZAKPs/8LsgEYb9p6RD+AWDAmTDUDofnD0q0UNRY4IUB3FsQ3ljdxmh52kjnfs99OpezXu1TVe2WQpOloFnkFWzZUMFtVHvKJ0l6ceVk9hzN0kSBGZvd74or3FP0ACCdo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=GpHwOJ+8; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="GpHwOJ+8" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-41ba1ba5591so37516695e9.1 for ; Wed, 01 May 2024 07:56:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1714575360; x=1715180160; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=nQvEn6eTVpgZ7ge0YdIc6SxCVLT/jwgprRg33qL4bbM=; b=GpHwOJ+8ic/QRgOaFULe4pEsyJRBTLRHzpL6+HJs/LuHH6LX6a39AupxOfj6HFlacS meenSSYKKw6LCQzhwcmdYvKbMGvZAjWwLsartU9ndvsHxjoVaaaCFQ5kprmiDnP2qyWv lXlJJFeiMSM4WsCZKL4/QqBbgKooTRat1Xximzm2VCSxEo/byGSxFDEJO3RKYtRxXylr d5IVpzQcDSdYLOrzWvMkP/P/7jrfcktOg/8UsdUm8Q0/7q478KOEPp3pz0L0njXlKLXt pkF9ksHPl3Q0DMspWaOzXMXhA2E30oy7AnhCnOkUj78y31PXKClW0TJLfMqjccYx+iRP bG1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714575360; x=1715180160; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nQvEn6eTVpgZ7ge0YdIc6SxCVLT/jwgprRg33qL4bbM=; b=aGY+iAukhAsLMl3ABQd3VYQKsFFsxYo5AXQdyL0SHSTpn2gk8c6SJCZZSa3kbiU2Pz kx77DJKPP9ioX+uhv4emc5PAtwiTJK08X29/OvNp2hWgikY0bww24gy/GEYmxSkhaUdR zfPxq0TcDQLCRI4ba8dlrKop0nojDNHJ0U2RNk+baQh2750AidCL7RkGRo1UpK5/Nsk3 Ro35CmSRJfV+hhuOYlBpfoLUrIlDC3nS183Hilaj5+dj71s7S3I8mBhwbkK0hrTWM2C0 bCyTJfYskTEIJbk2izrpUUvvgR1a3bbJahIMsEo5RF6BYzOTsseQcXGXQCOwQs3XojR6 5Zww== X-Forwarded-Encrypted: i=1; AJvYcCU6XIQG1TWlazMJL6vQXiHPeJ7XgRBUhu7W8+CBTVDbd4HJgtPI4I6OPJiE5sWCWdL5tbS+sMgaC5NKtHWmb3v+iVKsaVcvveRqn4Fz X-Gm-Message-State: AOJu0YxQW4HCGO0uASOi3dia51GPFveQw9povZKqlWjTpPvoKDW+cHQC NPfL/mNH/Zpfa7m8OQj6/b768m8dePlEm1a0zV/cWgLeNKTH2x3ojloxGhk+oIo= X-Google-Smtp-Source: AGHT+IFPiOA5OgO2LcEiOeQ9z95Elxo3H/VFN/MqqHOCNEN/VLCkZAllpFjJjc9lb1KKraoJW4trZQ== X-Received: by 2002:a05:600c:3148:b0:416:536b:683a with SMTP id h8-20020a05600c314800b00416536b683amr1823734wmo.32.1714575360127; Wed, 01 May 2024 07:56:00 -0700 (PDT) Received: from [192.168.1.61] ([2a02:842a:d52e:6101:6fd0:6c4:5d68:f0a5]) by smtp.gmail.com with ESMTPSA id o27-20020a05600c511b00b00418a386c17bsm2422999wms.12.2024.05.01.07.55.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 01 May 2024 07:55:59 -0700 (PDT) From: Julien Stephan Date: Wed, 01 May 2024 16:55:43 +0200 Subject: [PATCH RFC v6 10/10] iio: adc: ad7380: add support for resolution boost 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: <20240501-adding-new-ad738x-driver-v6-10-3c0741154728@baylibre.com> References: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> In-Reply-To: <20240501-adding-new-ad738x-driver-v6-0-3c0741154728@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , David Lechner , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Liam Girdwood , Mark Brown Cc: kernel test robot , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Julien Stephan X-Mailer: b4 0.13.0 ad738x chips are able to use an additional 2 bits of resolution when using oversampling. The 14-bits chips can have up to 16 bits of resolution and the 16-bits chips can have up to 18 bits of resolution. In order to dynamically allow to enable/disable the resolution boost feature, we have to set iio realbits/storagebits to the maximum per chips. This means that for iio, data will always be on the higher resolution available, and to cope with that we adjust the iio scale and iio offset depending on the resolution boost status. The available scales can be displayed using the regular _scale_available attributes and can be set by writing the regular _scale attribute. The available scales depend on the oversampling status. Signed-off-by: Julien Stephan --- In order to support the resolution boost (additional 2 bits of resolution) we need to set realbits/storagebits to the maximum value i.e : - realbits =3D 16 + 2 =3D 18, and storagebits =3D 32 for 16-bits chips - realbits =3D 14 + 2 =3D 16, and storagebits =3D 16 for 14-bits chips For 14-bits chips this does not have a major impact, but this has the drawback of forcing 16-bits chip users to always use 32-bits words in buffers even if they are not using oversampling and resolution boost. Is there a better way of implementing this? For example implementing dynamic scan_type? Another issue is the location of the timestamps. I understood the need for ts to be consistent between chips, but right now I do not have a better solution.. I was thinking of maybe adding the timestamps at the beginning? That would imply to change the iio_chan_spec struct and maybe add a iio_push_to_buffers_with_timestamp_first() wrapper function? Is that an option? Any suggestion would be very much appreciated. --- drivers/iio/adc/ad7380.c | 226 ++++++++++++++++++++++++++++++++++++++++---= ---- 1 file changed, 194 insertions(+), 32 deletions(-) diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index 7b021bb9cf87..e240098708e9 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,8 @@ #define AD7380_CONFIG1_CRC_R BIT(4) #define AD7380_CONFIG1_ALERTEN BIT(3) #define AD7380_CONFIG1_RES BIT(2) +#define RESOLUTION_BOOST_DISABLE 0 +#define RESOLUTION_BOOST_ENABLE 1 #define AD7380_CONFIG1_REFSEL BIT(1) #define AD7380_CONFIG1_PMODE BIT(0) =20 @@ -86,6 +89,14 @@ struct ad7380_chip_info { const struct ad7380_timing_specs *timing_specs; }; =20 +/* + * realbits/storagebits cannot be dynamically changed, so in order to + * support the resolution boost (additional 2 bits of resolution) + * we need to set realbits/storagebits to the maximum value i.e : + * - realbits =3D 16 + 2 =3D 18, and storagebits =3D 32 for 16-bits chips + * - realbits =3D 14 + 2 =3D 16, and storagebits =3D 16 for 14-bits chips + * We need to adjust the scale depending on resolution boost status + */ #define AD7380_CHANNEL(index, bits, diff) { \ .type =3D IIO_VOLTAGE, \ .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW) | \ @@ -93,6 +104,7 @@ struct ad7380_chip_info { .info_mask_shared_by_type =3D BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ .info_mask_shared_by_type_available =3D \ + BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ .indexed =3D 1, \ .differential =3D (diff), \ @@ -101,8 +113,8 @@ struct ad7380_chip_info { .scan_index =3D (index), \ .scan_type =3D { \ .sign =3D 's', \ - .realbits =3D (bits), \ - .storagebits =3D 16, \ + .realbits =3D (bits) + 2, \ + .storagebits =3D ((bits) + 2 > 16) ? 32 : 16, \ .endianness =3D IIO_CPU, \ }, \ } @@ -259,6 +271,8 @@ struct ad7380_state { struct spi_device *spi; unsigned int oversampling_mode; unsigned int oversampling_ratio; + unsigned int scales[2][2]; + bool resolution_boost_enable; struct regmap *regmap; unsigned int vref_mv; unsigned int vcm_mv[MAX_NUM_CHANNELS]; @@ -270,7 +284,10 @@ struct ad7380_state { * As MAX_NUM_CHANNELS is 4 the layout of the structure is the same for a= ll parts */ struct { - u16 raw[MAX_NUM_CHANNELS]; + union { + u16 u16[MAX_NUM_CHANNELS]; + u32 u32[MAX_NUM_CHANNELS]; + } raw; =20 s64 ts __aligned(8); } scan_data __aligned(IIO_DMA_MINALIGN); @@ -359,23 +376,67 @@ static int ad7380_debugfs_reg_access(struct iio_dev *= indio_dev, u32 reg, unreachable(); } =20 +static int ad7380_prepare_spi_xfer(struct ad7380_state *st, struct spi_tra= nsfer *xfer) +{ + int bits_per_word; + + memset(xfer, 0, sizeof(*xfer)); + + xfer->rx_buf =3D &st->scan_data.raw; + + if (st->resolution_boost_enable =3D=3D RESOLUTION_BOOST_ENABLE) + bits_per_word =3D st->chip_info->channels[0].scan_type.realbits; + else + bits_per_word =3D st->chip_info->channels[0].scan_type.realbits - 2; + + xfer->bits_per_word =3D bits_per_word; + + xfer->len =3D (st->chip_info->num_channels - 1) * BITS_TO_BYTES(bits_per_= word); + + return bits_per_word; +} + static irqreturn_t ad7380_trigger_handler(int irq, void *p) { struct iio_poll_func *pf =3D p; struct iio_dev *indio_dev =3D pf->indio_dev; struct ad7380_state *st =3D iio_priv(indio_dev); - struct spi_transfer xfer =3D { - .bits_per_word =3D st->chip_info->channels[0].scan_type.realbits, - .len =3D (st->chip_info->num_channels - 1) * - BITS_TO_BYTES(st->chip_info->channels->scan_type.storagebits), - .rx_buf =3D st->scan_data.raw, - }; - int ret; + struct spi_transfer xfer; + int bits_per_word, realbits, i, ret; + + realbits =3D st->chip_info->channels[0].scan_type.realbits; + bits_per_word =3D ad7380_prepare_spi_xfer(st, &xfer); =20 ret =3D spi_sync_transfer(st->spi, &xfer, 1); if (ret) goto out; =20 + /* + * If bits_per_word =3D=3D realbits (resolution boost enabled), we don't + * need to manipulate the raw data, otherwise we may need to fix things + * up a bit to fit the scan_type specs + */ + if (bits_per_word < realbits) { + if (realbits > 16 && bits_per_word <=3D 16) { + /* + * Here realbits > 16 so storagebits is 32 and bits_per_word is <=3D 16 + * so we need to sign extend u16 to u32 using reverse order to + * avoid writing over union data + */ + for (i =3D st->chip_info->num_channels - 2; i >=3D 0; i--) + st->scan_data.raw.u32[i] =3D sign_extend32(st->scan_data.raw.u16[i], + bits_per_word - 1); + } else if (bits_per_word < 16) { + /* + * Here realbits <=3D 16 so storagebits is 16. + * We only need to sign extend only if bits_per_word is < 16 + */ + for (i =3D 0; i < st->chip_info->num_channels - 1; i++) + st->scan_data.raw.u16[i] =3D sign_extend32(st->scan_data.raw.u16[i], + bits_per_word - 1); + } + } + iio_push_to_buffers_with_timestamp(indio_dev, &st->scan_data, pf->timestamp); =20 @@ -388,7 +449,7 @@ static irqreturn_t ad7380_trigger_handler(int irq, void= *p) static int ad7380_read_direct(struct ad7380_state *st, struct iio_chan_spec const *chan, int *val) { - struct spi_transfer xfers[] =3D { + struct spi_transfer xfers[2] =3D { /* toggle CS (no data xfer) to trigger a conversion */ { .speed_hz =3D AD7380_REG_WR_SPEED_HZ, @@ -403,16 +464,11 @@ static int ad7380_read_direct(struct ad7380_state *st, .unit =3D SPI_DELAY_UNIT_NSECS, }, }, - /* then read all channels */ + /* then read all channels, it will be filled by ad7380_prepare_spi_xfer = */ { - .speed_hz =3D AD7380_REG_WR_SPEED_HZ, - .bits_per_word =3D chan->scan_type.realbits, - .rx_buf =3D st->scan_data.raw, - .len =3D (st->chip_info->num_channels - 1) * - ((chan->scan_type.storagebits > 16) ? 4 : 2), }, }; - int ret; + int bits_per_word, ret; =20 /* * In normal average oversampling we need to wait for multiple conversion= s to be done @@ -420,12 +476,18 @@ static int ad7380_read_direct(struct ad7380_state *st, if (st->oversampling_mode =3D=3D OS_MODE_NORMAL_AVERAGE && st->oversampli= ng_ratio > 1) xfers[0].delay.value =3D T_CONVERT_NS + 500 * st->oversampling_ratio; =20 + bits_per_word =3D ad7380_prepare_spi_xfer(st, &xfers[1]); + ret =3D spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); if (ret < 0) return ret; =20 - *val =3D sign_extend32(st->scan_data.raw[chan->scan_index], - chan->scan_type.realbits - 1); + if (bits_per_word > 16) + *val =3D sign_extend32(st->scan_data.raw.u32[chan->scan_index], + bits_per_word - 1); + else + *val =3D sign_extend32(st->scan_data.raw.u16[chan->scan_index], + bits_per_word - 1); =20 return IIO_VAL_INT; } @@ -435,6 +497,12 @@ static int ad7380_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long info) { struct ad7380_state *st =3D iio_priv(indio_dev); + int realbits; + + if (st->resolution_boost_enable =3D=3D RESOLUTION_BOOST_ENABLE) + realbits =3D chan->scan_type.realbits; + else + realbits =3D chan->scan_type.realbits - 2; =20 switch (info) { case IIO_CHAN_INFO_RAW: @@ -443,22 +511,16 @@ static int ad7380_read_raw(struct iio_dev *indio_dev, } unreachable(); case IIO_CHAN_INFO_SCALE: - /* - * According to the datasheet, the LSB size is: - * * (2 =C3=97 VREF) / 2^N, for differential chips - * * VREF / 2^N, for pseudo-differential chips - * where N is the ADC resolution (i.e realbits) - */ - *val =3D st->vref_mv; - *val2 =3D chan->scan_type.realbits - chan->differential; + *val =3D st->scales[st->resolution_boost_enable][0]; + *val2 =3D st->scales[st->resolution_boost_enable][1]; =20 - return IIO_VAL_FRACTIONAL_LOG2; + return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_OFFSET: /* * According to IIO ABI, offset is applied before scale, * so offset is: vcm_mv / scale */ - *val =3D st->vcm_mv[chan->channel] * (1 << chan->scan_type.realbits) + *val =3D st->vcm_mv[chan->channel] * (1 << realbits) / st->vref_mv; =20 return IIO_VAL_INT; @@ -494,6 +556,24 @@ static int ad7380_read_avail(struct iio_dev *indio_dev, } *type =3D IIO_VAL_INT; =20 + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SCALE: + *vals =3D (const int *)st->scales[0]; + /* + * Values are stored into a 2D matrix. + * We have 2 available scales depending on the resolution boost status + * (enabled/disabled). Resolution boost can be enabled only when oversam= pling + * is enabled (i.e OSR > 1). + * So depending on the oversampling ratio we display only the currently + * available scales. First scale is for normal mode, second scale is for= resolution + * boost enabled. + */ + if (st->oversampling_ratio > 1) + *length =3D 4; + else + *length =3D 2; + *type =3D IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; default: return -EINVAL; @@ -522,6 +602,25 @@ static inline int check_osr(const int *available_ratio= , int size, int ratio) return -EINVAL; } =20 +static int ad7380_set_resolution_boost(struct iio_dev *indio_dev, bool ena= ble) +{ + struct ad7380_state *st =3D iio_priv(indio_dev); + int ret; + + if (st->resolution_boost_enable =3D=3D enable) + return 0; + + ret =3D regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, + AD7380_CONFIG1_RES, + FIELD_PREP(AD7380_CONFIG1_RES, enable)); + + if (ret) + return ret; + + st->resolution_boost_enable =3D enable; + return 0; +} + static int ad7380_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) @@ -559,6 +658,13 @@ static int ad7380_write_raw(struct iio_dev *indio_dev, =20 st->oversampling_ratio =3D val; =20 + /* + * If oversampling is disabled (OSR =3D=3D 1), + * we need to disable resolution boost + */ + if (st->oversampling_ratio =3D=3D 1) + ad7380_set_resolution_boost(indio_dev, RESOLUTION_BOOST_DISABLE); + /* * Perform a soft reset. * This will flush the oversampling block and FIFO but will @@ -570,6 +676,25 @@ static int ad7380_write_raw(struct iio_dev *indio_dev, AD7380_CONFIG2_RESET_SOFT)); } return 0; + case IIO_CHAN_INFO_SCALE: + if (val =3D=3D st->scales[RESOLUTION_BOOST_DISABLE][0] && + val2 =3D=3D st->scales[RESOLUTION_BOOST_DISABLE][1]) { + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + return ad7380_set_resolution_boost(indio_dev, + RESOLUTION_BOOST_DISABLE); + } + unreachable(); + } + if (st->oversampling_ratio > 1 && + val =3D=3D st->scales[RESOLUTION_BOOST_ENABLE][0] && + val2 =3D=3D st->scales[RESOLUTION_BOOST_ENABLE][1]) { + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + return ad7380_set_resolution_boost(indio_dev, + RESOLUTION_BOOST_ENABLE); + } + unreachable(); + } + return -EINVAL; default: return -EINVAL; } @@ -614,6 +739,8 @@ static ssize_t oversampling_mode_store(struct device *d= ev, * Oversampling ratio depends on oversampling mode, to avoid * misconfiguration when changing oversampling mode, * disable oversampling by setting OSR to 0. + * Since we disable the oversampling, we also need to + * disable the resolution boost */ ret =3D regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, AD7380_CONFIG1_OSR, FIELD_PREP(AD7380_CONFIG1_OSR, 0)); @@ -622,6 +749,7 @@ static ssize_t oversampling_mode_store(struct device *d= ev, return ret; =20 st->oversampling_ratio =3D 1; + ad7380_set_resolution_boost(indio_dev, RESOLUTION_BOOST_DISABLE); =20 /* * Perform a soft reset. @@ -671,6 +799,36 @@ static const struct iio_info ad7380_info =3D { .debugfs_reg_access =3D &ad7380_debugfs_reg_access, }; =20 +static void ad7380_init_available_scales(struct ad7380_state *st) +{ + s64 tmp; + int value_micro, value_int, realbits, differential; + + /* + * Resolution boost allow to enable 2 higher bits resolution + * when oversampling is enabled, so we can have only two + * scales depending on the resolution boost status. + */ + realbits =3D st->chip_info->channels[0].scan_type.realbits; + differential =3D st->chip_info->channels[0].differential; + + /* + * According to the datasheet, the LSB size is: + * * (2 =C3=97 VREF) / 2^N, for differential chips + * * VREF / 2^N, for pseudo-differential chips + * where N is the ADC resolution (i.e realbits) + */ + tmp =3D (s64)st->vref_mv * MEGA >> (realbits - 2 - differential); + value_int =3D div_s64_rem(tmp, MEGA, &value_micro); + st->scales[RESOLUTION_BOOST_DISABLE][0] =3D value_int; + st->scales[RESOLUTION_BOOST_DISABLE][1] =3D value_micro; + + tmp =3D (s64)st->vref_mv * MEGA >> (realbits - differential); + value_int =3D div_s64_rem(tmp, MEGA, &value_micro); + st->scales[RESOLUTION_BOOST_ENABLE][0] =3D value_int; + st->scales[RESOLUTION_BOOST_ENABLE][1] =3D value_micro; +} + static int ad7380_init(struct ad7380_state *st, struct regulator *vref) { int ret; @@ -691,12 +849,16 @@ static int ad7380_init(struct ad7380_state *st, struc= t regulator *vref) if (ret < 0) return ret; =20 - /* Disable oversampling by default. - * This is the default value after reset, + /* Disable oversampling and resolution boost by default. + * This are the default values after reset, * so just initialize internal data */ st->oversampling_mode =3D OS_MODE_NORMAL_AVERAGE; st->oversampling_ratio =3D 1; + st->resolution_boost_enable =3D RESOLUTION_BOOST_DISABLE; + + /* initialize available scales */ + ad7380_init_available_scales(st); =20 /* SPI 1-wire mode */ return regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2, --=20 2.44.0