From nobody Mon Feb 9 17:27:30 2026 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (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 323641991B5 for ; Thu, 29 Aug 2024 12:33:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934800; cv=none; b=VNssarLUnHtO6alEQxnHL6TIKbKwNooSHt+rEaetekGASJIJmyt2NEk0sArKazkgrY4fpJ+woj0RJL4GHmnW/O/OxJuLr1krA8pItpmTXQKLI8x+7J+0ANzCURIhOnHyqRNby04A2UunXFr3MRy6J/J0+8jztxJ8m+dp2wpC+90= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934800; c=relaxed/simple; bh=E1ArSvYWlEKg2mj8U4mUHAOngGGn/icyww8fVMtpx+4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RzThKsyi8tNZ2uUuwNAN9STkUGsBu3zPrK5Ol9KqSbCNKS4BCTK4spgUef42r3zqPUTeTde0JTyX5RirGh92kOiAChzIcWAAlEVg1cPWeiwDJ3cX2aQnxyekEWow9+rXdlv79jjT46eiph5eB7v8m3Fodg4goiLqEk1/gRINFyM= 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=2V+wQm2z; arc=none smtp.client-ip=209.85.221.49 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="2V+wQm2z" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-371b97cfd6fso370580f8f.2 for ; Thu, 29 Aug 2024 05:33:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1724934796; x=1725539596; 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=XSbzKoZMSzlZLqSuQFsdX/6ISDzmO2lC8VpPGyPhuxI=; b=2V+wQm2zT6gV+I9dc2MhicjZTAz2TUjFB4pxuBfiTF4hTg2I65pvfNTd5SGsTuosVo FRRaWovJrAiDEXc/Qdmtei8CVQHOc7hZOarKFxkSS72CQbQKarQeHA6dOq6xSxab8cOV 3O/5gEaqoP5p9frAI9eFEbzReoG62eoi7KLEMDO08izTAjBM7BCtCtqY0/Rnzo8R8Gtg 5uj6bDDgegh6OpVPhV14hQr+eroPwANtNBLculJ70Q9o17U5pN1uUhnWVjz1qKotOEmI mYvoiUeyo2vuC8ZTwN4qHQ54qSCSqgb4DZi3jfqMyO3Pxg04P02I/mSoGbDv/29pmDqV YhAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724934796; x=1725539596; 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=XSbzKoZMSzlZLqSuQFsdX/6ISDzmO2lC8VpPGyPhuxI=; b=nvPOSAWCmBoN2Isc+cEY41JGNE3o9IPXyIlEhzLl3Lwkq10Rb/OxaPA5Md5PGWxVD3 EV2so3Y/JqMj0oP4P8ffVrRUVTF5cHPADpI8dDVQ5SsVE8Iq4GLoaTlU78UtnCcg3cwj 56FPJMEDW1OZujMWF71mRTySOvIVuE4lzi/1Wk3uZ0VLCzp3ws2sB0ZHPSNqqyFtADPf 6FqdU1q1To8AEJOm6A3swqZ0SD04ru9660ZSNcANl9eu3HPnXTd/3+LCztPRJoyGdbyc OpzWHMAYOMUcUc12WREr5uhngbFmi79Hru7ATyQ9/LmGHn/o4luY+OJOKrcJ1mwSI5P7 744A== X-Forwarded-Encrypted: i=1; AJvYcCU8y+jh3dsY9IsqgQnWuRKAUokmgFQ6jJUpJfWFwXIViHTG/VyAMLufWkrFP1L/gV09T/LWnINityzK8CI=@vger.kernel.org X-Gm-Message-State: AOJu0YzUrDjf8KuypHrO49pSAkE4/sue8E1eK2ZDdzt6tKEw2Eh5opR2 qTjUOBqnCL8IJyrXGwM9cZHAzJoe6MQXw55hHK2dy7NrSJK8R2JNyBInfVJ0HH2hJFiSbvErV58 Z X-Google-Smtp-Source: AGHT+IGdX+6BPRfUeoPV/k4K2aySBQ9Gqbyh0fWcL2k663Xqq0qtlZFTMJAWVJqZU/yqDbbxq9Fvzg== X-Received: by 2002:a05:6000:8e:b0:360:7812:6abc with SMTP id ffacd0b85a97d-3749b5890ecmr1729426f8f.60.1724934795974; Thu, 29 Aug 2024 05:33:15 -0700 (PDT) Received: from [127.0.1.1] (host-95-233-232-76.retail.telecomitalia.it. [95.233.232.76]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3749ee9978bsm1315042f8f.49.2024.08.29.05.33.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Aug 2024 05:33:15 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 29 Aug 2024 14:31:59 +0200 Subject: [PATCH RFC 1/8] dt-bindings: iio: dac: ad3552r: add io-backend property 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: <20240829-wip-bl-ad3552r-axi-v0-v1-1-b6da6015327a@baylibre.com> References: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> In-Reply-To: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello There is a version AXI DAC IP block (for FPGAs) that provides a physical bus for AD3552R and similar chips. This can be used instead of a typical SPI controller to be able to use the chip in ways that typical SPI controllers are not capable of. The binding is modified so that either the device is a SPI peripheral or it uses an io-backend. Signed-off-by: Angelo Dureghello --- .../devicetree/bindings/iio/dac/adi,ad3552r.yaml | 39 ++++++++++++++++++= ++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml b/D= ocumentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml index fc8b97f82077..1874486229ad 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml @@ -60,12 +60,34 @@ properties: $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 1, 2, 3] =20 + io-backends: + description: The iio backend reference. + An example backend can be found at + https://analogdevicesinc.github.io/hdl/library/axi_ad3552r/index.h= tml + maxItems: 1 + '#address-cells': const: 1 =20 '#size-cells': const: 0 =20 +if: + required: + - reg + +then: + $ref: /schemas/spi/spi-peripheral-props.yaml# + + properties: + io-backends: false + + required: [ spi-max-frequency ] + +else: + required: + - io-backends + patternProperties: "^channel@([0-1])$": type: object @@ -207,8 +229,6 @@ allOf: =20 required: - compatible - - reg - - spi-max-frequency =20 additionalProperties: false =20 @@ -238,4 +258,19 @@ examples: }; }; }; + + - | + fpga_axi { + ad3552r { + compatible =3D "adi,ad3552r"; + reset-gpios =3D <&gpio0 92 1>; + io-backends =3D <&backend>; + #address-cells =3D <1>; + #size-cells =3D <0>; + channel@0 { + reg =3D <0>; + adi,output-range-microvolt =3D <(-5000000) (5000000)>; + }; + }; + }; ... --=20 2.45.0.rc1 From nobody Mon Feb 9 17:27:30 2026 Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (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 828F9194C86 for ; Thu, 29 Aug 2024 12:33:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934802; cv=none; b=qGDPvIXW0BswT09tam89+E2uG40gTF17QAG+vzGz2BIL/GrY9QEA1EwMhFY9Sc0H/FPmZhc9eaMnDV/xiH7WD2Mqd+b6+hJ4Gs11yFuwzlmKQk9tArL9DIe2LsQq3808co1EXHy/n4CbpUgCFhMCmNPnN2DtXSb228eEzo7zOMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934802; c=relaxed/simple; bh=wkT2eJbbHDn6CRJOE1bDAGFMpoQwugJ7/2FLRi0phuE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nEvZPN46OwR8pjiYDuGtbVRQmYOKj6u+cKIO5Ud9mBi2EaLpFMQikVSyWtUc34uhWUl2yrDNGyBCA39bKEDKuh02LqcTWHXi3K65yneT+nIgFmXnyJAPPjIflMilS+aBLcGesHaKny21Uz2Za2xLPkbqoIaNt53PyYZeaouOiQQ= 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=aON/8Fow; arc=none smtp.client-ip=209.85.221.53 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="aON/8Fow" Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-3730749ee7aso384497f8f.2 for ; Thu, 29 Aug 2024 05:33:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1724934797; x=1725539597; 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=XZIJdxGSLG1ZplmaRmfbX1A1WfdoHrvq2/x6TRvaEig=; b=aON/8FowPkPPqjWFjYXBZ35+EcLA4TatYUQfrmFabPZuW9dAquEOgOKCVqPbf/fvWU U0Mz9SQpo53iJimseo4Jq9V3QU06AlCSyQiz3YLJZz95oLi0knJseGNYrBhnSt0gsQfC jvzcY2m79yqpnpcf+ssNzaRQVrPSXpeM20XJRGuB/ri+ndpeqJwm/cblnWy7rky1qmtL c9rwCHM0OcdIk8I+SRGEcy3k3+3C2LXf957sWB5Mrkfrn3zOGI2PplyeBTlzxfMG1+PO 1KARjRv9Pa4xKlV3D8Cv795BsXjb3E5BD4bYyiNE6fwLBg3mZoa2f5gSeHfAC22FZOKQ yUcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724934797; x=1725539597; 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=XZIJdxGSLG1ZplmaRmfbX1A1WfdoHrvq2/x6TRvaEig=; b=CVW5NumOujfc9OoljzGYKR1Rbqv2+caaiVcKkBXRVdnYazLbUpLIN7larYjY4dpsoS VgSY3bI2cuK5tKxgJKSpxJm9HdTUMu/aU9XXJ407nCW07hWIUgb1U0dBpBoRDqUKHwW0 p3AEKnRcr0sdeCKmBzYVsMuYxrXwXXVRGGVScGMs4ziHoBng5JLdX2164ELH5MZ197r8 aDnK4osfrSiPTF9z2ERj5TcjKs/Yf4LAEX01VebyG2o+F8kKagUCZCRnOBbfKAizfU6K k985ynMTlvgIsLnENppddf0rysXvqOVcHUnh2PHZ0NEXIQ1D1Bfk+tLpPlmCydaP01T+ ZrgQ== X-Forwarded-Encrypted: i=1; AJvYcCWu8rqWm+59pvpk7O0i5P7IY4UcRhHclpJw2/RL3l3KlZsXT71G2N8YVZJkE+rd04ro1Dru6aqwYezxbl4=@vger.kernel.org X-Gm-Message-State: AOJu0Yw9MLbEeZ3JXn5N6U3jANfMLI2HkUc+d8jL1pjDREpMJl8U++N3 FIGfLuRtt3vVIiFMPU3m6DdSI8V0/2ikYtW81hJfy0PvAuTZIQRnY4KJ/2SqBfE9EXAdYPbno5U v X-Google-Smtp-Source: AGHT+IGxh2bfPlBBmwr4Sxe/plUtt/ia6yuDkXt54pFc4P2rQUsQSwLDRtoC2rHcz/dySAce2HwbBg== X-Received: by 2002:adf:f410:0:b0:368:74a8:6c34 with SMTP id ffacd0b85a97d-3749b54d4ddmr1763573f8f.36.1724934797327; Thu, 29 Aug 2024 05:33:17 -0700 (PDT) Received: from [127.0.1.1] (host-95-233-232-76.retail.telecomitalia.it. [95.233.232.76]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3749ee9978bsm1315042f8f.49.2024.08.29.05.33.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Aug 2024 05:33:16 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 29 Aug 2024 14:32:00 +0200 Subject: [PATCH RFC 2/8] iio: backend: extend features 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: <20240829-wip-bl-ad3552r-axi-v0-v1-2-b6da6015327a@baylibre.com> References: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> In-Reply-To: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Extend backend features with new calls needed later on this patchset from axi version of ad3552r. A bus type property has been added to the devicetree to inform the backend about the type of bus (interface) in use bu the IP. The follwoing calls are added: iio_backend_ext_sync_enable enable synchronize channels on external trigger iio_backend_ext_sync_disable disable synchronize channels on external trigger iio_backend_ddr_enable enable ddr bus transfer iio_backend_ddr_disable disable ddr bus transfer iio_backend_set_bus_mode select the type of bus, so that specific read / write operations are performed accordingly iio_backend_buffer_enable enable buffer iio_backend_buffer_disable disable buffer iio_backend_data_transfer_addr define the target register address where the DAC sample will be written. iio_backend_bus_reg_read generic bus read, bus-type dependent iio_backend_bus_read_write generic bus write, bus-type dependent Signed-off-by: Angelo Dureghello --- drivers/iio/industrialio-backend.c | 151 +++++++++++++++++++++++++++++++++= ++++ include/linux/iio/backend.h | 24 ++++++ 2 files changed, 175 insertions(+) diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-= backend.c index a52a6b61c8b5..1f60c8626be7 100644 --- a/drivers/iio/industrialio-backend.c +++ b/drivers/iio/industrialio-backend.c @@ -718,6 +718,157 @@ static int __devm_iio_backend_get(struct device *dev,= struct iio_backend *back) return 0; } =20 +/** + * iio_backend_ext_sync_enable - Enable external synchronization + * @back: Backend device + * + * Enable synchronization by external signal. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_ext_sync_enable(struct iio_backend *back) +{ + return iio_backend_op_call(back, ext_sync_enable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_ext_sync_enable, IIO_BACKEND); + +/** + * iio_backend_ext_sync_disable - Disable external synchronization + * @back: Backend device + * + * Disable synchronization by external signal. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_ext_sync_disable(struct iio_backend *back) +{ + return iio_backend_op_call(back, ext_sync_disable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_ext_sync_disable, IIO_BACKEND); + +/** + * iio_backend_ddr_enable - Enable interface DDR (Double Data Rate) mode + * @back: Backend device + * + * Enabling DDR, data is generated by the IP at each front + * (raising and falling) of the bus clock signal. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_ddr_enable(struct iio_backend *back) +{ + return iio_backend_op_call(back, ddr_enable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_ddr_enable, IIO_BACKEND); + +/** + * iio_backend_ddr_disable - Disable interface DDR (Double Data Rate) mode + * @back: Backend device + * + * Disabling DDR data is generated byt the IP at rising or falling front + * of the interface clock signal (SDR, Single Data Rate). + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_ddr_disable(struct iio_backend *back) +{ + return iio_backend_op_call(back, ddr_disable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_ddr_disable, IIO_BACKEND); + +/** + * iio_backend_buffer_enable - Enable data buffering + * @back: Backend device + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_buffer_enable(struct iio_backend *back) +{ + return iio_backend_op_call(back, buffer_enable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_buffer_enable, IIO_BACKEND); + +/** + * iio_backend_set_buffer_disable - Disable data buffering + * @back: Backend device + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_buffer_disable(struct iio_backend *back) +{ + return iio_backend_op_call(back, buffer_disable); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_buffer_disable, IIO_BACKEND); + +/** + * iio_backend_buffer_transfer_addr - Set data address. + * @back: Backend device + * @chan_address: Channel register address + * + * Some devices may need to inform the backend about an address/location + * where to read or write the data. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_data_transfer_addr(struct iio_backend *back, u32 address) +{ + return iio_backend_op_call(back, data_transfer_addr, address); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_data_transfer_addr, IIO_BACKEND); + +/** + * iio_backend_bus_reg_read - Read from the interface bus + * @back: Backend device + * @reg: Register valule + * @val: Pointer to register value + * @size: Size, in bytes + * + * A backend may operate on a specific interface with a related bus. + * Read from the interface bus. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_bus_reg_read(struct iio_backend *back, + u32 reg, void *val, size_t size) +{ + if (!size) + return -EINVAL; + + return iio_backend_op_call(back, bus_reg_read, reg, val, size); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_bus_reg_read, IIO_BACKEND); + +/** + * iio_backend_bus_reg_write - Write on the interface bus + * @back: Backend device + * @reg: Register value + * @val: Register Value + * @size: Size in bytes + * + * A backend may operate on a specific interface with a related bus. + * Write to the interface bus. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int iio_backend_bus_reg_write(struct iio_backend *back, + u32 reg, void *val, size_t size) +{ + if (!size) + return -EINVAL; + + return iio_backend_op_call(back, bus_reg_write, reg, val, size); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_bus_reg_write, IIO_BACKEND); + static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *de= v, const char *name, struct fwnode_handle *fwnode) { diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h index 37d56914d485..6f56bbb9e391 100644 --- a/include/linux/iio/backend.h +++ b/include/linux/iio/backend.h @@ -14,12 +14,14 @@ struct iio_dev; enum iio_backend_data_type { IIO_BACKEND_TWOS_COMPLEMENT, IIO_BACKEND_OFFSET_BINARY, + IIO_BACKEND_DATA_UNSIGNED, IIO_BACKEND_DATA_TYPE_MAX }; =20 enum iio_backend_data_source { IIO_BACKEND_INTERNAL_CONTINUOUS_WAVE, IIO_BACKEND_EXTERNAL, + IIO_BACKEND_INTERNAL_RAMP_16, IIO_BACKEND_DATA_SOURCE_MAX }; =20 @@ -129,6 +131,17 @@ struct iio_backend_ops { size_t len); int (*debugfs_reg_access)(struct iio_backend *back, unsigned int reg, unsigned int writeval, unsigned int *readval); + int (*ext_sync_enable)(struct iio_backend *back); + int (*ext_sync_disable)(struct iio_backend *back); + int (*ddr_enable)(struct iio_backend *back); + int (*ddr_disable)(struct iio_backend *back); + int (*buffer_enable)(struct iio_backend *back); + int (*buffer_disable)(struct iio_backend *back); + int (*data_transfer_addr)(struct iio_backend *back, u32 address); + int (*bus_reg_read)(struct iio_backend *back, u32 reg, void *val, + size_t size); + int (*bus_reg_write)(struct iio_backend *back, u32 reg, void *val, + size_t size); }; =20 /** @@ -164,6 +177,17 @@ int iio_backend_data_sample_trigger(struct iio_backend= *back, int devm_iio_backend_request_buffer(struct device *dev, struct iio_backend *back, struct iio_dev *indio_dev); +int iio_backend_ext_sync_enable(struct iio_backend *back); +int iio_backend_ext_sync_disable(struct iio_backend *back); +int iio_backend_ddr_enable(struct iio_backend *back); +int iio_backend_ddr_disable(struct iio_backend *back); +int iio_backend_buffer_enable(struct iio_backend *back); +int iio_backend_buffer_disable(struct iio_backend *back); +int iio_backend_data_transfer_addr(struct iio_backend *back, u32 address); +int iio_backend_bus_reg_read(struct iio_backend *back, + u32 reg, void *val, size_t size); +int iio_backend_bus_reg_write(struct iio_backend *back, + u32 reg, void *val, size_t size); ssize_t iio_backend_ext_info_set(struct iio_dev *indio_dev, uintptr_t priv= ate, const struct iio_chan_spec *chan, const char *buf, size_t len); --=20 2.45.0.rc1 From nobody Mon Feb 9 17:27:30 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.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 E36661ABED0 for ; Thu, 29 Aug 2024 12:33:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934804; cv=none; b=Iqx6htTgBoAIEmMV1QeUAuXpiI0oqVlXGTZuEKVwaOO6W1EuL4rrvOsPuHblQFHN+as6n5GgwBxRXwDbQkoIo/fULExNHgGZKr9qVZD3/B3wphYISGCknoVj1f5AHyfRoX1AlxHlCwVJJtVa+k+SG/OmdEK1rm0TpTMEtsKiPGU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934804; c=relaxed/simple; bh=Ds+1ZPRh3Pd/h/lTlJUmag4WvGxvpkDuwvncfNYz2sg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ku9yJpX6eFDkNggsnLvlgWrNuKFsOfMVJMm+jOiiSCr3UbsVoZ1UHJGqrEf94WgWFXtxarPLOVMb6pgFG0ogbW9/piw3NHBNSwCJX6BbbkUKI5PiWyKuOfrFhaykVkbPBm3CIE8oxHizB5cVqgwtz1Z5CVvbQAwsPg0KkEdb0pQ= 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=s8PcnoZW; arc=none smtp.client-ip=209.85.128.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="s8PcnoZW" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-42bb6d3e260so5349355e9.1 for ; Thu, 29 Aug 2024 05:33:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1724934800; x=1725539600; 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=mqVLJgcYxuhDSoU47RjiW1Y6B/QvAm72bN+dtzZiOHM=; b=s8PcnoZWLeRXIkTIgS4KIXSNHGRgtCeksHgdgsMsIrKAGR5EOIc0CeOezOFzNrI4Pp ORIXTpwZXcZWvd0LPQvrjqWvKlfGPpdVO6xqIqV8aRYN+z9EBBVq595CfOQ+Y2Mnj1GJ BD55Yl2bCt/iQKC08Qfr5MxdjDsgbUelRwNNerQByRscYGHijAo1EfEYkZpH0HNVf3zk XIYee8ac8YlUP+shEVCnwTItMAKOmDadD3+IqCVTHJhNXhgpF5GsjzX2lRNbdyjvLqGg vWeE5IFYoHOUKsjJxeOeJtvaN+i8VfF1iS2O1xj5E1LxqTWc72IsyKMnGzBujY+flOtI //xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724934800; x=1725539600; 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=mqVLJgcYxuhDSoU47RjiW1Y6B/QvAm72bN+dtzZiOHM=; b=cOPJQkUjPv97XTt4g968rw9qNcdgQjp/7rOxodjtpti4014XdYtavUrLXSuuIMVc7+ M0FApTiLrL4wdXzvXO3jB0hnhtpS12+PHVFjtjLHFA5mBgOK6tQkZqOzOyj13KFYwXKG Tro9+ERo844zgJcTLAjcg1nJ2tiaqRc2gb7yHnCtPxP007DgCUIratAMOTCpKnNrRHKz mePFEVLaC/uSrpwMFS3ISO0rOfATO8N3Xzm4L82z6+f2l7v/cBJ9td+7AUqzPux+9WkI xHYPWg6NunrCE5ncsnBIxK5u0C/CC3emm2qGaaijlvcp+vLcKAYgQ6DAiogqK944TZiq 71QA== X-Forwarded-Encrypted: i=1; AJvYcCWVV6RKGTrA1w+R+zzEYMr6q6IuAoCRchZgiIDr4wqmDHh9242PRDcft4sS3vAv7JgsmzFUQf7Gc3gR4tw=@vger.kernel.org X-Gm-Message-State: AOJu0YwL/O9Yjjv2WGIbY5xM+LbClhGa2C3lfyqjotk1GFL0sEacYcuH 80rCGFpJW7gFjz0A/5mH6NVmbrkuEuN2MItrLHUT266POA76/D+GJRbciwpI5xTQ3/isaTCZN6f m X-Google-Smtp-Source: AGHT+IG0NOxZBVBUAP/6A4UX02MrGE4mR/ZJBrI4PfMf765zzw/1pd+sG3xgf1DVlP+a/JP5YPqKww== X-Received: by 2002:adf:e34f:0:b0:367:9d2c:95ea with SMTP id ffacd0b85a97d-3749b587ee3mr1694282f8f.56.1724934799815; Thu, 29 Aug 2024 05:33:19 -0700 (PDT) Received: from [127.0.1.1] (host-95-233-232-76.retail.telecomitalia.it. [95.233.232.76]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3749ee9978bsm1315042f8f.49.2024.08.29.05.33.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Aug 2024 05:33:18 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 29 Aug 2024 14:32:01 +0200 Subject: [PATCH RFC 3/8] iio: backend adi-axi-dac: backend features 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: <20240829-wip-bl-ad3552r-axi-v0-v1-3-b6da6015327a@baylibre.com> References: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> In-Reply-To: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Extend DAC backend with new features required for the AXI driver version for the a3552r DAC. Signed-off-by: Angelo Dureghello --- drivers/iio/dac/adi-axi-dac.c | 250 ++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 248 insertions(+), 2 deletions(-) diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c index 0cb00f3bec04..395f222e254d 100644 --- a/drivers/iio/dac/adi-axi-dac.c +++ b/drivers/iio/dac/adi-axi-dac.c @@ -44,11 +44,34 @@ #define AXI_DAC_RSTN_MMCM_RSTN BIT(1) #define AXI_DAC_RSTN_RSTN BIT(0) #define AXI_DAC_REG_CNTRL_1 0x0044 +#define AXI_DAC_EXT_SYNC_ARM BIT(1) +#define AXI_DAC_EXT_SYNC_DISARM BIT(2) #define AXI_DAC_SYNC BIT(0) #define AXI_DAC_REG_CNTRL_2 0x0048 -#define ADI_DAC_R1_MODE BIT(4) +#define AXI_DAC_SDR_DDR_N BIT(16) +#define AXI_DAC_SYMB_8B BIT(14) +#define ADI_DAC_R1_MODE BIT(5) +#define AXI_DAC_UNSIGNED_DATA BIT(4) +#define AXI_DAC_REG_STATUS_1 0x54 +#define AXI_DAC_REG_STATUS_2 0x58 #define AXI_DAC_DRP_STATUS 0x0074 #define AXI_DAC_DRP_LOCKED BIT(17) +#define AXI_DAC_CNTRL_DATA_RD 0x0080 +#define AXI_DAC_DATA_RD_8 GENMASK(7, 0) +#define AXI_DAC_DATA_RD_16 GENMASK(15, 0) +#define AXI_DAC_CNTRL_DATA_WR 0x0084 +#define AXI_DAC_DATA_WR_8 GENMASK(23, 16) +#define AXI_DAC_DATA_WR_16 GENMASK(23, 8) +#define AXI_DAC_UI_STATUS 0x0088 +#define AXI_DAC_BUSY BIT(4) +#define AXI_DAC_REG_CUSTOM_CTRL 0x008C +#define AXI_DAC_ADDRESS GENMASK(31, 24) +#define AXI_DAC_SYNCED_TRANSFER BIT(2) +#define AXI_DAC_STREAM BIT(1) +#define AXI_DAC_TRANSFER_DATA BIT(0) + +#define AXI_DAC_STREAM_ENABLE (AXI_DAC_TRANSFER_DATA | AXI_DAC_STREAM) + /* DAC Channel controls */ #define AXI_DAC_REG_CHAN_CNTRL_1(c) (0x0400 + (c) * 0x40) #define AXI_DAC_REG_CHAN_CNTRL_3(c) (0x0408 + (c) * 0x40) @@ -62,11 +85,20 @@ #define AXI_DAC_REG_CHAN_CNTRL_7(c) (0x0418 + (c) * 0x40) #define AXI_DAC_DATA_SEL GENMASK(3, 0) =20 +#define AXI_DAC_RD_ADDR(x) (BIT(7) | (x)) + /* 360 degrees in rad */ #define AXI_DAC_2_PI_MEGA 6283190 + enum { AXI_DAC_DATA_INTERNAL_TONE, AXI_DAC_DATA_DMA =3D 2, + AXI_DAC_DATA_INTERNAL_RAMP_16 =3D 11, +}; + +enum { + AXI_DAC_BUS_TYPE_NONE, + AXI_DAC_BUS_TYPE_QSPI, }; =20 struct axi_dac_state { @@ -80,6 +112,7 @@ struct axi_dac_state { u64 dac_clk; u32 reg_config; bool int_tone; + int bus_type; }; =20 static int axi_dac_enable(struct iio_backend *back) @@ -460,7 +493,13 @@ static int axi_dac_data_source_set(struct iio_backend = *back, unsigned int chan, case IIO_BACKEND_EXTERNAL: return regmap_update_bits(st->regmap, AXI_DAC_REG_CHAN_CNTRL_7(chan), - AXI_DAC_DATA_SEL, AXI_DAC_DATA_DMA); + AXI_DAC_DATA_SEL, + AXI_DAC_DATA_DMA); + case IIO_BACKEND_INTERNAL_RAMP_16: + return regmap_update_bits(st->regmap, + AXI_DAC_REG_CHAN_CNTRL_7(chan), + AXI_DAC_DATA_SEL, + AXI_DAC_DATA_INTERNAL_RAMP_16); default: return -EINVAL; } @@ -518,9 +557,204 @@ static int axi_dac_reg_access(struct iio_backend *bac= k, unsigned int reg, return regmap_write(st->regmap, reg, writeval); } =20 +static int axi_dac_ext_sync_enable(struct iio_backend *back) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + return regmap_set_bits(st->regmap, AXI_DAC_REG_CNTRL_1, + AXI_DAC_EXT_SYNC_ARM); +} + +static int axi_dac_ext_sync_disable(struct iio_backend *back) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + return regmap_clear_bits(st->regmap, AXI_DAC_REG_CNTRL_1, + AXI_DAC_EXT_SYNC_DISARM); +} + +static int axi_dac_ddr_enable(struct iio_backend *back) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + return regmap_clear_bits(st->regmap, AXI_DAC_REG_CNTRL_2, + AXI_DAC_SDR_DDR_N); +} + +static int axi_dac_ddr_disable(struct iio_backend *back) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + return regmap_set_bits(st->regmap, AXI_DAC_REG_CNTRL_2, + AXI_DAC_SDR_DDR_N); +} + +static int axi_dac_buffer_enable(struct iio_backend *back) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + return regmap_set_bits(st->regmap, AXI_DAC_REG_CUSTOM_CTRL, + AXI_DAC_STREAM_ENABLE); +} + +static int axi_dac_buffer_disable(struct iio_backend *back) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + return regmap_clear_bits(st->regmap, AXI_DAC_REG_CUSTOM_CTRL, + AXI_DAC_STREAM_ENABLE); +} + +static int axi_dac_data_transfer_addr(struct iio_backend *back, u32 addres= s) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + /* + * Sample register address, when the DAC is configured, or stream + * start address when the FSM is in stream state. + */ + return regmap_update_bits(st->regmap, AXI_DAC_REG_CUSTOM_CTRL, + AXI_DAC_ADDRESS, + FIELD_PREP(AXI_DAC_ADDRESS, address)); +} + +static int axi_dac_data_format_set(struct iio_backend *back, unsigned int = ch, + const struct iio_backend_data_fmt *data) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + if (data->type =3D=3D IIO_BACKEND_DATA_UNSIGNED) + return regmap_clear_bits(st->regmap, AXI_DAC_REG_CNTRL_2, + AXI_DAC_UNSIGNED_DATA); + + return -EINVAL; +} + +static int axi_dac_read_raw(struct iio_backend *back, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + switch (mask) { + case IIO_CHAN_INFO_FREQUENCY: + *val =3D clk_get_rate(devm_clk_get(st->dev, 0)); + + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int axi_dac_bus_reg_write(struct iio_backend *back, + u32 reg, void *val, size_t size) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + if (!st->bus_type) + return -EOPNOTSUPP; + + if (st->bus_type =3D=3D AXI_DAC_BUS_TYPE_QSPI) { + int ret; + u32 ival; + + if (size !=3D 1 && size !=3D 2) + return -EINVAL; + + switch (size) { + case 1: + ival =3D FIELD_PREP(AXI_DAC_DATA_WR_8, *(u8 *)val); + break; + case 2: + ival =3D FIELD_PREP(AXI_DAC_DATA_WR_16, *(u16 *)val); + break; + default: + return -EINVAL; + } + + ret =3D regmap_write(st->regmap, AXI_DAC_CNTRL_DATA_WR, ival); + if (ret) + return ret; + + /* + * Both REG_CNTRL_2 and AXI_DAC_CNTRL_DATA_WR need to know + * the data size. So keeping data size control here only, + * since data size is mandatory for to the current transfer. + * DDR state handled separately by specific backend calls, + * generally all raw register writes are SDR. + */ + if (size =3D=3D 1) + ret =3D regmap_set_bits(st->regmap, AXI_DAC_REG_CNTRL_2, + AXI_DAC_SYMB_8B); + else + ret =3D regmap_clear_bits(st->regmap, AXI_DAC_REG_CNTRL_2, + AXI_DAC_SYMB_8B); + if (ret) + return ret; + + ret =3D regmap_update_bits(st->regmap, AXI_DAC_REG_CUSTOM_CTRL, + AXI_DAC_ADDRESS, + FIELD_PREP(AXI_DAC_ADDRESS, reg)); + if (ret) + return ret; + + ret =3D regmap_update_bits(st->regmap, AXI_DAC_REG_CUSTOM_CTRL, + AXI_DAC_TRANSFER_DATA, + AXI_DAC_TRANSFER_DATA); + if (ret) + return ret; + + ret =3D regmap_read_poll_timeout(st->regmap, + AXI_DAC_REG_CUSTOM_CTRL, ival, + ival & AXI_DAC_TRANSFER_DATA, + 10, 100 * KILO); + if (ret) + return ret; + + return regmap_clear_bits(st->regmap, AXI_DAC_REG_CUSTOM_CTRL, + AXI_DAC_TRANSFER_DATA); + } + + return -EINVAL; +} + +static int axi_dac_bus_reg_read(struct iio_backend *back, + u32 reg, void *val, size_t size) +{ + struct axi_dac_state *st =3D iio_backend_get_priv(back); + + if (!st->bus_type) + return -EOPNOTSUPP; + + if (st->bus_type =3D=3D AXI_DAC_BUS_TYPE_QSPI) { + int ret; + u32 bval; + + if (size !=3D 1 && size !=3D 2) + return -EINVAL; + + bval =3D 0; + ret =3D axi_dac_bus_reg_write(back, + AXI_DAC_RD_ADDR(reg), &bval, size); + if (ret) + return ret; + + ret =3D regmap_read_poll_timeout(st->regmap, AXI_DAC_UI_STATUS, + bval, bval !=3D AXI_DAC_BUSY, + 10, 100); + if (ret) + return ret; + + return regmap_read(st->regmap, AXI_DAC_CNTRL_DATA_RD, val); + } + + return -EINVAL; +} + static const struct iio_backend_ops axi_dac_generic_ops =3D { .enable =3D axi_dac_enable, .disable =3D axi_dac_disable, + .read_raw =3D axi_dac_read_raw, .request_buffer =3D axi_dac_request_buffer, .free_buffer =3D axi_dac_free_buffer, .extend_chan_spec =3D axi_dac_extend_chan, @@ -528,6 +762,16 @@ static const struct iio_backend_ops axi_dac_generic_op= s =3D { .ext_info_get =3D axi_dac_ext_info_get, .data_source_set =3D axi_dac_data_source_set, .set_sample_rate =3D axi_dac_set_sample_rate, + .ext_sync_enable =3D axi_dac_ext_sync_enable, + .ext_sync_disable =3D axi_dac_ext_sync_disable, + .ddr_enable =3D axi_dac_ddr_enable, + .ddr_disable =3D axi_dac_ddr_disable, + .buffer_enable =3D axi_dac_buffer_enable, + .buffer_disable =3D axi_dac_buffer_disable, + .data_format_set =3D axi_dac_data_format_set, + .data_transfer_addr =3D axi_dac_data_transfer_addr, + .bus_reg_read =3D axi_dac_bus_reg_read, + .bus_reg_write =3D axi_dac_bus_reg_write, .debugfs_reg_access =3D iio_backend_debugfs_ptr(axi_dac_reg_access), }; =20 @@ -576,6 +820,8 @@ static int axi_dac_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(st->regmap), "failed to init register map\n"); =20 + device_property_read_u32(st->dev, "bus-type", &st->bus_type); + /* * Force disable the core. Up to the frontend to enable us. And we can * still read/write registers... --=20 2.45.0.rc1 From nobody Mon Feb 9 17:27:30 2026 Received: from mail-wr1-f50.google.com (mail-wr1-f50.google.com [209.85.221.50]) (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 5CF561AD5E6 for ; Thu, 29 Aug 2024 12:33:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934805; cv=none; b=ZYvIs1p7fMCKYJMIE/EEjINWpHQfBhKkYzHMGwEaDG6EhZ5XTnpxvXEydgMs2d9sKW+mwWuQnaTYxEZxTjNh9jWd0UJduR4xlkop9lBHz2JBreZ2KfFzcZc9UuV14gPVk9L+GrLrSdDIzMhnoK3VHTpJpqjU8vl9vnB+VNG131s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934805; c=relaxed/simple; bh=2seSKUbP20B+v4Da+nrC0RJo+JYqN7HNRn8x6mQUcuM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mg0mvPm37D561uIebCMw2uQ+RsOL6UTFBAGeaF7SCiRsiBbahQfh7dP0rpFtwv2fdJ4NdgRBEU6D1m2pVMQ7vsWXEFGCRJjnvwC8FCH4oPUxz3sv8EeYj1MjHrCfmB0KeMllWtgRHHeAonnAOTERr7kljTozKhrdazlA/fezQtY= 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=P9nU2OEB; arc=none smtp.client-ip=209.85.221.50 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="P9nU2OEB" Received: by mail-wr1-f50.google.com with SMTP id ffacd0b85a97d-371b098e699so507880f8f.2 for ; Thu, 29 Aug 2024 05:33:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1724934801; x=1725539601; 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=a5VzDkyGIipqeKFQeDDBEiAGYXukKHwmPdzrDO5GWeU=; b=P9nU2OEBgnzrZJGljOiBgOrUSLhSpbwndKa7eustG4XfEWFzoQ4UN25pNDuUiiJ1/S xcN2e0nUYgsjlmiw/ovM2ejuZpnZVCGj8uI/2zlvaayRwqkmWbthonT3e1NRC9MmZOVR x5g24S0gDrBGwWaTi3os1k/LEYBE3J1No/01ykWkWIKmlckwHYCgBjJgH3FO08IeFeYi A49SeD1LRsYr74XW6xF5dYW5kDBhPv6h5/DfIxKYKMfTNj8HOTKf5DjzhuzV6e9Q/HX3 yrfG0rwHP9kKwpv8njArh/2utnjuD2Aiq9nfGawKSoYuQm+I3OXGOf5u72b3W5f54Yrq hl4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724934801; x=1725539601; 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=a5VzDkyGIipqeKFQeDDBEiAGYXukKHwmPdzrDO5GWeU=; b=Zm5fbyC3ywTLoj1jZeMtLlEGl7yJbM2Fi1jnzEhIWD3Yw3jymdadvRP/qgP4OFRTLf Bls6OlYIQKPIog38FiDYwY/VpyfuEANggOnnuBx5XwbCP/YmPuJ9gLasXOZYOKTjtAJL CrTWgPkH2UA0PmCEXwjWb/Qs66eBFFVa3YHQ0qXSMLFEFDDR5/4+QRMrZza9i9bi7UCe GkjHpX9KQgOVt90P/7rDi+uoSt/cC9OPBrmEfBfeBcclVdjJDnDt1Q66YAxskjMWMLQL bpXTSLs0qa0BHAgKtWLuzsvENqGicRIZp9f0gUMH0XvAE6uB5Ls7RGX2V4F9V2+o+RKz Mt4g== X-Forwarded-Encrypted: i=1; AJvYcCXRMvlTdKCXlh1lLXTrXq2vrEsRQT2Wn9v+U/NfiLrrm/VQ/YZAWsm9/zUgdOprHZ+7xdMhIhozAPS5mrM=@vger.kernel.org X-Gm-Message-State: AOJu0YydrJab5ouP6aa+x3dx/QTwVA5uKpGSbYoy6CDJQEWEpFvF+EMP eZzPgwZSh7TYB89NCrBpbwddtkq3J2oqI8RvNmbpxlFDpqFKWAzryb29sthsXI8UC+EHORAj+9F 2 X-Google-Smtp-Source: AGHT+IEUn+XUGbwbcc82Z4ruGRiXJAYhB/DLqIvI8zIDgN4867faLz+fysRvLFTbaujzVS8Mo0daOw== X-Received: by 2002:a05:6000:cc1:b0:366:f04d:676f with SMTP id ffacd0b85a97d-3749b526222mr2464717f8f.12.1724934801188; Thu, 29 Aug 2024 05:33:21 -0700 (PDT) Received: from [127.0.1.1] (host-95-233-232-76.retail.telecomitalia.it. [95.233.232.76]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3749ee9978bsm1315042f8f.49.2024.08.29.05.33.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Aug 2024 05:33:20 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 29 Aug 2024 14:32:02 +0200 Subject: [PATCH RFC 4/8] dt-bindings: iio: dac: add adi axi-dac bus property 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: <20240829-wip-bl-ad3552r-axi-v0-v1-4-b6da6015327a@baylibre.com> References: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> In-Reply-To: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Add bus property. Signed-off-by: Angelo Dureghello --- Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml b/D= ocumentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml index a55e9bfc66d7..a7ce72e1cd81 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml @@ -38,6 +38,15 @@ properties: clocks: maxItems: 1 =20 + bus-type: + maxItems: 1 + description: | + Configure bus type: + - 0: none + - 1: qspi + enum: [0, 1] + default: 0 + '#io-backend-cells': const: 0 =20 --=20 2.45.0.rc1 From nobody Mon Feb 9 17:27:30 2026 Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (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 AC9F41AE055 for ; Thu, 29 Aug 2024 12:33:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934806; cv=none; b=jYfMS+JgsVKSVJ2aBijMdxRJn5+/IPWNL++buvUDQ2MzHyyI0NvLS25TjtkLUGkepPjNDYLZXyOOMWdoihAc08xP5TAIG3ussMDmBrQ/BHhi66WUtOhu3t/m5yJBumJ2m/VAX1QDeseLWxiaR9Efa9JlHth7i6nrXAXfnwDmnYw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934806; c=relaxed/simple; bh=sMitsse9OwZ43/jnWDZSTTm3YDm3vNttb5226BTU5WM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CA9llYn6Sd1oC24Ez3mx8DTvNP/RXdZIWNsgYE5yhAJuv41AN9SeegH9z5wSdtnsnhvfNuWHLcVYqQagk6aYf3+BNe9c5cKMwPUtp3CFLpiqQi/QBbGosZGfNfzdWT/EEyE7VX5nquuKRobFCT97ShkTo9/BoFiDioGhZLilM9c= 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=GhWDO9GE; arc=none smtp.client-ip=209.85.221.51 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="GhWDO9GE" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-371bb8322b2so346093f8f.0 for ; Thu, 29 Aug 2024 05:33:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1724934803; x=1725539603; 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=wVi9bp8wMnvig9NnCQi55+mSw7Gt/fL2Xra47qKymJg=; b=GhWDO9GEQefxJ0hIrFXujKfKvzZYX8j++BZdePrls5V1j0v8w9mpkI/rhNgDQO7M7M 917+yNNe3SX4KYobXn+ltGMQqGfr9XnRhzXbzvn1MQtR2Xr2ArKP3H/4SUAx7jrPIi0G 14h1Do2l/Dr/SuQIM/8pJti+RauHXD0L9ZFceqzhuXJMYuB4250YJKKotndOpK8xwCsL vg8aUd938aCo5BC4IqnJAa0OIxVJsSIqcPux4eTLkaJtqzEdTp+r/Plv4/KRzp6Sd2md gwphD6iHAFkmNSrb94w99Er2Roo/0kHUKuMm3f6XBS6ifNuVjnURkpnptU8w/Wyi72JZ M5Kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724934803; x=1725539603; 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=wVi9bp8wMnvig9NnCQi55+mSw7Gt/fL2Xra47qKymJg=; b=SVP/Y7PtS+plAT/llMrIrlIh55CgiO1d53Ri+xObv3rdNDMxZRP7brt/aTtk2YS4Bn cPD6KaHWpP4JFKftkaTDNw46KixWipeVx878Ow7uRzm3HcA0YY5gt353stzTaocl9Xx9 0tv0kL2Z14QZ4sYL6PgNhMylKSZgpLcGcxHBsYaZw9NqetpSVYrxZx0sREtULP6heKk5 c4fQr1p3847G9pbo42XUDGz8PSoxx3/uy+xuCuyAU/pW4BvfHzqbD4nzZV6bpmNBFyxP c4bLnMTFInIg/crDMgwJspGsiDToA5IA7Qply66MZcY/IJqP9ybcemBdjzI5gK31ppc4 ovTQ== X-Forwarded-Encrypted: i=1; AJvYcCXvIhKLH8jR0srtUukMfDMBPD9jy19z0uQxGu/66X05M53SlPJ8CchukYLa36w6y4ELqFflo4RHipXCpYY=@vger.kernel.org X-Gm-Message-State: AOJu0YyGhMjqgAkktCSjYB1LfKlaTGbQjhvzJ7P4YvXHkINTWkvsgNJo Opb1WBp4OijKzi0BzquyOOqyk2UEJWm2uA7pl5tBqif/cau3nHpfsih3aD6a1HwEyQZ+wf5SNu5 5 X-Google-Smtp-Source: AGHT+IFvz+dks44+NB50OaUiNL9nYoAbK/Wr2isb1tAidlomwnzr60+E/TwyMyoZP8nF71ge1wI5rg== X-Received: by 2002:adf:f001:0:b0:371:6fc7:d45d with SMTP id ffacd0b85a97d-3749fe439acmr1181477f8f.2.1724934802516; Thu, 29 Aug 2024 05:33:22 -0700 (PDT) Received: from [127.0.1.1] (host-95-233-232-76.retail.telecomitalia.it. [95.233.232.76]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3749ee9978bsm1315042f8f.49.2024.08.29.05.33.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Aug 2024 05:33:21 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 29 Aug 2024 14:32:03 +0200 Subject: [PATCH RFC 5/8] iio: dac: ad3552r: changes to use FIELD_PREP 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: <20240829-wip-bl-ad3552r-axi-v0-v1-5-b6da6015327a@baylibre.com> References: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> In-Reply-To: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Changes to use FIELD_PREP, so that driver-specific ad3552r_field_prep is removed. Variables (arrays) that was used to call ad3552r_field_prep are removerd too. Signed-off-by: Angelo Dureghello --- drivers/iio/dac/ad3552r.c | 126 ++++++++++++++++++------------------------= ---- 1 file changed, 49 insertions(+), 77 deletions(-) diff --git a/drivers/iio/dac/ad3552r.c b/drivers/iio/dac/ad3552r.c index bd37d304ca70..d867de7c90d1 100644 --- a/drivers/iio/dac/ad3552r.c +++ b/drivers/iio/dac/ad3552r.c @@ -285,45 +285,6 @@ struct ad3552r_desc { unsigned int num_ch; }; =20 -static const u16 addr_mask_map[][2] =3D { - [AD3552R_ADDR_ASCENSION] =3D { - AD3552R_REG_ADDR_INTERFACE_CONFIG_A, - AD3552R_MASK_ADDR_ASCENSION - }, - [AD3552R_SDO_DRIVE_STRENGTH] =3D { - AD3552R_REG_ADDR_INTERFACE_CONFIG_D, - AD3552R_MASK_SDO_DRIVE_STRENGTH - }, - [AD3552R_VREF_SELECT] =3D { - AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, - AD3552R_MASK_REFERENCE_VOLTAGE_SEL - }, -}; - -/* 0 -> reg addr, 1->ch0 mask, 2->ch1 mask */ -static const u16 addr_mask_map_ch[][3] =3D { - [AD3552R_CH_DAC_POWERDOWN] =3D { - AD3552R_REG_ADDR_POWERDOWN_CONFIG, - AD3552R_MASK_CH_DAC_POWERDOWN(0), - AD3552R_MASK_CH_DAC_POWERDOWN(1) - }, - [AD3552R_CH_AMPLIFIER_POWERDOWN] =3D { - AD3552R_REG_ADDR_POWERDOWN_CONFIG, - AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(0), - AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(1) - }, - [AD3552R_CH_OUTPUT_RANGE_SEL] =3D { - AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE, - AD3552R_MASK_CH_OUTPUT_RANGE_SEL(0), - AD3552R_MASK_CH_OUTPUT_RANGE_SEL(1) - }, - [AD3552R_CH_SELECT] =3D { - AD3552R_REG_ADDR_CH_SELECT_16B, - AD3552R_MASK_CH(0), - AD3552R_MASK_CH(1) - } -}; - static u8 _ad3552r_reg_len(u8 addr) { switch (addr) { @@ -399,11 +360,6 @@ static int ad3552r_read_reg(struct ad3552r_desc *dac, = u8 addr, u16 *val) return 0; } =20 -static u16 ad3552r_field_prep(u16 val, u16 mask) -{ - return (val << __ffs(mask)) & mask; -} - /* Update field of a register, shift val if needed */ static int ad3552r_update_reg_field(struct ad3552r_desc *dac, u8 addr, u16= mask, u16 val) @@ -416,21 +372,11 @@ static int ad3552r_update_reg_field(struct ad3552r_de= sc *dac, u8 addr, u16 mask, return ret; =20 reg &=3D ~mask; - reg |=3D ad3552r_field_prep(val, mask); + reg |=3D val; =20 return ad3552r_write_reg(dac, addr, reg); } =20 -static int ad3552r_set_ch_value(struct ad3552r_desc *dac, - enum ad3552r_ch_attributes attr, - u8 ch, - u16 val) -{ - /* Update register related to attributes in chip */ - return ad3552r_update_reg_field(dac, addr_mask_map_ch[attr][0], - addr_mask_map_ch[attr][ch + 1], val); -} - #define AD3552R_CH_DAC(_idx) ((struct iio_chan_spec) { \ .type =3D IIO_VOLTAGE, \ .output =3D true, \ @@ -510,8 +456,14 @@ static int ad3552r_write_raw(struct iio_dev *indio_dev, val); break; case IIO_CHAN_INFO_ENABLE: - err =3D ad3552r_set_ch_value(dac, AD3552R_CH_DAC_POWERDOWN, - chan->channel, !val); + if (chan->channel =3D=3D 0) + val =3D FIELD_PREP(AD3552R_MASK_CH_DAC_POWERDOWN(0), !val); + else + val =3D FIELD_PREP(AD3552R_MASK_CH_DAC_POWERDOWN(1), !val); + + err =3D ad3552r_update_reg_field(dac, AD3552R_REG_ADDR_POWERDOWN_CONFIG, + AD3552R_MASK_CH_DAC_POWERDOWN(chan->channel), + val); break; default: err =3D -EINVAL; @@ -715,9 +667,9 @@ static int ad3552r_reset(struct ad3552r_desc *dac) } =20 return ad3552r_update_reg_field(dac, - addr_mask_map[AD3552R_ADDR_ASCENSION][0], - addr_mask_map[AD3552R_ADDR_ASCENSION][1], - val); + AD3552R_REG_ADDR_INTERFACE_CONFIG_A, + AD3552R_MASK_ADDR_ASCENSION, + FIELD_PREP(AD3552R_MASK_ADDR_ASCENSION, val)); } =20 static void ad3552r_get_custom_range(struct ad3552r_desc *dac, s32 i, s32 = *v_min, @@ -812,20 +764,20 @@ static int ad3552r_configure_custom_gain(struct ad355= 2r_desc *dac, "mandatory custom-output-range-config property missing\n"); =20 dac->ch_data[ch].range_override =3D 1; - reg |=3D ad3552r_field_prep(1, AD3552R_MASK_CH_RANGE_OVERRIDE); + reg |=3D FIELD_PREP(AD3552R_MASK_CH_RANGE_OVERRIDE, 1); =20 err =3D fwnode_property_read_u32(gain_child, "adi,gain-scaling-p", &val); if (err) return dev_err_probe(dev, err, "mandatory adi,gain-scaling-p property missing\n"); - reg |=3D ad3552r_field_prep(val, AD3552R_MASK_CH_GAIN_SCALING_P); + reg |=3D FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_P, val); dac->ch_data[ch].p =3D val; =20 err =3D fwnode_property_read_u32(gain_child, "adi,gain-scaling-n", &val); if (err) return dev_err_probe(dev, err, "mandatory adi,gain-scaling-n property missing\n"); - reg |=3D ad3552r_field_prep(val, AD3552R_MASK_CH_GAIN_SCALING_N); + reg |=3D FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_N, val); dac->ch_data[ch].n =3D val; =20 err =3D fwnode_property_read_u32(gain_child, "adi,rfb-ohms", &val); @@ -841,9 +793,9 @@ static int ad3552r_configure_custom_gain(struct ad3552r= _desc *dac, dac->ch_data[ch].gain_offset =3D val; =20 offset =3D abs((s32)val); - reg |=3D ad3552r_field_prep((offset >> 8), AD3552R_MASK_CH_OFFSET_BIT_8); + reg |=3D FIELD_PREP(AD3552R_MASK_CH_OFFSET_BIT_8, (offset >> 8)); =20 - reg |=3D ad3552r_field_prep((s32)val < 0, AD3552R_MASK_CH_OFFSET_POLARITY= ); + reg |=3D FIELD_PREP(AD3552R_MASK_CH_OFFSET_POLARITY, (s32)val < 0); addr =3D AD3552R_REG_ADDR_CH_GAIN(ch); err =3D ad3552r_write_reg(dac, addr, offset & AD3552R_MASK_CH_OFFSET_BITS_0_7); @@ -886,9 +838,9 @@ static int ad3552r_configure_device(struct ad3552r_desc= *dac) } =20 err =3D ad3552r_update_reg_field(dac, - addr_mask_map[AD3552R_VREF_SELECT][0], - addr_mask_map[AD3552R_VREF_SELECT][1], - val); + AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, + AD3552R_MASK_REFERENCE_VOLTAGE_SEL, + FIELD_PREP(AD3552R_MASK_REFERENCE_VOLTAGE_SEL, val)); if (err) return err; =20 @@ -900,9 +852,9 @@ static int ad3552r_configure_device(struct ad3552r_desc= *dac) } =20 err =3D ad3552r_update_reg_field(dac, - addr_mask_map[AD3552R_SDO_DRIVE_STRENGTH][0], - addr_mask_map[AD3552R_SDO_DRIVE_STRENGTH][1], - val); + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SDO_DRIVE_STRENGTH, + FIELD_PREP(AD3552R_MASK_SDO_DRIVE_STRENGTH, val)); if (err) return err; } @@ -938,9 +890,15 @@ static int ad3552r_configure_device(struct ad3552r_des= c *dac) "Invalid adi,output-range-microvolt value\n"); =20 val =3D err; - err =3D ad3552r_set_ch_value(dac, - AD3552R_CH_OUTPUT_RANGE_SEL, - ch, val); + if (ch =3D=3D 0) + val =3D FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(0), val); + else + val =3D FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(1), val); + + err =3D ad3552r_update_reg_field(dac, + AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE, + AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch), + val); if (err) return err; =20 @@ -958,7 +916,14 @@ static int ad3552r_configure_device(struct ad3552r_des= c *dac) ad3552r_calc_gain_and_offset(dac, ch); dac->enabled_ch |=3D BIT(ch); =20 - err =3D ad3552r_set_ch_value(dac, AD3552R_CH_SELECT, ch, 1); + if (ch =3D=3D 0) + val =3D FIELD_PREP(AD3552R_MASK_CH(0), 1); + else + val =3D FIELD_PREP(AD3552R_MASK_CH(1), 1); + + err =3D ad3552r_update_reg_field(dac, + AD3552R_REG_ADDR_CH_SELECT_16B, + AD3552R_MASK_CH(ch), val); if (err < 0) return err; =20 @@ -970,8 +935,15 @@ static int ad3552r_configure_device(struct ad3552r_des= c *dac) /* Disable unused channels */ for_each_clear_bit(ch, &dac->enabled_ch, dac->model_data->num_hw_channels) { - err =3D ad3552r_set_ch_value(dac, AD3552R_CH_AMPLIFIER_POWERDOWN, - ch, 1); + if (ch =3D=3D 0) + val =3D FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(0), 1); + else + val =3D FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(1), 1); + + err =3D ad3552r_update_reg_field(dac, + AD3552R_REG_ADDR_POWERDOWN_CONFIG, + AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch), + val); if (err) return err; } --=20 2.45.0.rc1 From nobody Mon Feb 9 17:27:30 2026 Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.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 169DE1AE027 for ; Thu, 29 Aug 2024 12:33:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934809; cv=none; b=JdXxkend6/1KJrTtK3+GxIT6CRAEeSpsPHg1tjWe6xYathYs36CkuOxrmsOnczhvY70vP1FBHegea/57ecgAe/4vgsTAj2AtaKZ5rH1/RJHmJmoHahDTmcAa/usEqkA77RnCshDORvzNAwhKNivHVZWh2IaPG1jTo8k/t7bM8Bc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934809; c=relaxed/simple; bh=yVObNTbKruHg2Tdvo+Ftyt0hECcIrR0Syn95YxsZ/jE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=e5D9vIsovNIOES62QFwS7ASLcaUmHRnWGm9txYgAw36Q4fR2ueMMh6nAqLJE6ZUYx2SqheXWVFqjY7scGH1/dazB7G/hYtm+cuE87ZXwBjFbcPe8OKa6XDioEb5y8615CbZ/JhUF1yILsOYKbp03iUivCJce0noMh5HZk1FEqm0= 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=IbaBlbFb; arc=none smtp.client-ip=209.85.221.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="IbaBlbFb" Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-37182eee02dso364264f8f.1 for ; Thu, 29 Aug 2024 05:33:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1724934804; x=1725539604; 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=jqMPr8/Zk/eVIdO2ewPoiAiUs8EC2UTKzcb7DAIT2DU=; b=IbaBlbFb9cpQTanfu1KQ8JAw5izKwbuCf+KX1wx4pacB5MEvWQCs5f+75sBGWt53JP ugbuHwvyphW+rcs/R9O9G9bEhNVGm7Txd2yocHHzc52+HiNasJQBUV4Ua0RFsaZ2aPbA mNfHu9zXIg04G5OPwjgfAAriy+OXDRA2qyEFhD1GsB3FFaH0OXr0CLXCnIdzzTEBWWQ/ WS0J4rD8zyvL74KF9mnRZtmLMFMCA4+tt9xaL1s/FKYfAXSXOJPcWNV3HDqMOj0Jdqof R7qpBRdq6DNYcxYu9lG1W6TEPbIY6rpP3UqXgm5tu1G2Kwx9gzLg4oTTD/S9iLnZD00b ZK1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724934804; x=1725539604; 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=jqMPr8/Zk/eVIdO2ewPoiAiUs8EC2UTKzcb7DAIT2DU=; b=cQ4yCgOIW+k15SNMw/1Z3YOLsDC7kzdd6vmY8U93OebmY/YqkSqFP66yqDU8eXOCl+ A/2bnVYqApFZf2WMJvAtgaVAKX+j9BVPc4eIZWWNH62k5xULjCIAdvFWXH3m77hPRfCs rZNRp7SSG03Xwq8+i7ZZogorS5NcoUpTWqlqBowEQyoM7ys5LJNkVm9Jrm8/FdcItmML XZzhVYVk8FMwdLdtPbxaALJRWsRw96Ehk2k7DoTsJuKZAmOnkW9oonhTCc4kzSZ1em8R g4nDMyQonxBVb06L8jOCY01v9dQP/Z31Ngz6KtUqLQcKnobb87smokDhLW2Gt5kOF8Be 10FA== X-Forwarded-Encrypted: i=1; AJvYcCVjlKfAUQk7MtOUSlGnVqOaeeY+L1g2YI/WzLgjoiCa5pBdgyZOJUvddjQ4/6o7cdYBpal9hmGYbvYiTjY=@vger.kernel.org X-Gm-Message-State: AOJu0YxCLrgIHL7GU/XT+jgqb6vIxsYLhNHD6qK0Fi7UklQzOur33WEn mBX8kmtANz6cMxBAbRdBgvKvx3vAlQaq0SyuU0swhwefS8/p0ODaq9k/ANxinNCTKZPI1LC6vAN D X-Google-Smtp-Source: AGHT+IHsJt18NS8Q3S8/IX/ogmMk/0mYaWp6QmL7O+w4LQXo+CbHA2m4nS2SH5AeKNdqdAgvoRDMcQ== X-Received: by 2002:a5d:59a9:0:b0:35f:314a:229c with SMTP id ffacd0b85a97d-374a0232925mr1272703f8f.28.1724934803920; Thu, 29 Aug 2024 05:33:23 -0700 (PDT) Received: from [127.0.1.1] (host-95-233-232-76.retail.telecomitalia.it. [95.233.232.76]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3749ee9978bsm1315042f8f.49.2024.08.29.05.33.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Aug 2024 05:33:23 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 29 Aug 2024 14:32:04 +0200 Subject: [PATCH RFC 6/8] iio: dac: ad3552r: extract common code (no changes in behavior intended) 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: <20240829-wip-bl-ad3552r-axi-v0-v1-6-b6da6015327a@baylibre.com> References: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> In-Reply-To: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Extracting common code, to share common code to be used later by the AXI driver version (ad3552r-axi.c). Signed-off-by: Angelo Dureghello --- drivers/iio/dac/Makefile | 2 +- drivers/iio/dac/ad3552r-common.c | 163 +++++++++++++++++++++++ drivers/iio/dac/ad3552r.c | 276 ++++-------------------------------= ---- drivers/iio/dac/ad3552r.h | 199 ++++++++++++++++++++++++++++ 4 files changed, 389 insertions(+), 251 deletions(-) diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 2cf148f16306..56a125f56284 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -4,7 +4,7 @@ # =20 # When adding new entries keep the list in alphabetical order -obj-$(CONFIG_AD3552R) +=3D ad3552r.o +obj-$(CONFIG_AD3552R) +=3D ad3552r.o ad3552r-common.o obj-$(CONFIG_AD5360) +=3D ad5360.o obj-$(CONFIG_AD5380) +=3D ad5380.o obj-$(CONFIG_AD5421) +=3D ad5421.o diff --git a/drivers/iio/dac/ad3552r-common.c b/drivers/iio/dac/ad3552r-com= mon.c new file mode 100644 index 000000000000..c8ccfbe2e95e --- /dev/null +++ b/drivers/iio/dac/ad3552r-common.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright (c) 2010-2024 Analog Devices Inc. +// Copyright (c) 2024 Baylibre, SAS + +#include +#include +#include +#include + +#include "ad3552r.h" + +static const s32 ad3552r_ch_ranges[][2] =3D { + [AD3552R_CH_OUTPUT_RANGE_0__2P5V] =3D {0, 2500}, + [AD3552R_CH_OUTPUT_RANGE_0__5V] =3D {0, 5000}, + [AD3552R_CH_OUTPUT_RANGE_0__10V] =3D {0, 10000}, + [AD3552R_CH_OUTPUT_RANGE_NEG_5__5V] =3D {-5000, 5000}, + [AD3552R_CH_OUTPUT_RANGE_NEG_10__10V] =3D {-10000, 10000} +}; + +static const s32 ad3542r_ch_ranges[][2] =3D { + [AD3542R_CH_OUTPUT_RANGE_0__2P5V] =3D {0, 2500}, + [AD3542R_CH_OUTPUT_RANGE_0__3V] =3D {0, 3000}, + [AD3542R_CH_OUTPUT_RANGE_0__5V] =3D {0, 5000}, + [AD3542R_CH_OUTPUT_RANGE_0__10V] =3D {0, 10000}, + [AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V] =3D {-2500, 7500}, + [AD3542R_CH_OUTPUT_RANGE_NEG_5__5V] =3D {-5000, 5000} +}; + +void ad3552r_calc_custom_gain(u8 p, u8 n, s16 goffs, u16 *reg) +{ + *reg =3D FIELD_PREP(AD3552R_MASK_CH_RANGE_OVERRIDE, 1); + *reg |=3D FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_P, p); + *reg |=3D FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_N, n); + *reg |=3D FIELD_PREP(AD3552R_MASK_CH_OFFSET_BIT_8, abs((s32)goffs) >> 8); + *reg |=3D FIELD_PREP(AD3552R_MASK_CH_OFFSET_POLARITY, (s32)goffs < 0); +} + +int ad3552r_get_ref_voltage(struct device *dev, u32 *val) +{ + int voltage, delta =3D 100000; + + voltage =3D devm_regulator_get_enable_read_voltage(dev, "vref"); + if (voltage < 0 && voltage !=3D -ENODEV) + return dev_err_probe(dev, voltage, + "Error getting vref voltage\n"); + + if (voltage =3D=3D -ENODEV) { + if (device_property_read_bool(dev, "adi,vref-out-en")) + *val =3D AD3552R_INTERNAL_VREF_PIN_2P5V; + else + *val =3D AD3552R_INTERNAL_VREF_PIN_FLOATING; + } else { + if (voltage > 2500000 + delta || voltage < 2500000 - delta) { + dev_warn(dev, "vref-supply must be 2.5V"); + return -EINVAL; + } + *val =3D AD3552R_EXTERNAL_VREF_PIN_INPUT; + } + + return 0; +} + +int ad3552r_get_drive_strength(struct device *dev, u32 *val) +{ + int err; + + err =3D device_property_read_u32(dev, "adi,sdo-drive-strength", val); + if (!err && *val > 3) { + dev_err(dev, + "adi,sdo-drive-strength must be less than 4\n"); + return -EINVAL; + } + + return err; +} + +int ad3552r_get_custom_gain(struct device *dev, struct fwnode_handle *chil= d, + u8 *gs_p, u8 *gs_n, u16 *rfb, s16 *goffs) +{ + int err; + u32 val; + struct fwnode_handle *gain_child __free(fwnode_handle) + =3D fwnode_get_named_child_node(child, + "custom-output-range-config"); + + if (!gain_child) + return dev_err_probe(dev, -EINVAL, + "custom-output-range-config mandatory\n"); + + err =3D fwnode_property_read_u32(gain_child, "adi,gain-scaling-p", &val); + if (err) + return dev_err_probe(dev, err, + "adi,gain-scaling-p mandatory\n"); + *gs_p =3D val; + + err =3D fwnode_property_read_u32(gain_child, "adi,gain-scaling-n", &val); + if (err) + return dev_err_probe(dev, err, + "adi,gain-scaling-n property mandatory\n"); + *gs_n =3D val; + + err =3D fwnode_property_read_u32(gain_child, "adi,rfb-ohms", &val); + if (err) + return dev_err_probe(dev, err, + "adi,rfb-ohms mandatoryn"); + *rfb =3D val; + + err =3D fwnode_property_read_u32(gain_child, "adi,gain-offset", &val); + if (err) + return dev_err_probe(dev, err, + "adi,gain-offset mandatory\n"); + *goffs =3D val; + + return 0; +} + +static int ad3552r_find_range(u16 id, s32 *vals) +{ + int i, len; + const s32 (*ranges)[2]; + + if (id =3D=3D AD3542R_ID) { + len =3D ARRAY_SIZE(ad3542r_ch_ranges); + ranges =3D ad3542r_ch_ranges; + } else { + len =3D ARRAY_SIZE(ad3552r_ch_ranges); + ranges =3D ad3552r_ch_ranges; + } + + for (i =3D 0; i < len; i++) + if (vals[0] =3D=3D ranges[i][0] * 1000 && + vals[1] =3D=3D ranges[i][1] * 1000) + return i; + + return -EINVAL; +} + +int ad3552r_get_output_range(struct device *dev, enum ad3552r_id chip_id, + struct fwnode_handle *child, u32 *val) +{ + int ret; + s32 vals[2]; + + if (!fwnode_property_present(child, "adi,output-range-microvolt")) + return -ENOENT; + + ret =3D fwnode_property_read_u32_array(child, + "adi,output-range-microvolt", + vals, 2); + if (ret) + return dev_err_probe(dev, ret, + "invalid adi,output-range-microvolt\n"); + + ret =3D ad3552r_find_range(chip_id, vals); + if (ret < 0) + return dev_err_probe(dev, ret, + "invalid adi,output-range-microvolt value\n"); + + *val =3D ret; + + return 0; +} diff --git a/drivers/iio/dac/ad3552r.c b/drivers/iio/dac/ad3552r.c index d867de7c90d1..c149be9c8c7d 100644 --- a/drivers/iio/dac/ad3552r.c +++ b/drivers/iio/dac/ad3552r.c @@ -11,153 +11,9 @@ #include #include #include -#include #include =20 -/* Register addresses */ -/* Primary address space */ -#define AD3552R_REG_ADDR_INTERFACE_CONFIG_A 0x00 -#define AD3552R_MASK_SOFTWARE_RESET (BIT(7) | BIT(0)) -#define AD3552R_MASK_ADDR_ASCENSION BIT(5) -#define AD3552R_MASK_SDO_ACTIVE BIT(4) -#define AD3552R_REG_ADDR_INTERFACE_CONFIG_B 0x01 -#define AD3552R_MASK_SINGLE_INST BIT(7) -#define AD3552R_MASK_SHORT_INSTRUCTION BIT(3) -#define AD3552R_REG_ADDR_DEVICE_CONFIG 0x02 -#define AD3552R_MASK_DEVICE_STATUS(n) BIT(4 + (n)) -#define AD3552R_MASK_CUSTOM_MODES GENMASK(3, 2) -#define AD3552R_MASK_OPERATING_MODES GENMASK(1, 0) -#define AD3552R_REG_ADDR_CHIP_TYPE 0x03 -#define AD3552R_MASK_CLASS GENMASK(7, 0) -#define AD3552R_REG_ADDR_PRODUCT_ID_L 0x04 -#define AD3552R_REG_ADDR_PRODUCT_ID_H 0x05 -#define AD3552R_REG_ADDR_CHIP_GRADE 0x06 -#define AD3552R_MASK_GRADE GENMASK(7, 4) -#define AD3552R_MASK_DEVICE_REVISION GENMASK(3, 0) -#define AD3552R_REG_ADDR_SCRATCH_PAD 0x0A -#define AD3552R_REG_ADDR_SPI_REVISION 0x0B -#define AD3552R_REG_ADDR_VENDOR_L 0x0C -#define AD3552R_REG_ADDR_VENDOR_H 0x0D -#define AD3552R_REG_ADDR_STREAM_MODE 0x0E -#define AD3552R_MASK_LENGTH GENMASK(7, 0) -#define AD3552R_REG_ADDR_TRANSFER_REGISTER 0x0F -#define AD3552R_MASK_MULTI_IO_MODE GENMASK(7, 6) -#define AD3552R_MASK_STREAM_LENGTH_KEEP_VALUE BIT(2) -#define AD3552R_REG_ADDR_INTERFACE_CONFIG_C 0x10 -#define AD3552R_MASK_CRC_ENABLE (GENMASK(7, 6) |\ - GENMASK(1, 0)) -#define AD3552R_MASK_STRICT_REGISTER_ACCESS BIT(5) -#define AD3552R_REG_ADDR_INTERFACE_STATUS_A 0x11 -#define AD3552R_MASK_INTERFACE_NOT_READY BIT(7) -#define AD3552R_MASK_CLOCK_COUNTING_ERROR BIT(5) -#define AD3552R_MASK_INVALID_OR_NO_CRC BIT(3) -#define AD3552R_MASK_WRITE_TO_READ_ONLY_REGISTER BIT(2) -#define AD3552R_MASK_PARTIAL_REGISTER_ACCESS BIT(1) -#define AD3552R_MASK_REGISTER_ADDRESS_INVALID BIT(0) -#define AD3552R_REG_ADDR_INTERFACE_CONFIG_D 0x14 -#define AD3552R_MASK_ALERT_ENABLE_PULLUP BIT(6) -#define AD3552R_MASK_MEM_CRC_EN BIT(4) -#define AD3552R_MASK_SDO_DRIVE_STRENGTH GENMASK(3, 2) -#define AD3552R_MASK_DUAL_SPI_SYNCHROUNOUS_EN BIT(1) -#define AD3552R_MASK_SPI_CONFIG_DDR BIT(0) -#define AD3552R_REG_ADDR_SH_REFERENCE_CONFIG 0x15 -#define AD3552R_MASK_IDUMP_FAST_MODE BIT(6) -#define AD3552R_MASK_SAMPLE_HOLD_DIFFERENTIAL_USER_EN BIT(5) -#define AD3552R_MASK_SAMPLE_HOLD_USER_TRIM GENMASK(4, 3) -#define AD3552R_MASK_SAMPLE_HOLD_USER_ENABLE BIT(2) -#define AD3552R_MASK_REFERENCE_VOLTAGE_SEL GENMASK(1, 0) -#define AD3552R_REG_ADDR_ERR_ALARM_MASK 0x16 -#define AD3552R_MASK_REF_RANGE_ALARM BIT(6) -#define AD3552R_MASK_CLOCK_COUNT_ERR_ALARM BIT(5) -#define AD3552R_MASK_MEM_CRC_ERR_ALARM BIT(4) -#define AD3552R_MASK_SPI_CRC_ERR_ALARM BIT(3) -#define AD3552R_MASK_WRITE_TO_READ_ONLY_ALARM BIT(2) -#define AD3552R_MASK_PARTIAL_REGISTER_ACCESS_ALARM BIT(1) -#define AD3552R_MASK_REGISTER_ADDRESS_INVALID_ALARM BIT(0) -#define AD3552R_REG_ADDR_ERR_STATUS 0x17 -#define AD3552R_MASK_REF_RANGE_ERR_STATUS BIT(6) -#define AD3552R_MASK_DUAL_SPI_STREAM_EXCEEDS_DAC_ERR_STATUS BIT(5) -#define AD3552R_MASK_MEM_CRC_ERR_STATUS BIT(4) -#define AD3552R_MASK_RESET_STATUS BIT(0) -#define AD3552R_REG_ADDR_POWERDOWN_CONFIG 0x18 -#define AD3552R_MASK_CH_DAC_POWERDOWN(ch) BIT(4 + (ch)) -#define AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(ch) BIT(ch) -#define AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE 0x19 -#define AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch) ((ch) ? GENMASK(7, 4) :\ - GENMASK(3, 0)) -#define AD3552R_REG_ADDR_CH_OFFSET(ch) (0x1B + (ch) * 2) -#define AD3552R_MASK_CH_OFFSET_BITS_0_7 GENMASK(7, 0) -#define AD3552R_REG_ADDR_CH_GAIN(ch) (0x1C + (ch) * 2) -#define AD3552R_MASK_CH_RANGE_OVERRIDE BIT(7) -#define AD3552R_MASK_CH_GAIN_SCALING_N GENMASK(6, 5) -#define AD3552R_MASK_CH_GAIN_SCALING_P GENMASK(4, 3) -#define AD3552R_MASK_CH_OFFSET_POLARITY BIT(2) -#define AD3552R_MASK_CH_OFFSET_BIT_8 BIT(0) -/* - * Secondary region - * For multibyte registers specify the highest address because the access = is - * done in descending order - */ -#define AD3552R_SECONDARY_REGION_START 0x28 -#define AD3552R_REG_ADDR_HW_LDAC_16B 0x28 -#define AD3552R_REG_ADDR_CH_DAC_16B(ch) (0x2C - (1 - ch) * 2) -#define AD3552R_REG_ADDR_DAC_PAGE_MASK_16B 0x2E -#define AD3552R_REG_ADDR_CH_SELECT_16B 0x2F -#define AD3552R_REG_ADDR_INPUT_PAGE_MASK_16B 0x31 -#define AD3552R_REG_ADDR_SW_LDAC_16B 0x32 -#define AD3552R_REG_ADDR_CH_INPUT_16B(ch) (0x36 - (1 - ch) * 2) -/* 3 bytes registers */ -#define AD3552R_REG_START_24B 0x37 -#define AD3552R_REG_ADDR_HW_LDAC_24B 0x37 -#define AD3552R_REG_ADDR_CH_DAC_24B(ch) (0x3D - (1 - ch) * 3) -#define AD3552R_REG_ADDR_DAC_PAGE_MASK_24B 0x40 -#define AD3552R_REG_ADDR_CH_SELECT_24B 0x41 -#define AD3552R_REG_ADDR_INPUT_PAGE_MASK_24B 0x44 -#define AD3552R_REG_ADDR_SW_LDAC_24B 0x45 -#define AD3552R_REG_ADDR_CH_INPUT_24B(ch) (0x4B - (1 - ch) * 3) - -/* Useful defines */ -#define AD3552R_MAX_CH 2 -#define AD3552R_MASK_CH(ch) BIT(ch) -#define AD3552R_MASK_ALL_CH GENMASK(1, 0) -#define AD3552R_MAX_REG_SIZE 3 -#define AD3552R_READ_BIT BIT(7) -#define AD3552R_ADDR_MASK GENMASK(6, 0) -#define AD3552R_MASK_DAC_12B 0xFFF0 -#define AD3552R_DEFAULT_CONFIG_B_VALUE 0x8 -#define AD3552R_SCRATCH_PAD_TEST_VAL1 0x34 -#define AD3552R_SCRATCH_PAD_TEST_VAL2 0xB2 -#define AD3552R_GAIN_SCALE 1000 -#define AD3552R_LDAC_PULSE_US 100 - -enum ad3552r_ch_vref_select { - /* Internal source with Vref I/O floating */ - AD3552R_INTERNAL_VREF_PIN_FLOATING, - /* Internal source with Vref I/O at 2.5V */ - AD3552R_INTERNAL_VREF_PIN_2P5V, - /* External source with Vref I/O as input */ - AD3552R_EXTERNAL_VREF_PIN_INPUT -}; - -enum ad3552r_id { - AD3541R_ID =3D 0x400b, - AD3542R_ID =3D 0x4009, - AD3551R_ID =3D 0x400a, - AD3552R_ID =3D 0x4008, -}; - -enum ad3552r_ch_output_range { - /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ - AD3552R_CH_OUTPUT_RANGE_0__2P5V, - /* Range from 0 V to 5 V. Requires Rfb1x connection */ - AD3552R_CH_OUTPUT_RANGE_0__5V, - /* Range from 0 V to 10 V. Requires Rfb2x connection */ - AD3552R_CH_OUTPUT_RANGE_0__10V, - /* Range from -5 V to 5 V. Requires Rfb2x connection */ - AD3552R_CH_OUTPUT_RANGE_NEG_5__5V, - /* Range from -10 V to 10 V. Requires Rfb4x connection */ - AD3552R_CH_OUTPUT_RANGE_NEG_10__10V, -}; +#include "ad3552r.h" =20 static const s32 ad3552r_ch_ranges[][2] =3D { [AD3552R_CH_OUTPUT_RANGE_0__2P5V] =3D {0, 2500}, @@ -167,21 +23,6 @@ static const s32 ad3552r_ch_ranges[][2] =3D { [AD3552R_CH_OUTPUT_RANGE_NEG_10__10V] =3D {-10000, 10000} }; =20 -enum ad3542r_ch_output_range { - /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ - AD3542R_CH_OUTPUT_RANGE_0__2P5V, - /* Range from 0 V to 3 V. Requires Rfb1x connection */ - AD3542R_CH_OUTPUT_RANGE_0__3V, - /* Range from 0 V to 5 V. Requires Rfb1x connection */ - AD3542R_CH_OUTPUT_RANGE_0__5V, - /* Range from 0 V to 10 V. Requires Rfb2x connection */ - AD3542R_CH_OUTPUT_RANGE_0__10V, - /* Range from -2.5 V to 7.5 V. Requires Rfb2x connection */ - AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V, - /* Range from -5 V to 5 V. Requires Rfb2x connection */ - AD3542R_CH_OUTPUT_RANGE_NEG_5__5V, -}; - static const s32 ad3542r_ch_ranges[][2] =3D { [AD3542R_CH_OUTPUT_RANGE_0__2P5V] =3D {0, 2500}, [AD3542R_CH_OUTPUT_RANGE_0__3V] =3D {0, 3000}, @@ -733,72 +574,32 @@ static void ad3552r_calc_gain_and_offset(struct ad355= 2r_desc *dac, s32 ch) dac->ch_data[ch].offset_dec =3D div_s64(tmp, span); } =20 -static int ad3552r_find_range(const struct ad3552r_model_data *model_data, - s32 *vals) -{ - int i; - - for (i =3D 0; i < model_data->num_ranges; i++) - if (vals[0] =3D=3D model_data->ranges_table[i][0] * 1000 && - vals[1] =3D=3D model_data->ranges_table[i][1] * 1000) - return i; - - return -EINVAL; -} - static int ad3552r_configure_custom_gain(struct ad3552r_desc *dac, struct fwnode_handle *child, u32 ch) { struct device *dev =3D &dac->spi->dev; - u32 val; int err; u8 addr; - u16 reg =3D 0, offset; - - struct fwnode_handle *gain_child __free(fwnode_handle) - =3D fwnode_get_named_child_node(child, - "custom-output-range-config"); - if (!gain_child) - return dev_err_probe(dev, -EINVAL, - "mandatory custom-output-range-config property missing\n"); - - dac->ch_data[ch].range_override =3D 1; - reg |=3D FIELD_PREP(AD3552R_MASK_CH_RANGE_OVERRIDE, 1); - - err =3D fwnode_property_read_u32(gain_child, "adi,gain-scaling-p", &val); - if (err) - return dev_err_probe(dev, err, - "mandatory adi,gain-scaling-p property missing\n"); - reg |=3D FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_P, val); - dac->ch_data[ch].p =3D val; + u16 reg =3D 0; =20 - err =3D fwnode_property_read_u32(gain_child, "adi,gain-scaling-n", &val); + err =3D ad3552r_get_custom_gain(dev, child, + &dac->ch_data[ch].p, + &dac->ch_data[ch].n, + &dac->ch_data[ch].rfb, + &dac->ch_data[ch].gain_offset); if (err) - return dev_err_probe(dev, err, - "mandatory adi,gain-scaling-n property missing\n"); - reg |=3D FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_N, val); - dac->ch_data[ch].n =3D val; - - err =3D fwnode_property_read_u32(gain_child, "adi,rfb-ohms", &val); - if (err) - return dev_err_probe(dev, err, - "mandatory adi,rfb-ohms property missing\n"); - dac->ch_data[ch].rfb =3D val; + return err; =20 - err =3D fwnode_property_read_u32(gain_child, "adi,gain-offset", &val); - if (err) - return dev_err_probe(dev, err, - "mandatory adi,gain-offset property missing\n"); - dac->ch_data[ch].gain_offset =3D val; + dac->ch_data[ch].range_override =3D 1; =20 - offset =3D abs((s32)val); - reg |=3D FIELD_PREP(AD3552R_MASK_CH_OFFSET_BIT_8, (offset >> 8)); + ad3552r_calc_custom_gain(dac->ch_data[ch].p, dac->ch_data[ch].n, + dac->ch_data[ch].gain_offset, ®); =20 - reg |=3D FIELD_PREP(AD3552R_MASK_CH_OFFSET_POLARITY, (s32)val < 0); addr =3D AD3552R_REG_ADDR_CH_GAIN(ch); err =3D ad3552r_write_reg(dac, addr, - offset & AD3552R_MASK_CH_OFFSET_BITS_0_7); + abs((s32)dac->ch_data[ch].gain_offset) & + AD3552R_MASK_CH_OFFSET_BITS_0_7); if (err) return dev_err_probe(dev, err, "Error writing register\n"); =20 @@ -812,30 +613,17 @@ static int ad3552r_configure_custom_gain(struct ad355= 2r_desc *dac, static int ad3552r_configure_device(struct ad3552r_desc *dac) { struct device *dev =3D &dac->spi->dev; - int err, cnt =3D 0, voltage, delta =3D 100000; - u32 vals[2], val, ch; + int err, cnt =3D 0; + u32 val, ch; =20 dac->gpio_ldac =3D devm_gpiod_get_optional(dev, "ldac", GPIOD_OUT_HIGH); if (IS_ERR(dac->gpio_ldac)) return dev_err_probe(dev, PTR_ERR(dac->gpio_ldac), "Error getting gpio ldac"); =20 - voltage =3D devm_regulator_get_enable_read_voltage(dev, "vref"); - if (voltage < 0 && voltage !=3D -ENODEV) - return dev_err_probe(dev, voltage, "Error getting vref voltage\n"); - - if (voltage =3D=3D -ENODEV) { - if (device_property_read_bool(dev, "adi,vref-out-en")) - val =3D AD3552R_INTERNAL_VREF_PIN_2P5V; - else - val =3D AD3552R_INTERNAL_VREF_PIN_FLOATING; - } else { - if (voltage > 2500000 + delta || voltage < 2500000 - delta) { - dev_warn(dev, "vref-supply must be 2.5V"); - return -EINVAL; - } - val =3D AD3552R_EXTERNAL_VREF_PIN_INPUT; - } + err =3D ad3552r_get_ref_voltage(dev, &val); + if (err) + return err; =20 err =3D ad3552r_update_reg_field(dac, AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, @@ -844,13 +632,10 @@ static int ad3552r_configure_device(struct ad3552r_de= sc *dac) if (err) return err; =20 - err =3D device_property_read_u32(dev, "adi,sdo-drive-strength", &val); + err =3D ad3552r_get_drive_strength(dev, &val); + if (err) + return err; if (!err) { - if (val > 3) { - dev_err(dev, "adi,sdo-drive-strength must be less than 4\n"); - return -EINVAL; - } - err =3D ad3552r_update_reg_field(dac, AD3552R_REG_ADDR_INTERFACE_CONFIG_D, AD3552R_MASK_SDO_DRIVE_STRENGTH, @@ -875,21 +660,12 @@ static int ad3552r_configure_device(struct ad3552r_de= sc *dac) "reg must be less than %d\n", dac->model_data->num_hw_channels); =20 - if (fwnode_property_present(child, "adi,output-range-microvolt")) { - err =3D fwnode_property_read_u32_array(child, - "adi,output-range-microvolt", - vals, - 2); - if (err) - return dev_err_probe(dev, err, - "adi,output-range-microvolt property could not be parsed\n"); - - err =3D ad3552r_find_range(dac->model_data, vals); - if (err < 0) - return dev_err_probe(dev, err, - "Invalid adi,output-range-microvolt value\n"); + err =3D ad3552r_get_output_range(dev, dac->model_data->chip_id, + child, &val); + if (err && err !=3D -ENOENT) + return err; =20 - val =3D err; + if (!err) { if (ch =3D=3D 0) val =3D FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(0), val); else diff --git a/drivers/iio/dac/ad3552r.h b/drivers/iio/dac/ad3552r.h new file mode 100644 index 000000000000..cada1f12f000 --- /dev/null +++ b/drivers/iio/dac/ad3552r.h @@ -0,0 +1,199 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * AD3552R Digital <-> Analog converters common header + * + * Copyright 2024 Analog Devices Inc. + * Author: Angelo Dureghello + */ + +#ifndef __DRIVERS_IIO_DAC_AD3552R_H__ +#define __DRIVERS_IIO_DAC_AD3552R_H__ + +/* Register addresses */ +/* Primary address space */ +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_A 0x00 +#define AD3552R_MASK_SOFTWARE_RESET (BIT(7) | BIT(0)) +#define AD3552R_MASK_ADDR_ASCENSION BIT(5) +#define AD3552R_MASK_SDO_ACTIVE BIT(4) +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_B 0x01 +#define AD3552R_MASK_SINGLE_INST BIT(7) +#define AD3552R_MASK_SHORT_INSTRUCTION BIT(3) +#define AD3552R_REG_ADDR_DEVICE_CONFIG 0x02 +#define AD3552R_MASK_DEVICE_STATUS(n) BIT(4 + (n)) +#define AD3552R_MASK_CUSTOM_MODES GENMASK(3, 2) +#define AD3552R_MASK_OPERATING_MODES GENMASK(1, 0) +#define AD3552R_REG_ADDR_CHIP_TYPE 0x03 +#define AD3552R_MASK_CLASS GENMASK(7, 0) +#define AD3552R_REG_ADDR_PRODUCT_ID_L 0x04 +#define AD3552R_REG_ADDR_PRODUCT_ID_H 0x05 +#define AD3552R_REG_ADDR_CHIP_GRADE 0x06 +#define AD3552R_MASK_GRADE GENMASK(7, 4) +#define AD3552R_MASK_DEVICE_REVISION GENMASK(3, 0) +#define AD3552R_REG_ADDR_SCRATCH_PAD 0x0A +#define AD3552R_REG_ADDR_SPI_REVISION 0x0B +#define AD3552R_REG_ADDR_VENDOR_L 0x0C +#define AD3552R_REG_ADDR_VENDOR_H 0x0D +#define AD3552R_REG_ADDR_STREAM_MODE 0x0E +#define AD3552R_MASK_LENGTH GENMASK(7, 0) +#define AD3552R_REG_ADDR_TRANSFER_REGISTER 0x0F +#define AD3552R_MASK_MULTI_IO_MODE GENMASK(7, 6) +#define AD3552R_MASK_STREAM_LENGTH_KEEP_VALUE BIT(2) +#define AD3552R_MASK_DUAL_SPI BIT(6) +#define AD3552R_MASK_QUAD_SPI BIT(7) +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_C 0x10 +#define AD3552R_MASK_CRC_ENABLE (GENMASK(7, 6) |\ + GENMASK(1, 0)) +#define AD3552R_MASK_STRICT_REGISTER_ACCESS BIT(5) +#define AD3552R_REG_ADDR_INTERFACE_STATUS_A 0x11 +#define AD3552R_MASK_INTERFACE_NOT_READY BIT(7) +#define AD3552R_MASK_CLOCK_COUNTING_ERROR BIT(5) +#define AD3552R_MASK_INVALID_OR_NO_CRC BIT(3) +#define AD3552R_MASK_WRITE_TO_READ_ONLY_REGISTER BIT(2) +#define AD3552R_MASK_PARTIAL_REGISTER_ACCESS BIT(1) +#define AD3552R_MASK_REGISTER_ADDRESS_INVALID BIT(0) +#define AD3552R_REG_ADDR_INTERFACE_CONFIG_D 0x14 +#define AD3552R_MASK_ALERT_ENABLE_PULLUP BIT(6) +#define AD3552R_MASK_MEM_CRC_EN BIT(4) +#define AD3552R_MASK_SDO_DRIVE_STRENGTH GENMASK(3, 2) +#define AD3552R_MASK_DUAL_SPI_SYNCHROUNOUS_EN BIT(1) +#define AD3552R_MASK_SPI_CONFIG_DDR BIT(0) +#define AD3552R_REG_ADDR_SH_REFERENCE_CONFIG 0x15 +#define AD3552R_MASK_IDUMP_FAST_MODE BIT(6) +#define AD3552R_MASK_SAMPLE_HOLD_DIFF_USER_EN BIT(5) +#define AD3552R_MASK_SAMPLE_HOLD_USER_TRIM GENMASK(4, 3) +#define AD3552R_MASK_SAMPLE_HOLD_USER_ENABLE BIT(2) +#define AD3552R_MASK_REFERENCE_VOLTAGE_SEL GENMASK(1, 0) +#define AD3552R_REG_ADDR_ERR_ALARM_MASK 0x16 +#define AD3552R_MASK_REF_RANGE_ALARM BIT(6) +#define AD3552R_MASK_CLOCK_COUNT_ERR_ALARM BIT(5) +#define AD3552R_MASK_MEM_CRC_ERR_ALARM BIT(4) +#define AD3552R_MASK_SPI_CRC_ERR_ALARM BIT(3) +#define AD3552R_MASK_WRITE_TO_READ_ONLY_ALARM BIT(2) +#define AD3552R_MASK_PARTIAL_REGISTER_ACCESS_ALARM BIT(1) +#define AD3552R_MASK_REGISTER_ADDRESS_INVALID_ALARM BIT(0) +#define AD3552R_REG_ADDR_ERR_STATUS 0x17 +#define AD3552R_MASK_REF_RANGE_ERR_STATUS BIT(6) +#define AD3552R_MASK_STREAM_EXCEEDS_DAC_ERR_STATUS BIT(5) +#define AD3552R_MASK_MEM_CRC_ERR_STATUS BIT(4) +#define AD3552R_MASK_RESET_STATUS BIT(0) +#define AD3552R_REG_ADDR_POWERDOWN_CONFIG 0x18 +#define AD3552R_MASK_CH_DAC_POWERDOWN(ch) BIT(4 + (ch)) +#define AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(ch) BIT(ch) +#define AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE 0x19 +#define AD3552R_MASK_CH0_RANGE GENMASK(2, 0) +#define AD3552R_MASK_CH1_RANGE GENMASK(6, 4) +#define AD3552R_MASK_CH_OUTPUT_RANGE GENMASK(7, 0) +#define AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch) ((ch) ? \ + GENMASK(7, 4) : \ + GENMASK(3, 0)) +#define AD3552R_REG_ADDR_CH_OFFSET(ch) (0x1B + (ch) * 2) +#define AD3552R_MASK_CH_OFFSET_BITS_0_7 GENMASK(7, 0) +#define AD3552R_REG_ADDR_CH_GAIN(ch) (0x1C + (ch) * 2) +#define AD3552R_MASK_CH_RANGE_OVERRIDE BIT(7) +#define AD3552R_MASK_CH_GAIN_SCALING_N GENMASK(6, 5) +#define AD3552R_MASK_CH_GAIN_SCALING_P GENMASK(4, 3) +#define AD3552R_MASK_CH_OFFSET_POLARITY BIT(2) +#define AD3552R_MASK_CH_OFFSET_BIT_8 BIT(0) +/* + * Secondary region + * For multibyte registers specify the highest address because the access = is + * done in descending order + */ +#define AD3552R_SECONDARY_REGION_START 0x28 +#define AD3552R_REG_ADDR_HW_LDAC_16B 0x28 +#define AD3552R_REG_ADDR_CH_DAC_16B(ch) (0x2C - (1 - (ch)) * 2) +#define AD3552R_REG_ADDR_DAC_PAGE_MASK_16B 0x2E +#define AD3552R_REG_ADDR_CH_SELECT_16B 0x2F +#define AD3552R_REG_ADDR_INPUT_PAGE_MASK_16B 0x31 +#define AD3552R_REG_ADDR_SW_LDAC_16B 0x32 +#define AD3552R_REG_ADDR_CH_INPUT_16B(ch) (0x36 - (1 - (ch)) * 2) +/* 3 bytes registers */ +#define AD3552R_REG_START_24B 0x37 +#define AD3552R_REG_ADDR_HW_LDAC_24B 0x37 +#define AD3552R_REG_ADDR_CH_DAC_24B(ch) (0x3D - (1 - (ch)) * 3) +#define AD3552R_REG_ADDR_DAC_PAGE_MASK_24B 0x40 +#define AD3552R_REG_ADDR_CH_SELECT_24B 0x41 +#define AD3552R_REG_ADDR_INPUT_PAGE_MASK_24B 0x44 +#define AD3552R_REG_ADDR_SW_LDAC_24B 0x45 +#define AD3552R_REG_ADDR_CH_INPUT_24B(ch) (0x4B - (1 - (ch)) * 3) + +/* Useful defines */ +#define AD3552R_MAX_CH 2 +#define AD3552R_MASK_CH(ch) BIT(ch) +#define AD3552R_MASK_ALL_CH GENMASK(1, 0) +#define AD3552R_MAX_REG_SIZE 3 +#define AD3552R_READ_BIT BIT(7) +#define AD3552R_ADDR_MASK GENMASK(6, 0) +#define AD3552R_MASK_DAC_12B GENMASK(15, 4) +#define AD3552R_DEFAULT_CONFIG_B_VALUE 0x8 +#define AD3552R_SCRATCH_PAD_TEST_VAL1 0x34 +#define AD3552R_SCRATCH_PAD_TEST_VAL2 0xB2 +#define AD3552R_GAIN_SCALE 1000 +#define AD3552R_LDAC_PULSE_US 100 + +#define AD3552R_AXI_REG_MAX 0x35 +#define AD3552R_REF_INIT 0x00 +#define AD3552R_STREAM_2BYTE_LOOP 0x02 +#define AD3552R_STREAM_4BYTE_LOOP 0x04 + +#define AD3552R_CH0_ACTIVE BIT(0) +#define AD3552R_CH1_ACTIVE BIT(1) +#define AD3552R_CH0_CH1_ACTIVE (AD3552R_CH0_ACTIVE | \ + AD3552R_CH1_ACTIVE) + +#define AD3552R_TRANSFER_INIT (AD3552R_MASK_QUAD_SPI | \ + AD3552R_MASK_STREAM_LENGTH_KEEP_VALUE) + +enum ad3552r_id { + AD3541R_ID =3D 0x400b, + AD3542R_ID =3D 0x4009, + AD3551R_ID =3D 0x400a, + AD3552R_ID =3D 0x4008, +}; + +enum ad3552r_ch_vref_select { + /* Internal source with Vref I/O floating */ + AD3552R_INTERNAL_VREF_PIN_FLOATING, + /* Internal source with Vref I/O at 2.5V */ + AD3552R_INTERNAL_VREF_PIN_2P5V, + /* External source with Vref I/O as input */ + AD3552R_EXTERNAL_VREF_PIN_INPUT +}; + +enum ad3542r_ch_output_range { + /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ + AD3542R_CH_OUTPUT_RANGE_0__2P5V, + /* Range from 0 V to 3 V. Requires Rfb1x connection */ + AD3542R_CH_OUTPUT_RANGE_0__3V, + /* Range from 0 V to 5 V. Requires Rfb1x connection */ + AD3542R_CH_OUTPUT_RANGE_0__5V, + /* Range from 0 V to 10 V. Requires Rfb2x connection */ + AD3542R_CH_OUTPUT_RANGE_0__10V, + /* Range from -2.5 V to 7.5 V. Requires Rfb2x connection */ + AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V, + /* Range from -5 V to 5 V. Requires Rfb2x connection */ + AD3542R_CH_OUTPUT_RANGE_NEG_5__5V, +}; + +enum ad3552r_ch_output_range { + /* Range from 0 V to 2.5 V. Requires Rfb1x connection */ + AD3552R_CH_OUTPUT_RANGE_0__2P5V, + /* Range from 0 V to 5 V. Requires Rfb1x connection */ + AD3552R_CH_OUTPUT_RANGE_0__5V, + /* Range from 0 V to 10 V. Requires Rfb2x connection */ + AD3552R_CH_OUTPUT_RANGE_0__10V, + /* Range from -5 V to 5 V. Requires Rfb2x connection */ + AD3552R_CH_OUTPUT_RANGE_NEG_5__5V, + /* Range from -10 V to 10 V. Requires Rfb4x connection */ + AD3552R_CH_OUTPUT_RANGE_NEG_10__10V, +}; + +int ad3552r_get_output_range(struct device *dev, enum ad3552r_id id, + struct fwnode_handle *child, u32 *val); +int ad3552r_get_custom_gain(struct device *dev, struct fwnode_handle *chil= d, + u8 *gs_p, u8 *gs_n, u16 *rfb, s16 *goffs); +void ad3552r_calc_custom_gain(u8 p, u8 n, s16 goffs, u16 *reg); +int ad3552r_get_ref_voltage(struct device *dev, u32 *val); +int ad3552r_get_drive_strength(struct device *dev, u32 *val); + +#endif /* __DRIVERS_IIO_DAC_AD3552R_H__ */ --=20 2.45.0.rc1 From nobody Mon Feb 9 17:27:30 2026 Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (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 5EA1B1AED54 for ; Thu, 29 Aug 2024 12:33:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934810; cv=none; b=jGLPSJHliEUenjVZYdTGhKL+I6p3bCNbXCaECMBX0/Do5ScMLFl5JPNI5LSM2hbi7rdD7hchj0Ge9vG31ns2dJyhER7jL0KlyBX7NaahgylZr2wyEuZE8zrrUrNyWEj4SEsJAPhik4Xg6AAqI+r6CYqjUBHVGnLdkVdjG4MsqB0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934810; c=relaxed/simple; bh=w8nUYGJBv9bfyc6zTQO/J4ppZxo97XPP+m2Jiyw3Bnc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cqb0/xu0VWxmpUcJbw7AWIoKU9TrrFIsLqaTA7UxSsYRmoDhKrdu+tyqAkdJDLanwscrZpJjxomru47xNv6BCdgHFe33u19fVh+HLWNz4ncwT9lIF8+dMgxyIjherIOVxD3F7ZrAR+ji8RP2jIcGn9gAmGkxW9KyhXCOmTfAnsg= 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=P+YE62tV; arc=none smtp.client-ip=209.85.221.53 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="P+YE62tV" Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-367990aaef3so365269f8f.0 for ; Thu, 29 Aug 2024 05:33:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1724934805; x=1725539605; 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=xOI0/LkEfO3vRmpVZA8C5jtFpDcwMZaIECMkAHo2fGg=; b=P+YE62tV3TqLL+hVjgbnooc3u5HE19kUIej3h4GzTM6O2CI4ucDCfIDgphbCMbG0Zs STxLv+fsY75yitiBxaB4MfX2Rwl9M0TLTJiQe4kEhZf6RJIqiRXt5+yQmoK5l56cJpCX 8S4aklBoEKY75xS1kmKC2hY5N0o3XbTREMwvTFGXswptLhvI4Ex1b+VLrpbSzZNh4220 INsrn9ku21G2EeBFRGdTT4CJi/GaN83PXR7aHhLKZCXAKVYg/6H7GGarA2bqbQZPlDr9 RVo4PSAg1NAY8D400ZTup4qNSgDBMSW4yzeUuKM7ZgEAuoB+AjwL1BUI4i9Mi2wNicQ9 UtrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724934805; x=1725539605; 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=xOI0/LkEfO3vRmpVZA8C5jtFpDcwMZaIECMkAHo2fGg=; b=IHHGEyCx36VBwxS4PuxOcZ1A5Ts3EJhccX4fLsMWT7lkRUusLCmepiF9fvS9yFT451 9dx7oS/WHWGYi+JXGje0RYGlvZBFYO9+aHP+c7Jg2Hh0kfa1uxIR/9zd0/6iRKEvDd/x HQS6CkaiHZ3Or/bgBCszREmQ5G9VXdw2Mjnl2qxbFS+nsRTJSqZ35uL/adSBEIM9Y29x TfBd3GTP/OIqqs/3jS+q+j1dyUzlYJRJGcHnfBPFcBkF/ed+nB90Ghvl2jDGPIqutREp osuQNi1BCtuOq78/MiUVckS18fNXroQfz6Wkp2emCLTxEge0mOr/uoV/xEjMDF6EPK0p bdRw== X-Forwarded-Encrypted: i=1; AJvYcCUpjSMFYec6MooY/Af7g7PZqoQQsxBzJ05FmA5RLzqb6Oz0u6ojCm8KeEedoCNyJvdAIYp5qBEpEdg+Zq0=@vger.kernel.org X-Gm-Message-State: AOJu0Yyth6sVivlDYFY327s6qDoXwI5OB312Khme60GcyxqKGPOmpuIh g/gBwNDWzC3wCVBXU/cQwWHg0iAxL7GIoTm0GOyzHw4mSZrZhkFYCEcDWdHSaCnGP3L4ocJ8Vwh B X-Google-Smtp-Source: AGHT+IFdUw2IETmAulQYBiAIFcMarSHktWwFm/Cm9Eo5FKwCWrkpnRWQ5JZF4ue2V6ckuXT+5VD6XA== X-Received: by 2002:a05:6000:1f0e:b0:371:8a91:9e72 with SMTP id ffacd0b85a97d-3749b54cfd1mr1806377f8f.30.1724934805262; Thu, 29 Aug 2024 05:33:25 -0700 (PDT) Received: from [127.0.1.1] (host-95-233-232-76.retail.telecomitalia.it. [95.233.232.76]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3749ee9978bsm1315042f8f.49.2024.08.29.05.33.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Aug 2024 05:33:24 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 29 Aug 2024 14:32:05 +0200 Subject: [PATCH RFC 7/8] iio: dac: ad3552r: add axi platform driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240829-wip-bl-ad3552r-axi-v0-v1-7-b6da6015327a@baylibre.com> References: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> In-Reply-To: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Add support for ad3552r AXI DAC IP version. Signed-off-by: Angelo Dureghello --- drivers/iio/dac/Kconfig | 11 + drivers/iio/dac/Makefile | 1 + drivers/iio/dac/ad3552r-axi.c | 572 ++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 584 insertions(+) diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 1cfd7e2a622f..030af7702a3c 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -16,6 +16,17 @@ config AD3552R To compile this driver as a module, choose M here: the module will be called ad3552r. =20 +config AD3552R_AXI + tristate "Analog Devices AD3552R DAC driver, AXI version" + select IIO_BACKEND + help + Say yes here to build support for Analog Devices AD3552R + Digital to Analog Converter, connected through the Xilinx + fpga AXI interface. + + To compile this driver as a module, choose M here: the + module will be called ad3552r-axi. + config AD5064 tristate "Analog Devices AD5064 and similar multi-channel DAC driver" depends on (SPI_MASTER && I2C!=3Dm) || I2C diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 56a125f56284..cc2af3aa3f52 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -5,6 +5,7 @@ =20 # When adding new entries keep the list in alphabetical order obj-$(CONFIG_AD3552R) +=3D ad3552r.o ad3552r-common.o +obj-$(CONFIG_AD3552R_AXI) +=3D ad3552r-axi.o ad3552r-common.o obj-$(CONFIG_AD5360) +=3D ad5360.o obj-$(CONFIG_AD5380) +=3D ad5380.o obj-$(CONFIG_AD5421) +=3D ad5421.o diff --git a/drivers/iio/dac/ad3552r-axi.c b/drivers/iio/dac/ad3552r-axi.c new file mode 100644 index 000000000000..98e5da08c973 --- /dev/null +++ b/drivers/iio/dac/ad3552r-axi.c @@ -0,0 +1,572 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Analog Devices AD3552R + * Digital to Analog converter driver, AXI DAC backend version + * + * Copyright 2024 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ad3552r.h" + +enum ad3552r_synchronous_mode_status { + AD3552R_NO_SYNC, + AD3552R_EXT_SYNC_ARM, +}; + +struct ad3552r_axi_state { + struct gpio_desc *reset_gpio; + struct device *dev; + struct iio_backend *back; + unsigned long active_scan_mask; + enum ad3552r_id chip_id; + bool single_channel; + bool synced_transfer; +}; + +static int axi3552r_qspi_update_reg_bits(struct iio_backend *back, + u32 reg, u32 mask, u32 val, + size_t xfer_size) +{ + u32 rval; + int err; + + err =3D iio_backend_bus_reg_read(back, reg, &rval, xfer_size); + if (err) + return err; + + rval &=3D ~mask; + rval |=3D val; + + return iio_backend_bus_reg_write(back, reg, &rval, xfer_size); +} + +static int ad3552r_axi_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct ad3552r_axi_state *st =3D iio_priv(indio_dev); + int err, ch =3D chan->channel; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: { + int clk_rate; + + err =3D iio_backend_read_raw(st->back, chan, &clk_rate, 0, + IIO_CHAN_INFO_FREQUENCY); + if (err !=3D IIO_VAL_INT) + return err; + + /* + * Data stream SDR/DDR (clk_in/8 or clk_in/4 update rate). + * Samplerate has sense in DDR only. + */ + if (st->single_channel) + clk_rate =3D DIV_ROUND_CLOSEST(clk_rate, 4); + else + clk_rate =3D DIV_ROUND_CLOSEST(clk_rate, 8); + + *val =3D clk_rate; + + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_RAW: + err =3D iio_backend_bus_reg_read(st->back, + AD3552R_REG_ADDR_CH_DAC_16B(ch), + val, 2); + if (err) + return err; + + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int ad3552r_axi_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_RAW: + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + struct ad3552r_axi_state *st =3D iio_priv(indio_dev); + int ch =3D chan->channel; + + return iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_CH_DAC_16B(ch), &val, 2); + } + unreachable(); + default: + return -EINVAL; + } +} + +static int ad3552r_axi_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *active_scan_mask) +{ + struct ad3552r_axi_state *st =3D iio_priv(indio_dev); + + st->active_scan_mask =3D *active_scan_mask; + + return 0; +} + +static int ad3552r_axi_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad3552r_axi_state *st =3D iio_priv(indio_dev); + struct iio_backend_data_fmt fmt =3D { + .type =3D IIO_BACKEND_DATA_UNSIGNED + }; + int loop_len, val, err; + + /* Inform DAC chip to switch into DDR mode */ + err =3D axi3552r_qspi_update_reg_bits(st->back, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SPI_CONFIG_DDR, + AD3552R_MASK_SPI_CONFIG_DDR, 1); + if (err) + return err; + + /* Inform DAC IP to go for DDR mode from now on */ + err =3D iio_backend_ddr_enable(st->back); + if (err) + goto exit_err; + + switch (st->active_scan_mask) { + case AD3552R_CH0_ACTIVE: + st->single_channel =3D true; + loop_len =3D AD3552R_STREAM_2BYTE_LOOP; + val =3D AD3552R_REG_ADDR_CH_DAC_16B(0); + break; + case AD3552R_CH1_ACTIVE: + st->single_channel =3D true; + loop_len =3D AD3552R_STREAM_2BYTE_LOOP; + val =3D AD3552R_REG_ADDR_CH_DAC_16B(1); + break; + case AD3552R_CH0_CH1_ACTIVE: + st->single_channel =3D false; + loop_len =3D AD3552R_STREAM_4BYTE_LOOP; + val =3D AD3552R_REG_ADDR_CH_DAC_16B(1); + break; + default: + return -EINVAL; + } + + err =3D iio_backend_bus_reg_write(st->back, AD3552R_REG_ADDR_STREAM_MODE, + &loop_len, 1); + if (err) + goto exit_err; + + iio_backend_data_transfer_addr(st->back, val); + if (err) + goto exit_err; + /* + * The EXT_SYNC is mandatory in the CN0585 project where 2 instances + * of the IP are in the design and they need to generate the signals + * synchronized. + * + * Note: in first IP implementations CONFIG EXT_SYNC (RO) can be 0, + * but EXT_SYMC is anabled anyway. + */ + + if (st->synced_transfer =3D=3D AD3552R_EXT_SYNC_ARM) + err =3D iio_backend_ext_sync_enable(st->back); + else + err =3D iio_backend_ext_sync_disable(st->back); + if (err) + goto exit_err_sync; + + err =3D iio_backend_data_format_set(st->back, 0, &fmt); + if (err) + goto exit_err; + + err =3D iio_backend_buffer_enable(st->back); + if (!err) + return 0; + +exit_err_sync: + iio_backend_ext_sync_disable(st->back); + +exit_err: + axi3552r_qspi_update_reg_bits(st->back, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SPI_CONFIG_DDR, + 0, 1); + + iio_backend_ddr_disable(st->back); + + return err; +} + +static int ad3552r_axi_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad3552r_axi_state *st =3D iio_priv(indio_dev); + int err; + + err =3D iio_backend_buffer_disable(st->back); + if (err) + return err; + + /* Inform DAC to set in DDR mode */ + err =3D axi3552r_qspi_update_reg_bits(st->back, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SPI_CONFIG_DDR, + 0, 1); + if (err) + return err; + + return iio_backend_ddr_disable(st->back); +} + +static int ad3552r_axi_set_output_range(struct ad3552r_axi_state *st, + unsigned int mode) +{ + int range_ch_0 =3D FIELD_PREP(AD3552R_MASK_CH0_RANGE, mode); + int range_ch_1 =3D FIELD_PREP(AD3552R_MASK_CH1_RANGE, mode); + + return axi3552r_qspi_update_reg_bits(st->back, + AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE, + AD3552R_MASK_CH_OUTPUT_RANGE, + range_ch_0 | range_ch_1, 1); +} + +static int ad3552r_axi_reset(struct ad3552r_axi_state *st) +{ + int err; + + /* AXI reset performed by backend enable() */ + + st->reset_gpio =3D devm_gpiod_get_optional(st->dev, + "reset", GPIOD_OUT_LOW); + if (IS_ERR(st->reset_gpio)) + return PTR_ERR(st->reset_gpio); + + if (st->reset_gpio) { + gpiod_set_value_cansleep(st->reset_gpio, 1); + fsleep(10); + gpiod_set_value_cansleep(st->reset_gpio, 0); + } else { + err =3D axi3552r_qspi_update_reg_bits(st->back, + AD3552R_REG_ADDR_INTERFACE_CONFIG_A, + AD3552R_MASK_SOFTWARE_RESET, + AD3552R_MASK_SOFTWARE_RESET, 1); + if (err) + return err; + } + msleep(100); + + return 0; +} + +static int ad3552r_axi_setup(struct ad3552r_axi_state *st) +{ + struct fwnode_handle *child __free(fwnode_handle) =3D NULL; + u8 gs_p, gs_n; + s16 goffs; + u16 id, rfb, reg =3D 0, offset =3D 0; + u32 val, range; + int err; + + err =3D ad3552r_axi_reset(st); + if (err) + return err; + + err =3D iio_backend_ddr_disable(st->back); + if (err) + return err; + + val =3D AD3552R_SCRATCH_PAD_TEST_VAL1; + err =3D iio_backend_bus_reg_write(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + &val, 1); + if (err) + return err; + + err =3D iio_backend_bus_reg_read(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + &val, 1); + if (err) + return err; + + if (val !=3D AD3552R_SCRATCH_PAD_TEST_VAL1) { + dev_err(st->dev, + "SCRATCH_PAD_TEST mismatch. Expected 0x%x, Read 0x%x\n", + AD3552R_SCRATCH_PAD_TEST_VAL1, val); + return -EIO; + } + + val =3D AD3552R_SCRATCH_PAD_TEST_VAL2; + err =3D iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_SCRATCH_PAD, + &val, 1); + if (err) + return err; + + err =3D iio_backend_bus_reg_read(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + &val, 1); + if (err) + return err; + + if (val !=3D AD3552R_SCRATCH_PAD_TEST_VAL2) { + dev_err(st->dev, + "SCRATCH_PAD_TEST mismatch. Expected 0x%x, Read 0x%x\n", + AD3552R_SCRATCH_PAD_TEST_VAL2, val); + return -EIO; + } + + err =3D iio_backend_bus_reg_read(st->back, AD3552R_REG_ADDR_PRODUCT_ID_L, + &val, 1); + if (err) + return err; + + id =3D val; + mdelay(100); + + err =3D iio_backend_bus_reg_read(st->back, AD3552R_REG_ADDR_PRODUCT_ID_H, + &val, 1); + if (err) + return err; + + id |=3D val << 8; + if (id !=3D AD3552R_ID) { + dev_err(st->dev, "Chip ID mismatch. Expected 0x%x, Read 0x%x\n", + AD3552R_ID, id); + return -ENODEV; + } + + st->chip_id =3D id; + + val =3D AD3552R_REF_INIT; + err =3D iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, + &val, 1); + if (err) + return err; + + val =3D AD3552R_TRANSFER_INIT; + err =3D iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_TRANSFER_REGISTER, + &val, 1); + if (err) + return err; + + err =3D iio_backend_data_source_set(st->back, 0, IIO_BACKEND_EXTERNAL); + if (err) + return err; + + err =3D iio_backend_data_source_set(st->back, 1, IIO_BACKEND_EXTERNAL); + if (err) + return err; + + err =3D ad3552r_get_ref_voltage(st->dev, &val); + if (err) + return err; + + err =3D axi3552r_qspi_update_reg_bits(st->back, + AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, + AD3552R_MASK_REFERENCE_VOLTAGE_SEL, + val, 1); + if (err) + return err; + + err =3D ad3552r_get_drive_strength(st->dev, &val); + if (!err) { + err =3D axi3552r_qspi_update_reg_bits(st->back, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SDO_DRIVE_STRENGTH, + val, 1); + if (err) + return err; + } + + child =3D device_get_named_child_node(st->dev, "channel"); + if (!child) + return -EINVAL; + + err =3D ad3552r_get_output_range(st->dev, st->chip_id, child, &range); + if (!err) + return ad3552r_axi_set_output_range(st, range); + + if (err !=3D -ENOENT) + return err; + + /* Try to get custom range */ + err =3D ad3552r_get_custom_gain(st->dev, child, + &gs_p, &gs_n, &rfb, &goffs); + if (err) + return err; + + ad3552r_calc_custom_gain(gs_p, gs_n, goffs, ®); + + offset =3D abs((s32)goffs); + + err =3D iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_CH_OFFSET(0), + &offset, 1); + if (err) + return dev_err_probe(st->dev, err, + "Error writing register\n"); + + err =3D iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_CH_OFFSET(1), + &offset, 1); + if (err) + return dev_err_probe(st->dev, err, + "Error writing register\n"); + + err =3D iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_CH_GAIN(0), + ®, 1); + if (err) + return dev_err_probe(st->dev, err, + "Error writing register\n"); + + err =3D iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_CH_GAIN(1), + ®, 1); + if (err) + return dev_err_probe(st->dev, err, + "Error writing register\n"); + + return 0; +} + +static const struct iio_buffer_setup_ops ad3552r_axi_buffer_setup_ops =3D { + .postenable =3D ad3552r_axi_buffer_postenable, + .predisable =3D ad3552r_axi_buffer_predisable, +}; + +static int ad3552r_set_synchronous_mode_status(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int status) +{ + struct ad3552r_axi_state *st =3D iio_priv(indio_dev); + + st->synced_transfer =3D status; + + return 0; +} + +static int ad3552r_get_synchronous_mode_status(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ad3552r_axi_state *st =3D iio_priv(indio_dev); + + return st->synced_transfer; +} + +static const char *const synchronous_mode_status[] =3D { + [AD3552R_NO_SYNC] =3D "no_sync", + [AD3552R_EXT_SYNC_ARM] =3D "ext_sync_arm", +}; + +static const struct iio_enum ad3552r_synchronous_mode_enum =3D { + .items =3D synchronous_mode_status, + .num_items =3D ARRAY_SIZE(synchronous_mode_status), + .get =3D ad3552r_get_synchronous_mode_status, + .set =3D ad3552r_set_synchronous_mode_status, +}; + +static const struct iio_chan_spec_ext_info ad3552r_axi_ext_info[] =3D { + IIO_ENUM("synchronous_mode", IIO_SHARED_BY_TYPE, + &ad3552r_synchronous_mode_enum), + IIO_ENUM_AVAILABLE("synchronous_mode", IIO_SHARED_BY_TYPE, + &ad3552r_synchronous_mode_enum), + {}, +}; + +#define AD3552R_CHANNEL(ch) { \ + .type =3D IIO_VOLTAGE, \ + .info_mask_separate =3D BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_all =3D (((ch) =3D=3D 0) ? \ + BIT(IIO_CHAN_INFO_SAMP_FREQ) : 0), \ + .output =3D 1, \ + .indexed =3D 1, \ + .channel =3D (ch), \ + .scan_index =3D (ch), \ + .scan_type =3D { \ + .sign =3D 'u', \ + .realbits =3D 16, \ + .storagebits =3D 16, \ + .shift =3D 0, \ + .endianness =3D IIO_BE, \ + }, \ + .ext_info =3D ad3552r_axi_ext_info, \ +} + +static struct iio_chan_spec ad3552r_axi_channels[] =3D { + AD3552R_CHANNEL(0), + AD3552R_CHANNEL(1), +}; + +static const struct iio_info ad3552r_axi_info =3D { + .read_raw =3D &ad3552r_axi_read_raw, + .write_raw =3D &ad3552r_axi_write_raw, + .update_scan_mode =3D ad3552r_axi_update_scan_mode, +}; + +static int ad3552r_axi_probe(struct platform_device *pdev) +{ + struct ad3552r_axi_state *st; + struct iio_dev *indio_dev; + int ret; + + indio_dev =3D devm_iio_device_alloc(&pdev->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st =3D iio_priv(indio_dev); + st->dev =3D &pdev->dev; + + st->back =3D devm_iio_backend_get(&pdev->dev, NULL); + if (IS_ERR(st->back)) + return PTR_ERR(st->back); + + ret =3D devm_iio_backend_enable(&pdev->dev, st->back); + if (ret) + return ret; + + indio_dev->name =3D "ad3552r"; + indio_dev->modes =3D INDIO_DIRECT_MODE; + indio_dev->setup_ops =3D &ad3552r_axi_buffer_setup_ops; + indio_dev->channels =3D ad3552r_axi_channels; + indio_dev->num_channels =3D ARRAY_SIZE(ad3552r_axi_channels); + indio_dev->info =3D &ad3552r_axi_info; + + ret =3D devm_iio_backend_request_buffer(&pdev->dev, st->back, indio_dev); + if (ret) + return ret; + + ret =3D ad3552r_axi_setup(st); + if (ret) + return ret; + + return devm_iio_device_register(&pdev->dev, indio_dev); +} + +static const struct of_device_id ad3552r_axi_of_id[] =3D { + { .compatible =3D "adi,ad3552r" }, + {} +}; +MODULE_DEVICE_TABLE(of, ad3552r_axi_of_id); + +static struct platform_driver axi_ad3552r_driver =3D { + .driver =3D { + .name =3D "ad3552r-axi", + .of_match_table =3D ad3552r_axi_of_id, + }, + .probe =3D ad3552r_axi_probe, +}; +module_platform_driver(axi_ad3552r_driver); + +MODULE_AUTHOR("Dragos Bogdan "); +MODULE_AUTHOR("Angelo Dureghello "); +MODULE_DESCRIPTION("AD3552R Driver - AXI IP version"); +MODULE_LICENSE("GPL"); --=20 2.45.0.rc1 From nobody Mon Feb 9 17:27:30 2026 Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.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 938451B0114 for ; Thu, 29 Aug 2024 12:33:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934810; cv=none; b=qEb7hc0Duk5g1NB+5Qb+0iyDufxiklb+RhISFKKfF2LKybySEpTpqlvBHRlPl7s5m8CiizgMmbfjCDpVks4f/rNbPksyUVfERDpN2v4e96QuMXdPopbsVVsvUv/Mt2KLZAjXBvTzfqwc9Wnl+n9xl5HEC/LkbNFuztuEdmXa2WM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724934810; c=relaxed/simple; bh=2mPWOtyTd/YBLFdmdjfe2ZHlnUKUTSLx+XgVmvWKRLs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gjPbr6LvsUYSzzxBaDuUyvmJH4nD1Mf1gZy/iz3TKMDndyfeKVsKQ5W+kN0KdZHTX+Rbb9HpDbyHPCOTlqLqqCuwm8ZDD66+mP/VDISbAHTta4P9BGYswoYHh1PAyn7v9tplbvjZHfCM/yyzbfHtVvL8hBFmxkA+xkqIBs7XKio= 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=bCYOTh5i; arc=none smtp.client-ip=209.85.221.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="bCYOTh5i" Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-371bb8322b2so346267f8f.0 for ; Thu, 29 Aug 2024 05:33:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1724934806; x=1725539606; 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=E1lPvyLwxDQjEGBnGsrIyA9bdmn+GnJfAmZj6pMaXAQ=; b=bCYOTh5iayHuymcaJQrT4KhXgZiJPYbfIfJxSdTbevM3yKaW03uOlJy/gyrFUs9mO8 oQCEDAjGML3FHjU3AjOf4f7DmHm+CWUSAEbacILnMAuGvy4BiRrdRS8gyNuX6deOuWkA b295QL78osWwbjnAz35Wxbr3tf66mhFB+WEv2fAuFHWAFvlK1TjlRZwmRczYTKbghv33 1/5Xeo9HHsPhqsjvXGbBmiId8SX9kxYcjSvo3RHaNohn5ipdRLpb6xUq36cPC8zF1CTt /gB0XyV4DuS066RH+0/JGtbbL94u5ESljZ1Qe/v4x1jq2D3AApy44NIGSkQ9jplGTAnV fI1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724934807; x=1725539607; 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=E1lPvyLwxDQjEGBnGsrIyA9bdmn+GnJfAmZj6pMaXAQ=; b=iegXNlJl8YpDHBCDnITsmpHW1I8CZuHlEMO4mKe5gAw2gBxoSMhtWZ8gf4KGpRPnia EpIUblH1hzn6p4SO2+eNx0tSMH5TZjLbz7G/LtQ+vhZ1GXfDv98U1Jbb5eNSJ558dLU6 +djLYV3ioxRq5HIM8xGye11zUdPl/NOqPyKo0VjXhVv+0V3sTFDkVx/+sctubgm3x5rM Al0ncr69ruXU1FAQKVMoxDUx3V8pmHGSkmBd972eBlPNbEIiIaymKxN3kE2HEL6cVS1k CvzPtsn0nQABDQNbvhXqH1zreUI1HSjUAZ+GDyKfEJnUzSHEJm6UI2nHEuJiWgWtG44k m0AA== X-Forwarded-Encrypted: i=1; AJvYcCWaRwRu/qUzOR9eybUr9rTa9ibaqahkVNs687BM2zFruUibzT1FUR3g40QHDL3oByjYtkpxmLJKW633qvo=@vger.kernel.org X-Gm-Message-State: AOJu0YzKm1H57e9WryWsoYf22kUeK1YIZ4Un719dGyCcZU6+7SUowjKT U53y3rO12iUQShCqUyypmSTZVKqD47jIGhf6ypEqk0+akQjtfumX/2Cfaxa8FvvZuiunQCTJ4dc A X-Google-Smtp-Source: AGHT+IFN3lOIB6gGygWvS7enFigGG4fh8ywN6uYsYc1jl1ZrAvYUvR4AaWIuj9iAzaNIUxh1F8FLFg== X-Received: by 2002:a5d:61c4:0:b0:360:70e3:ef2b with SMTP id ffacd0b85a97d-374a02318f1mr1095378f8f.26.1724934806553; Thu, 29 Aug 2024 05:33:26 -0700 (PDT) Received: from [127.0.1.1] (host-95-233-232-76.retail.telecomitalia.it. [95.233.232.76]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3749ee9978bsm1315042f8f.49.2024.08.29.05.33.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Aug 2024 05:33:26 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 29 Aug 2024 14:32:06 +0200 Subject: [PATCH RFC 8/8] iio: ABI: add DAC sysfs synchronous_mode parameter 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: <20240829-wip-bl-ad3552r-axi-v0-v1-8-b6da6015327a@baylibre.com> References: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> In-Reply-To: <20240829-wip-bl-ad3552r-axi-v0-v1-0-b6da6015327a@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , =?utf-8?q?Nuno_S=C3=A1?= , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Some DACs as ad3552r need a synchronous mode setting, adding this parameter for ad3552r and for future use on other DACs, if needed. Signed-off-by: Angelo Dureghello --- Documentation/ABI/testing/sysfs-bus-iio-dac | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dac b/Documentation/AB= I/testing/sysfs-bus-iio-dac index 810eaac5533c..a3012baf90b3 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-dac +++ b/Documentation/ABI/testing/sysfs-bus-iio-dac @@ -59,3 +59,10 @@ Description: multiple predefined symbols. Each symbol corresponds to a different output, denoted as out_voltageY_rawN, where N is the integer value of the symbol. Writing an integer value N will select out_voltageY_rawN. + +What: /sys/bus/iio/devices/iio:deviceX/out_voltage_synchronous_mode +KernelVersion: 6.13 +Contact: linux-iio@vger.kernel.org +Description: + This attribute allows a specific synchronization mode, mainly + intended for DACs where multiple synchronization methods are available. --=20 2.45.0.rc1