From patchwork Thu Sep 5 15:17:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13792580 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B66A48289A for ; Thu, 5 Sep 2024 15:18:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549534; cv=none; b=Ep/AEvESNz3YkBlMyyIrEnNja67myz9UU1mwpeiC3RwB+T5K9WfbBp+IFEYCb2T/LMA+siw9mjQ3zb/tcTcNzlsnxZUygF9r4ZlBOSUq06AKdaS1sw2PII3+qDv2Q+sjiAbRMCYqG7L+WoBFXABW1m/0cyP8vFvYA5VK1rog55k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549534; c=relaxed/simple; bh=z/eAL85+Stkl1y4Ul6ptW+vDl8DzLb24T1aicacKSuY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=t95pC/4jVe5QQkwa15BJDchNCMAFDzVPpr9LbOQ+GwH81YK+SN2lKcATWpoVQ8akL9T9LLuUje+BW6Jl0qShCefgQc/2cdC68V+qCkINL8luQwAXcX5C3Dpf/ix6LaVuKVbhBNIOn0W3FmgZoPPcjEQr6il2//TkJRXolPvLyh0= 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=D9EkiPVv; arc=none smtp.client-ip=209.85.128.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="D9EkiPVv" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-42c94eb9822so7538805e9.0 for ; Thu, 05 Sep 2024 08:18:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1725549531; x=1726154331; 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=J+pBsXxWmPsUINwVEM73NhnNRhkHrDQ3OXCzogbxm5A=; b=D9EkiPVv3LCsym5vjYXAIFlUN5kyy6dvw/9+ECYp2XJu5Wx6es2U1l2COl9x7F0Yex d1FsP7htfEtE6K4rYT8zURgGKVgdRisO+ERYWAOOZES1xAUeFy4GEjoiGnt2Fr4BOi/g sjlvrz3+Q+Cbl/uMYRkcFJusgkLYNdP34+3bcyoUpbOAr+9LAuFd6hXRuVYCQA1R/GKL qQA8mScxxNp/TUltF5re4ZVz1RsLwSzyiapXFBZm+p9Xy8upLgYt9YuFtb5YuDj7MW05 fc+p/WRb8MpePthk2XKxCIQ8T9IOXC8VpoUuaqHMXDc2wKKQ1mBmHe8Uy5uY3Ve66rzi Qicg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725549531; x=1726154331; 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=J+pBsXxWmPsUINwVEM73NhnNRhkHrDQ3OXCzogbxm5A=; b=YzAmZEOSV8XoBmK1mx4kL7O92gFJvGN9k+qj19mkI+00Xbcf0bt1FIPSAVs5U+5kdN 3oKk7O4V8Wc0PQZcLZSbDUdS6xlKb/HwIqI6Hv1Ced/UMe/ComGq1bIaSYpvPuJLj/lK 3PDh0hLma6aZ1f6vRaFv7PJvbRVRazPjivHT8KeOKHwpsILDq9Uu5m6hC6JuIcmbEmbE 5bYVnr2VTD0UC+CUEUjQKtjRXvd2lEYAKGLEUXSQaW2GSYMI+bhVfqSGpEBEkxcylcdL WgMLHM6aZRczyFqgMWofkORsO8SMKN4bp1n0obsDCOIF27Oux5zItDFyGDhZQhLh24sJ dbSQ== X-Gm-Message-State: AOJu0YyRctO1JZOjcdvlHLHsyENkWIYXf+U7gkstWubf2nBxw2TgKIug p7fo7x6L/rY2a6fqrKyarHIQhwXAyRxee0f5qzoPcGUvpDRn8CfF4uoHULF9exI= X-Google-Smtp-Source: AGHT+IGMtKkHEjH1/QBXvm71HwV6HrgYuJ8pRKgPHpUaa29RWeMdklaPHmHLjNcPgTRqGi+NronBag== X-Received: by 2002:a05:600c:1c0d:b0:429:994:41ae with SMTP id 5b1f17b1804b1-42c7b59e84cmr109955125e9.2.1725549530949; Thu, 05 Sep 2024 08:18:50 -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-374c1de81b2sm14031076f8f.30.2024.09.05.08.18.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Sep 2024 08:18:50 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 05 Sep 2024 17:17:31 +0200 Subject: [PATCH v2 1/9] dt-bindings: iio: dac: ad3552r: add io-backend property Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-1-87d669674c00@baylibre.com> References: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@baylibre.com> In-Reply-To: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@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, David Lechner , 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 | 42 ++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml index fc8b97f82077..a6ce863ca93c 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml @@ -60,12 +60,30 @@ properties: $ref: /schemas/types.yaml#/definitions/uint32 enum: [0, 1, 2, 3] + io-backends: + description: The iio backend reference. + An example backend can be found at + https://analogdevicesinc.github.io/hdl/library/axi_ad3552r/index.html + maxItems: 1 + '#address-cells': const: 1 '#size-cells': const: 0 +if: + required: + - reg + +then: + $ref: /schemas/spi/spi-peripheral-props.yaml# + + properties: + io-backends: false + + required: [ spi-max-frequency ] + patternProperties: "^channel@([0-1])$": type: object @@ -207,8 +225,6 @@ allOf: required: - compatible - - reg - - spi-max-frequency additionalProperties: false @@ -238,4 +254,26 @@ examples: }; }; }; + + - | + backend: axi_dac@44a70000 { + compatible = "adi,axi-dac-ad3552r"; + reg = <0x44a70000 0x1000>; + dmas = <&dac_tx_dma 0>; + dma-names = "tx"; + #io-backend-cells = <0>; + clocks = <&ref_clk>; + dac { + compatible = "adi,ad3552r"; + reset-gpios = <&gpio0 92 1>; + io-backends = <&backend>; + #address-cells = <1>; + #size-cells = <0>; + channel@0 { + reg = <0>; + adi,output-range-microvolt = <(-10000000) (10000000)>; + }; + }; + }; + ... From patchwork Thu Sep 5 15:17:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13792581 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 A694A198E84 for ; Thu, 5 Sep 2024 15:18:54 +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=1725549538; cv=none; b=WGgjUP69qHc+iJ/w7QO/j6XtO5NaEG8au5T0a0PjaAL4IUi3cUGIxrZxXPwHW1tRn5F9fsZSn8AM6mSVoYunXuH0mnqa6mB0W+kirdqATLvRnJzJsKPXZxXOqTUOTMkUaDmhos0jyotqDnd29AZrMK8v2RKRXFeL2gPdekFIR/E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549538; c=relaxed/simple; bh=7mDmujuW9L23gvDEPfcAQPH04sCLGsDLCdPBzT9HWoA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QybpAvxuWxrxh5J2iuuZhvhMcmxe6racN3ekok1dVRcok9iVsk1G0a2Xn3q7wmr+75YO0fWL6GvbQKqHLdJcecdbK0+8IdBQ4g3K3IURJZEDHinE6RW+x3flGhfD5NW8msrOSl6qNCeejA21TJ/90OTzb/dqWsdRyILD2qKvHRs= 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=JlQcpuWZ; 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="JlQcpuWZ" Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-374c7d14191so1134097f8f.0 for ; Thu, 05 Sep 2024 08:18:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1725549533; x=1726154333; 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=kAGC06t4jFVXSncjE9DHaxIHM4cxIKLmC+jNq9K1LOE=; b=JlQcpuWZKBO6oDCRyVleW83Uzrgb+pgUsMHpJUgZda6rpQVYt523pes+pq6C2X7Cba pXscfz6DWlZ02ao5D76gGP+XZhaB6nEcpSeoqAlnrzrSuHci+YcB3tj3NNq1Aly40odd 8WRoAHDHQ9eyr6hHk0DRQ7C72dA2FJpsEzWTkbvWGIq3OpXTpEnIw6Wm435bnhBTg3R4 7puNVYbSPbWRGqiYCEOcm9zQ1UU3c9jM0PhsChg7VZ2RbUmjOaC9w2068SUayW1zjY0/ zgXAZUglcGypU1FvBXhoI3y2kbi6I3JnDDTkUbiiqejKueyTNQax1VrmSF9Cw+67U/pX 9p3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725549533; x=1726154333; 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=kAGC06t4jFVXSncjE9DHaxIHM4cxIKLmC+jNq9K1LOE=; b=JbbjmQRb0veh2JkP56I7upYMxoTVAs+VF7MCMHkcLWhJPfKe1Njjgwvhzepod2tNpR GPlxNjR10/81LHOk/JYAExCfCn4p6AGpjnM5PWdabChfG2j5VxPh0Bw1PqGlgxiZl0iW JZnES/2lMRxtu4YtPvtKGRjv1PQob6Uxm1WS24dvrpxaa42thAc3MPUbsANew8XrB/Ae CjK59H98A3jOljX/ipYvZTeXG306Ju8pefY62relrgeDdOYzfgjoQLIQeAdHZc/SqtVj klwY6Ik67EEqyKAdgQz8KkfcUFtz2wOa5andgMnKIxBEGQfGxWr2BxwnZlAXSXOQc2uP mMUQ== X-Gm-Message-State: AOJu0YyDdw6IahV9JwandI1h00zOiUWyUUXpSoioZycoH1PCH8aGw3Oe FuVjj5XBk5qvvhOxbt+BLMF1c2dyLrMM7zEDYOWeu3HDWuT5g39mtqSaoaUHK0E= X-Google-Smtp-Source: AGHT+IEj0EPzxJ72BXRwSGmQVESxYruu+cPifDeDKcs58e/d2y2rA/DPkYkIDxDAURV3CSqEkg/WYw== X-Received: by 2002:a5d:55ca:0:b0:371:8685:84c with SMTP id ffacd0b85a97d-3779a70775amr3826341f8f.15.1725549532900; Thu, 05 Sep 2024 08:18:52 -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-374c1de81b2sm14031076f8f.30.2024.09.05.08.18.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Sep 2024 08:18:51 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 05 Sep 2024 17:17:32 +0200 Subject: [PATCH v2 2/9] iio: backend: extend features Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-2-87d669674c00@baylibre.com> References: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@baylibre.com> In-Reply-To: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@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, David Lechner , 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 | 157 +++++++++++++++++++++++++++++++++++++ include/linux/iio/backend.h | 33 ++++++++ 2 files changed, 190 insertions(+) diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c index 20b3b5212da7..231bef4b560e 100644 --- a/drivers/iio/industrialio-backend.c +++ b/drivers/iio/industrialio-backend.c @@ -718,6 +718,163 @@ static int __devm_iio_backend_get(struct device *dev, struct iio_backend *back) return 0; } +/** + * 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 iio buffering + * @back: Backend device + * + * Enabling the buffer, buffer data is processed and sent out from the + * bus interface. + * + * 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_buffer_disable - Disable iio buffering + * @back: Backend device + * + * Disabling the buffer, buffer data transfer on the bus interface + * is stopped. + * + * 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_data_transfer_addr - Set data address. + * @back: Backend device + * @address: Data register address + * + * Some devices may need to inform the backend about an address + * 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 + * @data_size: Transfer data 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, + unsigned int *val, size_t data_size) +{ + if (!data_size) + return -EINVAL; + + return iio_backend_op_call(back, bus_reg_read, reg, val, data_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 + * @data_size: Transfer data 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, + unsigned int val, size_t data_size) +{ + if (!data_size) + return -EINVAL; + + return iio_backend_op_call(back, bus_reg_write, reg, val, data_size); +} +EXPORT_SYMBOL_NS_GPL(iio_backend_bus_reg_write, IIO_BACKEND); + static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, const char *name, struct fwnode_handle *fwnode) { diff --git a/include/linux/iio/backend.h b/include/linux/iio/backend.h index 37d56914d485..eb8c5bb74bb5 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 }; enum iio_backend_data_source { IIO_BACKEND_INTERNAL_CONTINUOUS_WAVE, IIO_BACKEND_EXTERNAL, + IIO_BACKEND_INTERNAL_RAMP_16, IIO_BACKEND_DATA_SOURCE_MAX }; @@ -89,6 +91,15 @@ enum iio_backend_sample_trigger { * @read_raw: Read a channel attribute from a backend device * @debugfs_print_chan_status: Print channel status into a buffer. * @debugfs_reg_access: Read or write register value of backend. + * @ext_sync_enable: Enable external synchronization. + * @ext_sync_disable: Disable external synchronization. + * @ddr_enable: Enable interface DDR (Double Data Rate) mode. + * @ddr_disable: Disable interface DDR (Double Data Rate) mode. + * @buffer_enable: Enable data buffer. + * @buffer_disable: Disable data buffer. + * @data_transfer_addr: Set data address. + * @bus_reg_read: Read from the interface bus. + * @bus_reg_write: Write on the interface bus. **/ struct iio_backend_ops { int (*enable)(struct iio_backend *back); @@ -129,6 +140,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, + unsigned int *val, size_t data_size); + int (*bus_reg_write)(struct iio_backend *back, u32 reg, + unsigned int val, size_t data_size); }; /** @@ -164,6 +186,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, + unsigned int *val, size_t data_size); +int iio_backend_bus_reg_write(struct iio_backend *back, u32 reg, + unsigned int val, size_t data_size); ssize_t iio_backend_ext_info_set(struct iio_dev *indio_dev, uintptr_t private, const struct iio_chan_spec *chan, const char *buf, size_t len); From patchwork Thu Sep 5 15:17:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13792582 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (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 5E4BD19DF44 for ; Thu, 5 Sep 2024 15:18:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549538; cv=none; b=el7AxxemCJEBO1vzs6BZ2AKnVzxVmJZ7+CaQmuI/aft7NXqUK5crKcq2wASMg85rShUZzya3IY1suT4uMNBrVmXLQ+G4N5lUkUiW3qabwtGuRd/Hs0XSiZsA7aZOyZ/t4DIQsVM28E3jQ53iDikIkxqt1b9Pb8vTzYfBD7UdMPs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549538; c=relaxed/simple; bh=zqR8Ma3kQq7AIwQIpNx2PJFyFY9OTdv+a2GS2Z1e4G0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NiiwfjP3mHcs6ckLSlOS4OQOFpp4YkqVTiagKBuUKcTHazpSuePgOyVRIEcmEkQAKxnrEt3uVlodXrqt2ouoYGkosv/qYKtKEkXTfxGifJ07gHHcN/2Z+CeGTwU6dr9wHGcyVFlmpd7ul55c03/+Tg4iP7EICPxFuAKDCouh1j0= 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=K0hnjoBb; arc=none smtp.client-ip=209.85.128.48 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="K0hnjoBb" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-42bb81e795bso7464875e9.1 for ; Thu, 05 Sep 2024 08:18:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1725549535; x=1726154335; 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=rZWIl1ehBhaIBfAagiEJ5QO2cnvkrw2A+Y1bB2atjQg=; b=K0hnjoBboJvUBQAtSk8q3E2JYWvum5tTPMfRhd9BVoW0RCyfZQMnvuI2w8T2noNMLi 2g8TTr5Y4tO53CNqIJc5VdrDovVjly9CqHpGY/0IEX4+JMgfWctAfF8z6MVCnDyS1L3T Tz/1Jb5IBrEVUcV4SnOWIr3BNNhoGQ3IvYr/94ZTUxwKIEgvTn9wGZIVWhzqeDmmzpz2 BktJNOpU3aOl/ak563b59SQMSqNWK/bcxIlZfjrUkNhhVSs152SU88L4H62C0GVEHsip QE5+Hffy85qIzo9OBFti48S23iGTHtgbjkiVg1j6LHChE+DP4C3DqTGs+xup0S+3mmnk XirQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725549535; x=1726154335; 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=rZWIl1ehBhaIBfAagiEJ5QO2cnvkrw2A+Y1bB2atjQg=; b=GfCHMaf4n1lGBULI9bDLmRF/9dDwNSocPiJmbNcis9Tg1HStcgHMXhgj27tY3JhaeZ 4QhZm1cZbnIAVCNcy20CT1Ow6ArW1ci1DZZgKEzDc0T7RsiOa6nzi5QHqF0P7cJpTigm IyOYhbTJPVCkov4+o6BLu2vPKH7BRm1KDbZ72/QjZ8VSkQGU4XlC5dPq4zbV62PWIIdC 2zLOFojwR/XfzxGxK/xY0bk3pgc/Qz4TCDyvCePH8vf2xPKhNCcErB+LK1kVfGCgoC3X kjKrfEXR6+hoLKaDoS4ZD6QFuz55D8bpLzc1larZo3X7jkwXdQa1F+5w5De7wG1UVErI Ol+g== X-Gm-Message-State: AOJu0YzUk/V4PGBgiM6BpKgHyJ4ybLUt+b5Y7pcpILATH8vEgdFGWiSx DO/eb2hmR0ASh9MuEkphBtcQORQdlsUhSE/qrsrYZl7/cxpPLmCFRbxL1ug8GB0= X-Google-Smtp-Source: AGHT+IFfv6NcUGX8vOG3/4+6e/vDUUbSoXMb7KdUiar5eVs0/9ZUn5U0xFyGbxxUh5XllqbeOb6wdw== X-Received: by 2002:a05:600c:34c3:b0:426:5fe1:ec7a with SMTP id 5b1f17b1804b1-42bbb440201mr145238975e9.31.1725549534679; Thu, 05 Sep 2024 08:18:54 -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-374c1de81b2sm14031076f8f.30.2024.09.05.08.18.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Sep 2024 08:18:54 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 05 Sep 2024 17:17:33 +0200 Subject: [PATCH v2 3/9] iio: backend adi-axi-dac: extend features Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-3-87d669674c00@baylibre.com> References: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@baylibre.com> In-Reply-To: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@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, David Lechner , 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 ad3552r DAC. Mainly, a new compatible string has been added to support a DAC IP very similar to the generic DAC IP but with some customizations to work with the ad3552r. Then, a serie of generic functions has been added to match with ad3552r needs. Function names has been kept generic as much as possible, to allow re-utilization from other frontend drivers. Signed-off-by: Angelo Dureghello Co-developed-by: David Lechner Co-developed-by: Nuno Sá --- drivers/iio/dac/adi-axi-dac.c | 267 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 257 insertions(+), 10 deletions(-) diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c index 0cb00f3bec04..cc31e1dcd1df 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,25 @@ #define AXI_DAC_REG_CHAN_CNTRL_7(c) (0x0418 + (c) * 0x40) #define AXI_DAC_DATA_SEL GENMASK(3, 0) +#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 = 2, + AXI_DAC_DATA_INTERNAL_RAMP_16 = 11, +}; + +enum { + AXI_DAC_BUS_TYPE_NONE, + AXI_DAC_BUS_TYPE_DDR_QSPI, +}; + +struct axi_dac_info { + unsigned int version; + int bus_type; }; struct axi_dac_state { @@ -77,6 +114,7 @@ struct axi_dac_state { * data/variables. */ struct mutex lock; + const struct axi_dac_info *info; u64 dac_clk; u32 reg_config; bool int_tone; @@ -461,6 +499,11 @@ static int axi_dac_data_source_set(struct iio_backend *back, unsigned int chan, return regmap_update_bits(st->regmap, AXI_DAC_REG_CHAN_CNTRL_7(chan), 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 +561,192 @@ static int axi_dac_reg_access(struct iio_backend *back, unsigned int reg, return regmap_write(st->regmap, reg, writeval); } +static int axi_dac_ext_sync_enable(struct iio_backend *back) +{ + struct axi_dac_state *st = 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 = 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 = 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 = 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 = 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 = 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 address) +{ + struct axi_dac_state *st = 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 = iio_backend_get_priv(back); + + if (data->type == 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 = iio_backend_get_priv(back); + + switch (mask) { + case IIO_CHAN_INFO_FREQUENCY: + *val = 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, + unsigned int val, size_t data_size) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + + switch (st->info->bus_type) { + case AXI_DAC_BUS_TYPE_DDR_QSPI: { + int ret; + u32 ival; + + if (data_size == 2) + ival = FIELD_PREP(AXI_DAC_DATA_WR_16, val); + else + ival = FIELD_PREP(AXI_DAC_DATA_WR_8, val); + + ret = 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 (data_size == 1) + ret = regmap_set_bits(st->regmap, AXI_DAC_REG_CNTRL_2, + AXI_DAC_SYMB_8B); + else + ret = regmap_clear_bits(st->regmap, AXI_DAC_REG_CNTRL_2, + AXI_DAC_SYMB_8B); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AXI_DAC_REG_CUSTOM_CTRL, + AXI_DAC_ADDRESS, + FIELD_PREP(AXI_DAC_ADDRESS, reg)); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AXI_DAC_REG_CUSTOM_CTRL, + AXI_DAC_TRANSFER_DATA, + AXI_DAC_TRANSFER_DATA); + if (ret) + return ret; + + ret = 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); + } + break; + default: + return -EOPNOTSUPP; + } +} + +static int axi_dac_bus_reg_read(struct iio_backend *back, u32 reg, + unsigned int *val, size_t data_size) +{ + struct axi_dac_state *st = iio_backend_get_priv(back); + + switch (st->info->bus_type) { + case AXI_DAC_BUS_TYPE_DDR_QSPI: { + int ret; + u32 bval; + + bval = 0; + ret = axi_dac_bus_reg_write(back, AXI_DAC_RD_ADDR(reg), 0, + data_size); + if (ret) + return ret; + + ret = regmap_read_poll_timeout(st->regmap, AXI_DAC_UI_STATUS, + bval, bval != AXI_DAC_BUSY, + 10, 100); + if (ret) + return ret; + + return regmap_read(st->regmap, AXI_DAC_CNTRL_DATA_RD, val); + } + break; + default: + return -EOPNOTSUPP; + } +} + static const struct iio_backend_ops axi_dac_generic_ops = { .enable = axi_dac_enable, .disable = axi_dac_disable, + .read_raw = axi_dac_read_raw, .request_buffer = axi_dac_request_buffer, .free_buffer = axi_dac_free_buffer, .extend_chan_spec = axi_dac_extend_chan, @@ -528,6 +754,16 @@ static const struct iio_backend_ops axi_dac_generic_ops = { .ext_info_get = axi_dac_ext_info_get, .data_source_set = axi_dac_data_source_set, .set_sample_rate = axi_dac_set_sample_rate, + .ext_sync_enable = axi_dac_ext_sync_enable, + .ext_sync_disable = axi_dac_ext_sync_disable, + .ddr_enable = axi_dac_ddr_enable, + .ddr_disable = axi_dac_ddr_disable, + .buffer_enable = axi_dac_buffer_enable, + .buffer_disable = axi_dac_buffer_disable, + .data_format_set = axi_dac_data_format_set, + .data_transfer_addr = axi_dac_data_transfer_addr, + .bus_reg_read = axi_dac_bus_reg_read, + .bus_reg_write = axi_dac_bus_reg_write, .debugfs_reg_access = iio_backend_debugfs_ptr(axi_dac_reg_access), }; @@ -545,8 +781,8 @@ static const struct regmap_config axi_dac_regmap_config = { static int axi_dac_probe(struct platform_device *pdev) { - const unsigned int *expected_ver; struct axi_dac_state *st; + const struct axi_dac_info *info; void __iomem *base; unsigned int ver; struct clk *clk; @@ -556,10 +792,12 @@ static int axi_dac_probe(struct platform_device *pdev) if (!st) return -ENOMEM; - expected_ver = device_get_match_data(&pdev->dev); - if (!expected_ver) + info = device_get_match_data(&pdev->dev); + if (!info) return -ENODEV; + st->info = info; + clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(clk)) return dev_err_probe(&pdev->dev, PTR_ERR(clk), @@ -588,12 +826,13 @@ static int axi_dac_probe(struct platform_device *pdev) if (ret) return ret; - if (ADI_AXI_PCORE_VER_MAJOR(ver) != ADI_AXI_PCORE_VER_MAJOR(*expected_ver)) { + if (ADI_AXI_PCORE_VER_MAJOR(ver) != + ADI_AXI_PCORE_VER_MAJOR(st->info->version)) { dev_err(&pdev->dev, "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", - ADI_AXI_PCORE_VER_MAJOR(*expected_ver), - ADI_AXI_PCORE_VER_MINOR(*expected_ver), - ADI_AXI_PCORE_VER_PATCH(*expected_ver), + ADI_AXI_PCORE_VER_MAJOR(st->info->version), + ADI_AXI_PCORE_VER_MINOR(st->info->version), + ADI_AXI_PCORE_VER_PATCH(st->info->version), ADI_AXI_PCORE_VER_MAJOR(ver), ADI_AXI_PCORE_VER_MINOR(ver), ADI_AXI_PCORE_VER_PATCH(ver)); @@ -631,10 +870,18 @@ static int axi_dac_probe(struct platform_device *pdev) return 0; } -static unsigned int axi_dac_9_1_b_info = ADI_AXI_PCORE_VER(9, 1, 'b'); +static const struct axi_dac_info dac_generic = { + .version = ADI_AXI_PCORE_VER(9, 1, 'b'), +}; + +static const struct axi_dac_info dac_ad3552r = { + .version = ADI_AXI_PCORE_VER(9, 1, 'b'), + .bus_type = AXI_DAC_BUS_TYPE_DDR_QSPI, +}; static const struct of_device_id axi_dac_of_match[] = { - { .compatible = "adi,axi-dac-9.1.b", .data = &axi_dac_9_1_b_info }, + { .compatible = "adi,axi-dac-9.1.b", .data = &dac_generic }, + { .compatible = "adi,axi-dac-ad3552r", .data = &dac_ad3552r }, {} }; MODULE_DEVICE_TABLE(of, axi_dac_of_match); From patchwork Thu Sep 5 15:17:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13792584 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 5D7FC19EEA6 for ; Thu, 5 Sep 2024 15:18:58 +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=1725549543; cv=none; b=h5/hG10mgxcZYGyZftadgf+Hkf3LBFRizdxribI4WPqpVeoqDXZ2NWmvcmyuSLptGvd3QdraJIHE72GDJM+sfmXMDBmSjrXKpM4SF2D2ZYGWMmo6MPZO4nO08CCykBeqc78wSaTk9XVnKZEY2Rgb515r7RX6RBYXr4NpzjMDHEU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549543; c=relaxed/simple; bh=6rh93EwLIsxFVPtcu7P4JnnZPCEmutiOeQSQf56BzFU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N8HKxlmgR0qRP3xSW6mQDSTEZp/ffFw5U6C7yLW0pvN73UYi+OD4+/6XYP3EnxvXK+GFRuO0ErXj5Idzj14wyA7APCgnuCqQCFyny5RBMZZe4/cCNWGxUp2yhqV+rlgbgCZZUMQDiAxE4ENTvdwyCVg8NsntZPDmdX79GD6SpJQ= 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=TUZoxsZP; 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="TUZoxsZP" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-42bc19e94bdso7406125e9.3 for ; Thu, 05 Sep 2024 08:18:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1725549537; x=1726154337; 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=t0Vl4tpyTXDZrAVsn0EizZ+7WJ1GTPckaSr1yyqR3dE=; b=TUZoxsZPwJ08qSLvVkHVbY25wijbjm8nk/D6AZ3aHWV1MWQ56TMhn6HmbGBt/WPWZt GerK/SjNVEw7bw/jK/U9EpaGLLN7w9hsZjbJUIukMx6xB+KxLIroKjRgm7wtEjWrnqeA 4eRUzQJHAdU38CDi7y6DzvYEiNI+KJ3oqcUSQXbUF52c4mwH1db6mkXnaKy7O00peTU/ B5DSnG/gc8XO3nRUPWoOvpSrceVmsV2vh1fqn6eMmM3zbyOPo/qFo3vPlCyjtgIEskd3 1BlJSl00NqPqgDeqiBpqgQbkd3uViCt1vCHAdgpW8AlbIlngx8z2HY/L5wXa9Yn5Uw1t 0tWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725549537; x=1726154337; 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=t0Vl4tpyTXDZrAVsn0EizZ+7WJ1GTPckaSr1yyqR3dE=; b=sQn7pV0YZ2GOjRBzxZeHNp4XO/zR0QZDdtukQDeUDt77m+VwhxSvC1xMt1dXbFeH0M T0tmIPNqR8rQ9idAxv5BkfMZZE/WLcXi9jsycZL9RYsJ2f0tyZv4cKo2TrevMPXa+M/l abQgJdv25uhQ/KXzETA0e6At+Aux77r6aMZFYmDOPUmV1m6L3THwVIxMS/OHuO/GqcAa eudzHZX460PtsSvp5ggI8wNfWQnhTbH/i6zRjIz0V6M//5xMdKfI6Xb+/mSiYUGVz8CA vUn9QS7Pu5jxSEKCR1LPYTN+jkhypvlumoWqW/sLCsYvnxNDcUcjdaxrod2hWx0D6VpU CMtg== X-Gm-Message-State: AOJu0YzGMKNbklD4Yva1q/i8/Uc//4Co3IV1Vss8A9jiM9EE2F92M1/m wTkOeQDCAob8QGKpZLyoItlOjHdqes4zzKva+uYWFE2YDPxH5DCH+0uGpAfgrKg= X-Google-Smtp-Source: AGHT+IH9xNazHjmSJ3hyxjYKXfwqg38Yj2TRfF9FzTKUtl1iILlE3/VnMeWvebaRlN6CdsKg6540yg== X-Received: by 2002:a5d:440b:0:b0:374:c847:852 with SMTP id ffacd0b85a97d-376dd71aa2bmr5172236f8f.29.1725549536653; Thu, 05 Sep 2024 08:18:56 -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-374c1de81b2sm14031076f8f.30.2024.09.05.08.18.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Sep 2024 08:18:55 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 05 Sep 2024 17:17:34 +0200 Subject: [PATCH v2 4/9] iio: backend adi-axi-dac: add registering of child fdt node Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-4-87d669674c00@baylibre.com> References: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@baylibre.com> In-Reply-To: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@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, David Lechner , Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Change to obtain the fdt use case as reported in the adi,ad3552r.yaml file in this patchset, with the DAC device that is actually using the backend set as a child node of the backend. To obtain this, registering all the child fdt nodes as platform devices. Signed-off-by: Angelo Dureghello Co-developed-by: David Lechner Co-developed-by: Nuno Sá --- drivers/iio/dac/adi-axi-dac.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c index cc31e1dcd1df..e883cd557b6a 100644 --- a/drivers/iio/dac/adi-axi-dac.c +++ b/drivers/iio/dac/adi-axi-dac.c @@ -783,6 +783,7 @@ static int axi_dac_probe(struct platform_device *pdev) { struct axi_dac_state *st; const struct axi_dac_info *info; + struct platform_device *child_pdev; void __iomem *base; unsigned int ver; struct clk *clk; @@ -862,6 +863,20 @@ static int axi_dac_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, ret, "failed to register iio backend\n"); + device_for_each_child_node_scoped(&pdev->dev, child) { + struct platform_device_info pi; + + memset(&pi, 0, sizeof(pi)); + + pi.name = fwnode_get_name(child); + pi.id = PLATFORM_DEVID_AUTO; + pi.fwnode = child; + + child_pdev = platform_device_register_full(&pi); + if (IS_ERR(child_pdev)) + return PTR_ERR(child_pdev); + } + dev_info(&pdev->dev, "AXI DAC IP core (%d.%.2d.%c) probed\n", ADI_AXI_PCORE_VER_MAJOR(ver), ADI_AXI_PCORE_VER_MINOR(ver), From patchwork Thu Sep 5 15:17:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13792583 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (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 7980D16F839 for ; Thu, 5 Sep 2024 15:19:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549542; cv=none; b=cR/q8fqoHrXsPvDxDEed8ZvAgFrnBSCLVuryAMRHm8Ci00F3BviraFkFtmEG7N5DHi9WypYyZMD0DEwOKx+XUx2unzDFT5eeQQUDJBjwAs2XX0uy9RwMl1ZnFEsWGgsFiAXDxPoR6rgPG7Saw4dH1SN5osf/wEpFeCr7EW11uCI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549542; c=relaxed/simple; bh=+u+kBqfT5sVB+pgsFs493wfhD6zF/8fwgOOVhk+vQOQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sYHPH1LL9h18Bhxum9NX6G87+KOnXO5WNNBkKJsQVqJJlSF5djBzEsI/zoocw8CkqcoBc0i8Knn0eM6I79Lmg9hGYX3hL7SAMwoirxvOzMcxCMiagsg1kec5gF2PYuduxHmpF/8lmP+TrOB8658Pfw34TJS9wFLA5grjslzpHKs= 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=OG90m6Ec; arc=none smtp.client-ip=209.85.128.48 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="OG90m6Ec" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-428e1915e18so7501495e9.1 for ; Thu, 05 Sep 2024 08:19:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1725549539; x=1726154339; 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=ugfbUTgXER9ktB6DH95mWqrkHVrS6OETUlZJp5IMaqg=; b=OG90m6EckykyxpfIygSNoioRBx0sZo+ytJ1w4LE13WrmFna9pgOC2Q28H+M03cSwk8 bkx3V0jCFMvJi4VwQ7+Jez6KuYqNBn7xjxU97uPpRreoGDe1dqrubboeLXX6TLoLjNzj oBSvkMcZwFEfS4JBZEGkEpuO1WBSlW0MiCczuxpohkq7OEIATluSfozs7JHx5wy0/w/h 5bEjF9LF0QdZPoAAIMXeCYdAkkAUlZdPNVDZ3lkXDCFZjn9Zc8gRyg/GkB/8k1Od1ALa 6v8ZwRBUprrfeIyfWSw0ZMKay5DjF/PQoNdenjKYCJqqd/pQ2CyiTe7nQrhrYNbNJfkO FPlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725549539; x=1726154339; 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=ugfbUTgXER9ktB6DH95mWqrkHVrS6OETUlZJp5IMaqg=; b=EuNEWx9bUsNxQLu1Aqt7HLJqZX81uooDCyM2PZs7CT9fxFKpwqGruvZOKL1vhgqa+v n9jG7vAkWUL8jBQdlOAR//0+fqj+UR5zzu3jJY06l+LvS1r12J2jQ6vZuPmsqFJCFVy4 cplOk3OshIBip9jaUhA6cBbckvEufX/rURvqkWrL7I55ieraYNSLOJxFFH+SJfN1wwmr 3JKeEpiTP0+9xMJMn6HULHI+yEgjTnChNJexH632QN8mZCqYMs7qit5FkBskQZyqF2rZ pFLuoWUNA8ps0kv2mca9YkQtzVJS48a3V9KvyGJ/xjs2Fej2GKWEawOChIgeFUxB5AbG JueQ== X-Gm-Message-State: AOJu0YwR4Pp1sW69waFF5M2c1SH2wRVDFoN8MjCik8jl1GepJ0yV3HD7 a7bvNKdA3Nid7puT4WNuuLs+ZXz4bOXz1/8AocCZJcMyNwAK3OxBWIDZfEPTVx8= X-Google-Smtp-Source: AGHT+IHTvRUw/LubhoyB2Z9CNuafV/MrTgCADVJk/19v/j2hC2bB+gVGpGuNn3EZdHWvkvbBzx4dzA== X-Received: by 2002:a05:600c:1c0d:b0:429:994:41ae with SMTP id 5b1f17b1804b1-42c7b59e84cmr109958235e9.2.1725549538880; Thu, 05 Sep 2024 08:18:58 -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-374c1de81b2sm14031076f8f.30.2024.09.05.08.18.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Sep 2024 08:18:57 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 05 Sep 2024 17:17:35 +0200 Subject: [PATCH v2 5/9] dt-bindings: iio: dac: add ad3552r axi-dac compatible Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-5-87d669674c00@baylibre.com> References: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@baylibre.com> In-Reply-To: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@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, David Lechner , Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Add a new compatible for the ad3552r variant of the generic DAC IP. The ad3552r DAC IP variant is very similar to the generic DAC IP, register map is the same, but some register fields are specific to this IP, and also, a DDR QSPI bus has been included in the IP. Signed-off-by: Angelo Dureghello --- Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml index a55e9bfc66d7..c0cccb7a99a4 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml @@ -24,6 +24,7 @@ properties: compatible: enum: - adi,axi-dac-9.1.b + - adi,axi-dac-ad3552r reg: maxItems: 1 From patchwork Thu Sep 5 15:17:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13792585 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 97AAF199938 for ; Thu, 5 Sep 2024 15:19:08 +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=1725549550; cv=none; b=AMil6YO+1OWQFOyyG577rNIeUew0LRjBLE1HhrHh6Jb7ERatbF8UTy9u1swljs3cnBkWGBvp1GoWEdEfnoKoqvU4gUf6b6iBzps6ToseSEuzxRnL789Lv1hnw8wiOVHtfRWm71XtO3ztPCOQ+5y7kp/RLXHzpAcBAoFKsYfJ268= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549550; c=relaxed/simple; bh=Rdl1xXj7ZbflufQp/lw7xY4gYzEtySEFO1gNKT4EeBE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lj6EcJ8Bql2H3lsAnLOuwTxpcG2K0yKHsSCMop72xBzPcqj1k/DGfc2xDQLYbYv6aryx4Pg06Pi2nk9YtqsRf4XkmgggIgsXzzlDsNKnkOu8HQd7LOyLCH3dwyc4xXq3aOyD2ld8O6WRl0W6dffjym97+5ocDzcqxKn7zE7Subg= 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=in0EtCpH; 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="in0EtCpH" Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-371941bbfb0so620478f8f.0 for ; Thu, 05 Sep 2024 08:19:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1725549547; x=1726154347; 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=6pxcjcnGUFkl/bUYlUeEUYB7gqM62d8PVJakM9XYciY=; b=in0EtCpHE//eOaqzz5mfjL/3GNaXzGElZYyJOwBHTvhzaBcEEhhmtS9P7HyOTJD9MP 3nq2xP3ntQY1FUHGdcriaoqZRxR3ruDEW76uMLXeeC+jEQTmeSll1kipS2nekpvudI72 RIS5TSEDpZyHJTPpOMgwLLoHRxHWBM4z15c43IqGeYAq2kfbjwE8rUISnjZ03dWDvq5A TEKrGKelDPgiQ7VPSF8m15vvvpueuL6j5ECaKvN4c7SGcnoCcl1v9rAme8EtMVpMNu8Y pEwUoLDiStwpy36WTeYiQf8QOhKnlyJL0OcmtE4lYxGXzsYMSdyAT3ptlivgkS4KQHuU PqUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725549547; x=1726154347; 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=6pxcjcnGUFkl/bUYlUeEUYB7gqM62d8PVJakM9XYciY=; b=G4uDIVwzuhIyJxKzy7rI0hg46EyhB7h2LRB43mVQBQjSvWU9own4neRvbtj95ngMej OICr2mCVFPAgqdVgmSIjM9wC1sddWde+ZJJrMZLIa8zOqWQ1UmcCAvPtGGSjp9ky9dE7 yqdmqbpGZkh0qgUGK/PZfrrVtgFZCtyid0lgu6bggrIbQLtsuMa2TyWF4iCK4YLGdsCL 3Wg0bdi+LDVF3ItdbYUWoAk+X0UaHjafPpfny2L3Rctrygp6NSZY5vlAYSUBtBUCsZaR gkuQpfO61DbuKl0bhIOYRyWS95ByF/Mjvc6vHXPtBa2+Orr9SzLslcZ2m4cx+B1LCKiq /3IA== X-Gm-Message-State: AOJu0YweaE4vV65IKYviLoDr+hSs52see7rzEioFwwrT2O98+a05dNaA 5LS3GUSojUdd6PQArO9tgNFsizhVIYVdTZPUnIo9uhr89iPwSLwo6w0mCmWr3UA= X-Google-Smtp-Source: AGHT+IEsOJBJQ2XzcKuflH1vmokodyjc4mYJVysXSAQR0oPY3PxZcq1kr+FWnfbpBldo0aOaDbs7Mw== X-Received: by 2002:a5d:6043:0:b0:374:c79b:ca5f with SMTP id ffacd0b85a97d-374c79bcc0amr9725069f8f.46.1725549546767; Thu, 05 Sep 2024 08:19:06 -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-374c1de81b2sm14031076f8f.30.2024.09.05.08.18.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Sep 2024 08:19:00 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 05 Sep 2024 17:17:36 +0200 Subject: [PATCH v2 6/9] iio: dac: ad3552r: changes to use FIELD_PREP Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-6-87d669674c00@baylibre.com> References: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@baylibre.com> In-Reply-To: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@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, David Lechner , 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 removed 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; }; -static const u16 addr_mask_map[][2] = { - [AD3552R_ADDR_ASCENSION] = { - AD3552R_REG_ADDR_INTERFACE_CONFIG_A, - AD3552R_MASK_ADDR_ASCENSION - }, - [AD3552R_SDO_DRIVE_STRENGTH] = { - AD3552R_REG_ADDR_INTERFACE_CONFIG_D, - AD3552R_MASK_SDO_DRIVE_STRENGTH - }, - [AD3552R_VREF_SELECT] = { - 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] = { - [AD3552R_CH_DAC_POWERDOWN] = { - AD3552R_REG_ADDR_POWERDOWN_CONFIG, - AD3552R_MASK_CH_DAC_POWERDOWN(0), - AD3552R_MASK_CH_DAC_POWERDOWN(1) - }, - [AD3552R_CH_AMPLIFIER_POWERDOWN] = { - AD3552R_REG_ADDR_POWERDOWN_CONFIG, - AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(0), - AD3552R_MASK_CH_AMPLIFIER_POWERDOWN(1) - }, - [AD3552R_CH_OUTPUT_RANGE_SEL] = { - AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE, - AD3552R_MASK_CH_OUTPUT_RANGE_SEL(0), - AD3552R_MASK_CH_OUTPUT_RANGE_SEL(1) - }, - [AD3552R_CH_SELECT] = { - 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; } -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_desc *dac, u8 addr, u16 mask, return ret; reg &= ~mask; - reg |= ad3552r_field_prep(val, mask); + reg |= val; return ad3552r_write_reg(dac, addr, reg); } -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 = IIO_VOLTAGE, \ .output = true, \ @@ -510,8 +456,14 @@ static int ad3552r_write_raw(struct iio_dev *indio_dev, val); break; case IIO_CHAN_INFO_ENABLE: - err = ad3552r_set_ch_value(dac, AD3552R_CH_DAC_POWERDOWN, - chan->channel, !val); + if (chan->channel == 0) + val = FIELD_PREP(AD3552R_MASK_CH_DAC_POWERDOWN(0), !val); + else + val = FIELD_PREP(AD3552R_MASK_CH_DAC_POWERDOWN(1), !val); + + err = ad3552r_update_reg_field(dac, AD3552R_REG_ADDR_POWERDOWN_CONFIG, + AD3552R_MASK_CH_DAC_POWERDOWN(chan->channel), + val); break; default: err = -EINVAL; @@ -715,9 +667,9 @@ static int ad3552r_reset(struct ad3552r_desc *dac) } 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)); } 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 ad3552r_desc *dac, "mandatory custom-output-range-config property missing\n"); dac->ch_data[ch].range_override = 1; - reg |= ad3552r_field_prep(1, AD3552R_MASK_CH_RANGE_OVERRIDE); + reg |= FIELD_PREP(AD3552R_MASK_CH_RANGE_OVERRIDE, 1); err = 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 |= ad3552r_field_prep(val, AD3552R_MASK_CH_GAIN_SCALING_P); + reg |= FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_P, val); dac->ch_data[ch].p = val; err = 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 |= ad3552r_field_prep(val, AD3552R_MASK_CH_GAIN_SCALING_N); + reg |= FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_N, val); dac->ch_data[ch].n = val; err = 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 = val; offset = abs((s32)val); - reg |= ad3552r_field_prep((offset >> 8), AD3552R_MASK_CH_OFFSET_BIT_8); + reg |= FIELD_PREP(AD3552R_MASK_CH_OFFSET_BIT_8, (offset >> 8)); - reg |= ad3552r_field_prep((s32)val < 0, AD3552R_MASK_CH_OFFSET_POLARITY); + reg |= FIELD_PREP(AD3552R_MASK_CH_OFFSET_POLARITY, (s32)val < 0); addr = AD3552R_REG_ADDR_CH_GAIN(ch); err = 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) } err = 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; @@ -900,9 +852,9 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac) } err = 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_desc *dac) "Invalid adi,output-range-microvolt value\n"); val = err; - err = ad3552r_set_ch_value(dac, - AD3552R_CH_OUTPUT_RANGE_SEL, - ch, val); + if (ch == 0) + val = FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(0), val); + else + val = FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(1), val); + + err = ad3552r_update_reg_field(dac, + AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE, + AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch), + val); if (err) return err; @@ -958,7 +916,14 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac) ad3552r_calc_gain_and_offset(dac, ch); dac->enabled_ch |= BIT(ch); - err = ad3552r_set_ch_value(dac, AD3552R_CH_SELECT, ch, 1); + if (ch == 0) + val = FIELD_PREP(AD3552R_MASK_CH(0), 1); + else + val = FIELD_PREP(AD3552R_MASK_CH(1), 1); + + err = ad3552r_update_reg_field(dac, + AD3552R_REG_ADDR_CH_SELECT_16B, + AD3552R_MASK_CH(ch), val); if (err < 0) return err; @@ -970,8 +935,15 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac) /* Disable unused channels */ for_each_clear_bit(ch, &dac->enabled_ch, dac->model_data->num_hw_channels) { - err = ad3552r_set_ch_value(dac, AD3552R_CH_AMPLIFIER_POWERDOWN, - ch, 1); + if (ch == 0) + val = FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(0), 1); + else + val = FIELD_PREP(AD3552R_MASK_CH_OUTPUT_RANGE_SEL(1), 1); + + err = ad3552r_update_reg_field(dac, + AD3552R_REG_ADDR_POWERDOWN_CONFIG, + AD3552R_MASK_CH_OUTPUT_RANGE_SEL(ch), + val); if (err) return err; } From patchwork Thu Sep 5 15:17:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13792586 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.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 6E2CC1A073C for ; Thu, 5 Sep 2024 15:19:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549556; cv=none; b=T4m80/CXZZ7MlLpUa2H/SIxje9J1YQDEQ5UR8k8grNVRFSt3hgpqqz2q+eiujcuBbkpFOQWLsZFIHMfOOfncPMqwo/0qgm0Nk8jN93XjqMdox66/A5C0akBAURSaZhqO926sygJ73i0buMdfsTm/yxy5KxXS4xy+GQ/8MZjqVZ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549556; c=relaxed/simple; bh=yVObNTbKruHg2Tdvo+Ftyt0hECcIrR0Syn95YxsZ/jE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N3VIB1PL5D19DA/bjXbzfW5fWL2ti+cYDNUmVcwQxkG5TJc7d3HPsC1fnRAWvDl5NRBm1DPDtbrSoytpZ5+tKJloTXz80dehbxVk8oH00AeWSZ5Xrghl2YAfxkTiSxHilbMG6f0k50iboK7K3n/JoNUOePf46esHaiqm/Ekw/KU= 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=j5EGUgfa; arc=none smtp.client-ip=209.85.128.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="j5EGUgfa" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-42bb6d3e260so7840605e9.1 for ; Thu, 05 Sep 2024 08:19:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1725549552; x=1726154352; 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=j5EGUgfapqc/wCHukK3FiX5UwlqGCULtyDqgaAMupmx6TzElBPeDi8sSjm4X5cjcW0 FPiaaTKe/QfcbTFTNw8yS/je+3ML52JPQ8ltZNdy7VtEmYw/vRXTbQLi8eefyT/Q59M+ 6YOeOabb9vBqz3FhJbdx7+7A0nQKWQ2xVUducHIw8ebixtIW8IFpZIEjBbbR3g9+5vr9 Jg/NGkUVL8Djw8F4in7UTDsHwRl4E/2BOIzfEHVCc9pUTfvPzaEi4qBCJx3GiLTO/GN4 V5AGgnhQHvzTZbnSVpB+ivDqyslFK5l43dCKd5im56vXG/xgKBmA61DYO0b+V7nILHj9 7/gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725549552; x=1726154352; 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=U9JmDFcxKkeSVCeoCYxc3YRpI7s9FGgV2ltb/0J2o0xpGMra4kRE8dpzIz9OiRkWUR ++iyvMAFbTjpMIaZuYWO3K3x/dCoJxF9BPJvzyuxIMg/o6429QuwFxZdy7TOyhl3/h7A TZRQPJJvvWOoZnSRUmOQz/q7SDBQ4hlM8ZdQ//AnDtxcUwENX1nBdZ4vtqu+94TQdq3M 5wKBzNOnkSfBDr4AZ+SEXwEDsugGoYKQBrHx2Luqn9/U/kYwUo2OolkBttl/ikPwfUJ5 d6BjooW3Upd67bFG7i0jFpe+vo2wcgx3J2st4FBxMSo2tPXcA54fc68Dd8RLecDtUUw7 E5MA== X-Gm-Message-State: AOJu0YzTp1ACwmPMiAEHdO91B8UraFkaxkufLS2WBGpOWhNmuM3mO/WK J7eLftMTSd1Fj5aOU5DSTZSez5F2BMMFBk23geWl5nr7e7CSfmxTMQ9VEqFXF9Y= X-Google-Smtp-Source: AGHT+IExOflVlRVMp7tK4vgj0ckxKlr0Q5V3hhROTi5OfTMSoJ92LPqEKn6hlVspgeKmwxy/Rynl4g== X-Received: by 2002:a5d:5c85:0:b0:377:2ce0:a760 with SMTP id ffacd0b85a97d-3772ce0a886mr4685053f8f.49.1725549551660; Thu, 05 Sep 2024 08:19:11 -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-374c1de81b2sm14031076f8f.30.2024.09.05.08.19.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Sep 2024 08:19:08 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 05 Sep 2024 17:17:37 +0200 Subject: [PATCH v2 7/9] iio: dac: ad3552r: extract common code (no changes in behavior intended) Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-7-87d669674c00@baylibre.com> References: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@baylibre.com> In-Reply-To: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@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, David Lechner , 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 @@ # # When adding new entries keep the list in alphabetical order -obj-$(CONFIG_AD3552R) += ad3552r.o +obj-$(CONFIG_AD3552R) += ad3552r.o ad3552r-common.o obj-$(CONFIG_AD5360) += ad5360.o obj-$(CONFIG_AD5380) += ad5380.o obj-$(CONFIG_AD5421) += ad5421.o diff --git a/drivers/iio/dac/ad3552r-common.c b/drivers/iio/dac/ad3552r-common.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] = { + [AD3552R_CH_OUTPUT_RANGE_0__2P5V] = {0, 2500}, + [AD3552R_CH_OUTPUT_RANGE_0__5V] = {0, 5000}, + [AD3552R_CH_OUTPUT_RANGE_0__10V] = {0, 10000}, + [AD3552R_CH_OUTPUT_RANGE_NEG_5__5V] = {-5000, 5000}, + [AD3552R_CH_OUTPUT_RANGE_NEG_10__10V] = {-10000, 10000} +}; + +static const s32 ad3542r_ch_ranges[][2] = { + [AD3542R_CH_OUTPUT_RANGE_0__2P5V] = {0, 2500}, + [AD3542R_CH_OUTPUT_RANGE_0__3V] = {0, 3000}, + [AD3542R_CH_OUTPUT_RANGE_0__5V] = {0, 5000}, + [AD3542R_CH_OUTPUT_RANGE_0__10V] = {0, 10000}, + [AD3542R_CH_OUTPUT_RANGE_NEG_2P5__7P5V] = {-2500, 7500}, + [AD3542R_CH_OUTPUT_RANGE_NEG_5__5V] = {-5000, 5000} +}; + +void ad3552r_calc_custom_gain(u8 p, u8 n, s16 goffs, u16 *reg) +{ + *reg = FIELD_PREP(AD3552R_MASK_CH_RANGE_OVERRIDE, 1); + *reg |= FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_P, p); + *reg |= FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_N, n); + *reg |= FIELD_PREP(AD3552R_MASK_CH_OFFSET_BIT_8, abs((s32)goffs) >> 8); + *reg |= FIELD_PREP(AD3552R_MASK_CH_OFFSET_POLARITY, (s32)goffs < 0); +} + +int ad3552r_get_ref_voltage(struct device *dev, u32 *val) +{ + int voltage, delta = 100000; + + voltage = devm_regulator_get_enable_read_voltage(dev, "vref"); + if (voltage < 0 && voltage != -ENODEV) + return dev_err_probe(dev, voltage, + "Error getting vref voltage\n"); + + if (voltage == -ENODEV) { + if (device_property_read_bool(dev, "adi,vref-out-en")) + *val = AD3552R_INTERNAL_VREF_PIN_2P5V; + else + *val = 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 = AD3552R_EXTERNAL_VREF_PIN_INPUT; + } + + return 0; +} + +int ad3552r_get_drive_strength(struct device *dev, u32 *val) +{ + int err; + + err = 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 *child, + u8 *gs_p, u8 *gs_n, u16 *rfb, s16 *goffs) +{ + int err; + u32 val; + struct fwnode_handle *gain_child __free(fwnode_handle) + = 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 = 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 = val; + + err = 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 = val; + + err = fwnode_property_read_u32(gain_child, "adi,rfb-ohms", &val); + if (err) + return dev_err_probe(dev, err, + "adi,rfb-ohms mandatoryn"); + *rfb = val; + + err = fwnode_property_read_u32(gain_child, "adi,gain-offset", &val); + if (err) + return dev_err_probe(dev, err, + "adi,gain-offset mandatory\n"); + *goffs = val; + + return 0; +} + +static int ad3552r_find_range(u16 id, s32 *vals) +{ + int i, len; + const s32 (*ranges)[2]; + + if (id == AD3542R_ID) { + len = ARRAY_SIZE(ad3542r_ch_ranges); + ranges = ad3542r_ch_ranges; + } else { + len = ARRAY_SIZE(ad3552r_ch_ranges); + ranges = ad3552r_ch_ranges; + } + + for (i = 0; i < len; i++) + if (vals[0] == ranges[i][0] * 1000 && + vals[1] == 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 = 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 = ad3552r_find_range(chip_id, vals); + if (ret < 0) + return dev_err_probe(dev, ret, + "invalid adi,output-range-microvolt value\n"); + + *val = 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 -/* 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 = 0x400b, - AD3542R_ID = 0x4009, - AD3551R_ID = 0x400a, - AD3552R_ID = 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" static const s32 ad3552r_ch_ranges[][2] = { [AD3552R_CH_OUTPUT_RANGE_0__2P5V] = {0, 2500}, @@ -167,21 +23,6 @@ static const s32 ad3552r_ch_ranges[][2] = { [AD3552R_CH_OUTPUT_RANGE_NEG_10__10V] = {-10000, 10000} }; -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] = { [AD3542R_CH_OUTPUT_RANGE_0__2P5V] = {0, 2500}, [AD3542R_CH_OUTPUT_RANGE_0__3V] = {0, 3000}, @@ -733,72 +574,32 @@ static void ad3552r_calc_gain_and_offset(struct ad3552r_desc *dac, s32 ch) dac->ch_data[ch].offset_dec = div_s64(tmp, span); } -static int ad3552r_find_range(const struct ad3552r_model_data *model_data, - s32 *vals) -{ - int i; - - for (i = 0; i < model_data->num_ranges; i++) - if (vals[0] == model_data->ranges_table[i][0] * 1000 && - vals[1] == 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 = &dac->spi->dev; - u32 val; int err; u8 addr; - u16 reg = 0, offset; - - struct fwnode_handle *gain_child __free(fwnode_handle) - = 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 = 1; - reg |= FIELD_PREP(AD3552R_MASK_CH_RANGE_OVERRIDE, 1); - - err = 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 |= FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_P, val); - dac->ch_data[ch].p = val; + u16 reg = 0; - err = fwnode_property_read_u32(gain_child, "adi,gain-scaling-n", &val); + err = 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 |= FIELD_PREP(AD3552R_MASK_CH_GAIN_SCALING_N, val); - dac->ch_data[ch].n = val; - - err = 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 = val; + return err; - err = 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 = val; + dac->ch_data[ch].range_override = 1; - offset = abs((s32)val); - reg |= 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, ®); - reg |= FIELD_PREP(AD3552R_MASK_CH_OFFSET_POLARITY, (s32)val < 0); addr = AD3552R_REG_ADDR_CH_GAIN(ch); err = 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"); @@ -812,30 +613,17 @@ static int ad3552r_configure_custom_gain(struct ad3552r_desc *dac, static int ad3552r_configure_device(struct ad3552r_desc *dac) { struct device *dev = &dac->spi->dev; - int err, cnt = 0, voltage, delta = 100000; - u32 vals[2], val, ch; + int err, cnt = 0; + u32 val, ch; dac->gpio_ldac = 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"); - voltage = devm_regulator_get_enable_read_voltage(dev, "vref"); - if (voltage < 0 && voltage != -ENODEV) - return dev_err_probe(dev, voltage, "Error getting vref voltage\n"); - - if (voltage == -ENODEV) { - if (device_property_read_bool(dev, "adi,vref-out-en")) - val = AD3552R_INTERNAL_VREF_PIN_2P5V; - else - val = 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 = AD3552R_EXTERNAL_VREF_PIN_INPUT; - } + err = ad3552r_get_ref_voltage(dev, &val); + if (err) + return err; err = ad3552r_update_reg_field(dac, AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, @@ -844,13 +632,10 @@ static int ad3552r_configure_device(struct ad3552r_desc *dac) if (err) return err; - err = device_property_read_u32(dev, "adi,sdo-drive-strength", &val); + err = 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 = 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_desc *dac) "reg must be less than %d\n", dac->model_data->num_hw_channels); - if (fwnode_property_present(child, "adi,output-range-microvolt")) { - err = 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 = ad3552r_find_range(dac->model_data, vals); - if (err < 0) - return dev_err_probe(dev, err, - "Invalid adi,output-range-microvolt value\n"); + err = ad3552r_get_output_range(dev, dac->model_data->chip_id, + child, &val); + if (err && err != -ENOENT) + return err; - val = err; + if (!err) { if (ch == 0) val = 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 = 0x400b, + AD3542R_ID = 0x4009, + AD3551R_ID = 0x400a, + AD3552R_ID = 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 *child, + 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__ */ From patchwork Thu Sep 5 15:17:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13792587 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.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 3B8961A08BA for ; Thu, 5 Sep 2024 15:19:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549563; cv=none; b=mYqL31lz0DkX+RqakvdWdaRkWLJ9wMg9Ik43Dfjr0oDcGMgR/HgiOpdiYQ/B/M3lD8DinMIg8mNJwyehLQ8Vwb4t32zuuwxwpWLXHQLsNPIW2kWV+FHv5GaZ6FC+Y/Hg4WapAZbXZJYKrckAfwR3g3d1NOIqJlaPixJeiG8yA4g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549563; c=relaxed/simple; bh=lI1gtJVyDHy48zQkd2d6kbfKlHnZ8EcgEnH6Aw5T1bw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=c3VEIhSvhazswZK1tx4buqq6PjRXqr/iWKElMBoJ9biSV5TsCp7jYXg+4mQ+oGD6FsGfSwzExV7Et8p5hXXINw1+xjtIDMnTmH24xYdqYGSfNSfaOlOTkbtzQfJnrmlC6fdQhbwzY+e3rwrDnDfhf4kbdbsY+OAaeZrRbthONvs= 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=kylLoXha; arc=none smtp.client-ip=209.85.128.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="kylLoXha" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-42bbe908380so7783585e9.2 for ; Thu, 05 Sep 2024 08:19:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1725549560; x=1726154360; 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=2NczfyexhZhIfp/ANPsZ2m3BHeYjUbb1KyHqj1qX1qc=; b=kylLoXhap8B3vvEVgSxifmtQOmvCnJPzrKB4/owl/+jT7JxTLqaW54jvrRimSfeI7d A1ZpcTF9qi6CLrm3F+VtU6lkXi21cPR/vi6gWqoYrQsaogOXj4/j4uvxh93pRx+zkNw3 Qa3M1MSUzRo1owcGogVWTj0jXCzW8H7HGipDcAhObHt6krxMMK2Q3LxsxFkAN87waaZf cxxjJxa7VAl71zN31yOOjoUvZAzyt3bgic5rw9mcltanDjXylesM6GvBvSrGBnjvUgrV WIl1Pens3IApstr0KQdSMrb0GnUFPrXy3RQngc7mlbMnNLD7cK6gRdeBaAN0RsmpHqfr mKFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725549560; x=1726154360; 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=2NczfyexhZhIfp/ANPsZ2m3BHeYjUbb1KyHqj1qX1qc=; b=BUamJeJa8Rh8xqubW5DLvPuUnPYWZuWyNZr11Bb1V37V0+Uw1Ondy7TcxkmIzuPEFd UP1/jw7ERzdmXe3CSMsQ71c2cLrqELQrrbzxPwXL/nfx6M8tMhyqm0pvp3GReQ2UMsys y2udHlteEk9Mt73ZkBUYON84oWchio/4W9omri+P/04GEVbzrvBXuJ0XjqzdEN4Db9iB 1XfSSiN0n8UctlV9xWFcNYVIm6bwNKm2xDFbRHfcqgwNExY+4gtgtVvpNXKGcuD0Z57l lAxM2QulTTT41prxRZYkSp1d8gWE+L8hn5Q48R/lEM9GLJRPD3kTg6ncJIpA4hncwIFw IYHA== X-Gm-Message-State: AOJu0Yy/b1D3r4colIhMMGxzjGB8ef0jf5nDJFaGJYhK+XNSXSrwgbih osEilUqosM33wVY4SzZFwg0aJPRnWQg1KaH3Fwl1H3FS7UlzFV9pzXv+3E+BDKY= X-Google-Smtp-Source: AGHT+IFg2VEC7Uz0WAqqyr9WpHHEFI7lj806Vy9UFqGm8HYWJRNA7e8sLy5pAMB4uV5wxsccWuRfDQ== X-Received: by 2002:adf:e3d0:0:b0:368:64e:a7dd with SMTP id ffacd0b85a97d-374bcff3b7fmr11061019f8f.53.1725549559550; Thu, 05 Sep 2024 08:19: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-374c1de81b2sm14031076f8f.30.2024.09.05.08.19.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Sep 2024 08:19:15 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 05 Sep 2024 17:17:38 +0200 Subject: [PATCH v2 8/9] iio: dac: ad3552r: add axi platform driver Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-8-87d669674c00@baylibre.com> References: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@baylibre.com> In-Reply-To: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@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, David Lechner , Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Add support for ad3552r-axi, where ad3552r has to be controlled by the custom (fpga-based) ad3552r AXI DAC IP. Signed-off-by: Angelo Dureghello Co-developed-by: David Lechner Co-developed-by: Nuno Sá --- drivers/iio/dac/Kconfig | 11 + drivers/iio/dac/Makefile | 1 + drivers/iio/dac/ad3552r-axi.c | 567 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 579 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. +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!=m) || 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 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_AD3552R) += ad3552r.o ad3552r-common.o +obj-$(CONFIG_AD3552R_AXI) += ad3552r-axi.o ad3552r-common.o obj-$(CONFIG_AD5360) += ad5360.o obj-$(CONFIG_AD5380) += ad5380.o obj-$(CONFIG_AD5421) += ad5421.o diff --git a/drivers/iio/dac/ad3552r-axi.c b/drivers/iio/dac/ad3552r-axi.c new file mode 100644 index 000000000000..a9311f29f45d --- /dev/null +++ b/drivers/iio/dac/ad3552r-axi.c @@ -0,0 +1,567 @@ +// 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 + +#include "ad3552r.h" + +enum ad3552r_synchronous_mode_status { + AD3552R_NO_SYNC, + AD3552R_EXT_SYNC_ARM, +}; + +struct ad3552r_axi_model_data { + const char *model_name; + enum ad3552r_id chip_id; + unsigned int num_hw_channels; +}; + +struct ad3552r_axi_state { + const struct ad3552r_axi_model_data *model_data; + struct gpio_desc *reset_gpio; + struct device *dev; + struct iio_backend *back; + 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 = iio_backend_bus_reg_read(back, reg, &rval, xfer_size); + if (err) + return err; + + rval &= ~mask; + rval |= 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 = iio_priv(indio_dev); + int err, ch = chan->channel; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: { + int clk_rate; + + err = iio_backend_read_raw(st->back, chan, &clk_rate, 0, + IIO_CHAN_INFO_FREQUENCY); + if (err != 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 = DIV_ROUND_CLOSEST(clk_rate, 4); + else + clk_rate = DIV_ROUND_CLOSEST(clk_rate, 8); + + *val = clk_rate; + + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_RAW: + err = 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 = iio_priv(indio_dev); + int ch = 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_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad3552r_axi_state *st = iio_priv(indio_dev); + struct iio_backend_data_fmt fmt = { + .type = IIO_BACKEND_DATA_UNSIGNED + }; + int loop_len, val, err; + + /* Inform DAC chip to switch into DDR mode */ + err = 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 = iio_backend_ddr_enable(st->back); + if (err) + goto exit_err; + + switch (*indio_dev->active_scan_mask) { + case AD3552R_CH0_ACTIVE: + st->single_channel = true; + loop_len = AD3552R_STREAM_2BYTE_LOOP; + val = AD3552R_REG_ADDR_CH_DAC_16B(0); + break; + case AD3552R_CH1_ACTIVE: + st->single_channel = true; + loop_len = AD3552R_STREAM_2BYTE_LOOP; + val = AD3552R_REG_ADDR_CH_DAC_16B(1); + break; + case AD3552R_CH0_CH1_ACTIVE: + st->single_channel = false; + loop_len = AD3552R_STREAM_4BYTE_LOOP; + val = AD3552R_REG_ADDR_CH_DAC_16B(1); + break; + default: + return -EINVAL; + } + + err = iio_backend_bus_reg_write(st->back, AD3552R_REG_ADDR_STREAM_MODE, + loop_len, 1); + if (err) + goto exit_err; + + 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 (ext synch ability) is enabled anyway. + */ + if (st->synced_transfer == AD3552R_EXT_SYNC_ARM) + err = iio_backend_ext_sync_enable(st->back); + else + err = iio_backend_ext_sync_disable(st->back); + if (err) + goto exit_err_sync; + + err = iio_backend_data_format_set(st->back, 0, &fmt); + if (err) + goto exit_err_sync; + + err = iio_backend_buffer_enable(st->back); + if (err) + goto exit_err_sync; + + 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 = iio_priv(indio_dev); + int err; + + err = iio_backend_buffer_disable(st->back); + if (err) + return err; + + /* Inform DAC to set in SDR mode */ + err = 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 = FIELD_PREP(AD3552R_MASK_CH0_RANGE, mode); + int range_ch_1 = 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; + + st->reset_gpio = 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 = 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) = NULL; + u8 gs_p, gs_n; + s16 goffs; + u16 id, rfb; + u16 reg = 0, offset = 0; + u32 val, range; + int err; + + err = ad3552r_axi_reset(st); + if (err) + return err; + + err = iio_backend_ddr_disable(st->back); + if (err) + return err; + + err = iio_backend_bus_reg_write(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + AD3552R_SCRATCH_PAD_TEST_VAL1, 1); + if (err) + return err; + + err = iio_backend_bus_reg_read(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + &val, 1); + if (err) + return err; + + if (val != 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; + } + + err = iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_SCRATCH_PAD, + AD3552R_SCRATCH_PAD_TEST_VAL2, 1); + if (err) + return err; + + err = iio_backend_bus_reg_read(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + &val, 1); + if (err) + return err; + + if (val != 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 = iio_backend_bus_reg_read(st->back, AD3552R_REG_ADDR_PRODUCT_ID_L, + &val, 1); + if (err) + return err; + + id = val; + + err = iio_backend_bus_reg_read(st->back, AD3552R_REG_ADDR_PRODUCT_ID_H, + &val, 1); + if (err) + return err; + + id |= val << 8; + if (id != st->model_data->chip_id) { + dev_err(st->dev, "Chip ID mismatch. Expected 0x%x, Read 0x%x\n", + AD3552R_ID, id); + } + + err = iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, + AD3552R_REF_INIT, 1); + if (err) + return err; + + err = iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_TRANSFER_REGISTER, + AD3552R_TRANSFER_INIT, 1); + if (err) + return err; + + err = iio_backend_data_source_set(st->back, 0, IIO_BACKEND_EXTERNAL); + if (err) + return err; + + err = iio_backend_data_source_set(st->back, 1, IIO_BACKEND_EXTERNAL); + if (err) + return err; + + err = ad3552r_get_ref_voltage(st->dev, &val); + if (err) + return err; + + err = 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 = ad3552r_get_drive_strength(st->dev, &val); + if (!err) { + err = 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 = device_get_named_child_node(st->dev, "channel"); + if (!child) + return -EINVAL; + + err = ad3552r_get_output_range(st->dev, st->model_data->chip_id, + child, &range); + if (!err) + return ad3552r_axi_set_output_range(st, range); + + if (err != -ENOENT) + return err; + + /* Try to get custom range */ + err = 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 = abs((s32)goffs); + + err = 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 = 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 = iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_CH_GAIN(0), + reg, 1); + if (err) + return dev_err_probe(st->dev, err, + "Error writing register\n"); + + err = iio_backend_bus_reg_write(st->back, + AD3552R_REG_ADDR_CH_GAIN(1), + reg, 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 = { + .postenable = ad3552r_axi_buffer_postenable, + .predisable = 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 = iio_priv(indio_dev); + + st->synced_transfer = 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 = iio_priv(indio_dev); + + return st->synced_transfer; +} + +static const char *const synchronous_mode_status[] = { + [AD3552R_NO_SYNC] = "no_sync", + [AD3552R_EXT_SYNC_ARM] = "ext_sync_arm", +}; + +static const struct iio_enum ad3552r_synchronous_mode_enum = { + .items = synchronous_mode_status, + .num_items = ARRAY_SIZE(synchronous_mode_status), + .get = ad3552r_get_synchronous_mode_status, + .set = ad3552r_set_synchronous_mode_status, +}; + +static const struct iio_chan_spec_ext_info ad3552r_axi_ext_info[] = { + 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 = IIO_VOLTAGE, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .output = 1, \ + .indexed = 1, \ + .channel = (ch), \ + .scan_index = (ch), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_BE, \ + }, \ + .ext_info = ad3552r_axi_ext_info, \ +} + +static struct iio_chan_spec ad3552r_axi_channels[] = { + AD3552R_CHANNEL(0), + AD3552R_CHANNEL(1), +}; + +static const struct iio_info ad3552r_axi_info = { + .read_raw = &ad3552r_axi_read_raw, + .write_raw = &ad3552r_axi_write_raw, +}; + +static int ad3552r_axi_probe(struct platform_device *pdev) +{ + struct ad3552r_axi_state *st; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->dev = &pdev->dev; + + st->back = devm_iio_backend_get(&pdev->dev, NULL); + if (IS_ERR(st->back)) + return PTR_ERR(st->back); + + ret = devm_iio_backend_enable(&pdev->dev, st->back); + if (ret) + return ret; + + st->model_data = device_get_match_data(&pdev->dev); + + indio_dev->name = "ad3552r"; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->setup_ops = &ad3552r_axi_buffer_setup_ops; + indio_dev->channels = ad3552r_axi_channels; + indio_dev->num_channels = ARRAY_SIZE(ad3552r_axi_channels); + indio_dev->info = &ad3552r_axi_info; + + ret = devm_iio_backend_request_buffer(&pdev->dev, st->back, indio_dev); + if (ret) + return ret; + + ret = ad3552r_axi_setup(st); + if (ret) + return ret; + + return devm_iio_device_register(&pdev->dev, indio_dev); +} + +static const struct ad3552r_axi_model_data ad3552r_model_data = { + .model_name = "ad3552r", + .chip_id = AD3552R_ID, + .num_hw_channels = 2, +}; + +static const struct of_device_id ad3552r_axi_of_id[] = { + { .compatible = "adi,ad3552r", .data = &ad3552r_model_data }, + { } +}; +MODULE_DEVICE_TABLE(of, ad3552r_axi_of_id); + +static struct platform_driver axi_ad3552r_driver = { + .driver = { + .name = "ad3552r-axi", + .of_match_table = ad3552r_axi_of_id, + }, + .probe = 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"); From patchwork Thu Sep 5 15:17:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13792588 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.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 A78361A0AF4 for ; Thu, 5 Sep 2024 15:19:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549566; cv=none; b=YTK4+z9IHshCopT+kiJ4LSnuCEXlkNoqqvYAv5VBaY7UZoYJLWgi5zsC5FNCO+qmvLsp04Y3Mzft8gPXf9mI8HtiiXIaqshErzVN+MJR4KcsPyc/Jb6paU9VP28C832jPG6VGHx7/V0BDeWBp7LuaQTQkJUWSEIFDVXuydp2ePg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725549566; c=relaxed/simple; bh=qn4Pz1FllPoafjD4D/Ys3jtfWUZjxE9556qRfvpMii8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=S+mAe1b2OLYiZ/+QkL8o2wMQOyR8TJwoIu9Xx83UBaTb31e71Qoa4DuBJNFAV98jh3SBx7a9TeYgLhgOy8V7Jwq9/0nUhSAfB3/2/gWim/QWJCZryEHFL9BqgwvpYdL6icNGHD9CGeWduGaFuigf67lXxDa5IJeQY0XDPwqkGrU= 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=G2LzPf2D; arc=none smtp.client-ip=209.85.128.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="G2LzPf2D" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-42bbc70caa4so7500045e9.0 for ; Thu, 05 Sep 2024 08:19:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1725549563; x=1726154363; 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=driisr0A3MH4MgRKuQS7KG+TfR2Tlhzey12qVcFwLZA=; b=G2LzPf2D21heF38NkGLIviwTrIilT7IgpccZlVSko2SWS8wTjsXsmA2w9SCOu47Qtx 45xoiu6oM68HtzzwhrNR6f6xg6hpnshJMWpHiMS+TPG4QtsKd+R5sNw/u1wPNntJu94R KAcYQYMEibfkDp3ML2C6m5phHaT7KdlLFFTk/s60Owa9dzOV755pS9c6r/FaecJpl8Uv 3O60s9B5xLTFzgCNsPyZwS3T9v5Byy2HQBIHo6yPStyAkI9FYPbIWYPmyYhUuih9RmFy 48W0v/lImCbDhc3cxmYyRmtwn0ALBl/7A19+ufW22r5ENtMVBaz8aasXtSVjS/9PjC0n AamA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725549563; x=1726154363; 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=driisr0A3MH4MgRKuQS7KG+TfR2Tlhzey12qVcFwLZA=; b=SfWb6OfFKAI/xlxdKnshnIMPmGntK20CRbzM5hn4dpldRW23k02YIlbHzAldp1/c0z Mx4vlmAH4HxdfDHi15tiBEU0dR3qU1Xj9iAg8wzPO7StVrTlmZUehQMyb4qrvH+4oNjY 5cuCx+H+yt0HEKONyKy3zsaxQXoy7qA8rd+/i7o5a4Uw5B+asc7fyPEQBZZsdH1Jjw9w iYhj35OTLLB2u4SuMbjcZbeoqIdxMi8TPpKggPj4zhcKuIBcbsKLusaKHbBUVZnu6RTL EZgC/WLQXqK/tfUU+zLn96gZyBgl+5CKijeGZ80yYfq509Am0RrK8ORHZ1Pd7+y+iNXb +O3A== X-Gm-Message-State: AOJu0YwE1pi5WiBXjxNiIK9Y8N9MNHRJVrAjOM+ZKUgN4w+PXhbQTFXc pHDgdMndfp0Nc9z57aqeios0yC8rN93/IEhQroiklePTAQnB8ltkGxXI8/vWrQc= X-Google-Smtp-Source: AGHT+IEC17EB/IJUmMU3G5MrSDuKVOJd/AkOUmfnYOuz4m0Ufmsilaa1BcxFoMVn0wGFcbEWuW6q2w== X-Received: by 2002:a05:600c:1c90:b0:426:6d1a:d497 with SMTP id 5b1f17b1804b1-42c8de79fdemr60732675e9.12.1725549562913; Thu, 05 Sep 2024 08:19: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-374c1de81b2sm14031076f8f.30.2024.09.05.08.19.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Sep 2024 08:19:20 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 05 Sep 2024 17:17:39 +0200 Subject: [PATCH v2 9/9] iio: ABI: add DAC sysfs synchronous_mode parameter Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-9-87d669674c00@baylibre.com> References: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@baylibre.com> In-Reply-To: <20240905-wip-bl-ad3552r-axi-v0-iio-testing-v2-0-87d669674c00@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, David Lechner , 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 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dac b/Documentation/ABI/testing/sysfs-bus-iio-dac index 810eaac5533c..2f4960c79385 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-dac +++ b/Documentation/ABI/testing/sysfs-bus-iio-dac @@ -59,3 +59,19 @@ 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: + Arm or disarm a wait-for-synchronization flag. Arming this flag + means the DAC will wait for a synchronizatiopn signal on a + specific internal or external wired connection. I.e., there are + cases where multiple DACs IP are built in the same chip or fpga + design, and they need to start the data stream synchronized. + +What: /sys/bus/iio/devices/iio:deviceX/out_voltage_synchronous_mode_available +KernelVersion: 6.13 +Contact: linux-iio@vger.kernel.org +Description: + List of available values for synchronous_mode.