From patchwork Fri May 31 19:42:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dumitru Ceclan via B4 Relay X-Patchwork-Id: 13682056 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80111179654; Fri, 31 May 2024 19:42:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184571; cv=none; b=KP/MVPTRlJvFC0GSC67HnBY10adwmvC+ZqXPG69aP8/NLvT9+XSwfVpWEugkhVu8vAwd/jH7Zck9vKG1zFrb9ay15CpFuH8O29Qs7E82iCJig4mnAPw5XgjONPzS0ZE4VwcgmxxRcFUhUZIVoOefuWSgVoS7d889tfSeCUUmDOs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184571; c=relaxed/simple; bh=iGaZp8H3G4+QX/RI/q+767NxJulbdkdzJpWxohTv6YI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HbTvgLwfk27sLKu591L2GDvkI9p090gWU/njCWPJh3s+Dq4DowY2HoFyOkpRXk5wks8OIxX6G2kGt4gjFSq1AXc56/hHHxFSmGdoigEXJ9eMxSxNehv0/hyBFRlCzBbHg63LdRTDAfFH0tgtWpaKz1jxaHVwu5YoYC+LdtgYA0w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=D3h/IR6H; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="D3h/IR6H" Received: by smtp.kernel.org (Postfix) with ESMTPS id 27E80C32789; Fri, 31 May 2024 19:42:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717184571; bh=iGaZp8H3G4+QX/RI/q+767NxJulbdkdzJpWxohTv6YI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=D3h/IR6HuYKdmFxbvwXBBRhEbDowhv9erwKELzeccUbmiwZ846sFDO1vD2j3M6C+f gk7ngOvOHrlHM6Zef7BXQyb0/KhugLnDPOLjl46WcVySa87FKSKanxB+cuW6BWHutk xVknFt6CM39ooioevqi6apwBGzex93L/koUf9MlD4K0U0llZDH+7RwzQF+AbpVnLUR n1NEaujExo9JQA4Xuooy8FiVNpP9Aj6g64pAmZRBY5IwU1APKOYFQUSbguY8g3KMKb okambjdTYtDvJYT5CqyFajKkYs5FK+041iSJAGgK4L6tdEh4lLgCLrfkkHyJ7rHwAW nfrFKRe7oOxQw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11F5CC27C4F; Fri, 31 May 2024 19:42:51 +0000 (UTC) From: Dumitru Ceclan via B4 Relay Date: Fri, 31 May 2024 22:42:27 +0300 Subject: [PATCH v4 1/6] dt-bindings: adc: ad7173: add support for ad411x Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240531-ad4111-v4-1-64607301c057@analog.com> References: <20240531-ad4111-v4-0-64607301c057@analog.com> In-Reply-To: <20240531-ad4111-v4-0-64607301c057@analog.com> To: Ceclan Dumitru Cc: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , David Lechner , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Dumitru Ceclan X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717184569; l=8710; i=dumitru.ceclan@analog.com; s=20240313; h=from:subject:message-id; bh=PM7BwdJbpQwyM+2GI7zCVGR1f3pC7c+bSTpc05Tuc/w=; b=AFBu9RsoKmBp4kpQQz3r2cV0PDeTCGhrpuulZ2AgYboM4za+gI7KAt3sWFq/nBQS5ehFU2m7k 7gSKaQ+dr9QDZYryaq5V6Srp5Lsb0y0K3/QwgTgMcXyxUOvVG5KklZk X-Developer-Key: i=dumitru.ceclan@analog.com; a=ed25519; pk=HdqMlVyrcazwoiai7oN6ghU+Bj1pusGUFRl30jhS7Bo= X-Endpoint-Received: by B4 Relay for dumitru.ceclan@analog.com/20240313 with auth_id=140 X-Original-From: Dumitru Ceclan Reply-To: dumitru.ceclan@analog.com From: Dumitru Ceclan Add support for: AD4111, AD4112, AD4114, AD4115, AD4116. AD411x family ADCs support a VCOM pin. The purpose of this pin is to offer a dedicated common-mode voltage input for single-ended channels. This pin is specified as supporting a differential channel with VIN10 on model AD4116. AD4111/AD4112 support current channels. Support is implemented using single-channel and "adi,current-channel". Signed-off-by: Dumitru Ceclan --- .../devicetree/bindings/iio/adc/adi,ad7173.yaml | 192 ++++++++++++++++++++- 1 file changed, 190 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7173.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7173.yaml index ea6cfcd0aff4..d8474eee553e 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7173.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7173.yaml @@ -19,7 +19,18 @@ description: | primarily for measurement of signals close to DC but also delivers outstanding performance with input bandwidths out to ~10kHz. + Analog Devices AD411x ADC's: + The AD411X family encompasses a series of low power, low noise, 24-bit, + sigma-delta analog-to-digital converters that offer a versatile range of + specifications. They integrate an analog front end suitable for processing + fully differential/single-ended and bipolar voltage inputs. + Datasheets for supported chips: + https://www.analog.com/media/en/technical-documentation/data-sheets/AD4111.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/AD4112.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/AD4114.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/AD4115.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/AD4116.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD7172-2.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD7172-4.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD7173-8.pdf @@ -31,6 +42,11 @@ description: | properties: compatible: enum: + - adi,ad4111 + - adi,ad4112 + - adi,ad4114 + - adi,ad4115 + - adi,ad4116 - adi,ad7172-2 - adi,ad7172-4 - adi,ad7173-8 @@ -129,10 +145,54 @@ patternProperties: maximum: 15 diff-channels: + description: | + This property is used for defining the inputs of a differential + voltage channel. The first value is the positive input and the second + value is the negative input of the channel. + + Family AD411x supports a dedicated VINCOM voltage input. + To select it set the second channel to 16. + (VIN2, VINCOM) -> diff-channels = <2 16> + + There are special values that can be selected besides the voltage + analog inputs: + 21: REF+ + 22: REF− + Supported only by AD7172-2, AD7172-4, AD7175-2, AD7175-8, AD7177-2: + 19: ((AVDD1 − AVSS)/5)+ + 20: ((AVDD1 − AVSS)/5)− + items: minimum: 0 maximum: 31 + single-channel: + description: | + This property is used for defining a current channel or the positive + input of a voltage channel (single-ended or pseudo-differential). + + Models AD4111 and AD4112 support current channels. + Example: (IIN2+, IIN2−) -> single-channel = <2> + To correctly configure a current channel set the "adi,current-channel" + property to true. + + To configure a single-ended/pseudo-differential channel set the + "adi,common-mode-channel" property to the desired negative voltage input. + + When used as a voltage channel, special inputs are valid as well. + minimum: 0 + maximum: 31 + + adi,common-mode-channel: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + This property is used for defining the negative input of a + single-ended or pseudo-differential voltage channel. + + Special inputs are valid as well. + minimum: 0 + maximum: 31 + adi,reference-select: description: | Select the reference source to use when converting on @@ -154,9 +214,31 @@ patternProperties: - avdd default: refout-avss + adi,current-channel: + description: | + Signal that the selected inputs are current channels. + Only available on AD4111 and AD4112. + type: boolean + required: - reg - - diff-channels + + allOf: + - oneOf: + - required: [single-channel] + properties: + diff-channels: false + - required: [diff-channels] + properties: + single-channel: false + adi,current-channel: false + adi,common-mode-channel: false + + - if: + required: ["adi,common-mode-channel"] + then: + properties: + adi,current-channel: false required: - compatible @@ -166,7 +248,6 @@ allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# # Only ad7172-4, ad7173-8 and ad7175-8 support vref2 - # Other models have [0-3] channel registers - if: properties: compatible: @@ -187,6 +268,37 @@ allOf: - vref - refout-avss - avdd + + - if: + properties: + compatible: + contains: + enum: + - adi,ad4114 + - adi,ad4115 + - adi,ad4116 + - adi,ad7173-8 + - adi,ad7175-8 + then: + patternProperties: + "^channel@[0-9a-f]$": + properties: + reg: + maximum: 15 + + - if: + properties: + compatible: + contains: + enum: + - adi,ad7172-2 + - adi,ad7175-2 + - adi,ad7176-2 + - adi,ad7177-2 + then: + patternProperties: + "^channel@[0-9a-f]$": + properties: reg: maximum: 3 @@ -210,6 +322,34 @@ allOf: required: - adi,reference-select + - if: + properties: + compatible: + contains: + enum: + - adi,ad4111 + - adi,ad4112 + - adi,ad4114 + - adi,ad4115 + - adi,ad4116 + then: + properties: + avdd2-supply: false + + - if: + properties: + compatible: + not: + contains: + enum: + - adi,ad4111 + - adi,ad4112 + then: + patternProperties: + "^channel@[0-9a-f]$": + properties: + adi,current-channel: false + - if: anyOf: - required: [clock-names] @@ -221,6 +361,7 @@ allOf: unevaluatedProperties: false examples: + # Example AD7173-8 with external reference connected to REF+/REF-: - | #include #include @@ -277,3 +418,50 @@ examples: }; }; }; + + # Example AD4111 with current channel and single-ended channel: + - | + #include + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad4111"; + reg = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + interrupts = <25 IRQ_TYPE_EDGE_FALLING>; + interrupt-names = "rdy"; + interrupt-parent = <&gpio>; + spi-max-frequency = <5000000>; + gpio-controller; + #gpio-cells = <2>; + #clock-cells = <0>; + + channel@0 { + reg = <0>; + bipolar; + diff-channels = <4 5>; + }; + + // Single ended channel VIN2/VINCOM + channel@1 { + reg = <1>; + bipolar; + single-channel = <2>; + adi,common-mode-channel = <16>; + }; + + // Current channel IN2+/IN2- + channel@2 { + reg = <2>; + single-channel = <2>; + adi,current-channel; + }; + }; + }; From patchwork Fri May 31 19:42:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dumitru Ceclan via B4 Relay X-Patchwork-Id: 13682057 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 96BAD17C223; Fri, 31 May 2024 19:42:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184571; cv=none; b=tRmi+FxPNbkS2fzs8cEwW+fyL4C4HpFlPx81S5QHKwOIV4/GtZQNrtfAbbqAXzRjJmedVHbUuGSZk70nzqcPaaKDPjbznU8MFbcp8GoQpYklzX8KGUGc7FpwF0uFvRZIfnyhU1VlnEgqQfTI70+NuKCDQ7tBXrEJNImo07D0gok= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184571; c=relaxed/simple; bh=sLlNh5KM9caSYG90x2iutDPvdP6uUJqRbn814aBoYIk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dcUFBx6ujXUe6hCJKTFudoR6GvRzsltxcjgY4G6z51sZ8kW8mk4NosoztE2GREq5PlQafYq5m/1FeLVTmiJ8UqnRJWrYvj8nKyNSKbt5WEXzhV49ksCxWDKq1VIbG9uFZARBc9glleH4qE8UrVOu8IU3esqSsaEaC/jdUMGXtTk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mhzkntFP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mhzkntFP" Received: by smtp.kernel.org (Postfix) with ESMTPS id 3C246C4AF0B; Fri, 31 May 2024 19:42:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717184571; bh=sLlNh5KM9caSYG90x2iutDPvdP6uUJqRbn814aBoYIk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=mhzkntFP1mcEZ1D0J+hIEC2PpjFdQrYvZozm33tPdlxZrQNTjD+rZPCj+XNy+0XwA jlmbQqwbNmYCk62FvvPP17sUPaFIwKm3AnA1WAwqZ2UJo/MWGa5wsQZgYR4vItjfiU S7lXZKc8lJJhzJQiXY3EM5Rw0JLnXccOCy7k0lkS5kbrMVuPXMaaMFrDUGA7w8JgoK rGgxExlfkkbSWNvB9inTIDNFhivYdAl6hJI2bJgbxlWXQTv/AHWbaaIH69FZI8YRs4 0Ep6FCasPZI8/eCIj1ohPJP4a9aBt2vJ2SlD1+yCVY/+k9BFH52uZ7zpZW/KsWB771 bUn7etG72ddvA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F891C25B7C; Fri, 31 May 2024 19:42:51 +0000 (UTC) From: Dumitru Ceclan via B4 Relay Date: Fri, 31 May 2024 22:42:28 +0300 Subject: [PATCH v4 2/6] iio: adc: ad7173: refactor channel configuration parsing Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240531-ad4111-v4-2-64607301c057@analog.com> References: <20240531-ad4111-v4-0-64607301c057@analog.com> In-Reply-To: <20240531-ad4111-v4-0-64607301c057@analog.com> To: Ceclan Dumitru Cc: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , David Lechner , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Dumitru Ceclan , Jonathan Cameron , Nuno Sa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717184569; l=2390; i=dumitru.ceclan@analog.com; s=20240313; h=from:subject:message-id; bh=tyfIBjq9+3kqvLQ3iYrfTDEdse1O9TimBWVFOmM0qog=; b=DTeTcfTX5k8OZQ8f3AaMWc5IifhiebXkxIwsMzcSHA4ddZchb5XI0DLAlSwkAD0LyjeiBUbfj 5Ly49LIRkrEAqDUjwvn2wCJDyP4Oaa9F82xwpoWLSIo09YbRUT66myh X-Developer-Key: i=dumitru.ceclan@analog.com; a=ed25519; pk=HdqMlVyrcazwoiai7oN6ghU+Bj1pusGUFRl30jhS7Bo= X-Endpoint-Received: by B4 Relay for dumitru.ceclan@analog.com/20240313 with auth_id=140 X-Original-From: Dumitru Ceclan Reply-To: dumitru.ceclan@analog.com From: Dumitru Ceclan Move configurations regarding number of channels from *_fw_parse_device_config to *_fw_parse_channel_config. Suggested-by: Jonathan Cameron Link: https://lore.kernel.org/all/20240303162148.3ad91aa2@jic23-huawei/ Reviewed-by: David Lechner Reviewed-by: Nuno Sa Signed-off-by: Dumitru Ceclan --- drivers/iio/adc/ad7173.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c index 638e2468efbf..6e249628bc64 100644 --- a/drivers/iio/adc/ad7173.c +++ b/drivers/iio/adc/ad7173.c @@ -912,7 +912,23 @@ static int ad7173_fw_parse_channel_config(struct iio_dev *indio_dev) struct device *dev = indio_dev->dev.parent; struct iio_chan_spec *chan_arr, *chan; unsigned int ain[2], chan_index = 0; - int ref_sel, ret; + int ref_sel, ret, num_channels; + + num_channels = device_get_child_node_count(dev); + + if (st->info->has_temp) + num_channels++; + + if (num_channels == 0) + return dev_err_probe(dev, -ENODATA, "No channels specified\n"); + + if (num_channels > st->info->num_channels) + return dev_err_probe(dev, -EINVAL, + "Too many channels specified. Maximum is %d, not including temperature channel if supported.\n", + st->info->num_channels); + + indio_dev->num_channels = num_channels; + st->num_channels = num_channels; chan_arr = devm_kcalloc(dev, sizeof(*indio_dev->channels), st->num_channels, GFP_KERNEL); @@ -1007,7 +1023,6 @@ static int ad7173_fw_parse_device_config(struct iio_dev *indio_dev) { struct ad7173_state *st = iio_priv(indio_dev); struct device *dev = indio_dev->dev.parent; - unsigned int num_channels; int ret; st->regulators[0].supply = ad7173_ref_sel_str[AD7173_SETUP_REF_SEL_EXT_REF]; @@ -1066,16 +1081,6 @@ static int ad7173_fw_parse_device_config(struct iio_dev *indio_dev) ad7173_sigma_delta_info.irq_line = ret; - num_channels = device_get_child_node_count(dev); - - if (st->info->has_temp) - num_channels++; - - if (num_channels == 0) - return dev_err_probe(dev, -ENODATA, "No channels specified\n"); - indio_dev->num_channels = num_channels; - st->num_channels = num_channels; - return ad7173_fw_parse_channel_config(indio_dev); } From patchwork Fri May 31 19:42:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dumitru Ceclan via B4 Relay X-Patchwork-Id: 13682059 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB47517D343; Fri, 31 May 2024 19:42:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184571; cv=none; b=VCgCvY0NauBgo6KgmT9+BfTOqBKZALCOoqnYxDYzDOCsWa3oWvtfPBBiEyo6t2pAaqbT14i1xTl0hV0mJhJCPxSDLgjR6Bmt9EKxvEJoF9MjJqctan7/pMun4Y0r7lu95g6wChQBRLSZuuyvq5u+scPsJXwt8Aw5N8F0Mskr82A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184571; c=relaxed/simple; bh=coty3zmiVkzC0+Ab+NP3vBQIUemt6njlqQD0stWfSn4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PbQGnruLEY/2MwZaEgzRhF+q/bVDwp24uF/rslokQFXMBlVsPMUCg0hrsUCL5TM0e5/o3C4SyM/uNXwBF/WdzFyGoXsK9dNrIrcyqtDqCcsVp6GYzA3LJKy95hYytxLsaMNu1jRv/bH387ChZQCiaN8ZSvQLts25BnWV+JPHQpk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KKHULrhD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KKHULrhD" Received: by smtp.kernel.org (Postfix) with ESMTPS id 5493EC4AF0F; Fri, 31 May 2024 19:42:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717184571; bh=coty3zmiVkzC0+Ab+NP3vBQIUemt6njlqQD0stWfSn4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=KKHULrhD16NlqabMnShbPtVFP9CbnKW1V3nH1+G74/nLcYDpBFPKD+wQFNTAWwiK1 ul8G2wSx9qmQOdFdm8Xn8JECyTN1kXAF/pWXvMWZNFWmoMtsGU91QHzg/peQZ1USVh BQzKiw9Y4yoQIxVMDlMOmICIjpMbUTxNFCceArSO1L+1/kBCjPuSETR8UmhfhkSQs8 dYf0QOb2aiVWEDg3qC1/6jOXHPXVk2TKtPMxIy2tIfBAEb4RY7f3+4ZNwZ9VrCafS7 V+HJkAtXhD1nvqpDmINx0NzQbbP4sqpkqWRTmMRd+0rxDbivklyh/f9suoA32ZGUJS VUQC3pnbY7PjA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4B82DC27C4F; Fri, 31 May 2024 19:42:51 +0000 (UTC) From: Dumitru Ceclan via B4 Relay Date: Fri, 31 May 2024 22:42:29 +0300 Subject: [PATCH v4 3/6] iio: adc: ad7173: refactor ain and vref selection Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240531-ad4111-v4-3-64607301c057@analog.com> References: <20240531-ad4111-v4-0-64607301c057@analog.com> In-Reply-To: <20240531-ad4111-v4-0-64607301c057@analog.com> To: Ceclan Dumitru Cc: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , David Lechner , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Dumitru Ceclan X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717184569; l=4550; i=dumitru.ceclan@analog.com; s=20240313; h=from:subject:message-id; bh=7xTLh9Dt46L6LmGcvJeBdLPREQkljJ0gREj2u5d2Mow=; b=XPE9rYupnMn63Ou1dEHEiVk8PJKUaxKx/OB6jyyZqEwr3OucVpbqQeX9vpSAAXqKcLC9KbSME 5RzBrEZTSkTBlSIUIEs5wYHXykhgdwJDaKluwDf2axqfVqOae6XGpue X-Developer-Key: i=dumitru.ceclan@analog.com; a=ed25519; pk=HdqMlVyrcazwoiai7oN6ghU+Bj1pusGUFRl30jhS7Bo= X-Endpoint-Received: by B4 Relay for dumitru.ceclan@analog.com/20240313 with auth_id=140 X-Original-From: Dumitru Ceclan Reply-To: dumitru.ceclan@analog.com From: Dumitru Ceclan Move validation of analog inputs and reference voltage selection to separate functions to reduce the size of the channel config parsing function and improve readability. Add defines for the number of analog inputs in a channel. Reviewed-by: David Lechner Signed-off-by: Dumitru Ceclan --- drivers/iio/adc/ad7173.c | 71 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c index 6e249628bc64..a20831d99aa5 100644 --- a/drivers/iio/adc/ad7173.c +++ b/drivers/iio/adc/ad7173.c @@ -60,6 +60,7 @@ #define AD7173_CH_SETUP_AINPOS_MASK GENMASK(9, 5) #define AD7173_CH_SETUP_AINNEG_MASK GENMASK(4, 0) +#define AD7173_NO_AINS_PER_CHANNEL 2 #define AD7173_CH_ADDRESS(pos, neg) \ (FIELD_PREP(AD7173_CH_SETUP_AINPOS_MASK, pos) | \ FIELD_PREP(AD7173_CH_SETUP_AINNEG_MASK, neg)) @@ -623,6 +624,7 @@ static int ad7173_setup(struct iio_dev *indio_dev) static unsigned int ad7173_get_ref_voltage_milli(struct ad7173_state *st, u8 reference_select) { + struct device *dev = &st->sd.spi->dev; int vref; switch (reference_select) { @@ -646,9 +648,11 @@ static unsigned int ad7173_get_ref_voltage_milli(struct ad7173_state *st, return -EINVAL; } - if (vref < 0) + if (vref < 0) { + dev_err(dev, "Cannot use reference %u. Error:%d\n", + reference_select, vref); return vref; - + } return vref / (MICRO / MILLI); } @@ -905,13 +909,50 @@ static int ad7173_register_clk_provider(struct iio_dev *indio_dev) &st->int_clk_hw); } +static int ad7173_validate_voltage_ain_inputs(struct ad7173_state *st, + const unsigned int ain[AD7173_NO_AINS_PER_CHANNEL]) +{ + struct device *dev = &st->sd.spi->dev; + + for (int i = 0; i < AD7173_NO_AINS_PER_CHANNEL; i++) { + if (ain[i] < st->info->num_inputs) + continue; + + return dev_err_probe(dev, -EINVAL, + "Input pin number out of range for pair (%d %d).\n", + ain[0], ain[1]); + } + + return 0; +} + +static int ad7173_validate_reference(struct ad7173_state *st, int ref_sel) +{ + struct device *dev = &st->sd.spi->dev; + int ret; + + if (ref_sel == AD7173_SETUP_REF_SEL_INT_REF && !st->info->has_int_ref) + return dev_err_probe(dev, -EINVAL, + "Internal reference is not available on current model.\n"); + + if (ref_sel == AD7173_SETUP_REF_SEL_EXT_REF2 && !st->info->has_ref2) + return dev_err_probe(dev, -EINVAL, + "External reference 2 is not available on current model.\n"); + + ret = ad7173_get_ref_voltage_milli(st, ref_sel); + if (ret < 0) + return ret; + + return 0; +} + static int ad7173_fw_parse_channel_config(struct iio_dev *indio_dev) { struct ad7173_channel *chans_st_arr, *chan_st_priv; struct ad7173_state *st = iio_priv(indio_dev); struct device *dev = indio_dev->dev.parent; struct iio_chan_spec *chan_arr, *chan; - unsigned int ain[2], chan_index = 0; + unsigned int ain[AD7173_NO_AINS_PER_CHANNEL], chan_index = 0; int ref_sel, ret, num_channels; num_channels = device_get_child_node_count(dev); @@ -965,11 +1006,9 @@ static int ad7173_fw_parse_channel_config(struct iio_dev *indio_dev) if (ret) return ret; - if (ain[0] >= st->info->num_inputs || - ain[1] >= st->info->num_inputs) - return dev_err_probe(dev, -EINVAL, - "Input pin number out of range for pair (%d %d).\n", - ain[0], ain[1]); + ret = ad7173_validate_voltage_ain_inputs(st, ain); + if (ret) + return ret; ret = fwnode_property_match_property_string(child, "adi,reference-select", @@ -980,19 +1019,9 @@ static int ad7173_fw_parse_channel_config(struct iio_dev *indio_dev) else ref_sel = ret; - if (ref_sel == AD7173_SETUP_REF_SEL_INT_REF && - !st->info->has_int_ref) - return dev_err_probe(dev, -EINVAL, - "Internal reference is not available on current model.\n"); - - if (ref_sel == AD7173_SETUP_REF_SEL_EXT_REF2 && !st->info->has_ref2) - return dev_err_probe(dev, -EINVAL, - "External reference 2 is not available on current model.\n"); - - ret = ad7173_get_ref_voltage_milli(st, ref_sel); - if (ret < 0) - return dev_err_probe(dev, ret, - "Cannot use reference %u\n", ref_sel); + ret = ad7173_validate_reference(st, ref_sel); + if (ret) + return ret; if (ref_sel == AD7173_SETUP_REF_SEL_INT_REF) st->adc_mode |= AD7173_ADC_MODE_REF_EN; From patchwork Fri May 31 19:42:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dumitru Ceclan via B4 Relay X-Patchwork-Id: 13682060 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BCAF817D354; Fri, 31 May 2024 19:42:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184571; cv=none; b=fkRPbflvfSMnYbKTlDaK+5k6X1jk+ie2c+PoteB40xgVs3zGlUWutQJv2mk8R4FHDo6UcRJ8I5wgOXp10Py4e2X1h46NSubxlEcIaIJPVOzqDLOhzW58nPnALymfkAD4F330VkdWGy9IGyft2adsOJEY/hQWEmusyHgxKcJrt58= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184571; c=relaxed/simple; bh=SPG7Z3QvR5evzT6qu+PUUSOfdaN8wsOF5rzy4+2fzwI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZjSAQqOhWdZg7AA8To4OiaXo1/LcnecGQQySQ2yAtHO+V/jo/cmeyVIJzLevonzbmuBykNOGqD01QwJb9eaYxnJDCRuZFkuyxz3R6BGp3pcb5Bvtd/0v3mxjh/Hh5YQULApSfmS0bheQetawYPBwvcy/0aTa8Izp17198/n9rfk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FSEeah8Z; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FSEeah8Z" Received: by smtp.kernel.org (Postfix) with ESMTPS id 6BB3CC4AF13; Fri, 31 May 2024 19:42:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717184571; bh=SPG7Z3QvR5evzT6qu+PUUSOfdaN8wsOF5rzy4+2fzwI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=FSEeah8ZG4pkcyWFvpV2mAujbQmDCa/SwGtP9K7cFH7zX3DUnHgR16dfHmLWCKcTB 6rBCqnS9FzdHtut6QrvFvDZpMwKLfSnVQEAwBJv4gf15QK5i/0OZCtZWtU6+tZnXx+ dBYa6nE1nXRsM9oc9c9YaUA/5cP04sYgHSRfgyu0N+hBJSaguakhRaXsV+4QntiSHz K060ob1Bjtfp6iDArI/zyXUO0dtdlUd20Pffm+sUldYE+eA5eB/NapaEz0PjRRku9T O/Ya97TcI99RXQnNjb+7mNo00TkoWgR8LUIRa4335wUfbWZU+bqdiXR0s/SLDiUhCT KWQx9yjwa/s4w== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5FEB1C25B75; Fri, 31 May 2024 19:42:51 +0000 (UTC) From: Dumitru Ceclan via B4 Relay Date: Fri, 31 May 2024 22:42:30 +0300 Subject: [PATCH v4 4/6] iio: adc: ad7173: add support for special inputs Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240531-ad4111-v4-4-64607301c057@analog.com> References: <20240531-ad4111-v4-0-64607301c057@analog.com> In-Reply-To: <20240531-ad4111-v4-0-64607301c057@analog.com> To: Ceclan Dumitru Cc: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , David Lechner , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Dumitru Ceclan , Nuno Sa X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717184569; l=3895; i=dumitru.ceclan@analog.com; s=20240313; h=from:subject:message-id; bh=cB8o2kcrbEPNFNzCdWPShKZlvMUHAlRTNWGqJZsx23M=; b=1C5Nu3lQyjq+AULdmA9qCer108QWZ/p2cc+WRco1kxVyDtZc2kOVPqz1LELkzbu7DhXNB92Nv XFphNlajH7yAKq7ih96vrRdnywbKcNJhdoglIOpkoe6gjGmVO1rPSOl X-Developer-Key: i=dumitru.ceclan@analog.com; a=ed25519; pk=HdqMlVyrcazwoiai7oN6ghU+Bj1pusGUFRl30jhS7Bo= X-Endpoint-Received: by B4 Relay for dumitru.ceclan@analog.com/20240313 with auth_id=140 X-Original-From: Dumitru Ceclan Reply-To: dumitru.ceclan@analog.com From: Dumitru Ceclan Add support for selecting REF+ and REF- inputs on all models. Add support for selecting ((AVDD1 − AVSS)/5) inputs on supported models. Reviewed-by: Nuno Sa Signed-off-by: Dumitru Ceclan --- drivers/iio/adc/ad7173.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c index a20831d99aa5..ebfd2d5f9632 100644 --- a/drivers/iio/adc/ad7173.c +++ b/drivers/iio/adc/ad7173.c @@ -66,6 +66,10 @@ FIELD_PREP(AD7173_CH_SETUP_AINNEG_MASK, neg)) #define AD7173_AIN_TEMP_POS 17 #define AD7173_AIN_TEMP_NEG 18 +#define AD7173_AIN_COM_IN_POS 19 +#define AD7173_AIN_COM_IN_NEG 20 +#define AD7173_AIN_REF_POS 21 +#define AD7173_AIN_REF_NEG 22 #define AD7172_2_ID 0x00d0 #define AD7175_ID 0x0cd0 @@ -146,6 +150,8 @@ struct ad7173_device_info { unsigned int id; char *name; bool has_temp; + /* ((AVDD1 − AVSS)/5) */ + bool has_common_input; bool has_input_buf; bool has_int_ref; bool has_ref2; @@ -216,6 +222,7 @@ static const struct ad7173_device_info ad7173_device_info[] = { .has_temp = true, .has_input_buf = true, .has_int_ref = true, + .has_common_input = true, .clock = 2 * HZ_PER_MHZ, .sinc5_data_rates = ad7173_sinc5_data_rates, .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), @@ -230,6 +237,7 @@ static const struct ad7173_device_info ad7173_device_info[] = { .has_temp = false, .has_input_buf = true, .has_ref2 = true, + .has_common_input = true, .clock = 2 * HZ_PER_MHZ, .sinc5_data_rates = ad7173_sinc5_data_rates, .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), @@ -245,6 +253,7 @@ static const struct ad7173_device_info ad7173_device_info[] = { .has_input_buf = true, .has_int_ref = true, .has_ref2 = true, + .has_common_input = false, .clock = 2 * HZ_PER_MHZ, .sinc5_data_rates = ad7173_sinc5_data_rates, .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), @@ -259,6 +268,7 @@ static const struct ad7173_device_info ad7173_device_info[] = { .has_temp = true, .has_input_buf = true, .has_int_ref = true, + .has_common_input = true, .clock = 16 * HZ_PER_MHZ, .sinc5_data_rates = ad7175_sinc5_data_rates, .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), @@ -274,6 +284,7 @@ static const struct ad7173_device_info ad7173_device_info[] = { .has_input_buf = true, .has_int_ref = true, .has_ref2 = true, + .has_common_input = true, .clock = 16 * HZ_PER_MHZ, .sinc5_data_rates = ad7175_sinc5_data_rates, .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), @@ -288,6 +299,7 @@ static const struct ad7173_device_info ad7173_device_info[] = { .has_temp = false, .has_input_buf = false, .has_int_ref = true, + .has_common_input = false, .clock = 16 * HZ_PER_MHZ, .sinc5_data_rates = ad7175_sinc5_data_rates, .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), @@ -302,6 +314,7 @@ static const struct ad7173_device_info ad7173_device_info[] = { .has_temp = true, .has_input_buf = true, .has_int_ref = true, + .has_common_input = true, .clock = 16 * HZ_PER_MHZ, .odr_start_value = AD7177_ODR_START_VALUE, .sinc5_data_rates = ad7175_sinc5_data_rates, @@ -918,6 +931,14 @@ static int ad7173_validate_voltage_ain_inputs(struct ad7173_state *st, if (ain[i] < st->info->num_inputs) continue; + if (ain[i] == AD7173_AIN_REF_POS || ain[i] == AD7173_AIN_REF_NEG) + continue; + + if ((ain[i] == AD7173_AIN_COM_IN_POS || + ain[i] == AD7173_AIN_COM_IN_NEG) && + st->info->has_common_input) + continue; + return dev_err_probe(dev, -EINVAL, "Input pin number out of range for pair (%d %d).\n", ain[0], ain[1]); From patchwork Fri May 31 19:42:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dumitru Ceclan via B4 Relay X-Patchwork-Id: 13682058 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ABCAB17D341; Fri, 31 May 2024 19:42:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184571; cv=none; b=pW0biCmqVQ6Ui+zJfVM3YDBRmy/e61JP/xncHNDBHlOvOWqAGsNNhnPXT4J0NnrPT0vCdd37Fa5F+tqUACOArL5WiZobT1RwbzN5E1B/k6GHOYJnzLPSnUikimDHtyEx4UK7T/NECHiHGjVwpjpRWu0v86+2BNGLucPefT2+lOk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184571; c=relaxed/simple; bh=M1LcMgmmfpY2D4207JTUEyEzHZwxRlMHXw5z2scj/Oc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qhJSJ/HonT9pSiMEJkEF3rGqbWeWVwm32YiFXwmxI6HyMaR2oYGyTbVVKtKBrvSQ0CNIYuW7+z14bSV7yJx/bJEAqyQrfJPAoCGVLSrH+E9YwWmXqUGHWnoONVcDw3i9a4zwBBd2i5o1VFgdnRAgj9ns6IgCK8Ux8AlfKZmkGWI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=h4cPIUg8; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="h4cPIUg8" Received: by smtp.kernel.org (Postfix) with ESMTPS id 7D2FFC4AF17; Fri, 31 May 2024 19:42:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717184571; bh=M1LcMgmmfpY2D4207JTUEyEzHZwxRlMHXw5z2scj/Oc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=h4cPIUg8tvUfcPA6XZ4wEHVMAEC4CbNHWvEpcBl8z992GCJCa7Dwg2F4PG8xBnW3f 3gpvObwgSZsgP4NHpHRhjY6+z5ajakmvvECHKq6GVWTWt/0hXjSIbBSvklNXVFOwgI Zjz03iZInMPm302SGTeBcQbe8gzYphe7UMPk3UtMwUoB39G1Ckti1MdM4jq9U9TZFw Ets1xAYZx1EUAiSMv9VapVYltk4dm1YEICJMgt7gOsPyTVDfY68NLiidR5GNvZ7x6s MFQOmfP9V6J11+AtslpZVEmiswFCvFDIbGfDiv8jigSEOc+Cmh5QHbamrS9rK2ICR4 pIsKKkwZxV4aw== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6F2B7C27C50; Fri, 31 May 2024 19:42:51 +0000 (UTC) From: Dumitru Ceclan via B4 Relay Date: Fri, 31 May 2024 22:42:31 +0300 Subject: [PATCH v4 5/6] iio: adc: ad7173: refactor device info structs Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240531-ad4111-v4-5-64607301c057@analog.com> References: <20240531-ad4111-v4-0-64607301c057@analog.com> In-Reply-To: <20240531-ad4111-v4-0-64607301c057@analog.com> To: Ceclan Dumitru Cc: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , David Lechner , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Dumitru Ceclan X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717184569; l=9509; i=dumitru.ceclan@analog.com; s=20240313; h=from:subject:message-id; bh=RCX3Uz+DiXHXyd/q5TMDm1Ci7vN+X3ks6WalypeIWPs=; b=yrUXe7DKclgkoK4krd0WMdGy1JW/vd6D0gaHhIl7hemmldgRFzLGCCAqB73oNwipnHBFFVyze mWljF2CzCUcAdbEL/0gBxyJwFIuemAcb6clSnCie25xj21VXMUR+Wq+ X-Developer-Key: i=dumitru.ceclan@analog.com; a=ed25519; pk=HdqMlVyrcazwoiai7oN6ghU+Bj1pusGUFRl30jhS7Bo= X-Endpoint-Received: by B4 Relay for dumitru.ceclan@analog.com/20240313 with auth_id=140 X-Original-From: Dumitru Ceclan Reply-To: dumitru.ceclan@analog.com From: Dumitru Ceclan Drop array of device info structs and use individual structs for all; drop models enum as no longer needed. This improves readability as the structs are pointed directly. Signed-off-by: Dumitru Ceclan --- drivers/iio/adc/ad7173.c | 267 ++++++++++++++++++++++------------------------- 1 file changed, 127 insertions(+), 140 deletions(-) diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c index ebfd2d5f9632..ed8ff8c5f343 100644 --- a/drivers/iio/adc/ad7173.c +++ b/drivers/iio/adc/ad7173.c @@ -129,16 +129,6 @@ #define AD7173_FILTER_ODR0_MASK GENMASK(5, 0) #define AD7173_MAX_CONFIGS 8 -enum ad7173_ids { - ID_AD7172_2, - ID_AD7172_4, - ID_AD7173_8, - ID_AD7175_2, - ID_AD7175_8, - ID_AD7176_2, - ID_AD7177_2, -}; - struct ad7173_device_info { const unsigned int *sinc5_data_rates; unsigned int num_sinc5_data_rates; @@ -211,115 +201,119 @@ static const unsigned int ad7175_sinc5_data_rates[] = { 5000, /* 20 */ }; -static const struct ad7173_device_info ad7173_device_info[] = { - [ID_AD7172_2] = { - .name = "ad7172-2", - .id = AD7172_2_ID, - .num_inputs = 5, - .num_channels = 4, - .num_configs = 4, - .num_gpios = 2, - .has_temp = true, - .has_input_buf = true, - .has_int_ref = true, - .has_common_input = true, - .clock = 2 * HZ_PER_MHZ, - .sinc5_data_rates = ad7173_sinc5_data_rates, - .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), - }, - [ID_AD7172_4] = { - .name = "ad7172-4", - .id = AD7172_4_ID, - .num_inputs = 9, - .num_channels = 8, - .num_configs = 8, - .num_gpios = 4, - .has_temp = false, - .has_input_buf = true, - .has_ref2 = true, - .has_common_input = true, - .clock = 2 * HZ_PER_MHZ, - .sinc5_data_rates = ad7173_sinc5_data_rates, - .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), - }, - [ID_AD7173_8] = { - .name = "ad7173-8", - .id = AD7173_ID, - .num_inputs = 17, - .num_channels = 16, - .num_configs = 8, - .num_gpios = 4, - .has_temp = true, - .has_input_buf = true, - .has_int_ref = true, - .has_ref2 = true, - .has_common_input = false, - .clock = 2 * HZ_PER_MHZ, - .sinc5_data_rates = ad7173_sinc5_data_rates, - .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), - }, - [ID_AD7175_2] = { - .name = "ad7175-2", - .id = AD7175_2_ID, - .num_inputs = 5, - .num_channels = 4, - .num_configs = 4, - .num_gpios = 2, - .has_temp = true, - .has_input_buf = true, - .has_int_ref = true, - .has_common_input = true, - .clock = 16 * HZ_PER_MHZ, - .sinc5_data_rates = ad7175_sinc5_data_rates, - .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), - }, - [ID_AD7175_8] = { - .name = "ad7175-8", - .id = AD7175_8_ID, - .num_inputs = 17, - .num_channels = 16, - .num_configs = 8, - .num_gpios = 4, - .has_temp = true, - .has_input_buf = true, - .has_int_ref = true, - .has_ref2 = true, - .has_common_input = true, - .clock = 16 * HZ_PER_MHZ, - .sinc5_data_rates = ad7175_sinc5_data_rates, - .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), - }, - [ID_AD7176_2] = { - .name = "ad7176-2", - .id = AD7176_ID, - .num_inputs = 5, - .num_channels = 4, - .num_configs = 4, - .num_gpios = 2, - .has_temp = false, - .has_input_buf = false, - .has_int_ref = true, - .has_common_input = false, - .clock = 16 * HZ_PER_MHZ, - .sinc5_data_rates = ad7175_sinc5_data_rates, - .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), - }, - [ID_AD7177_2] = { - .name = "ad7177-2", - .id = AD7177_ID, - .num_inputs = 5, - .num_channels = 4, - .num_configs = 4, - .num_gpios = 2, - .has_temp = true, - .has_input_buf = true, - .has_int_ref = true, - .has_common_input = true, - .clock = 16 * HZ_PER_MHZ, - .odr_start_value = AD7177_ODR_START_VALUE, - .sinc5_data_rates = ad7175_sinc5_data_rates, - .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), - }, +static const struct ad7173_device_info ad7172_2_device_info = { + .name = "ad7172-2", + .id = AD7172_2_ID, + .num_inputs = 5, + .num_channels = 4, + .num_configs = 4, + .num_gpios = 2, + .has_temp = true, + .has_input_buf = true, + .has_int_ref = true, + .has_common_input = true, + .clock = 2 * HZ_PER_MHZ, + .sinc5_data_rates = ad7173_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), +}; + +static const struct ad7173_device_info ad7172_4_device_info = { + .name = "ad7172-4", + .id = AD7172_4_ID, + .num_inputs = 9, + .num_channels = 8, + .num_configs = 8, + .num_gpios = 4, + .has_temp = false, + .has_input_buf = true, + .has_ref2 = true, + .has_common_input = true, + .clock = 2 * HZ_PER_MHZ, + .sinc5_data_rates = ad7173_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), +}; + +static const struct ad7173_device_info ad7173_8_device_info = { + .name = "ad7173-8", + .id = AD7173_ID, + .num_inputs = 17, + .num_channels = 16, + .num_configs = 8, + .num_gpios = 4, + .has_temp = true, + .has_input_buf = true, + .has_int_ref = true, + .has_ref2 = true, + .has_common_input = false, + .clock = 2 * HZ_PER_MHZ, + .sinc5_data_rates = ad7173_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), +}; + +static const struct ad7173_device_info ad7175_2_device_info = { + .name = "ad7175-2", + .id = AD7175_2_ID, + .num_inputs = 5, + .num_channels = 4, + .num_configs = 4, + .num_gpios = 2, + .has_temp = true, + .has_input_buf = true, + .has_int_ref = true, + .has_common_input = true, + .clock = 16 * HZ_PER_MHZ, + .sinc5_data_rates = ad7175_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), +}; + +static const struct ad7173_device_info ad7175_8_device_info = { + .name = "ad7175-8", + .id = AD7175_8_ID, + .num_inputs = 17, + .num_channels = 16, + .num_configs = 8, + .num_gpios = 4, + .has_temp = true, + .has_input_buf = true, + .has_int_ref = true, + .has_ref2 = true, + .has_common_input = true, + .clock = 16 * HZ_PER_MHZ, + .sinc5_data_rates = ad7175_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), +}; + +static const struct ad7173_device_info ad7176_2_device_info = { + .name = "ad7176-2", + .id = AD7176_ID, + .num_inputs = 5, + .num_channels = 4, + .num_configs = 4, + .num_gpios = 2, + .has_temp = false, + .has_input_buf = false, + .has_int_ref = true, + .has_common_input = false, + .clock = 16 * HZ_PER_MHZ, + .sinc5_data_rates = ad7175_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), +}; + +static const struct ad7173_device_info ad7177_2_device_info = { + .name = "ad7177-2", + .id = AD7177_ID, + .num_inputs = 5, + .num_channels = 4, + .num_configs = 4, + .num_gpios = 2, + .has_temp = true, + .has_input_buf = true, + .has_int_ref = true, + .has_common_input = true, + .clock = 16 * HZ_PER_MHZ, + .odr_start_value = AD7177_ODR_START_VALUE, + .sinc5_data_rates = ad7175_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7175_sinc5_data_rates), }; static const char *const ad7173_ref_sel_str[] = { @@ -1190,32 +1184,25 @@ static int ad7173_probe(struct spi_device *spi) } static const struct of_device_id ad7173_of_match[] = { - { .compatible = "adi,ad7172-2", - .data = &ad7173_device_info[ID_AD7172_2]}, - { .compatible = "adi,ad7172-4", - .data = &ad7173_device_info[ID_AD7172_4]}, - { .compatible = "adi,ad7173-8", - .data = &ad7173_device_info[ID_AD7173_8]}, - { .compatible = "adi,ad7175-2", - .data = &ad7173_device_info[ID_AD7175_2]}, - { .compatible = "adi,ad7175-8", - .data = &ad7173_device_info[ID_AD7175_8]}, - { .compatible = "adi,ad7176-2", - .data = &ad7173_device_info[ID_AD7176_2]}, - { .compatible = "adi,ad7177-2", - .data = &ad7173_device_info[ID_AD7177_2]}, + { .compatible = "adi,ad7172-2", .data = &ad7172_2_device_info}, + { .compatible = "adi,ad7172-4", .data = &ad7172_4_device_info}, + { .compatible = "adi,ad7173-8", .data = &ad7173_8_device_info}, + { .compatible = "adi,ad7175-2", .data = &ad7175_2_device_info}, + { .compatible = "adi,ad7175-8", .data = &ad7175_8_device_info}, + { .compatible = "adi,ad7176-2", .data = &ad7176_2_device_info}, + { .compatible = "adi,ad7177-2", .data = &ad7177_2_device_info}, { } }; MODULE_DEVICE_TABLE(of, ad7173_of_match); static const struct spi_device_id ad7173_id_table[] = { - { "ad7172-2", (kernel_ulong_t)&ad7173_device_info[ID_AD7172_2]}, - { "ad7172-4", (kernel_ulong_t)&ad7173_device_info[ID_AD7172_4]}, - { "ad7173-8", (kernel_ulong_t)&ad7173_device_info[ID_AD7173_8]}, - { "ad7175-2", (kernel_ulong_t)&ad7173_device_info[ID_AD7175_2]}, - { "ad7175-8", (kernel_ulong_t)&ad7173_device_info[ID_AD7175_8]}, - { "ad7176-2", (kernel_ulong_t)&ad7173_device_info[ID_AD7176_2]}, - { "ad7177-2", (kernel_ulong_t)&ad7173_device_info[ID_AD7177_2]}, + { "ad7172-2", (kernel_ulong_t)&ad7172_2_device_info}, + { "ad7172-4", (kernel_ulong_t)&ad7172_4_device_info}, + { "ad7173-8", (kernel_ulong_t)&ad7173_8_device_info}, + { "ad7175-2", (kernel_ulong_t)&ad7175_2_device_info}, + { "ad7175-8", (kernel_ulong_t)&ad7175_8_device_info}, + { "ad7176-2", (kernel_ulong_t)&ad7176_2_device_info}, + { "ad7177-2", (kernel_ulong_t)&ad7177_2_device_info}, { } }; MODULE_DEVICE_TABLE(spi, ad7173_id_table); From patchwork Fri May 31 19:42:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dumitru Ceclan via B4 Relay X-Patchwork-Id: 13682061 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DBD2B17D889; Fri, 31 May 2024 19:42:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184572; cv=none; b=JggtVZSntqm/We2NSjog6oE32cYxeQoC55IXzlSEosNqWdi2ZbEBzJVnTRTkxldqe1bM+zpTDjJiVMV0VovKNLCK30r6XBkQ9UmUf5HZgZ9RVcI3aB6d0zXgKwizyjELQIhoHabS2wwRaO0ae6wwfjTyqXL0FZzeOxEJp6CamhA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717184572; c=relaxed/simple; bh=VjuEHl7ywHX/TGdk9wsHnEzZ647ndEnzQYkQ50nUzhU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZpYCc5gR/eiK4RNrdXdPVJBfsUSUnbNb44fGw6bmNhS0Oal9GzxWtCRH53ZFv3BpfxgbaoZv/YD14OJZU4+RMkTGCuLCAlfGxGNY8B6tH/8vtpL1Tj81Sp7hIKzbHatkE6mHcqmyaI8Yi/EUBlRq0AYoG7ShRVXTVlC1nGfK38E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kA1lvtID; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kA1lvtID" Received: by smtp.kernel.org (Postfix) with ESMTPS id 8A19EC4AF08; Fri, 31 May 2024 19:42:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1717184571; bh=VjuEHl7ywHX/TGdk9wsHnEzZ647ndEnzQYkQ50nUzhU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=kA1lvtIDwoD5z/peigGSusneI6BkVIwzMDEHIOO3x4fEfJMDHzm5fZuA8iJgTlkvW 0LB8mnFBIca6TVhMnj8sQW3vlGGUH1vpM7OPM8v4pxOFCXNioqa9d+cJX9n4kIYFCZ x/OP6KWiVEJeXSLSymhKWp0ySI/EuBZKv7DfNG0uLFKGKakhd+tk7SyB+YWsgg/oux kUcY+mA6FxTLNXmSufFSo2VNT277e3QQcP+SqKv4l4Rx5WFVqFypzxrA2ut+Nb7DR2 c1NXHi/FbXitnZJHuZLlK8tuRdGBFKjWpRshZ/MOmvnGNUIisd4QdNA7floDd2i6Fw ZXcqxYlFI4VHg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81B43C27C4F; Fri, 31 May 2024 19:42:51 +0000 (UTC) From: Dumitru Ceclan via B4 Relay Date: Fri, 31 May 2024 22:42:32 +0300 Subject: [PATCH v4 6/6] iio: adc: ad7173: Add support for AD411x devices Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240531-ad4111-v4-6-64607301c057@analog.com> References: <20240531-ad4111-v4-0-64607301c057@analog.com> In-Reply-To: <20240531-ad4111-v4-0-64607301c057@analog.com> To: Ceclan Dumitru Cc: Lars-Peter Clausen , Michael Hennerich , Jonathan Cameron , Rob Herring , Krzysztof Kozlowski , Conor Dooley , David Lechner , linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Dumitru Ceclan X-Mailer: b4 0.13.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1717184569; l=20467; i=dumitru.ceclan@analog.com; s=20240313; h=from:subject:message-id; bh=+Jer71u+2s2SErZzNbJ2vN6+VUIEztmhSxqfPzotNrw=; b=pnUsobtKh4MmGFWLGDC8kr47BxvpFrMEW183T0amQzGmJ6ihyLJzgBbYHWuU8DvXJYCTu+GdP jCRcwL7vCCUCP0T/qwTHEbMaEWjNMx7CMnyuprNsONNnu+m7osCpBYY X-Developer-Key: i=dumitru.ceclan@analog.com; a=ed25519; pk=HdqMlVyrcazwoiai7oN6ghU+Bj1pusGUFRl30jhS7Bo= X-Endpoint-Received: by B4 Relay for dumitru.ceclan@analog.com/20240313 with auth_id=140 X-Original-From: Dumitru Ceclan Reply-To: dumitru.ceclan@analog.com From: Dumitru Ceclan Add support for AD4111/AD4112/AD4114/AD4115/AD4116. The AD411X family encompasses a series of low power, low noise, 24-bit, sigma-delta analog-to-digital converters that offer a versatile range of specifications. This family of ADCs integrates an analog front end suitable for processing both fully differential and single-ended, bipolar voltage inputs addressing a wide array of industrial and instrumentation requirements. - All ADCs have inputs with a precision voltage divider with a division ratio of 10. - AD4116 has 5 low level inputs without a voltage divider. - AD4111 and AD4112 support current inputs (0 mA to 20 mA) using a 50ohm shunt resistor. Signed-off-by: Dumitru Ceclan --- drivers/iio/adc/ad7173.c | 336 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 307 insertions(+), 29 deletions(-) diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c index ed8ff8c5f343..91ff984eedf4 100644 --- a/drivers/iio/adc/ad7173.c +++ b/drivers/iio/adc/ad7173.c @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * AD717x family SPI ADC driver + * AD717x and AD411x family SPI ADC driver * * Supported devices: + * AD4111/AD4112/AD4114/AD4115/AD4116 * AD7172-2/AD7172-4/AD7173-8/AD7175-2 * AD7175-8/AD7176-2/AD7177-2 * @@ -77,6 +78,11 @@ #define AD7175_2_ID 0x0cd0 #define AD7172_4_ID 0x2050 #define AD7173_ID 0x30d0 +#define AD4111_ID AD7173_ID +#define AD4112_ID AD7173_ID +#define AD4114_ID AD7173_ID +#define AD4116_ID 0x34d0 +#define AD4115_ID 0x38d0 #define AD7175_8_ID 0x3cd0 #define AD7177_ID 0x4fd0 #define AD7173_ID_MASK GENMASK(15, 4) @@ -107,6 +113,7 @@ #define AD7173_GPO12_DATA(x) BIT((x) + 0) #define AD7173_GPO23_DATA(x) BIT((x) + 4) +#define AD4111_GPO01_DATA(x) BIT((x) + 6) #define AD7173_GPO_DATA(x) ((x) < 2 ? AD7173_GPO12_DATA(x) : AD7173_GPO23_DATA(x)) #define AD7173_INTERFACE_DATA_STAT BIT(6) @@ -125,26 +132,46 @@ #define AD7173_VOLTAGE_INT_REF_uV 2500000 #define AD7173_TEMP_SENSIIVITY_uV_per_C 477 #define AD7177_ODR_START_VALUE 0x07 +#define AD4111_SHUNT_RESISTOR_OHM 50 +#define AD4111_DIVIDER_RATIO 10 +#define AD411X_VCOM_INPUT 0X10 +#define AD4111_CURRENT_CHAN_CUTOFF 16 #define AD7173_FILTER_ODR0_MASK GENMASK(5, 0) #define AD7173_MAX_CONFIGS 8 +enum ad4111_current_channels { + AD4111_CURRENT_IN0P_IN0N, + AD4111_CURRENT_IN1P_IN1N, + AD4111_CURRENT_IN2P_IN2N, + AD4111_CURRENT_IN3P_IN3N, +}; + struct ad7173_device_info { const unsigned int *sinc5_data_rates; unsigned int num_sinc5_data_rates; unsigned int odr_start_value; + /* + * AD4116 has both inputs with a voltage divider and without. + * These inputs cannot be mixed in the channel configuration. + * Does not include the VINCOM input. + */ + unsigned int num_voltage_in_div; unsigned int num_channels; unsigned int num_configs; - unsigned int num_inputs; + unsigned int num_voltage_in; unsigned int clock; unsigned int id; char *name; + bool has_current_inputs; + bool has_vcom_input; bool has_temp; /* ((AVDD1 − AVSS)/5) */ bool has_common_input; bool has_input_buf; bool has_int_ref; bool has_ref2; + bool higher_gpio_bits; u8 num_gpios; }; @@ -186,6 +213,24 @@ struct ad7173_state { #endif }; +static unsigned int ad4115_sinc5_data_rates[] = { + 24845000, 24845000, 20725000, 20725000, /* 0-3 */ + 15564000, 13841000, 10390000, 10390000, /* 4-7 */ + 4994000, 2499000, 1000000, 500000, /* 8-11 */ + 395500, 200000, 100000, 59890, /* 12-15 */ + 49920, 20000, 16660, 10000, /* 16-19 */ + 5000, 2500, 2500, /* 20-22 */ +}; + +static unsigned int ad4116_sinc5_data_rates[] = { + 12422360, 12422360, 12422360, 12422360, /* 0-3 */ + 10362690, 10362690, 7782100, 6290530, /* 4-7 */ + 5194800, 2496900, 1007600, 499900, /* 8-11 */ + 390600, 200300, 100000, 59750, /* 12-15 */ + 49840, 20000, 16650, 10000, /* 16-19 */ + 5000, 2500, 1250, /* 20-22 */ +}; + static const unsigned int ad7173_sinc5_data_rates[] = { 6211000, 6211000, 6211000, 6211000, 6211000, 6211000, 5181000, 4444000, /* 0-7 */ 3115000, 2597000, 1007000, 503800, 381000, 200300, 100500, 59520, /* 8-15 */ @@ -201,13 +246,113 @@ static const unsigned int ad7175_sinc5_data_rates[] = { 5000, /* 20 */ }; +static unsigned int ad4111_current_channel_config[] = { + [AD4111_CURRENT_IN0P_IN0N] = 0x1E8, + [AD4111_CURRENT_IN1P_IN1N] = 0x1C9, + [AD4111_CURRENT_IN2P_IN2N] = 0x1AA, + [AD4111_CURRENT_IN3P_IN3N] = 0x18B, +}; + +static const struct ad7173_device_info ad4111_device_info = { + .name = "ad4111", + .id = AD4111_ID, + .num_voltage_in_div = 8, + .num_channels = 16, + .num_configs = 8, + .num_voltage_in = 8, + .num_gpios = 2, + .higher_gpio_bits = true, + .has_temp = true, + .has_vcom_input = true, + .has_input_buf = true, + .has_current_inputs = true, + .has_int_ref = true, + .clock = 2 * HZ_PER_MHZ, + .sinc5_data_rates = ad7173_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), +}; + +static const struct ad7173_device_info ad4112_device_info = { + .name = "ad4112", + .id = AD4112_ID, + .num_voltage_in_div = 8, + .num_channels = 16, + .num_configs = 8, + .num_voltage_in = 8, + .num_gpios = 2, + .higher_gpio_bits = true, + .has_vcom_input = true, + .has_temp = true, + .has_input_buf = true, + .has_current_inputs = true, + .has_int_ref = true, + .clock = 2 * HZ_PER_MHZ, + .sinc5_data_rates = ad7173_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), +}; + +static const struct ad7173_device_info ad4114_device_info = { + .name = "ad4114", + .id = AD4114_ID, + .num_voltage_in_div = 16, + .num_channels = 16, + .num_configs = 8, + .num_voltage_in = 16, + .num_gpios = 4, + .higher_gpio_bits = true, + .has_vcom_input = true, + .has_temp = true, + .has_input_buf = true, + .has_int_ref = true, + .clock = 2 * HZ_PER_MHZ, + .sinc5_data_rates = ad7173_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad7173_sinc5_data_rates), +}; + +static const struct ad7173_device_info ad4115_device_info = { + .name = "ad4115", + .id = AD4115_ID, + .num_voltage_in_div = 16, + .num_channels = 16, + .num_configs = 8, + .num_voltage_in = 16, + .num_gpios = 4, + .higher_gpio_bits = true, + .has_vcom_input = true, + .has_temp = true, + .has_input_buf = true, + .has_int_ref = true, + .clock = 8 * HZ_PER_MHZ, + .sinc5_data_rates = ad4115_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad4115_sinc5_data_rates), +}; + +static const struct ad7173_device_info ad4116_device_info = { + .name = "ad4116", + .id = AD4116_ID, + .num_voltage_in_div = 11, + .num_channels = 16, + .num_configs = 8, + .num_voltage_in = 16, + .num_gpios = 4, + .higher_gpio_bits = true, + .has_vcom_input = true, + .has_temp = true, + .has_input_buf = true, + .has_int_ref = true, + .clock = 4 * HZ_PER_MHZ, + .sinc5_data_rates = ad4116_sinc5_data_rates, + .num_sinc5_data_rates = ARRAY_SIZE(ad4116_sinc5_data_rates), +}; + static const struct ad7173_device_info ad7172_2_device_info = { .name = "ad7172-2", .id = AD7172_2_ID, - .num_inputs = 5, + .num_voltage_in = 5, .num_channels = 4, .num_configs = 4, .num_gpios = 2, + .higher_gpio_bits = false, .has_temp = true, .has_input_buf = true, .has_int_ref = true, @@ -220,10 +365,11 @@ static const struct ad7173_device_info ad7172_2_device_info = { static const struct ad7173_device_info ad7172_4_device_info = { .name = "ad7172-4", .id = AD7172_4_ID, - .num_inputs = 9, + .num_voltage_in = 9, .num_channels = 8, .num_configs = 8, .num_gpios = 4, + .higher_gpio_bits = false, .has_temp = false, .has_input_buf = true, .has_ref2 = true, @@ -236,10 +382,11 @@ static const struct ad7173_device_info ad7172_4_device_info = { static const struct ad7173_device_info ad7173_8_device_info = { .name = "ad7173-8", .id = AD7173_ID, - .num_inputs = 17, + .num_voltage_in = 17, .num_channels = 16, .num_configs = 8, .num_gpios = 4, + .higher_gpio_bits = false, .has_temp = true, .has_input_buf = true, .has_int_ref = true, @@ -253,10 +400,11 @@ static const struct ad7173_device_info ad7173_8_device_info = { static const struct ad7173_device_info ad7175_2_device_info = { .name = "ad7175-2", .id = AD7175_2_ID, - .num_inputs = 5, + .num_voltage_in = 5, .num_channels = 4, .num_configs = 4, .num_gpios = 2, + .higher_gpio_bits = false, .has_temp = true, .has_input_buf = true, .has_int_ref = true, @@ -269,10 +417,11 @@ static const struct ad7173_device_info ad7175_2_device_info = { static const struct ad7173_device_info ad7175_8_device_info = { .name = "ad7175-8", .id = AD7175_8_ID, - .num_inputs = 17, + .num_voltage_in = 17, .num_channels = 16, .num_configs = 8, .num_gpios = 4, + .higher_gpio_bits = false, .has_temp = true, .has_input_buf = true, .has_int_ref = true, @@ -286,10 +435,11 @@ static const struct ad7173_device_info ad7175_8_device_info = { static const struct ad7173_device_info ad7176_2_device_info = { .name = "ad7176-2", .id = AD7176_ID, - .num_inputs = 5, + .num_voltage_in = 5, .num_channels = 4, .num_configs = 4, .num_gpios = 2, + .higher_gpio_bits = false, .has_temp = false, .has_input_buf = false, .has_int_ref = true, @@ -302,10 +452,11 @@ static const struct ad7173_device_info ad7176_2_device_info = { static const struct ad7173_device_info ad7177_2_device_info = { .name = "ad7177-2", .id = AD7177_ID, - .num_inputs = 5, + .num_voltage_in = 5, .num_channels = 4, .num_configs = 4, .num_gpios = 2, + .higher_gpio_bits = false, .has_temp = true, .has_input_buf = true, .has_int_ref = true, @@ -355,6 +506,15 @@ static int ad7173_mask_xlate(struct gpio_regmap *gpio, unsigned int base, return 0; } +static int ad4111_mask_xlate(struct gpio_regmap *gpio, unsigned int base, + unsigned int offset, unsigned int *reg, + unsigned int *mask) +{ + *mask = AD4111_GPO01_DATA(offset); + *reg = base; + return 0; +} + static void ad7173_gpio_disable(void *data) { struct ad7173_state *st = data; @@ -387,7 +547,10 @@ static int ad7173_gpio_init(struct ad7173_state *st) gpio_regmap.regmap = st->reg_gpiocon_regmap; gpio_regmap.ngpio = st->info->num_gpios; gpio_regmap.reg_set_base = AD7173_REG_GPIO; - gpio_regmap.reg_mask_xlate = ad7173_mask_xlate; + if (st->info->higher_gpio_bits) + gpio_regmap.reg_mask_xlate = ad4111_mask_xlate; + else + gpio_regmap.reg_mask_xlate = ad7173_mask_xlate; st->gpio_regmap = devm_gpio_regmap_register(dev, &gpio_regmap); ret = PTR_ERR_OR_ZERO(st->gpio_regmap); @@ -686,18 +849,33 @@ static int ad7173_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - if (chan->type == IIO_TEMP) { + + switch (chan->type) { + case IIO_TEMP: temp = AD7173_VOLTAGE_INT_REF_uV * MILLI; temp /= AD7173_TEMP_SENSIIVITY_uV_per_C; *val = temp; *val2 = chan->scan_type.realbits; - } else { + return IIO_VAL_FRACTIONAL_LOG2; + case IIO_VOLTAGE: *val = ad7173_get_ref_voltage_milli(st, ch->cfg.ref_sel); *val2 = chan->scan_type.realbits - !!(ch->cfg.bipolar); + + if (chan->channel < st->info->num_voltage_in_div) + *val *= AD4111_DIVIDER_RATIO; + return IIO_VAL_FRACTIONAL_LOG2; + case IIO_CURRENT: + *val = ad7173_get_ref_voltage_milli(st, ch->cfg.ref_sel); + *val /= AD4111_SHUNT_RESISTOR_OHM; + *val2 = chan->scan_type.realbits - ch->cfg.bipolar; + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; } - return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_OFFSET: - if (chan->type == IIO_TEMP) { + + switch (chan->type) { + case IIO_TEMP: /* 0 Kelvin -> raw sample */ temp = -ABSOLUTE_ZERO_MILLICELSIUS; temp *= AD7173_TEMP_SENSIIVITY_uV_per_C; @@ -706,10 +884,14 @@ static int ad7173_read_raw(struct iio_dev *indio_dev, AD7173_VOLTAGE_INT_REF_uV * MILLI); *val = -temp; - } else { + return IIO_VAL_INT; + case IIO_VOLTAGE: + case IIO_CURRENT: *val = -BIT(chan->scan_type.realbits - 1); + return IIO_VAL_INT; + default: + return -EINVAL; } - return IIO_VAL_INT; case IIO_CHAN_INFO_SAMP_FREQ: reg = st->channels[chan->address].cfg.odr; @@ -736,6 +918,21 @@ static int ad7173_write_raw(struct iio_dev *indio_dev, return ret; switch (info) { + /* + * This attribute sets the sampling frequency to each channel individually. + * There are no issues for raw or buffered reads of an individual channel. + * + * When multiple channels are enabled in buffered mode, the effective + * sampling rate of a channel is lowered in correlation to the number + * of channels enabled and the sampling rate of the other channels. + * + * Example: 3 channels enabled with rates CH1:6211sps CH2,CH3:10sps + * While the reading of CH1 takes only 0.16ms, the reading of CH2 and CH3 + * will take 100ms each. + * + * This will cause the reading of CH1 to be actually done once every + * 200.16ms, an effective rate of 4.99sps. + */ case IIO_CHAN_INFO_SAMP_FREQ: freq = val * MILLI + val2 / MILLI; for (i = st->info->odr_start_value; i < st->info->num_sinc5_data_rates - 1; i++) @@ -916,13 +1113,34 @@ static int ad7173_register_clk_provider(struct iio_dev *indio_dev) &st->int_clk_hw); } +static int ad4111_validate_current_ain(struct ad7173_state *st, + const unsigned int ain[AD7173_NO_AINS_PER_CHANNEL]) +{ + struct device *dev = &st->sd.spi->dev; + + if (!st->info->has_current_inputs) + return dev_err_probe(dev, -EINVAL, + "Model %s does not support current channels\n", + st->info->name); + + if (ain[0] >= ARRAY_SIZE(ad4111_current_channel_config)) + return dev_err_probe(dev, -EINVAL, + "For current channels single-channel must be <[0-3]>\n"); + + return 0; +} + static int ad7173_validate_voltage_ain_inputs(struct ad7173_state *st, const unsigned int ain[AD7173_NO_AINS_PER_CHANNEL]) { struct device *dev = &st->sd.spi->dev; + bool ain_selects_normal_input[] = { + ain[0] < st->info->num_voltage_in, + ain[1] < st->info->num_voltage_in + }; for (int i = 0; i < AD7173_NO_AINS_PER_CHANNEL; i++) { - if (ain[i] < st->info->num_inputs) + if (ain_selects_normal_input[i]) continue; if (ain[i] == AD7173_AIN_REF_POS || ain[i] == AD7173_AIN_REF_NEG) @@ -933,11 +1151,27 @@ static int ad7173_validate_voltage_ain_inputs(struct ad7173_state *st, st->info->has_common_input) continue; + if (st->info->has_vcom_input && ain[i] == AD411X_VCOM_INPUT) { + if (ain_selects_normal_input[(i + 1) % 2] && + ain[(i + 1) % 2] >= st->info->num_voltage_in_div) + return dev_err_probe(dev, -EINVAL, + "VCOM must be paired with inputs having divider.\n"); + + continue; + } + return dev_err_probe(dev, -EINVAL, "Input pin number out of range for pair (%d %d).\n", ain[0], ain[1]); } + if ((ain_selects_normal_input[0] && ain_selects_normal_input[1]) && + ((ain[0] >= st->info->num_voltage_in_div) != + (ain[1] >= st->info->num_voltage_in_div))) + return dev_err_probe(dev, -EINVAL, + "Both inputs must either have a voltage divider or not have: (%d %d).\n", + ain[0], ain[1]); + return 0; } @@ -968,7 +1202,7 @@ static int ad7173_fw_parse_channel_config(struct iio_dev *indio_dev) struct device *dev = indio_dev->dev.parent; struct iio_chan_spec *chan_arr, *chan; unsigned int ain[AD7173_NO_AINS_PER_CHANNEL], chan_index = 0; - int ref_sel, ret, num_channels; + int ref_sel, ret, is_current_chan, num_channels; num_channels = device_get_child_node_count(dev); @@ -1015,15 +1249,41 @@ static int ad7173_fw_parse_channel_config(struct iio_dev *indio_dev) device_for_each_child_node_scoped(dev, child) { chan = &chan_arr[chan_index]; + *chan = ad7173_channel_template; chan_st_priv = &chans_st_arr[chan_index]; ret = fwnode_property_read_u32_array(child, "diff-channels", ain, ARRAY_SIZE(ain)); - if (ret) - return ret; + if (ret) { + ret = fwnode_property_read_u32_array(child, "single-channel", + ain, 1); + if (ret) + return dev_err_probe(dev, ret, + "Channel must define one of diff-channels or single-channel.\n"); - ret = ad7173_validate_voltage_ain_inputs(st, ain); - if (ret) - return ret; + is_current_chan = fwnode_property_read_bool(child, "adi,current-channel"); + } else { + chan->differential = true; + } + + if (is_current_chan) { + ret = ad4111_validate_current_ain(st, ain); + if (ret) + return ret; + is_current_chan = true; + ain[1] = 0; + } else { + if (!chan->differential) { + ret = fwnode_property_read_u32_array(child, + "adi,common-mode-channel", ain + 1, 1); + if (ret) + return dev_err_probe(dev, ret, + "adi,common-mode-channel must be defined for single-ended channels.\n"); + } + ret = ad7173_validate_voltage_ain_inputs(st, ain); + if (ret) + return ret; + is_current_chan = false; + } ret = fwnode_property_match_property_string(child, "adi,reference-select", @@ -1042,22 +1302,30 @@ static int ad7173_fw_parse_channel_config(struct iio_dev *indio_dev) st->adc_mode |= AD7173_ADC_MODE_REF_EN; chan_st_priv->cfg.ref_sel = ref_sel; - *chan = ad7173_channel_template; chan->address = chan_index; chan->scan_index = chan_index; chan->channel = ain[0]; chan->channel2 = ain[1]; - chan->differential = true; - - chan_st_priv->ain = AD7173_CH_ADDRESS(ain[0], ain[1]); chan_st_priv->chan_reg = chan_index; chan_st_priv->cfg.input_buf = st->info->has_input_buf; chan_st_priv->cfg.odr = 0; - chan_st_priv->cfg.bipolar = fwnode_property_read_bool(child, "bipolar"); + if (chan_st_priv->cfg.bipolar) chan->info_mask_separate |= BIT(IIO_CHAN_INFO_OFFSET); + if (is_current_chan) { + chan->type = IIO_CURRENT; + chan->differential = false; + ain[1] = FIELD_GET(AD7173_CH_SETUP_AINNEG_MASK, + ad4111_current_channel_config[ain[0]]); + ain[0] = FIELD_GET(AD7173_CH_SETUP_AINPOS_MASK, + ad4111_current_channel_config[ain[0]]); + } else { + chan_st_priv->cfg.input_buf = st->info->has_input_buf; + } + chan_st_priv->ain = AD7173_CH_ADDRESS(ain[0], ain[1]); + chan_index++; } return 0; @@ -1184,6 +1452,11 @@ static int ad7173_probe(struct spi_device *spi) } static const struct of_device_id ad7173_of_match[] = { + { .compatible = "ad4111", .data = &ad4111_device_info}, + { .compatible = "ad4112", .data = &ad4112_device_info}, + { .compatible = "ad4114", .data = &ad4114_device_info}, + { .compatible = "ad4115", .data = &ad4115_device_info}, + { .compatible = "ad4116", .data = &ad4116_device_info}, { .compatible = "adi,ad7172-2", .data = &ad7172_2_device_info}, { .compatible = "adi,ad7172-4", .data = &ad7172_4_device_info}, { .compatible = "adi,ad7173-8", .data = &ad7173_8_device_info}, @@ -1196,6 +1469,11 @@ static const struct of_device_id ad7173_of_match[] = { MODULE_DEVICE_TABLE(of, ad7173_of_match); static const struct spi_device_id ad7173_id_table[] = { + { "ad4111", (kernel_ulong_t)&ad4111_device_info}, + { "ad4112", (kernel_ulong_t)&ad4112_device_info}, + { "ad4114", (kernel_ulong_t)&ad4114_device_info}, + { "ad4115", (kernel_ulong_t)&ad4115_device_info}, + { "ad4116", (kernel_ulong_t)&ad4116_device_info}, { "ad7172-2", (kernel_ulong_t)&ad7172_2_device_info}, { "ad7172-4", (kernel_ulong_t)&ad7172_4_device_info}, { "ad7173-8", (kernel_ulong_t)&ad7173_8_device_info}, @@ -1220,5 +1498,5 @@ module_spi_driver(ad7173_driver); MODULE_IMPORT_NS(IIO_AD_SIGMA_DELTA); MODULE_AUTHOR("Lars-Peter Clausen "); MODULE_AUTHOR("Dumitru Ceclan "); -MODULE_DESCRIPTION("Analog Devices AD7172/AD7173/AD7175/AD7176 ADC driver"); +MODULE_DESCRIPTION("Analog Devices AD7173 and similar ADC driver"); MODULE_LICENSE("GPL");