From patchwork Tue May 13 12:33:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Marcelo Schmitt X-Patchwork-Id: 889715 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (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 C1D87433C8; Tue, 13 May 2025 12:34:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747139661; cv=none; b=tRwqOeK4mKopF7ftEL65GzjmoQ7wG/TkR33170zWAIOSfS+Um1VLa8M48zCweCUGJ18ggyMSQ+u3qQqnv4bbBE666Qh2tMS0nv3iFdlVVInqDH/sxTxKGteb92XSOIrPwKGFPgUUp2d+UdLEBemDaVJR4DxOQ1r4b8FMCiyBvqQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747139661; c=relaxed/simple; bh=imWSPaOXD9MeCqg/vjBPtip3n1AsC7/GDfvELLCNQ1M=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XqoC3UfNqsNdQA4yzwSZtZ3Gyi7ryavBdacYG7CWLJH2UivNzVl2rcBGxdQEr/WC9kyCYQwZD9AktUv7Lf2wWHWs0AhWIUE6uCDLQYlYseyFVxnjNU5b633M7dnoh8gUyIfgBN/9ZEzyuBafaLwwcMYX4lPtB0t5iRBSBzcpMMk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=1vhiSDFI; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="1vhiSDFI" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 54DBMTUq007943; Tue, 13 May 2025 08:33:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=/r5FV 5HQTRpHspXnEoltgAt2Vpkpbz7Pm8vdzh3ZMSE=; b=1vhiSDFIfa667eN/DoyFn 8nfxCgavFDhblF0UQ/BUx5VmLC6SHhxiWLbP2MBitkGxYmCkP6ylof1EWpMRQ7Zj dAvR+E7u8Nnp4U/XDwfnARFe8fL8XAcS2bDVOvV88ItW9Qm9F5h7bNZn07dVxFY+ +QZF6NwewCpxjAfB8FK3yJ4buN06HgO+kxmRqktmiyfx1qQtzrUT6pQ65eF55m4H KVWUcgRiXa4z5aw90sWPBj1rtA9wk8uGGk1Nm5CtnMBc/xwuPYZ46Alo4glIvRt1 uvgZQo6rZFPMdoh9UYNMd+spBHhAVbTi5awykfZDZ+XcnskehQLIa3KTkoAnsP7B g== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 46kx53aep0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 13 May 2025 08:33:58 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 54DCXvvE040937 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 13 May 2025 08:33:57 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Tue, 13 May 2025 08:33:57 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.986.14 via Frontend Transport; Tue, 13 May 2025 08:33:57 -0400 Received: from work.ad.analog.com (HYB-hERzalRezfV.ad.analog.com [10.65.205.9]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 54DCXgHb007451; Tue, 13 May 2025 08:33:44 -0400 From: Marcelo Schmitt To: , , , CC: , , , , , , , , , , , Subject: [PATCH v3 01/10] dt-bindings: iio: adc: Add AD4170 Date: Tue, 13 May 2025 09:33:40 -0300 Message-ID: <5fa867cff437c0c6d3f0122af823e1677a12d189.1747083143.git.marcelo.schmitt@analog.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=a4sw9VSF c=1 sm=1 tr=0 ts=68233c37 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=dt9VzEwgFbYA:10 a=gEfo2CItAAAA:8 a=gAnH3GRIAAAA:8 a=VwQbUJbxAAAA:8 a=qjk4kMxMGZ-Z2-xVo1MA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=sptkURWiP4Gy88Gu7hUp:22 X-Proofpoint-ORIG-GUID: iB1SWDxRugx3S0CZhlzamogTx2ShpjVP X-Proofpoint-GUID: iB1SWDxRugx3S0CZhlzamogTx2ShpjVP X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNTEzMDExOSBTYWx0ZWRfX+qd+qu7aCTwn eeRaz9+Cy+v3O1xh8MiINJ70HOt5xGBILowZW9IjU8eqBsTNDPnJ6YE5nKkBq8z9xqWGmBVSe9x /9On7ShJRrQIlWLrItHsZukip2EpT+70Cg3Td3G0U+w8erEISJxgL/Nus1tN2hrY7jIS+H/K+hm 8ci2E4xbhfACvo+ZXL2ePMoOo+qML+OLYuu4pj1WjThz7aEwq+QMEQymhMy+NQX8/MjZ7Z41w4G kQ+Pgg3VvAHpZT4YdKJZNjD1xip9Y1Zuzs2JBoxSI6eFQoIPOdbSC1Yk8lh3tIbV5Jdl0bZJ2aB MK3hE9j14+9MHAzi7W9hlviXfsK3PPKh5t8LNO/UJpgpkiLdQHlCeTXoNVwHX+8ait6F51cm2TU Q7xrtoF/jRgVtMOYbTXXjvXC9Rl+yoxycnztORNwo0xyEzmyHvF7DZ8EvW8kQ0CFWc+6qNsH X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-05-13_01,2025-05-09_01,2025-02-21_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 mlxscore=0 impostorscore=0 lowpriorityscore=0 malwarescore=0 phishscore=0 spamscore=0 clxscore=1011 bulkscore=0 mlxlogscore=999 priorityscore=1501 adultscore=0 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2504070000 definitions=main-2505130119 Add device tree documentation for AD4170 and similar sigma-delta ADCs. The AD4170 is a 24-bit, multichannel, sigma-delta ADC. Signed-off-by: Marcelo Schmitt --- Change log v2 -> v3 [device tree changes] - Removed unneeded allOf. - Removed occurences of adi,sensor-type type re-declaration. - Created type for the AD4170 channels, allowing to avoid dt doc repetition. .../bindings/iio/adc/adi,ad4170.yaml | 544 ++++++++++++++++++ MAINTAINERS | 7 + 2 files changed, 551 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/adi,ad4170.yaml diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4170.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4170.yaml new file mode 100644 index 000000000000..0a06258b6631 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4170.yaml @@ -0,0 +1,544 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad4170.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD4170 and similar Analog to Digital Converters + +maintainers: + - Marcelo Schmitt + +description: | + Analog Devices AD4170 series of Sigma-delta Analog to Digital Converters. + Specifications can be found at: + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4170-4.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4190-4.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4195-4.pdf + +$ref: /schemas/spi/spi-peripheral-props.yaml# + +$defs: + ad4170-channel: + type: object + $ref: /schemas/iio/adc/adc.yaml# + description: + Common properties for configuring AD4170 channels. + + properties: + adi,reference-select: + description: | + Selects the reference source to use when converting on the specific + channel. Valid values are: + 0: Differential reference voltage REFIN+ - REFIN−. + 1: Differential reference voltage REFIN2+ - REFIN2−. + 2: Internal 2.5V referece (REFOUT) relative to AVSS. + 3: Analog supply voltage (AVDD) relative AVSS. + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [0, 1, 2, 3] + + + sensor-node: + type: object + $ref: '#/$defs/ad4170-channel' + description: + The AD4170 and similar designs have features to aid interfacing with weigh + scale, RTD, and thermocouple sensors. Each of those sensor types requires + either distinct wiring configuration or external circuitry for proper + sensor operation and can use different AD4170 functionality on their + setups. A key characteristic of those external sensors is that they must + be excited either by voltage supply or by AD4170 excitation signals. The + sensor can then be read through a pair of analog inputs. These properties + describe external sensor circuitry connected to the ADC. + + properties: + reg: + description: + Channel number. Connects the sensor to the channel with this number + of the device. + minimum: 1 + maximum: 16 + + diff-channels: + description: + Defines the ADC input pins used to read sensor data. Only regular + analog input pins can be used. + items: + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8] + + bipolar: true + + adi,sensor-type: + description: | + Type of sensor connected to the device. Depending on the sensor type + (weigh scale, RTD, or thermocouple) the values of sensor-node + properties have slightly different constraints. This property + specifies which particular external sensor is connected to the ADC so + the sensor-node properties can be properly parsed and verified. The + possible sensor types are: + 0: weigh scale; + 1: RTD; + 2: thermocouple. + $ref: /schemas/types.yaml#/definitions/uint8 + + adi,excitation-ac: + type: boolean + description: + Whether the external sensor has to be AC or DC excited. + + adi,excitation-pins: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: + Pins used to excite the sensor or external circuit that contains the + sensor. Thermocouples and RTD sensors are excited either with one + current source or with a pair of current sources to minimize the + excitation current mismatch and the excitation current drift matching + on the ADC. E.g. <0>; <1>; <0 1>. Load cell weigh scales may be + excited with one current source, a pair of excitation currents, or two + pairs of excitation currents. When four pins are defined, the first + two values specify the first pair and the last ones specify the second + pair of excitation currents. E.g. <0>; <0 1>; <0 1 2 3>. + items: + minimum: 0 + maximum: 20 + + adi,excitation-current-microamp: + description: + Excitation current in microamperes to be output to each excitation pin + specified by adi,excitation-pins property. If not provided and + adi,excitation-ac is true, use predefined ACX1, ACX1 negated, ACX2, + and ACX2 negated signals to AC excite the bridge circuit. Those + singals are output on GPIO2, GPIO0, GPIO3, and GPIO1, respectively. + enum: [0, 10, 50, 100, 250, 500, 1000, 1500] + default: 0 + + adi,power-down-switch-pin: + description: + Number of the GPIO used as power-down switch for the bridge circuit. + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [0, 1] + + adi,vbias: + type: boolean + description: + For unbiased thermocouple applications, the voltage generated by the + thermocouple must be biased around some DC voltage. When present, this + property specifies a bias voltage of (AVDD + AVSS)/2 to be applied as + common-mode voltage for the sensor. + + required: + - reg + - diff-channels + - bipolar + - adi,sensor-type + - adi,reference-select + + +properties: + compatible: + enum: + - adi,ad4170 + - adi,ad4190 + - adi,ad4195 + + avss-supply: + description: + Referece voltage supply for AVSS. If provided, describes the magnitude + (absolute value) of the negative voltage supplied to the AVSS pin. Since + AVSS must be −2.625V minimum and 0V maximum, the declared supply voltage + must be between 0 and 2.65V. If not provided, AVSS is assumed to be at + system ground (0V). + + avdd-supply: + description: + A supply of 4.75V to 5.25V relative to AVSS that powers the chip (AVDD). + + iovdd-supply: + description: 1.7V to 5.25V reference supply to the serial interface (IOVDD). + + refin1p-supply: + description: REFIN+ supply that can be used as reference for conversion. + + refin1n-supply: + description: REFIN- supply that can be used as reference for conversion. If + provided, describes the magnitude (absolute value) of the negative voltage + supplied to the REFIN- pin. + + refin2p-supply: + description: REFIN2+ supply that can be used as reference for conversion. + + refin2n-supply: + description: REFIN2- supply that can be used as reference for conversion. If + provided, describes the magnitude (absolute value) of the negative voltage + supplied to the REFIN2- pin. + + spi-cpol: true + + spi-cpha: true + + interrupts: + maxItems: 1 + + interrupt-names: + description: + Specify which pin should be configured as Data Ready interrupt. + enum: + - sdo + - dig_aux1 + default: sdo + + clocks: + maxItems: 1 + description: + Optional external clock source. Can specify either an external clock or + external crystal. + + clock-names: + enum: + - ext-clk + - xtal + default: ext-clk + + '#clock-cells': + const: 0 + + clock-output-names: + maxItems: 1 + + gpio-controller: true + + "#gpio-cells": + const: 2 + description: | + The first cell is for the GPIO number: 0 to 3. + The second cell takes standard GPIO flags. + + ldac-gpios: + description: + GPIO connected to DIG_AUX2 pin to be used as LDAC toggle to control the + transfer of data from the DAC_INPUT_A register to the DAC. + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +patternProperties: + "^channel@[0-9a-f]$": + $ref: '#/$defs/ad4170-channel' + unevaluatedProperties: false + description: + Represents the external channels which are connected to the ADC. + + properties: + reg: + description: + The channel number. + minimum: 0 + 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. + + Besides the analog input pins AIN0 to AIN8, there are special inputs + that can be selected with the following values: + 17: Internal temperature sensor + 18: (AVDD-AVSS)/5 + 19: (IOVDD-DGND)/5 + 20: DAC output + 21: ALDO + 22: DLDO + 23: AVSS + 24: DGND + 25: REFIN+ + 26: REFIN- + 27: REFIN2+ + 28: REFIN2- + 29: REFOUT + For the internal temperature sensor, use the input number for both + inputs (i.e. diff-channels = <17 17>). + items: + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29] + + single-channel: true + + common-mode-channel: true + + bipolar: true + + adi,buffered-positive: + description: | + Enable precharge buffer, full buffer, or skip reference buffering of + the positive voltage reference. Because the output impedance of the + source driving the voltage reference inputs may be dynamic, RC + combinations of those inputs can cause DC gain errors if the reference + inputs go unbuffered into the ADC. Enable reference buffering if the + provided reference source has dynamic high impedance output. Note the + absolute voltage allowed on positive reference inputs (REFIN+, + REFIN2+) is from AVSS − 50 mV to AVDD + 50 mV when the reference + buffers are disabled but narrows to AVSS to AVDD when reference + buffering is enabled or in precharge mode. + 0: Reference precharge buffer. + 1: Full Buffer. + 2: Bypass reference buffers (buffering disabled). + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [0, 1, 2] + default: 1 + + adi,buffered-negative: + description: | + Enable precharge buffer, full buffer, or skip reference buffering of + the negative voltage reference. Because the output impedance of the + source driving the voltage reference inputs may be dynamic, RC + combinations of those inputs can cause DC gain errors if the reference + inputs go unbuffered into the ADC. Enable reference buffering if the + provided reference source has dynamic high impedance output. Note the + absolute voltage allowed on negative reference inputs (REFIN-, + REFIN2-) is from AVSS − 50 mV to AVDD + 50 mV when the reference + buffers are disabled but narrows to AVSS to AVDD when reference + buffering is enabled or in precharge mode. + 0: Reference precharge buffer. + 1: Full Buffer. + 2: Bypass reference buffers (buffering disabled). + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [0, 1, 2] + default: 1 + + required: + - reg + + oneOf: + - required: [single-channel] + properties: + diff-channels: false + - required: [diff-channels] + properties: + single-channel: false + common-mode-channel: false + + "^weighscale@": + $ref: '#/$defs/sensor-node' + unevaluatedProperties: false + + properties: + diff-channels: true + bipolar: true + + adi,sensor-type: + description: Weigh scale sensor. + const: 0 + + adi,excitation-pins: true + + "^rtd@": + $ref: '#/$defs/sensor-node' + unevaluatedProperties: false + + properties: + diff-channels: true + bipolar: true + + adi,sensor-type: + description: RTD sensor. + const: 1 + + adi,excitation-pins: true + + adi,excitation-current-microamp: true + + required: + - adi,excitation-pins + - adi,excitation-current-microamp + + "^thermocouple@": + $ref: '#/$defs/sensor-node' + unevaluatedProperties: false + + properties: + diff-channels: true + bipolar: true + + adi,sensor-type: + description: Thermocouple sensor. + const: 2 + + required: + - adi,excitation-pins + - adi,excitation-current-microamp + +required: + - compatible + - reg + - avdd-supply + - iovdd-supply + - spi-cpol + - spi-cpha + +allOf: + # Some devices don't have integrated DAC + - if: + properties: + compatible: + contains: + enum: + - adi,ad4190 + - adi,ad4195 + then: + properties: + ldac-gpios: false + +unevaluatedProperties: false + +examples: + - | + #include + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad4170"; + reg = <0>; + spi-max-frequency = <20000000>; + spi-cpol; + spi-cpha; + avdd-supply = <&avdd>; + iovdd-supply = <&iovdd>; + interrupt-parent = <&gpio_in>; + interrupts = <0 IRQ_TYPE_EDGE_FALLING>; + #address-cells = <1>; + #size-cells = <0>; + + // Sample AIN0 with respect to DGND throughout AVDD/DGND input range + // Pseudo-differential unipolar + channel@0 { + reg = <0>; + single-channel = <0>; + common-mode-channel = <24>; + adi,reference-select = /bits/ 8 <3>; + }; + // Weigh scale sensor + weighscale@1 { + reg = <1>; + bipolar; + diff-channels = <1 2>; + adi,sensor-type = /bits/ 8 <0>; + adi,reference-select = /bits/ 8 <0>; + adi,excitation-ac; + adi,excitation-pins = <19 20>; + adi,power-down-switch-pin = /bits/ 8 <0>; + }; + // RTD sensor + rtd@2 { + reg = <2>; + bipolar; + diff-channels = <3 4>; + adi,sensor-type = /bits/ 8 <1>; + adi,reference-select = /bits/ 8 <0>; + adi,excitation-ac; + adi,excitation-pins = <5 6>; + adi,excitation-current-microamp = <500>; + }; + // Thermocouple sensor + thermocouple@3 { + reg = <3>; + bipolar; + diff-channels = <7 8>; + adi,sensor-type = /bits/ 8 <2>; + adi,reference-select = /bits/ 8 <0>; + adi,excitation-pins = <18>; + adi,excitation-current-microamp = <500>; + adi,vbias; + }; + }; + }; + - | + #include + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad4170"; + reg = <0>; + spi-max-frequency = <20000000>; + spi-cpol; + spi-cpha; + avdd-supply = <&avdd>; + iovdd-supply = <&iovdd>; + interrupt-parent = <&gpio_in>; + interrupts = <0 IRQ_TYPE_EDGE_FALLING>; + #address-cells = <1>; + #size-cells = <0>; + + // Sample AIN0 with respect to AIN1 throughout AVDD/AVSS input range + // Differential bipolar. If AVSS < 0V, differential true bipolar + channel@0 { + reg = <0>; + bipolar; + diff-channels = <0 1>; + adi,reference-select = /bits/ 8 <3>; + }; + // Sample AIN2 with respect to DGND throughout AVDD/DGND input range + // Pseudo-differential unipolar + channel@1 { + reg = <1>; + single-channel = <2>; + common-mode-channel = <24>; + adi,reference-select = /bits/ 8 <3>; + }; + // Sample AIN3 with respect to 2.5V throughout AVDD/AVSS input range + // Pseudo-differential bipolar + channel@2 { + reg = <2>; + bipolar; + single-channel = <3>; + common-mode-channel = <29>; + adi,reference-select = /bits/ 8 <3>; + }; + // Sample AIN4 with respect to DGND throughout AVDD/AVSS input range + // Pseudo-differential bipolar + channel@3 { + reg = <3>; + bipolar; + single-channel = <4>; + common-mode-channel = <24>; + adi,reference-select = /bits/ 8 <3>; + }; + // Sample AIN5 with respect to 2.5V throughout AVDD/AVSS input range + // Pseudo-differential unipolar (AD4170 datasheet page 46 example) + channel@4 { + reg = <4>; + single-channel = <5>; + common-mode-channel = <29>; + adi,reference-select = /bits/ 8 <3>; + }; + // Sample AIN6 with respect to 2.5V throughout REFIN+/REFIN- input range + // Pseudo-differential bipolar + channel@5 { + reg = <5>; + bipolar; + single-channel = <6>; + common-mode-channel = <29>; + adi,reference-select = /bits/ 8 <0>; + }; + // Weigh scale sensor + weighscale@6 { + reg = <6>; + bipolar; + diff-channels = <7 8>; + adi,reference-select = /bits/ 8 <0>; + adi,sensor-type = /bits/ 8 <0>; + adi,excitation-ac; + adi,excitation-pins = <17 18 19 20>; + }; + }; + }; +... + diff --git a/MAINTAINERS b/MAINTAINERS index cc9582b14ced..0a8f2c7a139c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1346,6 +1346,13 @@ F: Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 F: Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml F: drivers/iio/adc/ad4130.c +ANALOG DEVICES INC AD4170 DRIVER +M: Marcelo Schmitt +L: linux-iio@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/adc/adi,ad4170.yaml + ANALOG DEVICES INC AD4695 DRIVER M: Michael Hennerich M: Nuno Sá From patchwork Tue May 13 12:34:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Schmitt X-Patchwork-Id: 889714 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (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 6CFF628E611; Tue, 13 May 2025 12:34:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747139700; cv=none; b=dtAPWupeDILyvoTon00pIe2BGc5UsNKa+3deB0WJLLnOJ8miZrWqliQurWdGR4+cbE+LEcQvTYRoXKchp4/Vqa3qjQF1oJNS+ulkWWhyIfz1u3sMhUEbYAryxHaduJXcR0vDGxzCnhYoS8IDJErzzB6fJ+UF8jiGO6iSYu1XYR8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747139700; c=relaxed/simple; bh=hBqY7u/JnFjJI/w3/g/c4OXToszQ46fwTlYxmxVH6dk=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KrPNMxar265lRjBRmO6GHz54t+HGrcxhpfLbOHDvoEYGk8+rW1VybE5wy2z1cnsY6RhTcxOEAvrs73SR9nfuEe9aoYld8y6ULGaossaXh4SZh9JICW2UQ+dS//JVy/NmxVfXHgiW+xZKvUMuiF8+RTvEgKOHWOD5cKBlZeoGfX4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=CpuwGsgE; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="CpuwGsgE" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 54DBD59m008282; Tue, 13 May 2025 08:34:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=MecMS khtk5Z+MMSqon8pWjK1qRD4kS9uLF0Vm6JB3hs=; b=CpuwGsgEoyFjL/y05oHlP 7zNEK6XOgfrxgCE+zQEeEvwKnboFvg8miKY9UqjDAzypy6yoTQ1SeeCI9s5PQgb5 t8Fbr3qKM5S++MQxnBGu4vsN6zgIeg2OD3M38ssxYfzdcn3oIdkeEpvxt0K3w2T1 +taOiTa8jZkh02fzU6RQY4aZv2ifaeMdo5MMmnHPdYJQgX8K2Lvs8mu2DfasyDGG nJOLB3Aq79ZMcsCHCEo4EQmGh6MWKaE/Airoa5mKi6TKarzcRezeQsdf/7svNC1u JIfoGvdVtsjBrYDDmLeOZGGcga86oaFS0qPukuHXEqEINi3oN2xQzGUt9UdSkKHM A== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 46kx53aesr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 13 May 2025 08:34:41 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 54DCYeIB041010 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 13 May 2025 08:34:40 -0400 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Tue, 13 May 2025 08:34:40 -0400 Received: from ASHBMBX9.ad.analog.com (10.64.17.10) by ASHBCASHYB4.ad.analog.com (10.64.17.132) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Tue, 13 May 2025 08:34:40 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server id 15.2.986.14 via Frontend Transport; Tue, 13 May 2025 08:34:40 -0400 Received: from work.ad.analog.com (HYB-hERzalRezfV.ad.analog.com [10.65.205.9]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 54DCYM1r007472; Tue, 13 May 2025 08:34:25 -0400 From: Marcelo Schmitt To: , , , CC: , , , , , , , , , , , Subject: [PATCH v3 03/10] iio: adc: ad4170: Add support for calibration gain Date: Tue, 13 May 2025 09:34:20 -0300 Message-ID: <3d255162174ab160c3fd06af3c27360947c2a566.1747083143.git.marcelo.schmitt@analog.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=a4sw9VSF c=1 sm=1 tr=0 ts=68233c61 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=dt9VzEwgFbYA:10 a=gAnH3GRIAAAA:8 a=s1qB4CsIdprNQQnv0OQA:9 X-Proofpoint-ORIG-GUID: OecLo8QBvF6yxvGH-r1AeWdjWQvteiT_ X-Proofpoint-GUID: OecLo8QBvF6yxvGH-r1AeWdjWQvteiT_ X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNTEzMDExOSBTYWx0ZWRfX0fvxGeZTsq6H LmMDIsy7vkehmNs86dLtpPZl05swD8vXzA+FigZaSBhdMNB1xzNAJpWWSauryVaGhN3rsVsb/HW k3HT/2t57uf8cJFdHdriwN3vre15R2tr2s927T5HMHPqMr+UiTL8qs48R77DPXHgjB+ubcwJ7fF qFG3juiBgPu7BbPm/vMezpplZmwB5BARH2IltA6/vhqjFu0jGE+ymZQSO1JfXA7eF/X98HiTBGx LroblUkWmfT3jnKHDB+nBLmC5fHrPHyyyvf5sGiDTDRUIGOZtsUcc09MWSYm73fuG2dCikgB6AY CKUZeOiZf2tuvpfeT+6i4YuV/ExDWpWCPS235xR3nMyN39ND4VTxhfBdXY3jttCZkmyGve/pz/o j6+WRzQkEet/5s19cBzTwezG9/VpgBY8RzMIWuq78KL/9d/tdiwh4OQlWqa0BqHsw9HqUYuV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-05-13_01,2025-05-09_01,2025-02-21_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 mlxscore=0 impostorscore=0 lowpriorityscore=0 malwarescore=0 phishscore=0 spamscore=0 clxscore=1015 bulkscore=0 mlxlogscore=999 priorityscore=1501 adultscore=0 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2504070000 definitions=main-2505130119 Add support for ADC calibration gain configuration. Signed-off-by: Marcelo Schmitt --- Change log v2 -> v3 - New patch spun out of the base driver patch. drivers/iio/adc/ad4170.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/ad4170.c b/drivers/iio/adc/ad4170.c index bf19b31095ee..1df214f7fdec 100644 --- a/drivers/iio/adc/ad4170.c +++ b/drivers/iio/adc/ad4170.c @@ -642,7 +642,8 @@ static const struct iio_chan_spec ad4170_channel_template = { .differential = 1, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) | - BIT(IIO_CHAN_INFO_OFFSET), + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_CALIBSCALE), .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE), .scan_type = { .realbits = 24, @@ -953,6 +954,9 @@ static int ad4170_read_raw(struct iio_dev *indio_dev, pga = FIELD_GET(AD4170_AFE_PGA_GAIN_MSK, setup->afe); *val = chan_info->offset_tbl[pga]; return IIO_VAL_INT; + case IIO_CHAN_INFO_CALIBSCALE: + *val = setup->gain; + return IIO_VAL_INT; default: return -EINVAL; } @@ -1079,6 +1083,25 @@ static int ad4170_set_pga(struct ad4170_state *st, return 0; } +static int ad4170_set_calib_gain(struct ad4170_state *st, + struct iio_chan_spec const *chan, int val) +{ + struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address]; + struct ad4170_setup *setup = &chan_info->setup; + u32 old_gain; + int ret; + + guard(mutex)(&st->lock); + old_gain = setup->gain; + setup->gain = val; + + ret = ad4170_write_channel_setup(st, chan->address, false); + if (ret) + setup->gain = old_gain; + + return ret; +} + static int __ad4170_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long info) @@ -1088,6 +1111,8 @@ static int __ad4170_write_raw(struct iio_dev *indio_dev, switch (info) { case IIO_CHAN_INFO_SCALE: return ad4170_set_pga(st, chan, val, val2); + case IIO_CHAN_INFO_CALIBSCALE: + return ad4170_set_calib_gain(st, chan, val); default: return -EINVAL; } @@ -1114,6 +1139,8 @@ static int ad4170_write_raw_get_fmt(struct iio_dev *indio_dev, switch (info) { case IIO_CHAN_INFO_SCALE: return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_CALIBSCALE: + return IIO_VAL_INT; default: return -EINVAL; } From patchwork Tue May 13 12:35:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Schmitt X-Patchwork-Id: 889713 Received: from mx0b-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (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 3B3B328DB63; Tue, 13 May 2025 12:35:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747139744; cv=none; b=tSkVAuLgoWamXrrfIjN9rNnQJ102R1u+mPiDBDUdibCPQwQQtTMwb5zZyINgd/CjVzenFgnGNhlNeyCB/OaccXB9bc45LmBWJkbiQpjGxS750NY3MvTA5ueN0p4m+ucDEerXGgVerDwvpG2p3wCnUZPBGz4qjwnUcC7e8nzTuUU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747139744; c=relaxed/simple; bh=8i0mdMGfoV+X/otgRrlZNfCU3lN6XK+bfU0RN4b5sK0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=n4sbUwq5Ucgg/nRmUWw+iLYkKtHS56KK653/6vCvJmW6bGaG1OQTsGw/itVg07qmDakC+L+vLz9BTWBkyYTbguB7Zn+F2B/LCjHX4lowlcEycgd8KLoI2XZuLOwuoMJ36zAVETfujJJf/xWa6sMtnauntkU8a5O3i/RUEc3407w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=ZZRjlRKf; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="ZZRjlRKf" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 54D9mUiX024893; Tue, 13 May 2025 08:35:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=z8poM TgfgJpehm0CCKfPj8e7T093AIjwyYHgvo/BO88=; b=ZZRjlRKfOhPUFxOsrHdDx fyYWk1TdyKAeQXCyDGAYr3s+sa+VO9wq64WoiE8jwwHKazWCMmmmwVenBMBZD5YQ A4hAKNwkkLN21RS2tnFO3rFjRyZUmTt5bIrndvOyei0JQqAEEi7NnOTpZPupAtXK /JqfSqO15mGd/7D24YC2tpfMucYdIawUmmssZAiVHGlEsJpZ+E2677aqe5NrAs15 JQx6dBtFIiYH4BrpMwhdp3qfBA4uoif9lSJ3fQ2MQgU8wVFt99i4HziDIv+bGLRb A9tTBaN4SjMP3nu4Bv+zobyJrdv7Fp1Gb2C8yrEiZX9xFlP5YL0RjhEnAPolmKWg Q== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 46m3s98sr8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 13 May 2025 08:35:22 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 54DCZLH7041126 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 13 May 2025 08:35:21 -0400 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) by ASHBMBX9.ad.analog.com (10.64.17.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Tue, 13 May 2025 08:35:21 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBCASHYB5.ad.analog.com (10.64.17.133) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Tue, 13 May 2025 08:35:21 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.986.14 via Frontend Transport; Tue, 13 May 2025 08:35:21 -0400 Received: from work.ad.analog.com (HYB-hERzalRezfV.ad.analog.com [10.65.205.9]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 54DCZ4sH007517; Tue, 13 May 2025 08:35:07 -0400 From: Marcelo Schmitt To: , , , CC: , , , , , , , , , , , Subject: [PATCH v3 05/10] iio: adc: ad4170: Add digital filter and sample frequency config support Date: Tue, 13 May 2025 09:35:03 -0300 Message-ID: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: sWZ6MJWJqfHI8fPQzF6Q5Dv2TL1kCTBy X-Authority-Analysis: v=2.4 cv=ZaUdNtVA c=1 sm=1 tr=0 ts=68233c8a cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=dt9VzEwgFbYA:10 a=gAnH3GRIAAAA:8 a=EmSbnTKpHicewLe-UmcA:9 X-Proofpoint-GUID: sWZ6MJWJqfHI8fPQzF6Q5Dv2TL1kCTBy X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNTEzMDExNyBTYWx0ZWRfX+sHzHAvCyTfv WccJqfOY2JZ88YittuYCG0qnVSD9LrQz3FsHdH6iAKpMU0XGMJ0AzhYTKSiQPAHEH7eOKDrPQGF O/ie0HFBAMEZidmzjfU58Vz/BBNLwaNwGhGVrsjhkiYnDCD2QjVhjAX2j3GzKhY7Jca/Z5r9OfC yNJ90YfRycxySnajVwGASC9ycw4JP0qvyH7rd+hl2GXE2bTnMyvRJ+5fBq0EattRXRF8lLtGVKp ekVZUZpnYA0ykoXKNjl4qgO1AtFfP0ZOmQFaGVzTSzZvlUQXFHUA0fFF5sY3dr+9iSYi7ojkL+D kP/EyeQfwXQnctV45nob70fMpXGa6G8zKzq5O9c+E5dBrCocNR/GulcW+mSNj80k+AO2SmUSw1z LHwXokxYLNNmYclL2z8l9i4NyKNMtF1+C0TagnLG/ZkYCwuG9nkamE//gRklIQ7XIxro9uOW X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-05-13_01,2025-05-09_01,2025-02-21_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 malwarescore=0 bulkscore=0 phishscore=0 clxscore=1015 mlxscore=0 impostorscore=0 suspectscore=0 mlxlogscore=999 adultscore=0 spamscore=0 priorityscore=1501 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2504070000 definitions=main-2505130117 Add support for sinc3, sinc5, and averaged sinc5 digital filters along with sample frequency configuration. Signed-off-by: Marcelo Schmitt --- Change log v2 -> v3 - New patch spun out of the base driver patch. drivers/iio/adc/ad4170.c | 273 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 270 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ad4170.c b/drivers/iio/adc/ad4170.c index b02fdd25b4c8..218f768042fe 100644 --- a/drivers/iio/adc/ad4170.c +++ b/drivers/iio/adc/ad4170.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,9 @@ #define AD4170_AFE_BIPOLAR_MSK BIT(4) #define AD4170_AFE_PGA_GAIN_MSK GENMASK(3, 0) +/* AD4170_FILTER_REG */ +#define AD4170_FILTER_FILTER_TYPE_MSK GENMASK(3, 0) + /* AD4170 register constants */ /* AD4170_CHAN_MAP_REG constants */ @@ -109,6 +113,11 @@ #define AD4170_ADC_CTRL_MODE_SINGLE 0x4 #define AD4170_ADC_CTRL_MODE_IDLE 0x7 +/* AD4170_FILTER_REG constants */ +#define AD4170_FILTER_FILTER_TYPE_SINC5_AVG 0x0 +#define AD4170_FILTER_FILTER_TYPE_SINC5 0x4 +#define AD4170_FILTER_FILTER_TYPE_SINC3 0x6 + /* Device properties and auxiliary constants */ #define AD4170_NUM_ANALOG_PINS 9 @@ -117,6 +126,7 @@ #define AD4170_MAX_SETUPS 8 #define AD4170_INVALID_SETUP 9 #define AD4170_SPI_MAX_XFER_LEN 6 +#define AD4170_DEFAULT_SAMP_RATE (125 * HZ_PER_KHZ) #define AD4170_INT_REF_2_5V 2500000 @@ -125,6 +135,12 @@ #define AD4170_NUM_PGA_OPTIONS 10 +/* Digital filter properties */ +#define AD4170_SINC3_MIN_FS 4 +#define AD4170_SINC3_MAX_FS 65532 +#define AD4170_SINC5_MIN_FS 1 +#define AD4170_SINC5_MAX_FS 256 + #define AD4170_GAIN_REG_DEFAULT 0x555555 /* Analog pin functions */ @@ -181,6 +197,12 @@ enum ad4170_ref_select { AD4170_REF_AVDD }; +enum ad4170_filter_type { + AD4170_SINC5_AVG, + AD4170_SINC5, + AD4170_SINC3, +}; + enum ad4170_regulator { AD4170_AVDD_SUP, AD4170_AVSS_SUP, @@ -202,6 +224,18 @@ static const char * const ad4170_int_pin_names[] = { [AD4170_INT_PIN_DIG_AUX1] = "dig_aux1", }; +static const unsigned int ad4170_sinc3_filt_fs_tbl[] = { + 4, 8, 12, 16, 20, 40, 48, 80, /* 0 - 7 */ + 100, 256, 500, 1000, 5000, 8332, 10000, 25000, /* 8 - 15 */ + 50000, 65532, /* 16 - 17 */ +}; + +#define AD4170_MAX_FS_TBL_SIZE ARRAY_SIZE(ad4170_sinc3_filt_fs_tbl) + +static const unsigned int ad4170_sinc5_filt_fs_tbl[] = { + 1, 2, 4, 8, 12, 16, 20, 40, 48, 80, 100, 256, +}; + struct ad4170_chip_info { const char *name; }; @@ -259,6 +293,12 @@ struct ad4170_chan_info { bool enabled; }; +static const char * const ad4170_filt_names[] = { + [AD4170_SINC5_AVG] = "sinc5+avg", + [AD4170_SINC5] = "sinc5", + [AD4170_SINC3] = "sinc3", +}; + struct ad4170_state { struct mutex lock; /* Protect read-modify-write and multi write sequences */ int vrefs_uv[AD4170_MAX_SUP]; @@ -268,6 +308,7 @@ struct ad4170_state { struct ad4170_chan_info chan_infos[AD4170_MAX_CHANNELS]; struct spi_device *spi; struct regmap *regmap; + int sps_tbl[ARRAY_SIZE(ad4170_filt_names)][AD4170_MAX_FS_TBL_SIZE][2]; int pins_fn[AD4170_NUM_ANALOG_PINS]; u32 int_pin_sel; struct completion completion; @@ -279,6 +320,38 @@ struct ad4170_state { u8 rx_buf[4]; }; +static void ad4170_fill_sps_tbl(struct ad4170_state *st) +{ + unsigned int tmp0, tmp1, i; + + /* + * The ODR can be calculated the same way for sinc5+avg, sinc5, and + * sinc3 filter types with the exception that sinc5 filter has a + * narrowed range of allowed FILTER_FS values. + */ + for (i = 0; i < ARRAY_SIZE(ad4170_sinc3_filt_fs_tbl); i++) { + tmp0 = div_u64_rem(st->mclk_hz, 32 * ad4170_sinc3_filt_fs_tbl[i], + &tmp1); + tmp1 = mult_frac(tmp1, MICRO, 32 * ad4170_sinc3_filt_fs_tbl[i]); + /* Fill sinc5+avg filter SPS table */ + st->sps_tbl[AD4170_SINC5_AVG][i][0] = tmp0; /* Integer part */ + st->sps_tbl[AD4170_SINC5_AVG][i][1] = tmp1; /* Fractional part */ + + /* Fill sinc3 filter SPS table */ + st->sps_tbl[AD4170_SINC3][i][0] = tmp0; /* Integer part */ + st->sps_tbl[AD4170_SINC3][i][1] = tmp1; /* Fractional part */ + } + /* Sinc5 filter ODR doesn't use all FILTER_FS bits */ + for (i = 0; i < ARRAY_SIZE(ad4170_sinc5_filt_fs_tbl); i++) { + tmp0 = div_u64_rem(st->mclk_hz, 32 * ad4170_sinc5_filt_fs_tbl[i], + &tmp1); + tmp1 = mult_frac(tmp1, MICRO, 32 * ad4170_sinc5_filt_fs_tbl[i]); + /* Fill sinc5 filter SPS table */ + st->sps_tbl[AD4170_SINC5][i][0] = tmp0; /* Integer part */ + st->sps_tbl[AD4170_SINC5][i][1] = tmp1; /* Fractional part */ + } +} + static int ad4170_debugfs_reg_access(struct iio_dev *indio_dev, unsigned int reg, unsigned int writeval, unsigned int *readval) @@ -636,6 +709,105 @@ static int ad4170_set_channel_enable(struct ad4170_state *st, return 0; } +static int __ad4170_get_filter_type(unsigned int filter) +{ + u16 f_conf = FIELD_GET(AD4170_FILTER_FILTER_TYPE_MSK, filter); + + switch (f_conf) { + case AD4170_FILTER_FILTER_TYPE_SINC5_AVG: + return AD4170_SINC5_AVG; + case AD4170_FILTER_FILTER_TYPE_SINC5: + return AD4170_SINC5; + case AD4170_FILTER_FILTER_TYPE_SINC3: + return AD4170_SINC3; + default: + return -EINVAL; + } +} + +static int ad4170_set_filter_type(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + unsigned int val) +{ + struct ad4170_state *st = iio_priv(indio_dev); + struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address]; + struct ad4170_setup *setup = &chan_info->setup; + unsigned int old_filter_fs, old_filter, filter_type_conf; + int ret; + + switch (val) { + case AD4170_SINC5_AVG: + filter_type_conf = AD4170_FILTER_FILTER_TYPE_SINC5_AVG; + break; + case AD4170_SINC5: + filter_type_conf = AD4170_FILTER_FILTER_TYPE_SINC5; + break; + case AD4170_SINC3: + filter_type_conf = AD4170_FILTER_FILTER_TYPE_SINC3; + break; + default: + return -EINVAL; + } + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + guard(mutex)(&st->lock); + /* + * The filters provide the same ODR for a given filter_fs value but + * there are different minimum and maximum filter_fs limits for each + * filter. The filter_fs value will be adjusted if the current filter_fs + * is out of the limits of the just requested filter. Since the + * filter_fs value affects the ODR (sampling_frequency), changing the + * filter may lead to a change in the sampling frequency. + */ + old_filter = setup->filter; + old_filter_fs = setup->filter_fs; + if (val == AD4170_SINC5_AVG || val == AD4170_SINC3) + setup->filter_fs = clamp(val, AD4170_SINC3_MIN_FS, + AD4170_SINC3_MAX_FS); + else + setup->filter_fs = clamp(val, AD4170_SINC5_MIN_FS, + AD4170_SINC5_MAX_FS); + + setup->filter &= ~AD4170_FILTER_FILTER_TYPE_MSK; + setup->filter |= FIELD_PREP(AD4170_FILTER_FILTER_TYPE_MSK, + filter_type_conf); + + ret = ad4170_write_channel_setup(st, chan->address, false); + if (ret) { + setup->filter = old_filter; + setup->filter_fs = old_filter_fs; + } + + iio_device_release_direct(indio_dev); + return ret; +} + +static int ad4170_get_filter_type(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan) +{ + struct ad4170_state *st = iio_priv(indio_dev); + struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address]; + struct ad4170_setup *setup = &chan_info->setup; + + return __ad4170_get_filter_type(setup->filter); +} + +static const struct iio_enum ad4170_filter_type_enum = { + .items = ad4170_filt_names, + .num_items = ARRAY_SIZE(ad4170_filt_names), + .get = ad4170_get_filter_type, + .set = ad4170_set_filter_type, +}; + +static const struct iio_chan_spec_ext_info ad4170_filter_type_ext_info[] = { + IIO_ENUM("filter_type", IIO_SEPARATE, &ad4170_filter_type_enum), + IIO_ENUM_AVAILABLE("filter_type", IIO_SHARED_BY_TYPE, + &ad4170_filter_type_enum), + { } +}; + static const struct iio_chan_spec ad4170_channel_template = { .type = IIO_VOLTAGE, .indexed = 1, @@ -644,8 +816,11 @@ static const struct iio_chan_spec ad4170_channel_template = { BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_CALIBBIAS) | - BIT(IIO_CHAN_INFO_CALIBSCALE), - .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE), + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), + .ext_info = ad4170_filter_type_ext_info, .scan_type = { .realbits = 24, .storagebits = 32, @@ -935,7 +1110,8 @@ static int ad4170_read_raw(struct iio_dev *indio_dev, struct ad4170_state *st = iio_priv(indio_dev); struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address]; struct ad4170_setup *setup = &chan_info->setup; - unsigned int pga; + enum ad4170_filter_type f_type; + unsigned int pga, fs_idx; int ret; switch (info) { @@ -955,6 +1131,27 @@ static int ad4170_read_raw(struct iio_dev *indio_dev, pga = FIELD_GET(AD4170_AFE_PGA_GAIN_MSK, setup->afe); *val = chan_info->offset_tbl[pga]; return IIO_VAL_INT; + case IIO_CHAN_INFO_SAMP_FREQ: + f_type = __ad4170_get_filter_type(setup->filter); + switch (f_type) { + case AD4170_SINC5_AVG: + case AD4170_SINC3: + fs_idx = find_closest(setup->filter_fs, + ad4170_sinc3_filt_fs_tbl, + ARRAY_SIZE(ad4170_sinc3_filt_fs_tbl)); + *val = st->sps_tbl[f_type][fs_idx][0]; + *val2 = st->sps_tbl[f_type][fs_idx][1]; + return IIO_VAL_INT_PLUS_MICRO; + case AD4170_SINC5: + fs_idx = find_closest(setup->filter_fs, + ad4170_sinc5_filt_fs_tbl, + ARRAY_SIZE(ad4170_sinc5_filt_fs_tbl)); + *val = st->sps_tbl[f_type][fs_idx][0]; + *val2 = st->sps_tbl[f_type][fs_idx][1]; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } case IIO_CHAN_INFO_CALIBBIAS: *val = setup->offset; return IIO_VAL_INT; @@ -1040,6 +1237,7 @@ static int ad4170_read_avail(struct iio_dev *indio_dev, { struct ad4170_state *st = iio_priv(indio_dev); struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address]; + enum ad4170_filter_type f_type; switch (info) { case IIO_CHAN_INFO_SCALE: @@ -1047,6 +1245,21 @@ static int ad4170_read_avail(struct iio_dev *indio_dev, *length = ARRAY_SIZE(chan_info->scale_tbl) * 2; *type = IIO_VAL_INT_PLUS_NANO; return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + f_type = ad4170_get_filter_type(indio_dev, chan); + *vals = (int *)st->sps_tbl[f_type]; + *type = IIO_VAL_INT_PLUS_MICRO; + switch (f_type) { + case AD4170_SINC5_AVG: + case AD4170_SINC3: + *length = ARRAY_SIZE(ad4170_sinc3_filt_fs_tbl) * 2; + return IIO_AVAIL_LIST; + case AD4170_SINC5: + *length = ARRAY_SIZE(ad4170_sinc5_filt_fs_tbl) * 2; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } default: return -EINVAL; } @@ -1087,6 +1300,48 @@ static int ad4170_set_pga(struct ad4170_state *st, return 0; } +static int ad4170_set_channel_freq(struct ad4170_state *st, + struct iio_chan_spec const *chan, int val, + int val2) +{ + struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address]; + struct ad4170_setup *setup = &chan_info->setup; + enum ad4170_filter_type f_type = __ad4170_get_filter_type(setup->filter); + unsigned int old_filter_fs, i; + int filt_fs_tbl_size, ret; + + switch (f_type) { + case AD4170_SINC5_AVG: + case AD4170_SINC3: + filt_fs_tbl_size = ARRAY_SIZE(ad4170_sinc3_filt_fs_tbl); + break; + case AD4170_SINC5: + filt_fs_tbl_size = ARRAY_SIZE(ad4170_sinc5_filt_fs_tbl); + break; + } + + for (i = 0; i < filt_fs_tbl_size; i++) { + if (st->sps_tbl[f_type][i][0] == val && + st->sps_tbl[f_type][i][1] == val2) + break; + } + if (i == filt_fs_tbl_size) + return -EINVAL; + + guard(mutex)(&st->lock); + old_filter_fs = setup->filter_fs; + if (f_type == AD4170_SINC5) + setup->filter_fs = ad4170_sinc5_filt_fs_tbl[i]; + else + setup->filter_fs = ad4170_sinc3_filt_fs_tbl[i]; + + ret = ad4170_write_channel_setup(st, chan->address, false); + if (ret) + setup->filter_fs = old_filter_fs; + + return ret; +} + static int ad4170_set_calib_offset(struct ad4170_state *st, struct iio_chan_spec const *chan, int val) { @@ -1134,6 +1389,8 @@ static int __ad4170_write_raw(struct iio_dev *indio_dev, switch (info) { case IIO_CHAN_INFO_SCALE: return ad4170_set_pga(st, chan, val, val2); + case IIO_CHAN_INFO_SAMP_FREQ: + return ad4170_set_channel_freq(st, chan, val, val2); case IIO_CHAN_INFO_CALIBBIAS: return ad4170_set_calib_offset(st, chan, val); case IIO_CHAN_INFO_CALIBSCALE: @@ -1164,6 +1421,8 @@ static int ad4170_write_raw_get_fmt(struct iio_dev *indio_dev, switch (info) { case IIO_CHAN_INFO_SCALE: return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_SAMP_FREQ: + return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_CALIBBIAS: case IIO_CHAN_INFO_CALIBSCALE: return IIO_VAL_INT; @@ -1398,6 +1657,8 @@ static int ad4170_initial_config(struct iio_dev *indio_dev) unsigned int i; int ret; + ad4170_fill_sps_tbl(st); + ret = ad4170_set_mode(st, AD4170_ADC_CTRL_MODE_IDLE); if (ret) return dev_err_probe(dev, ret, @@ -1427,6 +1688,12 @@ static int ad4170_initial_config(struct iio_dev *indio_dev) return dev_err_probe(dev, ret, "Failed to write CHAN_MAP_REG\n"); + ret = ad4170_set_channel_freq(st, chan, + AD4170_DEFAULT_SAMP_RATE, 0); + if (ret) + return dev_err_probe(dev, ret, + "Failed to set channel freq\n"); + ret = ad4170_fill_scale_tbl(indio_dev, chan); if (ret) return dev_err_probe(dev, ret, From patchwork Tue May 13 12:35:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Marcelo Schmitt X-Patchwork-Id: 889712 Received: from mx0b-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (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 398C723957D; Tue, 13 May 2025 12:36:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747139783; cv=none; b=qcA3XPhpk5UpJS27V2tNXezIP94TqwsgcYgGrgzSuBoD/y760kukVvfE9vdS9tU45cUf39wWzcJr5pj0ajKeG6PMXsGUC8BX1xN1DlnbtdhoDGZ2TltmnYGoXd4DG+MDs6au0551dpDSSgTXHRlTJVL4j3muaob8OM/gI1rz79k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747139783; c=relaxed/simple; bh=g48L3w+JVLetESqqX32XneL1nuq5ExrV//oSXMzrWUM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=RqJp4bIyEgtyguNYqpE5Ic0mDP2363DXRfEBzKOXwtZlF+2IEafhuQ459FGy9n+S/8zIrV+Ab09J1sf/4BfgH4BuenkxIE4mggwgjeyKBcwAKd85NC5ogIq+msDvJQE8a2zyBIvHvg/pI+8O0hqBeDrfDwOYLUIvE7QcMmZz4F8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=p1kLs95g; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="p1kLs95g" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 54D9mUid024893; Tue, 13 May 2025 08:36:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=lGATG YZcOXsxd+o4S9Rph4vKmg3hISyWeCh2thUI9s0=; b=p1kLs95gGVEG7vei/7F+s 3ioPHBNmqwwUeka2URJ+qsJmugr8PYMMCZZOO8cLR7nx73rimR7f/PetxDlDSc94 4Z1lxrsxb1c9pZLJytPerWVlLhhebGBpDqMwuOaWOoK+lK9evQ8i7NzhfAtxO6kv 1oqbQxFoiY5BnS87ZFhtyndcOH3g+W+KdUzFE3GBlndpk8uEHKQf5iztd5VvuGO/ GoxuI7/i0u0l0KIvP6HOh9yGQ9HYE8BUpkuzp+x2V3Hr8R91DbixsiQ9wJdryZOC f4ZGN0f6U/vPD8RzDut63gx+V7G+1xryobu9IoxfxCveXlXQDzGAL9A6OHtoiUqb w== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 46m3s98sub-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 13 May 2025 08:36:03 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 54DCa2RT041171 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 13 May 2025 08:36:02 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Tue, 13 May 2025 08:36:02 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.986.14 via Frontend Transport; Tue, 13 May 2025 08:36:02 -0400 Received: from work.ad.analog.com (HYB-hERzalRezfV.ad.analog.com [10.65.205.9]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 54DCZlON007532; Tue, 13 May 2025 08:35:50 -0400 From: Marcelo Schmitt To: , , , CC: , , , , , , , , , , , Subject: [PATCH v3 07/10] iio: adc: ad4170: Add clock provider support Date: Tue, 13 May 2025 09:35:46 -0300 Message-ID: X-Mailer: git-send-email 2.39.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: vYWJGd9iGDPRTdL50APjgEAkuL5jp5At X-Authority-Analysis: v=2.4 cv=ZaUdNtVA c=1 sm=1 tr=0 ts=68233cb3 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=dt9VzEwgFbYA:10 a=gAnH3GRIAAAA:8 a=NQW59FIc28cfkTJrcWIA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: vYWJGd9iGDPRTdL50APjgEAkuL5jp5At X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNTEzMDExNyBTYWx0ZWRfX8MIE+r9MQxhx Rb9dOdM/s9Zpwxl+wy0A3bgVv0UbvIaZxbXiTGPbd97T4MnzvtpAaOsb4jNF2r2x21GJYIpQ2P/ zJ0wR6+/7xfM9ruZtKrkTnBT45A5VoYZtOTv12BGT3zWERH2sSWnpU12VyQ53bRY0cLyXSxVzzi FkRanCCFyMxzGH952VCYxjmq/1sVKpSPV5GfZk9kS7V1DCZ3r6O2xNqEbEnpAczxl9GjpOdbWT+ 04AK77V3ztB3RR5cwhe8NtxY2idYfvMHgEakTAK96aXZnSLHvhgDIPFCo9rzxlzZVD0udFS0Qvx LsdMrp3geeeTVcsRbgciOfKLCfenM5EC9hB5a5zjuM7/10rRgEYWvqqY/AYw+vNWGgHb2cot9pc 7tojP1LKYIlr1l46agqV/By7NU3aWtPXJzK47jOS69nMoABI1TGiW9PrfXOME96uoQh4fh3s X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-05-13_01,2025-05-09_01,2025-02-21_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 malwarescore=0 bulkscore=0 phishscore=0 clxscore=1015 mlxscore=0 impostorscore=0 suspectscore=0 mlxlogscore=999 adultscore=0 spamscore=0 priorityscore=1501 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2504070000 definitions=main-2505130117 The AD4170 chip can use an externally supplied clock at the XTAL2 pin, or an external crystal connected to the XTAL1 and XTAL2 pins. Alternatively, the AD4170 can provide its 16 MHz internal clock at the XTAL2 pin. Extend the AD4170 driver so it effectively uses the provided external clock, if any, or supplies its own clock as a clock provider. Reviewed-by: Nuno Sá Signed-off-by: Marcelo Schmitt --- Change log v2 -> v3 - Applied minor changes according to v2 review. - Avoid unmet dependencies by depending on COMMON_CLK rather than selecting that. - Brought early external clock defines from early patches to this one. - Picked up a review tag from v1 review that I failed to include in v2. drivers/iio/adc/Kconfig | 1 + drivers/iio/adc/ad4170.c | 144 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 144 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 0d3d3af862f8..6e4b14243599 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -77,6 +77,7 @@ config AD4170 select REGMAP_SPI select IIO_BUFFER select IIO_TRIGGERED_BUFFER + depends on COMMON_CLK help Say yes here to build support for Analog Devices AD4170 SPI analog to digital converters (ADC). diff --git a/drivers/iio/adc/ad4170.c b/drivers/iio/adc/ad4170.c index e8856c911dfd..9ab6df002e5e 100644 --- a/drivers/iio/adc/ad4170.c +++ b/drivers/iio/adc/ad4170.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include @@ -49,6 +51,7 @@ #define AD4170_CONFIG_A_REG 0x00 #define AD4170_DATA_24B_REG 0x1E #define AD4170_PIN_MUXING_REG 0x69 +#define AD4170_CLOCK_CTRL_REG 0x6B #define AD4170_ADC_CTRL_REG 0x71 #define AD4170_CHAN_EN_REG 0x79 #define AD4170_CHAN_SETUP_REG(x) (0x81 + 4 * (x)) @@ -69,6 +72,9 @@ /* AD4170_PIN_MUXING_REG */ #define AD4170_PIN_MUXING_DIG_AUX1_CTRL_MSK GENMASK(5, 4) +/* AD4170_CLOCK_CTRL_REG */ +#define AD4170_CLOCK_CTRL_CLOCKSEL_MSK GENMASK(1, 0) + /* AD4170_ADC_CTRL_REG */ #define AD4170_ADC_CTRL_MULTI_DATA_REG_SEL_MSK BIT(7) #define AD4170_ADC_CTRL_CONT_READ_MSK GENMASK(5, 4) @@ -96,6 +102,12 @@ /* AD4170 register constants */ +/* AD4170_CLOCK_CTRL_REG constants */ +#define AD4170_CLOCK_CTRL_CLOCKSEL_INT 0x0 +#define AD4170_CLOCK_CTRL_CLOCKSEL_INT_OUT 0x1 +#define AD4170_CLOCK_CTRL_CLOCKSEL_EXT 0x2 +#define AD4170_CLOCK_CTRL_CLOCKSEL_EXT_XTAL 0x3 + /* AD4170_CHAN_MAP_REG constants */ #define AD4170_CHAN_MAP_AIN(x) (x) #define AD4170_CHAN_MAP_TEMP_SENSOR 17 @@ -142,6 +154,8 @@ /* Internal and external clock properties */ #define AD4170_INT_CLOCK_16MHZ (16 * HZ_PER_MHZ) +#define AD4170_EXT_CLOCK_MHZ_MIN (1 * HZ_PER_MHZ) +#define AD4170_EXT_CLOCK_MHZ_MAX (17 * HZ_PER_MHZ) #define AD4170_NUM_PGA_OPTIONS 10 @@ -162,6 +176,7 @@ static const unsigned int ad4170_reg_size[] = { [AD4170_CONFIG_A_REG] = 1, [AD4170_DATA_24B_REG] = 3, [AD4170_PIN_MUXING_REG] = 2, + [AD4170_CLOCK_CTRL_REG] = 2, [AD4170_ADC_CTRL_REG] = 2, [AD4170_CHAN_EN_REG] = 2, /* @@ -227,6 +242,10 @@ enum ad4170_regulator { AD4170_MAX_SUP }; +static const char *const ad4170_clk_sel[] = { + "ext-clk", "xtal", +}; + enum ad4170_int_pin_sel { AD4170_INT_PIN_SDO, AD4170_INT_PIN_DIG_AUX1, @@ -329,6 +348,9 @@ struct ad4170_state { struct completion completion; int pins_fn[AD4170_NUM_ANALOG_PINS]; u32 int_pin_sel; + struct clk_hw int_clk_hw; + struct clk *ext_clk; + unsigned int clock_ctrl; /* * DMA (thus cache coherency maintenance) requires the transfer buffers * to live in their own cache lines. @@ -1656,6 +1678,120 @@ static int ad4170_parse_channels(struct iio_dev *indio_dev) return 0; } +static struct ad4170_state *clk_hw_to_ad4170(struct clk_hw *hw) +{ + return container_of(hw, struct ad4170_state, int_clk_hw); +} + +static unsigned long ad4170_sel_clk(struct ad4170_state *st, + unsigned int clk_sel) +{ + st->clock_ctrl &= ~AD4170_CLOCK_CTRL_CLOCKSEL_MSK; + st->clock_ctrl |= FIELD_PREP(AD4170_CLOCK_CTRL_CLOCKSEL_MSK, clk_sel); + return regmap_write(st->regmap, AD4170_CLOCK_CTRL_REG, st->clock_ctrl); +} + +static unsigned long ad4170_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return AD4170_INT_CLOCK_16MHZ; +} + +static int ad4170_clk_output_is_enabled(struct clk_hw *hw) +{ + struct ad4170_state *st = clk_hw_to_ad4170(hw); + u32 clk_sel; + + clk_sel = FIELD_GET(AD4170_CLOCK_CTRL_CLOCKSEL_MSK, st->clock_ctrl); + return clk_sel == AD4170_CLOCK_CTRL_CLOCKSEL_INT_OUT; +} + +static int ad4170_clk_output_prepare(struct clk_hw *hw) +{ + struct ad4170_state *st = clk_hw_to_ad4170(hw); + + return ad4170_sel_clk(st, AD4170_CLOCK_CTRL_CLOCKSEL_INT_OUT); +} + +static void ad4170_clk_output_unprepare(struct clk_hw *hw) +{ + struct ad4170_state *st = clk_hw_to_ad4170(hw); + + ad4170_sel_clk(st, AD4170_CLOCK_CTRL_CLOCKSEL_INT); +} + +static const struct clk_ops ad4170_int_clk_ops = { + .recalc_rate = ad4170_clk_recalc_rate, + .is_enabled = ad4170_clk_output_is_enabled, + .prepare = ad4170_clk_output_prepare, + .unprepare = ad4170_clk_output_unprepare, +}; + +static int ad4170_register_clk_provider(struct iio_dev *indio_dev) +{ + struct ad4170_state *st = iio_priv(indio_dev); + struct device *dev = indio_dev->dev.parent; + struct clk_init_data init = {}; + int ret; + + if (!IS_ENABLED(CONFIG_COMMON_CLK)) + return 0; + + if (device_property_read_string(dev, "clock-output-names", &init.name)) { + init.name = devm_kasprintf(dev, GFP_KERNEL, "%pfw", + dev_fwnode(dev)); + if (!init.name) + return -ENOMEM; + } + + init.ops = &ad4170_int_clk_ops; + + st->int_clk_hw.init = &init; + ret = devm_clk_hw_register(dev, &st->int_clk_hw); + if (ret) + return ret; + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, + &st->int_clk_hw); +} + +static int ad4170_clock_select(struct iio_dev *indio_dev) +{ + struct ad4170_state *st = iio_priv(indio_dev); + struct device *dev = &st->spi->dev; + int ret; + + st->mclk_hz = AD4170_INT_CLOCK_16MHZ; + ret = device_property_match_property_string(dev, "clock-names", + ad4170_clk_sel, + ARRAY_SIZE(ad4170_clk_sel)); + if (ret < 0) { + /* Use internal clock reference */ + st->clock_ctrl |= FIELD_PREP(AD4170_CLOCK_CTRL_CLOCKSEL_MSK, + AD4170_CLOCK_CTRL_CLOCKSEL_INT_OUT); + return ad4170_register_clk_provider(indio_dev); + } + + /* Use external clock reference */ + st->ext_clk = devm_clk_get_enabled(dev, ad4170_clk_sel[ret]); + if (IS_ERR(st->ext_clk)) + return dev_err_probe(dev, PTR_ERR(st->ext_clk), + "Failed to get external clock\n"); + + st->clock_ctrl |= FIELD_PREP(AD4170_CLOCK_CTRL_CLOCKSEL_MSK, + AD4170_CLOCK_CTRL_CLOCKSEL_EXT + ret); + + st->mclk_hz = clk_get_rate(st->ext_clk); + if (st->mclk_hz < AD4170_EXT_CLOCK_MHZ_MIN || + st->mclk_hz > AD4170_EXT_CLOCK_MHZ_MAX) { + return dev_err_probe(dev, -EINVAL, + "Invalid external clock frequency %u\n", + st->mclk_hz); + } + + return 0; +} + static int ad4170_parse_firmware(struct iio_dev *indio_dev) { struct ad4170_state *st = iio_priv(indio_dev); @@ -1663,7 +1799,13 @@ static int ad4170_parse_firmware(struct iio_dev *indio_dev) int reg_data, ret; unsigned int i; - st->mclk_hz = AD4170_INT_CLOCK_16MHZ; + ret = ad4170_clock_select(indio_dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to setup device clock\n"); + + ret = regmap_write(st->regmap, AD4170_CLOCK_CTRL_REG, st->clock_ctrl); + if (ret) + return ret; for (i = 0; i < AD4170_NUM_ANALOG_PINS; i++) st->pins_fn[i] = AD4170_PIN_UNASIGNED; From patchwork Tue May 13 12:36:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Marcelo Schmitt X-Patchwork-Id: 889711 Received: from mx0a-00128a01.pphosted.com (mx0a-00128a01.pphosted.com [148.163.135.77]) (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 A70892918FE; Tue, 13 May 2025 12:37:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.135.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747139827; cv=none; b=Jzq3BpMXe4CWc5oBG+EfOPuL/KpQcMisLPcwvXejwHl23W+sWFufBG+3IteRlSbJpPSk9IZcRqIqeYgBbW9D/kixkCpEZVr7Vnq2eWgenJf6QbWe6C1rUfvoncK9GhUVyxR9PvbRfBq8ldZ3kH2b+wf4I2h+XvTtbgGGXTqW3yk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747139827; c=relaxed/simple; bh=ABlBNAm7NhbMLcnjwxx9tP1Xus/dT1aDalOnCVDTQZ4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=h2wKjK1U+dmTolNijeW4tIFMlceWNi5UapmneqRcXwK8ix3fSgNjYZVNLtbwmDg0syr6GWo6Ag/WrfqGRSOW5m75XwwJINH1Oo7R1R4JgV9vtQVwmwR2Ew1+dSIsGDFX0wob9x5uBjLljOf5fePigQMj+p/0W4TRMiDr2O08dC0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com; spf=pass smtp.mailfrom=analog.com; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b=NOxSMVu7; arc=none smtp.client-ip=148.163.135.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=analog.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=analog.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=analog.com header.i=@analog.com header.b="NOxSMVu7" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 54DATTLL007631; Tue, 13 May 2025 08:36:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=DKIM; bh=GKIOD mBn2FfG59ksRytTYs71nRhAvHKLhXJLZhB35nA=; b=NOxSMVu70jBd/NWf+GRAN /GySqZbasLpPEWPjm9knqm3IBzHQSj+NdMpRAyDrhZ2Dc29qZ7p37SL+tDTUGERi 6EfwBNEzZNH/ePQsT3ZgHq5ixxKsGasXJIMmr3soiAVodDIEYCNCM0IbzFsRDm7Y Bv/lrKly11CAH/2XZuCvTNIUHLM8KR3Xjrkrp2Xe/hsLV9+l7PC3elc6n4UDByfO HxW1WrAlNoJQnOQj3G6/ViNNJ434Elw0dH6e/0piygClr8J2+aINQmJYx4SVC6j2 lM5mIqP7C70DEgW7Qc2fVLlQClbJ2eKATHQNqqdSKy0urN7BOWlJ28gxI8dLuWbX A== Received: from nwd2mta4.analog.com ([137.71.173.58]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 46kx53af2a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 13 May 2025 08:36:49 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta4.analog.com (8.14.7/8.14.7) with ESMTP id 54DCamvv041248 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 13 May 2025 08:36:48 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) by ASHBMBX8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.14; Tue, 13 May 2025 08:36:47 -0400 Received: from zeus.spd.analog.com (10.66.68.11) by ashbmbx8.ad.analog.com (10.64.17.5) with Microsoft SMTP Server id 15.2.986.14 via Frontend Transport; Tue, 13 May 2025 08:36:47 -0400 Received: from work.ad.analog.com (HYB-hERzalRezfV.ad.analog.com [10.65.205.9]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 54DCaTJK007554; Tue, 13 May 2025 08:36:32 -0400 From: Marcelo Schmitt To: , , , CC: , , , , , , , , , , , Subject: [PATCH v3 09/10] iio: adc: ad4170: Add support for internal temperature sensor Date: Tue, 13 May 2025 09:36:28 -0300 Message-ID: <3eceb02208b86be4bb66fe77f40b84ef928c0d80.1747083143.git.marcelo.schmitt@analog.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-gpio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ADIRuleOP-NewSCL: Rule Triggered X-Authority-Analysis: v=2.4 cv=a4sw9VSF c=1 sm=1 tr=0 ts=68233ce1 cx=c_pps a=3WNzaoukacrqR9RwcOSAdA==:117 a=3WNzaoukacrqR9RwcOSAdA==:17 a=IkcTkHD0fZMA:10 a=dt9VzEwgFbYA:10 a=gAnH3GRIAAAA:8 a=o3DtMFfdRpqB0q9FUmIA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 X-Proofpoint-ORIG-GUID: qhlJoeS5x-UaAa98ypbdDR61O5DB3T0M X-Proofpoint-GUID: qhlJoeS5x-UaAa98ypbdDR61O5DB3T0M X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNTEzMDEyMCBTYWx0ZWRfXxAidp9cg+n+G 2Doq1AOEXkUXA97VXS/kpj0/SdJUJ/84kL5o68h3c3ee3xdS0Weyt/fLczc45lQbqdyfFayDcjc UrKumG8K9mQGKBLzl+mYpbj5xH+omt2Zzj3V602L+AVFJDbal9W0cKwG9cWNmchuYGWcGRyqgHw E5dCv221Z7YNjEeDxwyN4kTlwAu4Uf5RCcdxCx4G2pUPrrJ77q+lATGLpZun5U2hZR/WlNdyNnF YuJT2H53SwDLWr90nHjEtlzrNh9/IeRPrPr8OSMPEMazJFsabd5HlaIULdfKvZdVk820mGEoTw9 hKx+O4yys8AXbQXdlBhB1aSNf/fzksN2/cK1JONhAqaBlQc4vtnvFc1pj+1NPt6Pw2v8bPy+85w Gg7UIyNZTxC82s0tq986iuZuTKg100tOQ73ciz/duHBAPiKhN8uv8VQUDq5ErBEsNxLddsxN X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-05-13_01,2025-05-09_01,2025-02-21_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 mlxscore=0 impostorscore=0 lowpriorityscore=0 malwarescore=0 phishscore=0 spamscore=0 clxscore=1015 bulkscore=0 mlxlogscore=999 priorityscore=1501 adultscore=0 classifier=spam authscore=0 authtc=n/a authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2504070000 definitions=main-2505130120 The AD4170 has an internal temperature sensor that can be read using the ADC. Whenever possible, configure an IIO channel to provide the chip's temperature. Reviewed-by: Nuno Sá Signed-off-by: Marcelo Schmitt --- Change log v2 -> v3 - Wrapped line according to logical approach. drivers/iio/adc/ad4170.c | 72 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/drivers/iio/adc/ad4170.c b/drivers/iio/adc/ad4170.c index 31f126a0f76f..1150c2e7ca1a 100644 --- a/drivers/iio/adc/ad4170.c +++ b/drivers/iio/adc/ad4170.c @@ -896,6 +896,27 @@ static const struct iio_chan_spec ad4170_channel_template = { }, }; +static const struct iio_chan_spec ad4170_temp_channel_template = { + .type = IIO_TEMP, + .indexed = 0, + .channel = 17, + .channel2 = 17, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS) | + BIT(IIO_CHAN_INFO_SAMP_FREQ), + .info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), + .scan_type = { + .sign = 's', + .realbits = 24, + .storagebits = 32, + .shift = 8, + .endianness = IIO_BE, + }, +}; + /* * Receives the number of a multiplexed AD4170 input (ain_n), and stores the * voltage (in µV) of the specified input into ain_voltage. If the input number @@ -1192,9 +1213,27 @@ static int ad4170_read_raw(struct iio_dev *indio_dev, return ret; case IIO_CHAN_INFO_SCALE: pga = FIELD_GET(AD4170_AFE_PGA_GAIN_MSK, setup->afe); - *val = chan_info->scale_tbl[pga][0]; - *val2 = chan_info->scale_tbl[pga][1]; - return IIO_VAL_INT_PLUS_NANO; + switch (chan->type) { + case IIO_VOLTAGE: + *val = chan_info->scale_tbl[pga][0]; + *val2 = chan_info->scale_tbl[pga][1]; + return IIO_VAL_INT_PLUS_NANO; + + case IIO_TEMP: + /* + * The scale_tbl converts output codes to mV units so + * multiply by MILLI to make the factor convert to µV. + * Then, apply the temperature sensor change sensitivity + * of 477 μV/K. Finally, multiply the result by MILLI + * again to comply with milli degrees Celsius IIO ABI. + */ + *val = 0; + *val2 = DIV_ROUND_CLOSEST(chan_info->scale_tbl[pga][1] * MILLI, 477) * + MILLI; + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } case IIO_CHAN_INFO_OFFSET: pga = FIELD_GET(AD4170_AFE_PGA_GAIN_MSK, setup->afe); *val = chan_info->offset_tbl[pga]; @@ -1878,12 +1917,39 @@ static int ad4170_parse_channels(struct iio_dev *indio_dev) if (num_channels > AD4170_MAX_CHANNELS) return dev_err_probe(dev, -EINVAL, "Too many channels\n"); + /* Add one for temperature */ + num_channels = min(num_channels + 1, AD4170_MAX_CHANNELS); + device_for_each_child_node_scoped(dev, child) { ret = ad4170_parse_channel_node(indio_dev, child, chan_num++); if (ret) return ret; } + /* + * Add internal temperature sensor channel if the maximum number of + * channels has not been reached. + */ + if (num_channels < AD4170_MAX_CHANNELS) { + struct ad4170_setup *setup = &st->chan_infos[chan_num].setup; + + st->chans[chan_num] = ad4170_temp_channel_template; + st->chans[chan_num].address = chan_num; + st->chans[chan_num].scan_index = chan_num; + + st->chan_infos[chan_num].setup_num = AD4170_INVALID_SETUP; + st->chan_infos[chan_num].initialized = true; + + setup->afe |= FIELD_PREP(AD4170_AFE_REF_SELECT_MSK, + AD4170_REF_AVDD); + + ret = ad4170_get_input_range(st, &st->chans[chan_num], chan_num, + AD4170_REF_AVDD); + if (ret < 0) + return dev_err_probe(dev, ret, "Invalid input config\n"); + + st->chan_infos[chan_num].input_range_uv = ret; + } indio_dev->num_channels = num_channels; indio_dev->channels = st->chans; return 0;