From patchwork Thu Sep 19 09:19:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13807567 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 F27CC1DA23 for ; Thu, 19 Sep 2024 09:21:36 +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=1726737699; cv=none; b=j8F2L8rvz45cpU2wYxSAUn29KSW50Onuelo53lRnqj4HSh1wh9Jy0+rn00VDwxOA4DP4p/VX5obvkQ3PsU6SD8PipmxGhza4mD8Q8+ExzwADSSgKlj41tQFB012iru2k7HJtYehGyoMS0IC2LiyYN5QrfXYQnm1causn4foupM0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737699; c=relaxed/simple; bh=Ou8OfT+69WBiLVaYkprtWanFi5XHSO9mF882Eoasusg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eOmPHFw8Aco6tI3JmJjDbYJPOx22nYRSOEtf3V2fLjjftPwIqpAs8BezeJbwFcucpHpjNe/0Cm4h5zNWQ483FgWyK2D9D5UPa/HQ8vxvv2oG6nedLE8h14mifW3pMA+vqiyDFuP21Myk3MelB02o67/Ls/aPUL3SXdg2yDF3dcs= 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=d+PSUCJZ; 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="d+PSUCJZ" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-42cb1758e41so4703475e9.1 for ; Thu, 19 Sep 2024 02:21:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1726737695; x=1727342495; 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=Bm+PhgVISoshe6+u0cv75nF5vnnSUSz3FJSs7aa+aiE=; b=d+PSUCJZmYdEiWLJZUNUc81ViaYPdsnZBvvzWuLxB/8qJoBWNoW3xz5GT4ZJ/rzFHM arpzuFQ3sUwXzIQeLaBvJlBuHD+xQK8wgB90nrjVJwNo3GUnCiJ/gW3FyNpCPdLZlaV3 ojUJ7EQXF7A9gK6qZLp+2ZvQs1TGitn6h5MaH36B43Tleu2JARY+jcx8TA7TVOIUEDSg ncs05gMPftiD3Pr6m/N8M+q72BRnYaRlmevyqQQmjmFw1h6XlL1DtoIHiIHR7p84gQrJ Q4qIeJpygube7gDVuWowf00VjauGlTxsDsgyhoKMOjCpbF8Es1z74YIg6CQWiSmF7nRl mYLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726737695; x=1727342495; 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=Bm+PhgVISoshe6+u0cv75nF5vnnSUSz3FJSs7aa+aiE=; b=gXTocXsje2zgBnJlgXcWt15Z5G9bH8Q4pdRYzW4O3HzVS8eJfV9eTxotseqp1lNCHH bua8w/emiaHjC6NQ2ttDb6UAOIKYEDtcpd8gQV+GIS/U6TTMz/ZYw43SQwPHEBJi80OI eH+EIHt1loTJf1CIkPp5eOqiconBImCfx1vqAka2E1D8yK8ILt1Et7UuaH7TaCN+S8kD VeTkJypW6G7+gH+rFda0bc+X67+BmgMTbkZ46QafcQYEnnb92c25TWED0YZ4y93V87FB TNjgUmv3b5OWhTIxlM6rMZt8wBkwrGT9Y7Zrut9iwHS8JyRDeA3El3OE106rZC2CQ8YB Hxig== X-Gm-Message-State: AOJu0Yys4+o+DHU7YvA9Phh9mmXgib2PIoO1dw6PT8mrqtatiZdr3OCq iSnwllvptCBlkqFXoI/PM841SdobYw1S0Sq7ycflDjuP2CcYkiTW1l6pIUZMSx+HZbrTHbPuZXI 6 X-Google-Smtp-Source: AGHT+IFZL+BpyLS0ETVBklimnTddQLSVyt3UeGyl8jNbw4TKvjYFJ4jVSTQlrNtqaiCtdzx8j5Sv0g== X-Received: by 2002:a05:600c:1c04:b0:426:6308:e2f0 with SMTP id 5b1f17b1804b1-42d964d8558mr144476935e9.26.1726737695103; Thu, 19 Sep 2024 02:21:35 -0700 (PDT) Received: from [127.0.1.1] (host-80-117-99-70.retail.telecomitalia.it. [80.117.99.70]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75468413sm16889465e9.45.2024.09.19.02.21.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 02:21:34 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 19 Sep 2024 11:19:57 +0200 Subject: [PATCH v3 01/10] iio: backend: adi-axi-dac: fix wrong register bitfield Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-1-a17b9b3d05d9@baylibre.com> References: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> In-Reply-To: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , Nuno Sa , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Fix ADI_DAC_R1_MODE of AXI_DAC_REG_CNTRL_2. Both generic DAC and ad3552r DAC IPs docs are reporting bit 5 for it. https://wiki.analog.com/resources/fpga/docs/axi_dac_ip https://analogdevicesinc.github.io/hdl/library/axi_ad3552r/index.html Signed-off-by: Angelo Dureghello Reviewed-by: Nuno Sa --- drivers/iio/dac/adi-axi-dac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c index 0cb00f3bec04..b8b4171b8043 100644 --- a/drivers/iio/dac/adi-axi-dac.c +++ b/drivers/iio/dac/adi-axi-dac.c @@ -46,7 +46,7 @@ #define AXI_DAC_REG_CNTRL_1 0x0044 #define AXI_DAC_SYNC BIT(0) #define AXI_DAC_REG_CNTRL_2 0x0048 -#define ADI_DAC_R1_MODE BIT(4) +#define ADI_DAC_R1_MODE BIT(5) #define AXI_DAC_DRP_STATUS 0x0074 #define AXI_DAC_DRP_LOCKED BIT(17) /* DAC Channel controls */ From patchwork Thu Sep 19 09:19:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13807568 Received: from mail-lj1-f176.google.com (mail-lj1-f176.google.com [209.85.208.176]) (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 D8F45199929 for ; Thu, 19 Sep 2024 09:21:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737700; cv=none; b=jWo6Cx6tW1pQ9pFl+qSExlPpKyOaXCsDwsFID3oMqq8JYdMuI4V4+kh4WF3w27YahJv0cC1xR4KGkKPqeoM9vbB+tKUYzSCn4aJNEx5JaAyiz7MPaAIkOB93AM/GhaBrzt7JF9eVc4aUfy3+YlzTxVXJ2G7YQG7BsdISFpn67V8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737700; c=relaxed/simple; bh=rmWek2CE7WPljPSo+Uou9ada/0CF37ebR/ci1deBjQw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rsiCVeJ80ScA7eXfTpe2qtmZCH3v02Kxhx8p9cAe8So81TYKBfZ0SSrzP4/v2T+WJ7iP8j0X+7cSUWzrEV5MPcv8sGjqyNhNSM9wFSzolIRpwXlcYbTPZ8nKpkK9n0uoX4G7Gluh6QTDKURPn2F3xjI4vtciypxMASj5CSZqEdE= 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=DtjLHv9O; arc=none smtp.client-ip=209.85.208.176 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="DtjLHv9O" Received: by mail-lj1-f176.google.com with SMTP id 38308e7fff4ca-2f74e468baeso6739251fa.2 for ; Thu, 19 Sep 2024 02:21:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1726737697; x=1727342497; 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=bi6dudpwiT1wruYc8KetPgHF34XRCEstNIC9Mcn08hE=; b=DtjLHv9Ok0R4aIHxyMuBkP8LraJYEh7yG/o52UX1tidVBege+0FrDV8wKmPw17Iwd5 oYobHesUlHNE8NGJZYDzR+slheh4nrwYxUnKV4fos8dTVVW+HiAwN+DAWEsJAbF7Ha2a V+TEEq01yIrac54AZWVi1+FcCt12+ut7zDp9sf/HEL9FYAFcEN/dNCvP14tOfmza7qIG wC5WQnI8pug1cEygt2xuBGeokXFBvBlPHDUgkIbKr/WPYmgarR2ZXYlOxHaN+bUWUYbo 2P4NAhkXyg0kBxATKopyCupSMRQrgNVB2B1rj/5/2gJqXqdkvqO6kyTHz51naQhpkozY g/cQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726737697; x=1727342497; 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=bi6dudpwiT1wruYc8KetPgHF34XRCEstNIC9Mcn08hE=; b=pB5tOfeiQScvsAmbeJJh6/pOo01YigxP9/A57WfMtynkl0+yOCc+g9zc4lHez78GNs TQheGDaCuOic7aWbczyuPXiowvbTf/a8foN0R0lQT3fWlV9OZGpFzXt0X33ytvsMjN9Q b4IweqM7U0cMoycp9UTR5I9dEAJ+Mu5mJKTTBu5/QRwnj8/lO/6YDv9/KFJsECsBEJlX hkj7ePl2N+nJRuic0Sf9dPdjlOQKiDdAgSBH4Zv6YDAj95msAL2xLPnggqmzSWTnbSvg vASyINkrlJ50swMOFTpNtVUFjUwx15R3FXZERc035DOuFsohkVqN98dXFVmw+zOSz/Dt wRKQ== X-Gm-Message-State: AOJu0YymF8mvc+xO+uz70uKsm2HLzNkWyDWR7nIZyOIL7OXZFe01nMmb GDN7KxEm+S85V3/0ijAMBSlDH/EqzGOW/v3tMBcjtXJ3tWSi/Si7VfnJJuG6Lpk= X-Google-Smtp-Source: AGHT+IHyCwBaP2n+hEG21y4E73ikctDq544q5tnqdl4FFCfiMtCFgczBe46WG484l0Gqo1n7oWO3cQ== X-Received: by 2002:a2e:4e02:0:b0:2f7:669c:93c1 with SMTP id 38308e7fff4ca-2f7919042b3mr86992431fa.14.1726737696632; Thu, 19 Sep 2024 02:21:36 -0700 (PDT) Received: from [127.0.1.1] (host-80-117-99-70.retail.telecomitalia.it. [80.117.99.70]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75468413sm16889465e9.45.2024.09.19.02.21.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 02:21:36 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 19 Sep 2024 11:19:58 +0200 Subject: [PATCH v3 02/10] dt-bindings: iio: dac: axi-dac: add ad3552r axi variant Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-2-a17b9b3d05d9@baylibre.com> References: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> In-Reply-To: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , Nuno Sa , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Add a new compatible and related bindigns for the fpga-based "ad3552r" AXI IP core, a variant of the generic AXI DAC IP. The AXI "ad3552r" IP is a very similar HDL (fpga) variant of the generic AXI "DAC" IP, intended to control ad3552r and similar chips, mainly to reach high speed transfer rates using an additional QSPI DDR interface. The ad3552r device is defined as a child of the AXI DAC, that in this case is acting as an SPI controller. Signed-off-by: Angelo Dureghello --- .../devicetree/bindings/iio/dac/adi,axi-dac.yaml | 40 ++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml index a55e9bfc66d7..6cf0c2cb84e7 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,axi-dac.yaml @@ -19,11 +19,13 @@ description: | memory via DMA into the DAC. https://wiki.analog.com/resources/fpga/docs/axi_dac_ip + https://analogdevicesinc.github.io/hdl/library/axi_ad3552r/index.html properties: compatible: enum: - adi,axi-dac-9.1.b + - adi,axi-ad3552r reg: maxItems: 1 @@ -41,22 +43,54 @@ properties: '#io-backend-cells': const: 0 + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + required: - compatible - dmas - reg - clocks +patternProperties: + "^.*@([0-9])$": + type: object + additionalProperties: true + properties: + io-backends: + description: | + AXI backend reference + required: + - io-backends + additionalProperties: false examples: - | dac@44a00000 { - compatible = "adi,axi-dac-9.1.b"; - reg = <0x44a00000 0x10000>; - dmas = <&tx_dma 0>; + compatible = "adi,axi-dac-9.1.b"; + reg = <0x44a00000 0x10000>; + dmas = <&tx_dma 0>; + dma-names = "tx"; + #io-backend-cells = <0>; + clocks = <&axi_clk>; + }; + + - | + axi_dac: spi@44a70000 { + compatible = "adi,axi-ad3552r"; + reg = <0x44a70000 0x1000>; + dmas = <&dac_tx_dma 0>; dma-names = "tx"; #io-backend-cells = <0>; clocks = <&axi_clk>; + + #address-cells = <1>; + #size-cells = <0>; + + /* DAC devices */ }; ... From patchwork Thu Sep 19 09:19:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13807569 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F082B199957 for ; Thu, 19 Sep 2024 09:21:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737701; cv=none; b=VLS+WeBhtxd6w141GF20NGXfAEmDhM2YwPE/XEgS5PHRzTqLjCJWEZPUgREmVmCP6/LnCYjOlAflui/7gsm8HEG+3q2NIBOSNG3hghZEfNdXtAN8Nf8Eq8wr+CcbCPZQmHCDSObOfZMWRuyusK3+isJQu8HK3oA0iO1jo+Ye/B0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737701; c=relaxed/simple; bh=i5PZepG1aoFBTCiFDPOYVCA2IFjIkELc4/8zmw5imSo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eLtX7NRY4ZvrVekWc/yhFU+oNElevLYA/P3LFTkCwaME7Rfkv3pqYrKOIjD2tLNLOV+b9JOYOOuIilTNRnaWbi1q2y/tkP6ZG09vMOqpdYRoJitRaWG+bohGkiICltULxgmMindV5gG4mx9fIZCeVJSiy0VU9tUFAqZ6GadkMEA= 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=GruvSxtG; arc=none smtp.client-ip=209.85.128.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="GruvSxtG" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-42cba0dc922so4590775e9.3 for ; Thu, 19 Sep 2024 02:21:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1726737698; x=1727342498; 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=aMa/yQ2Im0//zhcPUCeMNBxbg9N98XT4Go0CFqsD1eY=; b=GruvSxtGn9TXNzz/DRl1ik8zufhfSeZzIUD1oo/6oGTLyz+0Amwpy6h19B8ylUbj/u UOj2km66k6zmq3DpW7vbx7gYYnble0ojqbn+2huTythr84vx44PmoxLps4Q/8na1umR3 lKXxd04oBz1tKUzKf9d2cyF/iPEWbghnkLdsHPxLEM+8Lzilvi66lYYH+p1E+ZFNEODu fz7g8EtlgAPUQ9m7NQ98aBbCDxsnIt3mdXsAWWXrrs0v0yXsHAJLt6AXvXfg/n3Szn1c etrEjxtVkOZVB9RfCcBhZBuhxcuFRKKBGCxBIkRDOg/EkmKSvYjWxwBN45p8yht9E3KB 0Q7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726737698; x=1727342498; 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=aMa/yQ2Im0//zhcPUCeMNBxbg9N98XT4Go0CFqsD1eY=; b=AyeAhUPnHIxWI26GGCr4czbP+rGJkkdmRjqCYCTjOuB4xX3Uh7EZA/D/2Lb0Lsw7Cf JOdLnHiKCFp+G08TyENOjRWuKEeP0JOLXHXF9pdrZkCYlHNaZlrKnTHnSktHIOW4JidF dJg/tmdf8QZIiiiK/Z9wA0oroxtK1kkNHet4L24YRojTuGfgO8Xzuty8aTCSuH/OdKr0 DcyB5PTed9e52z930PG5nupEdGk4OwwHwVfhti9cMrW0P04LKnlsN+RW8fjOoqYypnRn 0dkfPpPF9LJXKYWyGfC3DOf3z/XGopzKHhHFqhe2aTxX6TVUFfbTPGNBzNIeoUgtv3VM P/bQ== X-Gm-Message-State: AOJu0YyyIibnWGMu3Gud8J0WS8CE7iOQcBiAttA6cI77V1kbuv0XQU3t 9qOiXK3WEsYhZEnMDdbWGtRXJWcyp8sdouyXuBDFLpMbe8Q9hbEIRki8ycu1gKM= X-Google-Smtp-Source: AGHT+IFzaSnso6ocrF9emwd2RsWQlvTAmzurK9UZ8AOuiIHpVPVrYdehMMnowjm9qAv3d8lc18uSxQ== X-Received: by 2002:a05:600c:4e8a:b0:427:abed:3602 with SMTP id 5b1f17b1804b1-42cdb5675f3mr190980895e9.24.1726737698218; Thu, 19 Sep 2024 02:21:38 -0700 (PDT) Received: from [127.0.1.1] (host-80-117-99-70.retail.telecomitalia.it. [80.117.99.70]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75468413sm16889465e9.45.2024.09.19.02.21.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 02:21:37 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 19 Sep 2024 11:19:59 +0200 Subject: [PATCH v3 03/10] dt-bindings: iio: dac: ad3552r: fix maximum spi speed Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-3-a17b9b3d05d9@baylibre.com> References: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> In-Reply-To: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , Nuno Sa , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Fix maximum SPI clock speed, as per datasheet (Rev. B, page 6). Signed-off-by: Angelo Dureghello --- Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml index fc8b97f82077..41fe00034742 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml @@ -30,7 +30,7 @@ properties: maxItems: 1 spi-max-frequency: - maximum: 30000000 + maximum: 66000000 reset-gpios: maxItems: 1 From patchwork Thu Sep 19 09:20:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13807570 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 63D6C199FDC for ; Thu, 19 Sep 2024 09:21:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737703; cv=none; b=qPd43pvr3wtb5F+bswSuDq14rl7ptzZEr2GT2Gw3WN7HhrHBjkOraZuDr3yLTMRCX+JPpczPGGwHsPrFrw4mFWCCWa4gjKUeHBcKUbnRDqAQRKFPpWWSpKahtYxzE/EdW7DggcDKl1iY6Dw8WOtwGGXJB/S84lFQJn8WlSenZR8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737703; c=relaxed/simple; bh=jcHHpxuLtdpMqMa6vj9yuUj6cUdqApIRaj7aqS82BZk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pntdX/0KEE9PFzqP/nq68TRjl7oQ2FmSRh+W6kCr1F5HaDzQ4YCjRNq2xmxVo9jks3riNNKkC/jwJW7Za8S4ytERBDGtL9qc7gdJc+4P7Gn5wQO8v9+DU3CLNJUqEN9FuVTzcwjB+pv/yaqNTHt5169/AkoyIi9DtwHgbqKjlQY= 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=g92ThZbj; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="g92ThZbj" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-42e5e758093so5169365e9.1 for ; Thu, 19 Sep 2024 02:21:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1726737700; x=1727342500; 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=as49kqRLaVJ2yNgnvKYi3cFO3j1mhGpPd7aIfEYa3yM=; b=g92ThZbjlKGnCY1JXRIeiJ73RFATexgcyYgmal0oWlScvd+JD5DLryT4dSOfz5DNMK sE1z6rxEfqFEKUJZef2m97qKBfnv7XHkcAlwmCwJFQhx7N02G9lTSNHhpdyIXswXy9n1 KslL0zkrFaxtvt1XOytDwv4tqlZm7UaEjQXWv8LY7vv+TT7L0EDuWRv1rD1Lzf0O5hf8 +4+DGW6iQBCgCIH6HRIBWaObqT8rWOEENI3PrUo17aoS4WAj3pmvgD3tPZyX1z/U5hjf s2FctNsHhYsWADKe2CXPLhZ+27KFH72bEbrUoQj8a2UlEDTv6Te31K0QF9WCXxfDnhnB S8UA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726737700; x=1727342500; 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=as49kqRLaVJ2yNgnvKYi3cFO3j1mhGpPd7aIfEYa3yM=; b=crqxMzCaY+nhCh7NoHRJHlq/46RV3wdKUnFUCGjSmuo1ryPS/Ejuo/xgJKlJLEnKg4 BP1kbdWuS5/jp1j14WUclia7N+murC9wj4tU8cm0zH90lhbsWdvvMAmvCGEixFViaWZK jUm8jcByHOVAXVB8CEdTwkt57jO+ftakZY8bpkARelhnzaTIhWztzID2KI0Fn/Ye/2p2 wdLvog1Iffxw6UsqK188E9SeJGpWhLk6daxeufWODj06WTU1st7VWyvv1aoJvuhf7koZ /kpIGsQ5DnOlKRvpGIWUfLAXM33b5M4CXyn/oxSd8h5dqC4asVcbY7P7ed2IaWsCy38v 27GQ== X-Gm-Message-State: AOJu0YzSPNIBgVYtCVrcBnSjLjYixcm5eLB69hRm079eGEuaGtutMl6T /o2iUfLWXqzEytEXl4+z2a2TWMMqCVGNh3jniJm/sM21TJzd5RIJK1pPgyIpRzs= X-Google-Smtp-Source: AGHT+IGWRcc6/8EOmc1T0X5CvPpjxQ1v9/oDjpa2olx4CY/PvhMRizP7HegUuy58IIILTSIW2C88EQ== X-Received: by 2002:a05:600c:4447:b0:42c:b63e:fe8f with SMTP id 5b1f17b1804b1-42d90817e87mr171803165e9.13.1726737699665; Thu, 19 Sep 2024 02:21:39 -0700 (PDT) Received: from [127.0.1.1] (host-80-117-99-70.retail.telecomitalia.it. [80.117.99.70]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75468413sm16889465e9.45.2024.09.19.02.21.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 02:21:39 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 19 Sep 2024 11:20:00 +0200 Subject: [PATCH v3 04/10] dt-bindings: iio: dac: ad3552r: add io-backend support Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-4-a17b9b3d05d9@baylibre.com> References: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> In-Reply-To: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , Nuno Sa , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello There is a version AXI DAC IP block (for FPGAs) that provides a physical bus for AD3552R and similar chips, and acts as an SPI controller. For this case, the binding is modified to include some additional properties. Signed-off-by: Angelo Dureghello --- .../devicetree/bindings/iio/dac/adi,ad3552r.yaml | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml index 41fe00034742..aca4a41c2633 100644 --- a/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml @@ -60,6 +60,18 @@ 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 + + adi,synchronous-mode: + description: Enable waiting for external synchronization signal. + Some AXI IP configuration can implement a dual-IP layout, with internal + wirings for streaming synchronization. + type: boolean + '#address-cells': const: 1 @@ -128,6 +140,7 @@ patternProperties: - custom-output-range-config allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# - if: properties: compatible: @@ -238,4 +251,33 @@ examples: }; }; }; + + - | + axi_dac: spi@44a70000 { + compatible = "adi,axi-ad3552r"; + reg = <0x44a70000 0x1000>; + dmas = <&dac_tx_dma 0>; + dma-names = "tx"; + #io-backend-cells = <0>; + clocks = <&ref_clk>; + + #address-cells = <1>; + #size-cells = <0>; + + dac@0 { + compatible = "adi,ad3552r"; + reg = <0>; + reset-gpios = <&gpio0 92 0>; + io-backends = <&axi_dac>; + spi-max-frequency = <66000000>; + + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + adi,output-range-microvolt = <(-10000000) (10000000)>; + }; + }; + }; ... From patchwork Thu Sep 19 09:20:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13807571 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF17919B59D for ; Thu, 19 Sep 2024 09:21:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737705; cv=none; b=HGdTwNNZJ8cwcbGSCm2Ra6ZCnZWJVWwRl5SEKiElEj2j+y8JgvgZUtBteRaVi+GB5kl9z0/wTm4H9MfWEAp3KeUuNOOz+K1HWcez/Nq6jMMblSxdMq6UePiQTblrynqrk93M3esRdGkUzufikDzkWs+RYgQv1FS3LU7vrijjCvA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737705; c=relaxed/simple; bh=ndWW4F3kvG2WWtSE6ODuaqI23NRH5daT94UTOq+wAJI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=USh37zPm5b4cewfF/hQAlMPp9dYwuxmZXy9vycFYmpOAW7X/5MlU+LnQzUPNUJ3yIfgeNhxgGam7ZLD37Nc4anhRn+MOnbX1ew5fkeIXOaAFJ4opre6bSuAqb6heHom3e1Gj+en/FuyOVR6sZiRzY0fDQz96mD+QjVoxdWtbXFA= 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=UXTqFOoU; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="UXTqFOoU" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-42cb60aff1eso5748745e9.0 for ; Thu, 19 Sep 2024 02:21:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1726737701; x=1727342501; 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=uheLizxjohrzTA32l5fB0xiBW6E/tfS41z/13OK6jvo=; b=UXTqFOoUk/wACY7y71+UTsX6Bo6ykuZf3S8diYTT1xdgzwSbNZGttxwiy5BKZHAN+S 848nYAXtyvTtl2nkQ/jNvBWMfydww4ILww9xJ62+koRudWtCNAvsOAQ56NGf58SNEwGZ 4Wp3c2oBsIJbrJT9E/NUOo2ff6WpEtslQ9i5TGSVOViBuoU1NnU1gIO7PyFCeA6hRcSX XJNXkbJpqKzB6JJS2WPTKaELrye62HUlhv3yLI6fi5WycLFtlBJEcpwix/eArZ9jXSem rWIOhAgkrWR3yjezlzWLFHRrSxOJ+5nug1PbIPl3Y0wxHmckNoEhGejSdJDovE8GxbWL guLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726737701; x=1727342501; 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=uheLizxjohrzTA32l5fB0xiBW6E/tfS41z/13OK6jvo=; b=bR+O2P+dpN0hnEJ2l9vy/BOf9HzatQehDyEIgm1IGrZ7Mx/5C4wMFEHhjJQ107V1YK GdsA5jOqtxFFeEzn9KKMTU1rb3b+jWzXYjUj6Befqenh8r2qwts+xUS6G5a4h0rz4rdB +a9NvxVz4aP+itIbRqrrpz27xcDRAndRohFCqPPKpw+xn0X+pdIM41OgRK/igJX1Qawn Jm5Z70Oyam587KA2POSA85h3Dxc9nJlfDUl4gIceHAefMPlWDWlaubAUIRaALRnT9YXA s06unXQ8PuoApRC+783fm5rqzCJFUzFg8k187l3ltOqKUH1bB7s4qajWoeGX9a9l5efJ D7ag== X-Gm-Message-State: AOJu0YzejmxAHg4x94f5timfEI9xMQzAhkjXo+tHVOL+WI8IuRacngQA fpGZFy/9UbanNuEXwwZMWbhvEEppq79+7nSI71LlF5Kqt8osRlztyUhhi+EhVNhvp7kw5h+Bcqv l X-Google-Smtp-Source: AGHT+IGo7k4GbR5Iqbckdvkvhmnrc/hp0sCtcOfUiHzER3VgMV4G+zqq7NZvGjYwmPZu7Anwy34WiA== X-Received: by 2002:a05:600c:511d:b0:42c:b62c:9f36 with SMTP id 5b1f17b1804b1-42cdb5389e4mr187787295e9.5.1726737701158; Thu, 19 Sep 2024 02:21:41 -0700 (PDT) Received: from [127.0.1.1] (host-80-117-99-70.retail.telecomitalia.it. [80.117.99.70]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75468413sm16889465e9.45.2024.09.19.02.21.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 02:21:40 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 19 Sep 2024 11:20:01 +0200 Subject: [PATCH v3 05/10] 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: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-5-a17b9b3d05d9@baylibre.com> References: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> In-Reply-To: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , Nuno Sa , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Extend backend features with new calls needed later on this patchset from axi version of ad3552r. 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. Signed-off-by: Angelo Dureghello --- drivers/iio/industrialio-backend.c | 111 +++++++++++++++++++++++++++++++++++++ include/linux/iio/backend.h | 23 ++++++++ 2 files changed, 134 insertions(+) diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c index 20b3b5212da7..f4802c422dbf 100644 --- a/drivers/iio/industrialio-backend.c +++ b/drivers/iio/industrialio-backend.c @@ -718,6 +718,117 @@ 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); + 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..41619b803cd6 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_16BIT, IIO_BACKEND_DATA_SOURCE_MAX }; @@ -89,6 +91,13 @@ 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. **/ struct iio_backend_ops { int (*enable)(struct iio_backend *back); @@ -129,6 +138,13 @@ 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); }; /** @@ -164,6 +180,13 @@ 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); 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 19 09:20:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13807572 Received: from mail-wr1-f52.google.com (mail-wr1-f52.google.com [209.85.221.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 767C619CC18 for ; Thu, 19 Sep 2024 09:21:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737706; cv=none; b=m5LXIsrWPIDyy8T2FugkicTQWj4o/Oy9U4thpnp7pQ26KltYkIOLJG+kk6TakLwUry8miTpNJBUYK/BcnXI7OaayijDfEMF88vfkRdcXMzBEksoeZ62TNWnAJVm0q6fyBtUO/xMhQReXnQ2rBs7/vpf6GAHLV9LXRMKuHcbUE8w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737706; c=relaxed/simple; bh=4XGzOom73gIUerRuQzf8Mp6Hdpu6jdjxRrE6nfsGpMw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qOMjE4vBYp3sGB6eeRDuxEIv/1HINMMGk4zs3hQXXoL7FT3SAGs3nDN4itBqYB3O6+WTGzsPxHnWbHeGJepMZzfNqCZa5t2Z16Q3DxhvNmFGBzZm4I6BwMK22ZTeI+aQ2/4U/dOn5vmHYMkkISdYvDFwPaClNtqoTa0caK7S6Zg= 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=XoFofSA6; arc=none smtp.client-ip=209.85.221.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="XoFofSA6" Received: by mail-wr1-f52.google.com with SMTP id ffacd0b85a97d-374ba78f192so383527f8f.3 for ; Thu, 19 Sep 2024 02:21:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1726737703; x=1727342503; 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=+NnBndRi3FD2u5hSLd2eWpqMwpmgUucEYsLUxhMHG+Y=; b=XoFofSA6f4r9Lr59vufIy3+8K+ALOQ7y8ga06BSSTdCmWw9hc3njoPABVQ8/HInq4H GvPA3bjtgIX038V3Q1xxwhN51RODz+TiuBZXeTW5JFvvMRqQGagtaZjzh5mXHQ8I1V39 jghM22vb+Ll2ypzn3Filonb9wK5Lj2AO4lAFuIqUfMw9Btf3+yWC/SiUEWQyDyubBrYU EfSG5EP9MF+hMGbbCM9uKbmZTNqPqqgAmBaCIdA+5bOTnE/axCpMW0/8tL7i8tkE+NgX 1Hgl9KUJW7xOfX7Qof0rtCqEUYRFC6o5II/e3PKCZ85GXcXHbaqqMCqMexGm80l+qPn+ iMoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726737703; x=1727342503; 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=+NnBndRi3FD2u5hSLd2eWpqMwpmgUucEYsLUxhMHG+Y=; b=ivUXf4VW4+vTYTbUjIeK1tqEHjBrSYlPKvr/dR0zp2Vaie/9YygmblukgzhHTnKqFC 2QxhKgMOw1J8zH02hKm+mOaWvwjGlVzVzT1blgZXVehVaQjfMPkY2jnYRwYilcQandoI uWZKVwRAmQzU1sX43fwwo2F0tNX4IjNSkHY6UT/86QCt7Dnh3hiLzMlMpSjXJMHlrqWt UCoao+eROW+VOaxi0lY7IcwMB3ALWNO6NiOicwuE06OqR01uMv2EaSeF5SEQD9N+5iqR qrJPx0ach1tCRyYvnJkwMrUO8ZHuTHzqEwTlNpoItofIBzkjOBUt+7RRfF5CMBZNhZKd FHew== X-Gm-Message-State: AOJu0YygAlBQw9ueOijnfz/AQhMsXOsDAZOQp0K/wI7R4yGmwj02wyCi GPv9BBA/F/B0LQTZRCxAHFsUrb2pxY0CwEiHMt4ubyBaPksJGPwDyRe5UwJz68k= X-Google-Smtp-Source: AGHT+IHZHQpR0mpe3LtuSi9Eaj8AoE1qOaflbXcjPyYtDfqSz6Dkp7VzXwt7Q9nBhYgyFNdk0J3Ogg== X-Received: by 2002:adf:8b9e:0:b0:377:205f:c494 with SMTP id ffacd0b85a97d-378c2cfebc6mr14578799f8f.11.1726737702631; Thu, 19 Sep 2024 02:21:42 -0700 (PDT) Received: from [127.0.1.1] (host-80-117-99-70.retail.telecomitalia.it. [80.117.99.70]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75468413sm16889465e9.45.2024.09.19.02.21.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 02:21:42 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 19 Sep 2024 11:20:02 +0200 Subject: [PATCH v3 06/10] 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: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-6-a17b9b3d05d9@baylibre.com> References: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> In-Reply-To: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , Nuno Sa , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Extend AXI-DAC backend with new features required to interface to the ad3552r DAC. Mainly, a new compatible string is added to support the ad3552r-axi 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 --- drivers/iio/dac/adi-axi-dac.c | 274 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 265 insertions(+), 9 deletions(-) diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c index b8b4171b8043..3ca3a14c575b 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 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_16BIT = 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_16BIT: + return regmap_update_bits(st->regmap, + AXI_DAC_REG_CHAN_CNTRL_7(chan), + AXI_DAC_DATA_SEL, + AXI_DAC_DATA_INTERNAL_RAMP_16BIT); default: return -EINVAL; } @@ -518,9 +561,206 @@ 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); + int err; + + switch (mask) { + case IIO_CHAN_INFO_FREQUENCY: { + int clk_in, reg; + + /* + * As from AXI IP documentation, + * returning the SCLK depending on the stream mode. + */ + clk_in = clk_get_rate(clk_get(st->dev, 0)); + + err = regmap_read(st->regmap, AXI_DAC_REG_CUSTOM_CTRL, ®); + if (err) + return err; + + if (reg & AXI_DAC_STREAM) + *val = clk_in / 2; + else + *val = clk_in / 8; + + 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 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); + } + 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; + + 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); + } + 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 +768,14 @@ 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, .debugfs_reg_access = iio_backend_debugfs_ptr(axi_dac_reg_access), }; @@ -545,7 +793,6 @@ 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; void __iomem *base; unsigned int ver; @@ -556,8 +803,8 @@ static int axi_dac_probe(struct platform_device *pdev) if (!st) return -ENOMEM; - expected_ver = device_get_match_data(&pdev->dev); - if (!expected_ver) + st->info = device_get_match_data(&pdev->dev); + if (!st->info) return -ENODEV; clk = devm_clk_get_enabled(&pdev->dev, NULL); @@ -588,12 +835,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 +879,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-ad3552r", .data = &dac_ad3552r }, {} }; MODULE_DEVICE_TABLE(of, axi_dac_of_match); From patchwork Thu Sep 19 09:20:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13807573 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D810E19D065 for ; Thu, 19 Sep 2024 09:21:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737708; cv=none; b=qmxLCv8nIgNLMYJAnZs5o8RAL6j37aFMh6HCyRrOTkYBwFX7sVeOgzOZ4D6zgM4a5NHBj5t9MXOlVAKJYbDdvyzbgsS792UmqBgIWRGsz6U09zUyqibcOdSWAY4DoNF4iq5aYM73a3Y8Amom5nASCFSYLwTW29Et6WC8NLnbdzE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737708; c=relaxed/simple; bh=iIDwGqolTd1HpLnj9SN11+oq2F3sidqm8mJBhcm2C6Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jmgHPkrnNElABaRAq18TzWS3I+mPyyzareyZ1X5qECPuOoY3annD0T9S9y/JScU8r7bc6UFyhvulzHbiscx1t8MIUdRsVCxu2gwmnGFf5RLDXaN0+k9jKnVecK3/+x01ZDZ9w5v5CMytRyCFws3c9NnvyxpXabsLGjqo6QqSo+Q= 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=VlxXMEGm; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="VlxXMEGm" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-42cacabd2e0so4836715e9.3 for ; Thu, 19 Sep 2024 02:21:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1726737704; x=1727342504; 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=JG7iKoFeabciCOG8LbA5wLcP1lXi7bRJI0HkySWmPCU=; b=VlxXMEGm5Jj00+tDLElu7jPtHeNZLD9ZOLvv7Zwcw+R+H23cbFWPnDwaRY/Dff7LCy vbAw1RjJGxRk6b3gDcrAGmkAMM62bJFxi13JeNfUrvZbHnv1CU0HTcGgalwbiLLzjxys 5aKwrS1K8WWkI5Q10sV+pb3W+ZdFc0/7R/VfbDF8hN5pI04vgQ8fw5vzogOnhXghyZPx WfiqKC669F9uFB2onvl+s3eDQDCPNz7O2MFrISX0yp7ZeU5ZicyDSVJVwm/BOFI4V3nx tuL/cDiGaKuYr+9yzHUCEwEUsB8OI/YBqE4GdrfSupReJtxVyM22qRHAEJgIBhyW7Afx 93xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726737704; x=1727342504; 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=JG7iKoFeabciCOG8LbA5wLcP1lXi7bRJI0HkySWmPCU=; b=JY/8HJGeKgQXR2c6q6cN4qAVA9bih8nkKH0qKsqSpkYP5ZChlI/09d0suDP9KdnQeT PAOJyaPRZ2PLp485yvDwb6jd8t/DLO5jPZ2/5WzwUM8r+5ruzDAO4nEI9dH63XNNiAhB ck0ypaW6qoa4pUAVLT15In6TNGqAU0GZ1dIB4cnvNuzw6rBmkhJ6Zp4UqutAzC2oQCQD fEbeqtiRxXdX3ID2yGXJqrnhNDHRpAqWNLsfV2xe8lanmIdi4WJfdz8fLcSuCQEXluxR FZIn1Uchu69kKhfunIJOLrc5RrRttlshX7tkAZQnLk0Xo74j3CyWk2pwklVT/lQN5UAr nFtA== X-Gm-Message-State: AOJu0YwV4B/wTYcO2pX04KDOLwxJi0vhD/PcSVE8Ef6SdzH3QOKrU7uA 0bHU7rPMW7sXQugagUK3APcsPYdlGSMyYLBs50QNgAzNUwYEhJcyzT9w3ELRht0= X-Google-Smtp-Source: AGHT+IGxDCZWwL0ddFAcwaMdzoqfXORY4yIQqNJDfTozWQfyIFo21DEnt6zWpZeyoweJLYMJkTCjNA== X-Received: by 2002:a05:600c:3b9e:b0:42c:bd4d:e8ba with SMTP id 5b1f17b1804b1-42cdb522847mr171812505e9.8.1726737704023; Thu, 19 Sep 2024 02:21:44 -0700 (PDT) Received: from [127.0.1.1] (host-80-117-99-70.retail.telecomitalia.it. [80.117.99.70]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75468413sm16889465e9.45.2024.09.19.02.21.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 02:21:43 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 19 Sep 2024 11:20:03 +0200 Subject: [PATCH v3 07/10] 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: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-7-a17b9b3d05d9@baylibre.com> References: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> In-Reply-To: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , Nuno Sa , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Changes to use FIELD_PREP, so that driver-specific ad3552r_field_prep is removed. Variables (arrays) that was used to call ad3552r_field_prep are removed too. Signed-off-by: Angelo Dureghello --- drivers/iio/dac/ad3552r.c | 166 ++++++++++++++-------------------------------- 1 file changed, 49 insertions(+), 117 deletions(-) diff --git a/drivers/iio/dac/ad3552r.c b/drivers/iio/dac/ad3552r.c index bd37d304ca70..c27706c5ba10 100644 --- a/drivers/iio/dac/ad3552r.c +++ b/drivers/iio/dac/ad3552r.c @@ -210,46 +210,6 @@ static const s32 gains_scaling_table[] = { [AD3552R_CH_GAIN_SCALING_0_125] = 125 }; -enum ad3552r_dev_attributes { - /* - Direct register values */ - /* From 0-3 */ - AD3552R_SDO_DRIVE_STRENGTH, - /* - * 0 -> Internal Vref, vref_io pin floating (default) - * 1 -> Internal Vref, vref_io driven by internal vref - * 2 or 3 -> External Vref - */ - AD3552R_VREF_SELECT, - /* Read registers in ascending order if set. Else descending */ - AD3552R_ADDR_ASCENSION, -}; - -enum ad3552r_ch_attributes { - /* DAC powerdown */ - AD3552R_CH_DAC_POWERDOWN, - /* DAC amplifier powerdown */ - AD3552R_CH_AMPLIFIER_POWERDOWN, - /* Select the output range. Select from enum ad3552r_ch_output_range */ - AD3552R_CH_OUTPUT_RANGE_SEL, - /* - * Over-rider the range selector in order to manually set the output - * voltage range - */ - AD3552R_CH_RANGE_OVERRIDE, - /* Manually set the offset voltage */ - AD3552R_CH_GAIN_OFFSET, - /* Sets the polarity of the offset. */ - AD3552R_CH_GAIN_OFFSET_POLARITY, - /* PDAC gain scaling */ - AD3552R_CH_GAIN_SCALING_P, - /* NDAC gain scaling */ - AD3552R_CH_GAIN_SCALING_N, - /* Rfb value */ - AD3552R_CH_RFB, - /* Channel select. When set allow Input -> DAC and Mask -> DAC */ - AD3552R_CH_SELECT, -}; - struct ad3552r_ch_data { s32 scale_int; s32 scale_dec; @@ -285,45 +245,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 +320,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 +332,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 +416,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 +627,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 +724,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 +753,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 +798,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 +812,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 +850,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 +876,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 +895,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 19 09:20:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13807574 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 794E819D07F for ; Thu, 19 Sep 2024 09:21:47 +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=1726737710; cv=none; b=FVZqK9ZhOV8V5kTVeMJwg1kjlz/3dU4XLvT0vcxbRDHUlCxMT6aysTascBZq8XRRbrgXtWfG2IHhh6I1QiBwEC0EYWwNgehif/+1WGs6k4v8+iAmtuk+Ngmt4/FoL8DUeqqXe80rS8NtPsU0oHgdXeY6aONfQd4yO9wyZIn2szk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737710; c=relaxed/simple; bh=j8/N+q3xx0zo4ME80s1UUW0CIjYONFrl4UbHv7FAPvc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=TEIlowjq1MrCDu0pvlLhKqbPQbZEGrWyS85vR24qF3dUYiko/5PhODAZoqUCRzbT7xcA8z0zCN5Biz7K1JshI7J/2I9d/vovHGBaWNLao0KUbjtw0F1bwD6A2GkD8Bcby8nH+/7squX+EyTvSPkfuPHmWOSYAG1SD69F44HEznY= 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=N8mkU/tw; 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="N8mkU/tw" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-42cb1758e41so4704875e9.1 for ; Thu, 19 Sep 2024 02:21:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1726737706; x=1727342506; 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=jLx6yZmvlbO/p8tBmjqsRCI8Q1K0tY4FhoZVF6Xko+Q=; b=N8mkU/tw1u8dQISyFCCDES7b9Q6G7WYIu2iwt67S/I2DrrnYmRpuxsNsiLfbZfxfWZ Gf+e9urPTbx105AUs7dXu5+691R/O2/udpsj5uk9xGnF9KqPHBE84i/m7t/1Spzdg48O JAsfXoSne/SwCBxZorLXBI8YlHScGH0B+uzHFwNDrox2tVlDpmY6wLuHwNGvVKH5g2cp VnlZwofNNibkzeaVNxkXUUlphCFRor/P+Hot5jk2zTf4BTspZMhYp1x+8QL1elun04Og +UTY+DG4cEHEsPK7qYwqNpM5qn2QPJFfOF9AU0A2joaK+trnr8A5XJTHNxxlwvt/kq0X fbBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726737706; x=1727342506; 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=jLx6yZmvlbO/p8tBmjqsRCI8Q1K0tY4FhoZVF6Xko+Q=; b=L54fZRXFyho7VNV3WgRXjyPrOy8enw7t+tuomyNmzDj/hM4c2jZoMej6VjKJgsq7Q4 48NUbeZGwwB5NYFcfbby1a7Z+lKFdSuNraPQ0k4+Zx8s/GlY9pdCRFn75rE6YodfFg6Q Eg9N/6/sGPj48dq2vN1IUgFTo4fHi3J6vqcTVnjaD5Lq5XB5nKMISkRlV15JYKKKMmic R1w7BwFAa5SVNgHY3iSpI6/bDUuKF1bQTEWqs/XvFFBnh0Dxb36uiAsUNjsZq4tcQ1rs ESZVEJ5OTOyVyZUzWy4agp8REQr7FssDFbI7Xd19Y7e9rNuLAAiATm7RGF0G7OA7dIPm 4nzQ== X-Gm-Message-State: AOJu0YyHAb4/YBDkG+kmrXdc5/5stH2duS2qZZC4ouUo8wU4Nqcb+u/J FkqMZmgiLKgYDZavSDa8TnahhSVMFCKpDSYhbuUIfy+PrQngVhuAbSoxxzmyfhg= X-Google-Smtp-Source: AGHT+IGZ77pIyE+dpexdg0tka3oR9qQL39jb24X5E5JrxZ854Rym7DSXSTt7pp1iQFPh66pwKu+itg== X-Received: by 2002:a05:600c:1c9a:b0:428:1b0d:8657 with SMTP id 5b1f17b1804b1-42d964d8579mr150036645e9.22.1726737705582; Thu, 19 Sep 2024 02:21:45 -0700 (PDT) Received: from [127.0.1.1] (host-80-117-99-70.retail.telecomitalia.it. [80.117.99.70]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75468413sm16889465e9.45.2024.09.19.02.21.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 02:21:45 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 19 Sep 2024 11:20:04 +0200 Subject: [PATCH v3 08/10] 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: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-8-a17b9b3d05d9@baylibre.com> References: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> In-Reply-To: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , Nuno Sa , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, dlechner@baylibre.com, Angelo Dureghello X-Mailer: b4 0.14.1 From: Angelo Dureghello Extracting common code, to share common code to be used later by the AXI driver version (ad3552r-axi.c). Signed-off-by: Angelo Dureghello --- drivers/iio/dac/Makefile | 2 +- drivers/iio/dac/ad3552r-common.c | 173 +++++++++++++++++++++++ drivers/iio/dac/ad3552r.c | 293 ++++----------------------------------- drivers/iio/dac/ad3552r.h | 190 +++++++++++++++++++++++++ 4 files changed, 390 insertions(+), 268 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..624f3f97cdea --- /dev/null +++ b/drivers/iio/dac/ad3552r-common.c @@ -0,0 +1,173 @@ +// 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" + +const s32 ad3552r_ch_ranges[AD3552R_MAX_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 } +}; +EXPORT_SYMBOL(ad3552r_ch_ranges); + +const s32 ad3542r_ch_ranges[AD3542R_MAX_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 } +}; +EXPORT_SYMBOL(ad3542r_ch_ranges); + +u16 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); + + return reg; +} + +int ad3552r_get_ref_voltage(struct device *dev) +{ + int voltage; + int 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")) + return AD3552R_INTERNAL_VREF_PIN_2P5V; + else + return AD3552R_INTERNAL_VREF_PIN_FLOATING; + } + + if (voltage > 2500000 + delta || voltage < 2500000 - delta) { + dev_warn(dev, "vref-supply must be 2.5V"); + return -EINVAL; + } + + return AD3552R_EXTERNAL_VREF_PIN_INPUT; +} + +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) + return err; + + if (*val > 3) { + dev_err(dev, + "adi,sdo-drive-strength must be less than 4\n"); + return -EINVAL; + } + + return 0; +} + +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 mandatory\n"); + *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]; + + /* This property is optional, so returning -ENOENT if missing */ + 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 c27706c5ba10..173282e5e1a1 100644 --- a/drivers/iio/dac/ad3552r.c +++ b/drivers/iio/dac/ad3552r.c @@ -11,185 +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, -}; - -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} -}; - -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}, - [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} -}; +#include "ad3552r.h" enum ad3552r_ch_gain_scaling { /* Gain scaling of 1 */ @@ -693,75 +517,35 @@ 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; - - 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 |= 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; + u16 reg; - err = fwnode_property_read_u32(gain_child, "adi,gain-offset", &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-offset property missing\n"); - dac->ch_data[ch].gain_offset = val; + return err; - offset = abs((s32)val); - reg |= FIELD_PREP(AD3552R_MASK_CH_OFFSET_BIT_8, (offset >> 8)); + dac->ch_data[ch].range_override = 1; - 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"); + reg = ad3552r_calc_custom_gain(dac->ch_data[ch].p, dac->ch_data[ch].n, + dac->ch_data[ch].gain_offset); + err = ad3552r_write_reg(dac, addr, reg); if (err) return dev_err_probe(dev, err, "Error writing register\n"); @@ -772,30 +556,19 @@ 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"); + err = ad3552r_get_ref_voltage(dev); + if (err < 0) + return err; - 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; - } + val = err; err = ad3552r_update_reg_field(dac, AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, @@ -804,13 +577,8 @@ 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) { - 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, @@ -835,21 +603,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..b1caa3c3e807 --- /dev/null +++ b/drivers/iio/dac/ad3552r.h @@ -0,0 +1,190 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * AD3552R Digital <-> Analog converters common header + * + * Copyright 2021-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_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_MAX_RANGES 5 +#define AD3542R_MAX_RANGES 6 + +extern const s32 ad3552r_ch_ranges[AD3552R_MAX_RANGES][2]; +extern const s32 ad3542r_ch_ranges[AD3542R_MAX_RANGES][2]; + +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); +u16 ad3552r_calc_custom_gain(u8 p, u8 n, s16 goffs); +int ad3552r_get_ref_voltage(struct device *dev); +int ad3552r_get_drive_strength(struct device *dev, u32 *val); + +#endif /* __DRIVERS_IIO_DAC_AD3552R_H__ */ From patchwork Thu Sep 19 09:20:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13807575 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (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 3C49619D886 for ; Thu, 19 Sep 2024 09:21:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737712; cv=none; b=GuLyCcS9Pxi8Lm9q1M06o8lVPBGlCueXL6OfDUI93X4BfAYpSQE2HM73lTjblnWsLVukEjMknVmrtL15666A2nFQV0QJdaDQYiiQ2UsAoEaPeNFnFQpm6VrAeY0WkzsUu29Q1dou2uFxkJL8QYo4NmTwo43Yr7hG6AGUDZGvsvI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737712; c=relaxed/simple; bh=dxIuSgsLljoogbghKvOdfLgQnWZp85dbsjJTAeiDw00=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=J3DS3FR0m7mqasOTuwmJrZGBWZZtr6DFCBOgoKlxWWCRjzqhuh8M/NAdYuo1JLin/heOYmIOliqlSkiBIOFaCwqONpomXLPTkHqd4WFanfhlbU2F8f7MKot1Lz9zG1POVuvl5y5lbssY1dXUFzvhX9lxLdhcdtiMV37GtBrmcms= 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=ez5Zdso8; arc=none smtp.client-ip=209.85.128.44 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="ez5Zdso8" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-42cde6b5094so4828115e9.3 for ; Thu, 19 Sep 2024 02:21:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1726737707; x=1727342507; 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=ENiS9ar8wrYoh8gKiE5vvZpqfPrqs1+FYPNEzNP0wSM=; b=ez5Zdso8aQCBskaujm/rgztdZJjjlDCVgB7eZ9vxFPHkngr8GYQqS8X1wX2Tkw9qSe sZdYKwqd2MD3O11hcIUMTo2AQ8qds+vHh9DvAHXb9sf7YNwSsArS2g7j2okfCtvfUQ0y 3BGTSjNPpX6LalVjPc2sdFm+71EIQpDeDUo4jeC8vLvmNP0a21KEttZot1CJut5O8WB3 8MC70ZX+AjtII4098xmHassJUahOAb5t8o6SiaAcaQVYytvurFY7c0XhNgXKRiQHJgf4 ZrdyQaV3LldMBCV+1/qP82chayT1YQBPfKX3fjhX5j/h1WwPvdoVV7L1rFoItdq5MSxU 7KUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726737707; x=1727342507; 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=ENiS9ar8wrYoh8gKiE5vvZpqfPrqs1+FYPNEzNP0wSM=; b=LQsxS9jOYN9sg1EZFpm1sm40W3HWhVnCjhLEzSZ8ci+HvxjerpmZxoJnCWG7keZ3/7 ZVbn0j4iTXHhnicMAMvR4OKrytOgSmhmkTEBXuCNbJ4wSlpB+NKblvKJJT7Ve7gbk3w/ TAkouYU4DoIWnxWWwH7rk2GD+4ZWpXd4QD8nZxyksGlF7ZLwnrOBDOXl4u2IfEMscUJX wzs7BNUPDr9+Qk/GELPRDIlbg8srwQb/axid9GEIq34KeLLBVE0ICNUk6gxae6PglIcG RDjkUDZbNlJ+68VhO2XztUZEx1oUcIoqVrRqpjidCiKF2fJIN8BkYy2NzxnKxoy1KRzV G1lg== X-Gm-Message-State: AOJu0YxJAO3kFuunml9IgZVrWh3KE9hsNL3zEYyEGL3bryJCeK4LXWaN mP1fvi6+m/pY/NVyL2Ict/fERSVKgb84faGJ/L/zOo8HPz0n/qz74U1ZC+8jMm0= X-Google-Smtp-Source: AGHT+IEec+xCrXFc4VYZ9eKpkFZm4VIatYJ6VSPDZ/dlXU0kfHZibngMFxhWwRl47n5tAWxI0/2DLA== X-Received: by 2002:a05:600c:3581:b0:42c:ae30:fc4d with SMTP id 5b1f17b1804b1-42cdb53190emr207000815e9.7.1726737707341; Thu, 19 Sep 2024 02:21:47 -0700 (PDT) Received: from [127.0.1.1] (host-80-117-99-70.retail.telecomitalia.it. [80.117.99.70]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75468413sm16889465e9.45.2024.09.19.02.21.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 02:21:46 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 19 Sep 2024 11:20:05 +0200 Subject: [PATCH v3 09/10] 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: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-9-a17b9b3d05d9@baylibre.com> References: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> In-Reply-To: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , Nuno Sa , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, dlechner@baylibre.com, 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 --- drivers/iio/dac/Kconfig | 11 + drivers/iio/dac/Makefile | 1 + drivers/iio/dac/ad3552r-axi.c | 567 ++++++++++++++++++++++++++++++ drivers/iio/dac/ad3552r.h | 9 + include/linux/platform_data/ad3552r-axi.h | 18 + 5 files changed, 606 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..85c594e149fa --- /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 + +#include "ad3552r.h" + +#define AD3552R_QSPI_LANES 4 + +struct ad3552r_axi_model_data { + const char *model_name; + enum ad3552r_id chip_id; + unsigned int num_hw_channels; + unsigned int sample_storage_bits; +}; + +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; + struct ad3552r_axi_platform_data *data; + bool ddr_mode; + bool synchronouos_mode; +}; + +static int ad3552r_qspi_update_reg_bits(struct ad3552r_axi_state *st, + u32 reg, u32 mask, u32 val, + size_t xfer_size) +{ + u32 rval; + int err; + + err = st->data->bus_reg_read(st->back, reg, &rval, xfer_size); + if (err) + return err; + + rval &= ~mask; + rval |= val; + + return st->data->bus_reg_write(st->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 ch = chan->channel; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: { + int sclk; + + ret = iio_backend_read_raw(st->back, chan, &sclk, 0, + IIO_CHAN_INFO_FREQUENCY); + if (ret != IIO_VAL_INT) + return -EINVAL; + + /* Using 4 lanes (QSPI) */ + *val = DIV_ROUND_CLOSEST(sclk * AD3552R_QSPI_LANES * + (1 + st->ddr_mode), + chan->scan_type.storagebits); + + return IIO_VAL_INT; + } + case IIO_CHAN_INFO_RAW: + ret = st->data->bus_reg_read(st->back, + AD3552R_REG_ADDR_CH_DAC_16B(ch), + val, 2); + if (ret) + return ret; + + 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) +{ + struct ad3552r_axi_state *st = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + iio_device_claim_direct_scoped(return -EBUSY, indio_dev) { + int ch = chan->channel; + + return st->data->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 = ad3552r_qspi_update_reg_bits(st, + 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) { + dev_warn(st->dev, "could not set DDR mode, not streaming"); + goto exit_err; + } + + st->ddr_mode = true; + + 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: + err = -EINVAL; + goto exit_err_ddr; + } + + err = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_STREAM_MODE, + loop_len, 1); + if (err) + goto exit_err_ddr; + + err = iio_backend_data_transfer_addr(st->back, val); + if (err) + goto exit_err_ddr; + + /* + * 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_SYNC (ext synch ability) is enabled anyway. + */ + if (st->synchronouos_mode) + err = iio_backend_ext_sync_enable(st->back); + else + err = iio_backend_ext_sync_disable(st->back); + if (err) + goto exit_err_ddr; + + 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_ddr: + iio_backend_ddr_disable(st->back); + +exit_err: + ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SPI_CONFIG_DDR, + 0, 1); + + iio_backend_ddr_disable(st->back); + + st->ddr_mode = false; + + 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; + + if (st->synchronouos_mode) { + err = iio_backend_ext_sync_disable(st->back); + if (err) + return err; + } + + /* Inform DAC to set in SDR mode */ + err = ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SPI_CONFIG_DDR, + 0, 1); + if (err) + return err; + + err = iio_backend_ddr_disable(st->back); + if (err) + return err; + + st->ddr_mode = false; + + return 0; +} + +static int ad3552r_axi_set_output_range(struct ad3552r_axi_state *st, + unsigned int mode) +{ + return ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_CH0_CH1_OUTPUT_RANGE, + AD3552R_MASK_CH_OUTPUT_RANGE, + FIELD_PREP(AD3552R_MASK_CH0_RANGE, mode) | + FIELD_PREP(AD3552R_MASK_CH1_RANGE, mode), + 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) { + fsleep(10); + gpiod_set_value_cansleep(st->reset_gpio, 1); + } else { + err = ad3552r_qspi_update_reg_bits(st, + 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_scratch_pad_test(struct ad3552r_axi_state *st) +{ + int err, val; + + err = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + AD3552R_SCRATCH_PAD_TEST_VAL1, 1); + if (err) + return err; + + err = st->data->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 = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_SCRATCH_PAD, + AD3552R_SCRATCH_PAD_TEST_VAL2, 1); + if (err) + return err; + + err = st->data->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; + } + + return 0; +} + +static int ad3552r_axi_setup_custom_gain(struct ad3552r_axi_state *st, + u16 gain, u16 offset) +{ + int err; + + err = st->data->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 = st->data->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 = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_CH_GAIN(0), + gain, 1); + if (err) + return dev_err_probe(st->dev, err, "Error writing register\n"); + + err = st->data->bus_reg_write(st->back, AD3552R_REG_ADDR_CH_GAIN(1), + gain, 1); + if (err) + return dev_err_probe(st->dev, err, "Error writing register\n"); + + 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 gain = 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 = ad3552r_axi_scratch_pad_test(st); + if (err) + return err; + + err = st->data->bus_reg_read(st->back, AD3552R_REG_ADDR_PRODUCT_ID_L, + &val, 1); + if (err) + return err; + + id = val; + + err = st->data->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_info(st->dev, "Chip ID error. Expected 0x%x, Read 0x%x\n", + AD3552R_ID, id); + + err = st->data->bus_reg_write(st->back, + AD3552R_REG_ADDR_SH_REFERENCE_CONFIG, + 0, 1); + if (err) + return err; + + err = st->data->bus_reg_write(st->back, + AD3552R_REG_ADDR_TRANSFER_REGISTER, + AD3552R_MASK_QUAD_SPI | + AD3552R_MASK_STREAM_LENGTH_KEEP_VALUE, 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); + if (err < 0) + return err; + + val = err; + + err = ad3552r_qspi_update_reg_bits(st, + 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 = ad3552r_qspi_update_reg_bits(st, + AD3552R_REG_ADDR_INTERFACE_CONFIG_D, + AD3552R_MASK_SDO_DRIVE_STRENGTH, + val, 1); + if (err) + return err; + } + + st->synchronouos_mode = + fwnode_property_read_bool(dev_fwnode(st->dev), + "adi,synchronous-mode"); + + child = device_get_named_child_node(st->dev, "channel"); + if (!child) + return -EINVAL; + + /* + * One of "adi,output-range-microvolt" or "custom-output-range-config" + * must be available in fdt. + */ + 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; + + err = ad3552r_get_custom_gain(st->dev, child, &gs_p, &gs_n, &rfb, + &goffs); + if (err) + return err; + + gain = ad3552r_calc_custom_gain(gs_p, gs_n, goffs); + offset = abs((s32)goffs); + + return ad3552r_axi_setup_custom_gain(st, gain, offset); +} + +static const struct iio_buffer_setup_ops ad3552r_axi_buffer_setup_ops = { + .postenable = ad3552r_axi_buffer_postenable, + .predisable = ad3552r_axi_buffer_predisable, +}; + +#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, \ + } \ +} + +static const 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->data = pdev->dev.platform_data; + if (!st->data) { + dev_err(&pdev->dev, "no platform data!\n"); + return -ENODEV; + } + + 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"); diff --git a/drivers/iio/dac/ad3552r.h b/drivers/iio/dac/ad3552r.h index b1caa3c3e807..02805eec69a5 100644 --- a/drivers/iio/dac/ad3552r.h +++ b/drivers/iio/dac/ad3552r.h @@ -38,6 +38,8 @@ #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)) @@ -129,6 +131,13 @@ #define AD3552R_GAIN_SCALE 1000 #define AD3552R_LDAC_PULSE_US 100 +#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_MAX_RANGES 5 #define AD3542R_MAX_RANGES 6 diff --git a/include/linux/platform_data/ad3552r-axi.h b/include/linux/platform_data/ad3552r-axi.h new file mode 100644 index 000000000000..7c0db307102c --- /dev/null +++ b/include/linux/platform_data/ad3552r-axi.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2010-2024 Analog Devices Inc. + * Copyright (c) 2024 Baylibre, SAS + */ +#ifndef __LINUX_PLATFORM_DATA_AD3552R_AXI_H__ +#define __LINUX_PLATFORM_DATA_AD3552R_AXI_H__ + +#include + +struct ad3552r_axi_platform_data { + 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); +}; + +#endif /* __LINUX_PLATFORM_DATA_AD3552R_AXI_H__ */ From patchwork Thu Sep 19 09:20:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Angelo Dureghello X-Patchwork-Id: 13807576 Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 93CB019D89E for ; Thu, 19 Sep 2024 09:21:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737712; cv=none; b=hQwqJDhxYYQfcuTVBUTv4YiDaWmeRzyUcRmR78gFf0RGF2l8QoujR7OgVXdFR9HL7hNTdWFvLyrFfO73glzPpdxQTruB3+cgBvAS8m8cED/CYLa/AUy/6aOVRUWWASY2Lf9mEtQUxFYuez/ftI/IAfovlGZNn/lxOt6LltJW0E8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726737712; c=relaxed/simple; bh=wTh4ZX/Lq4bxELrDl4dLXCSoDZv2J7fQ9IPUziM5on0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CqYyJdfhXnnSE8FRDI4m57A+iCKJZYtDRdefmG51LCjrbTfmdVR2JliDPsIYJurEj7XmBR/uNe11D95cbi9nlcySZwRLS3em4axs0eV2uo4upYNsTEq8f6x9BXAvRD6xUbbu6+kZy6RyIDBj0Y2N1jE0ooARFKWDgyg/NjbTBaA= 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=XuGsU8RH; arc=none smtp.client-ip=209.85.221.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="XuGsU8RH" Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-3770320574aso345497f8f.2 for ; Thu, 19 Sep 2024 02:21:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1726737709; x=1727342509; 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=oDBUjP1+gjd3K5h0oG5X/MTM074M3dAHmKYG+rdovVU=; b=XuGsU8RHmZy85fUTRkuCspmKvGIghq1qVeejrjM5BC4zp/UPiApGrjew28m1eZ7EjD kTS2r8UFnp2EBLgI5mfJP6AnFJrBBR+SSKSa6ihTMmTHkzF+U615OeIoBgMekxvv057g IDEGokjSMP331HwUGqjkXyzYK7XH2r3rb3Ngn3UVtISm04VIZnJpBh9hu0pGFeZxYXUp sdpOu+XT40mSjjL5L8kMPX7s4+s6U/6/M9Ymf0ACHza9Y2vah1EbnHDi6+S/J1UqzpeO X9ktsZhdlWCPd8YoH3vu5x94OiHKAznpSN+0zEQjgPw1kUf+3fEx6g5jYBfvNP0cHhx1 PcJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726737709; x=1727342509; 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=oDBUjP1+gjd3K5h0oG5X/MTM074M3dAHmKYG+rdovVU=; b=ryspcfiwSnDzuVn8aFeg4NOMD0IpvucWe6J8S6vHqtZ+fkUVH7u90tPbBleNW5owHY p9sizgEI7ZkMvDlaYM3957N8tgxIEX4+FtBtADFyMXgpDNPL6uihInxWZ3HBFAnzw1/w nKrIXO50IUGmysJdqcJ2UP5sNpzMMN8F0ynFnJ5qRVdCRg9hziOg9Da3eJ/g1HymWM3q xay1mGxRMx3MJPYeivbbnlJMt8hTf3m+aGQktJS6/Yl7YqVGU0ZUJ6vE0EUCODcpdJBj USEDcTgQ8aZSfA2+CkpvLY1M0RUOOTykxCQI8VtqP2S93ysI+RwHZT4Rmq7pDdWwaOrI X7wg== X-Gm-Message-State: AOJu0YwRv4yl2P0innlblnmVwRLmH8dWMX+8qa10kQCKyRmRcT8qMCKb +cQtf+WRPdbQGivsAkV1Z0PfJisJnAtLDmj7PqQQ96W2PagsBHfpcloKphUMlM0= X-Google-Smtp-Source: AGHT+IHxdr7iojwOBs/10Ra5p+6qT9Z1ZPpg9lcLP/NKiiCl3mLdNMdiNRDGvTctoAV4LaU/+V/Xag== X-Received: by 2002:a5d:4ec4:0:b0:374:c10c:83b3 with SMTP id ffacd0b85a97d-378c2d624a2mr13291883f8f.54.1726737708814; Thu, 19 Sep 2024 02:21:48 -0700 (PDT) Received: from [127.0.1.1] (host-80-117-99-70.retail.telecomitalia.it. [80.117.99.70]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42e75468413sm16889465e9.45.2024.09.19.02.21.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 02:21:48 -0700 (PDT) From: Angelo Dureghello X-Google-Original-From: Angelo Dureghello Date: Thu, 19 Sep 2024 11:20:06 +0200 Subject: [PATCH v3 10/10] 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: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-10-a17b9b3d05d9@baylibre.com> References: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> In-Reply-To: <20240919-wip-bl-ad3552r-axi-v0-iio-testing-v3-0-a17b9b3d05d9@baylibre.com> To: Lars-Peter Clausen , Michael Hennerich , Nuno Sa , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Olivier Moysan Cc: linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, dlechner@baylibre.com, 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. The DAC device is defined as a child node of the backend. Registering the child fdt node as a platform devices. Signed-off-by: Angelo Dureghello --- drivers/iio/dac/adi-axi-dac.c | 52 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c index 3ca3a14c575b..2afc1442cd5a 100644 --- a/drivers/iio/dac/adi-axi-dac.c +++ b/drivers/iio/dac/adi-axi-dac.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -109,6 +110,8 @@ struct axi_dac_info { struct axi_dac_state { struct regmap *regmap; struct device *dev; + /* Target DAC platform device */ + struct platform_device *dac_pdev; /* * lock to protect multiple accesses to the device registers and global * data/variables. @@ -757,6 +760,32 @@ static int axi_dac_bus_reg_read(struct iio_backend *back, u32 reg, } } +static int axi_dac_create_platform_device(struct axi_dac_state *st, + struct fwnode_handle *child) +{ + struct ad3552r_axi_platform_data pdata = { + .bus_reg_read = axi_dac_bus_reg_read, + .bus_reg_write = axi_dac_bus_reg_write, + }; + struct platform_device_info pi = { + .parent = st->dev, + .name = fwnode_get_name(child), + .id = PLATFORM_DEVID_AUTO, + .fwnode = child, + .data = &pdata, + .size_data = sizeof(pdata), + }; + struct platform_device *pdev; + + pdev = platform_device_register_full(&pi); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + st->dac_pdev = pdev; + + return 0; +} + static const struct iio_backend_ops axi_dac_generic_ops = { .enable = axi_dac_enable, .disable = axi_dac_disable, @@ -791,13 +820,22 @@ static const struct regmap_config axi_dac_regmap_config = { .max_register = 0x0800, }; +static void axi_dac_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct axi_dac_state *st = dev_get_drvdata(dev); + + if (st->dac_pdev) + platform_device_unregister(st->dac_pdev); +} + static int axi_dac_probe(struct platform_device *pdev) { struct axi_dac_state *st; void __iomem *base; unsigned int ver; struct clk *clk; - int ret; + int ret, val; st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL); if (!st) @@ -871,6 +909,17 @@ 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) { + /* Processing only reg 0 node */ + ret = fwnode_property_read_u32(child, "reg", &val); + if (ret || val != 0) + continue; + + ret = axi_dac_create_platform_device(st, child); + if (ret) + continue; + } + 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), @@ -901,6 +950,7 @@ static struct platform_driver axi_dac_driver = { .of_match_table = axi_dac_of_match, }, .probe = axi_dac_probe, + .remove = axi_dac_remove, }; module_platform_driver(axi_dac_driver);