From patchwork Fri Apr 12 03:20:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kim Seer Paller X-Patchwork-Id: 13626736 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 7B43617BDD; Fri, 12 Apr 2024 03:21:45 +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=1712892108; cv=none; b=EiHHip9S9dvcGbqCUiVpL6njlxKi8JZxkbY3TnxzRro5tJdJDUTJjn7dH75lCjnQXdcCKwgZgPzQcPcdBrYN98ELHoigShLo4tDkcvOSYAWIe4IGqdrWYZlbk6nHkkdvcOQcXAH6O7mE0uqcv3MdPV7ExoL6A3dAJ3Xlhfnja+s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712892108; c=relaxed/simple; bh=s+F1rYLVRy1dOXfg23CCJa23oTKZl1cSQ0ziX+0Jaro=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qQxpfSCI0svzEBBddztF8qNgDJJ0msvmsqwX8SKys9z9ZON55EFQdptAGvlgRk4zB8hLor7KQmgT1dZeOzeoVya782uhJErgNi/wUeYmZLbwcNR6pn+hwWfczRM2zUQstH2hO9LOt1ehJleHCWuO+VHOx5KfIVj3+ABUF3gho60= 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=vARRYLKU; 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="vARRYLKU" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 43C2Ov8s017716; Thu, 11 Apr 2024 23:21:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; s=DKIM; bh=1ijHFhz8iTwpvxYF++KYxOUW8UaegzpYcDEeWD+FMxk=; b=vARRYLKUkuA/ of8C+CSzqA6tw/4Sao5ObzY5LOcXUCGsTn6xAoMOTfkoDOASuHyv7eCsIeRoKRpl jDSgNqTiEimXU+Nwyu+FaQF03QKHVEDEyS5BqTUmQLcUtOQ+Jo5N6zWS4qEAXNpj 4X2hlq0KaNdPUW7mTK6W/WJImpL1Cis/qppB8974bTxL6XArqYSxq9/Gp6iZXRLc nbsUksfp1HQ4Joqm49CyPXz1S++3XT+MqYOXcb5rJCTYC0IEusjlbF/oDkuU5FsE 8JKfQxTFUwbh1pcVVTo3lVdJDFvx66uj8HZ0UhGB0kOFx4ktCKncnf0vqYa62eNq rxvmsQGNxQ== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 3xek1et80t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Apr 2024 23:21:29 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 43C3LScg021567 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Apr 2024 23:21:28 -0400 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) 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; Thu, 11 Apr 2024 23:21:27 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) 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; Thu, 11 Apr 2024 23:21:27 -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; Thu, 11 Apr 2024 23:21:27 -0400 Received: from kim-VirtualBox.ad.analog.com (KPALLER2-L03.ad.analog.com [10.117.220.36]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 43C3L8pf021230; Thu, 11 Apr 2024 23:21:20 -0400 From: Kim Seer Paller To: , , CC: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , "Liam Girdwood" , Mark Brown , "David Lechner" , Michael Hennerich Subject: [PATCH 1/4] dt-bindings: iio: dac: Add adi,ltc2664.yaml Date: Fri, 12 Apr 2024 11:20:59 +0800 Message-ID: <20240412032102.136071-2-kimseer.paller@analog.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412032102.136071-1-kimseer.paller@analog.com> References: <20240412032102.136071-1-kimseer.paller@analog.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: aV0YyGYa-J_CmqhskJGIr6HRmN35Om6P X-Proofpoint-GUID: aV0YyGYa-J_CmqhskJGIr6HRmN35Om6P X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-04-11_14,2024-04-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 impostorscore=0 bulkscore=0 mlxscore=0 clxscore=1015 suspectscore=0 phishscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2404010003 definitions=main-2404120023 Add documentation for ltc2664 and ltc2672. Co-developed-by: Michael Hennerich Signed-off-by: Michael Hennerich Signed-off-by: Kim Seer Paller --- .../bindings/iio/dac/adi,ltc2664.yaml | 230 ++++++++++++++++++ MAINTAINERS | 8 + 2 files changed, 238 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml new file mode 100644 index 000000000..2f581a9e5 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml @@ -0,0 +1,230 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/dac/adi,ltc2664.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices LTC2664 and LTC2672 DAC + +maintainers: + - Michael Hennerich + - Kim Seer Paller + +description: | + Analog Devices LTC2664 4 channel, 16 bit, +-10V DAC + Analog Devices LTC2672 5 channel, 16 bit, 300mA DAC + https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2664.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2672.pdf + +$defs: + toggle-operation: + type: object + description: Toggle mode channel setting. + + properties: + reg: + description: Channel number. + minimum: 0 + maximum: 4 + + adi,toggle-mode: + description: + Set the channel as a toggle enabled channel. Toggle operation enables + fast switching of a DAC output between two different DAC codes without + any SPI transaction. + type: boolean + +patternProperties: + "^channel@[0-4]$": + type: object + +properties: + compatible: + enum: + - adi,ltc2664 + - adi,ltc2672 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 50000000 + + vcc-supply: + description: Analog Supply Voltage Input. + + iovcc-supply: + description: Digital Input/Output Supply Voltage. + + vref-supply: + description: + Reference Input/Output. The voltage at the REF pin sets the full-scale + range of all channels. If not provided the internal reference is used and + also provided on the VREF pin. + + clr-gpios: + description: + If specified, it will be asserted during driver probe. As the line is + active low, it should be marked GPIO_ACTIVE_LOW. + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +allOf: + - if: + properties: + compatible: + contains: + const: adi,ltc2664 + then: + properties: + adi,manual-span-operation-config: + description: + This property must mimic the MSPAN pin configurations. + By tying the MSPAN pins (MSP2, MSP1 and MSP0) to GND + and/or VCC, any output range can be hardware-configured + with different mid-scale or zero-scale reset options. + The hardware configuration is latched during power on reset + for proper operation. + 0 - MPS2=GND, MPS1=GND, MSP0=GND + 1 - MPS2=GND, MPS1=GND, MSP0=VCC + 2 - MPS2=GND, MPS1=VCC, MSP0=GND + 3 - MPS2=GND, MPS1=VCC, MSP0=VCC + 4 - MPS2=VCC, MPS1=GND, MSP0=GND + 5 - MPS2=VCC, MPS1=GND, MSP0=VCC + 6 - MPS2=VCC, MPS1=VCC, MSP0=GND + 7 - MPS2=VCC, MPS1=VCC, MSP0=VCC (enables SoftSpan feature) + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3, 4, 5, 6, 7] + default: 7 + + patternProperties: + "^channel@([0-3])$": + $ref: '#/$defs/toggle-operation' + unevaluatedProperties: false + + description: Channel in toggle functionality. + + properties: + adi,output-range-microvolt: + description: Specify the channel output full scale range. + oneOf: + - items: + - const: 0 + - enum: [5000000, 10000000] + - items: + - const: -5000000 + - const: 5000000 + - items: + - const: -10000000 + - const: 10000000 + - items: + - const: -2500000 + - const: 2500000 + + required: + - adi,output-range-microvolt + + - if: + properties: + compatible: + contains: + const: adi,ltc2672 + then: + properties: + adi,rfsadj-ohms: + description: If FSADJ is tied to VCC, an internal RFSADJ (20 kΩ) is + selected, which results in nominal output ranges. When an external + resistor of 19 kΩ to 41 kΩ can be used instead by connecting the + resistor between FSADJ and GND it controls the scaling of the + ranges, and the internal resistor is automatically disconnected. + minimum: 19000 + maximum: 41000 + default: 20000 + + patternProperties: + "^channel@([0-4])$": + $ref: '#/$defs/toggle-operation' + unevaluatedProperties: false + + description: Configuration properties for a channel in toggle mode + + properties: + adi,output-range-microamp: + description: Specify the channel output full scale range. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [3125000, 6250000, 12500000, 25000000, 50000000, 100000000, + 200000000, 300000000] + + required: + - adi,output-range-microamp + +required: + - compatible + - reg + - spi-max-frequency + - vcc-supply + - iovcc-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + dac@0 { + compatible = "adi,ltc2664"; + reg = <0>; + spi-max-frequency = <10000000>; + + vcc-supply = <&vcc>; + iovcc-supply = <&vcc>; + vref-supply = <&vref>; + + #address-cells = <1>; + #size-cells = <0>; + channel@0 { + reg = <0>; + adi,toggle-mode; + adi,output-range-microvolt = <(-10000000) 10000000>; + }; + + channel@1 { + reg = <1>; + adi,output-range-microvolt = <0 10000000>; + }; + }; + }; + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + dac@0 { + compatible = "adi,ltc2672"; + reg = <0>; + spi-max-frequency = <10000000>; + + vcc-supply = <&vcc>; + iovcc-supply = <&vcc>; + vref-supply = <&vref>; + + #address-cells = <1>; + #size-cells = <0>; + channel@0 { + reg = <0>; + adi,toggle-mode; + adi,output-range-microamp = <3125000>; + }; + + channel@1 { + reg = <1>; + adi,output-range-microamp = <6250000>; + }; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index a7287cf44..bd8645f6e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12836,6 +12836,14 @@ S: Maintained F: Documentation/devicetree/bindings/iio/dac/lltc,ltc1660.yaml F: drivers/iio/dac/ltc1660.c +LTC2664 IIO DAC DRIVER +M: Michael Hennerich +M: Kim Seer Paller +L: linux-iio@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml + LTC2688 IIO DAC DRIVER M: Nuno Sá L: linux-iio@vger.kernel.org From patchwork Fri Apr 12 03:21:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kim Seer Paller X-Patchwork-Id: 13626737 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 D116218628; Fri, 12 Apr 2024 03:21:49 +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=1712892111; cv=none; b=mww6MAE2Sdt++vtimkp5F6laG00IfznRQCPT1+neRuQWiztVg+pPhtmk9KWUZsSGNc9CdNkiDvgGhc98HseqfRLfBTRNR7clIZdANCLZTe1up5Yr8zLFJDHQCy0POxcBcD1gnHzJrT8IysRwGDHx/5Ji9+/t1voG6JQgxoWe6i4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712892111; c=relaxed/simple; bh=+g8IIY5AHDgps6cDvY60z9DR4SBKIKd7nLXQX9Pq9FQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GI02+o4l7RH0uh2dVuaAkq7GBT6HagTJSf38l4H7SuMLMyMA2dhrDYQxks4p5N2bYhHqPkFGlVAbZ2xXIkqnDHhHOA383FNLAw5j63VPjPrHOgGozax74fxqwM6tVRZrB2R+LU/Qv288EGMnKr9hbXsYLogm1X9ZmhyMmAPkpn8= 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=lExjkPms; 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="lExjkPms" Received: from pps.filterd (m0167088.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 43C32K93017823; Thu, 11 Apr 2024 23:21:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s=DKIM; bh=HlFct+d0fLtrb7oDg7XDUOZwnnpyGtY1TPgAuLTT/yg=; b=lExjkPmsWDzo Eg+M7muqIAtqO0Sp1jFwyvk1XizdH6CaAQPJ5hxHggQHU41FQbwjp5ICIpwJRdIE 6bhXHeTeQeAG6LCs2/ojo9Sv9aGo5scXFBgMOdh8BvvWXsCjYu3ptSfpKi7E8VUQ 2fg8tTqCSgjo3W9kOg3b+L60sJI6nHNsyYN4s9kXO6wlhLTPUWCRIgBqba5LGPlA CrLHKYxUD3vewmZuv8+s629HC78R/lp4Dc/pQDsUMU/jmjuhRziEw5Sxlbzz+qqC 2+XwvWD/3kTrUd+gayrfbQhpSDBWyXPlWwvubkOThgp61tBep9GqPANSu8Z2tbvJ 14tfi8NZyw== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 3xek1fa87j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Apr 2024 23:21:34 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 43C3LXPk021576 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Apr 2024 23:21:33 -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; Thu, 11 Apr 2024 23:21:32 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) 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; Thu, 11 Apr 2024 23:21:32 -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; Thu, 11 Apr 2024 23:21:32 -0400 Received: from kim-VirtualBox.ad.analog.com (KPALLER2-L03.ad.analog.com [10.117.220.36]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 43C3L8pg021230; Thu, 11 Apr 2024 23:21:24 -0400 From: Kim Seer Paller To: , , CC: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , "Liam Girdwood" , Mark Brown , "David Lechner" , Michael Hennerich Subject: [PATCH 2/4] iio: ABI: add ABI file for the LTC2664 DAC Date: Fri, 12 Apr 2024 11:21:00 +0800 Message-ID: <20240412032102.136071-3-kimseer.paller@analog.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412032102.136071-1-kimseer.paller@analog.com> References: <20240412032102.136071-1-kimseer.paller@analog.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: TCUPznz4WRZzmKsO1puaT2PI3mczYDHO X-Proofpoint-ORIG-GUID: TCUPznz4WRZzmKsO1puaT2PI3mczYDHO X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-04-11_14,2024-04-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 spamscore=0 malwarescore=0 phishscore=0 impostorscore=0 mlxscore=0 lowpriorityscore=0 bulkscore=0 mlxlogscore=999 suspectscore=0 clxscore=1015 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2404010003 definitions=main-2404120023 Define the sysfs interface for toggle capable channels. Toggle enabled channels will have: * out_voltageY_toggle_en * out_voltageY_raw0 * out_voltageY_raw1 * out_voltageY_symbol The common interface present in all channels is: * out_voltageY_raw (not present in toggle enabled channels) * out_voltageY_raw_available * out_voltageY_powerdown * out_voltageY_scale * out_voltageY_offset Co-developed-by: Michael Hennerich Signed-off-by: Michael Hennerich Signed-off-by: Kim Seer Paller --- .../ABI/testing/sysfs-bus-iio-dac-ltc2664 | 30 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 31 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2664 diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2664 b/Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2664 new file mode 100644 index 000000000..4b656b7af --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2664 @@ -0,0 +1,30 @@ +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_toggle_en +KernelVersion: 5.18 +Contact: linux-iio@vger.kernel.org +Description: + Toggle enable. Write 1 to enable toggle or 0 to disable it. This is + useful when one wants to change the DAC output codes. The way it should + be done is: + + - disable toggle operation; + - change out_voltageY_raw0 and out_voltageY_raw1; + - enable toggle operation. + +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw0 +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_raw1 +KernelVersion: 5.18 +Contact: linux-iio@vger.kernel.org +Description: + It has the same meaning as out_voltageY_raw. This attribute is + specific to toggle enabled channels and refers to the DAC output + code in INPUT_A (_raw0) and INPUT_B (_raw1). The same scale and offset + as in out_voltageY_raw applies. + +What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_symbol +KernelVersion: 5.18 +Contact: linux-iio@vger.kernel.org +Description: + Performs a SW toggle. This attribute is specific to toggle + enabled channels and allows to toggle between out_voltageY_raw0 + and out_voltageY_raw1 through software. Writing 0 will select + out_voltageY_raw0 while 1 selects out_voltageY_raw1. diff --git a/MAINTAINERS b/MAINTAINERS index bd8645f6e..9ed00b364 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12842,6 +12842,7 @@ M: Kim Seer Paller L: linux-iio@vger.kernel.org S: Supported W: https://ez.analog.com/linux-software-drivers +F: Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2664 F: Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml LTC2688 IIO DAC DRIVER From patchwork Fri Apr 12 03:21:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kim Seer Paller X-Patchwork-Id: 13626738 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 1380617BDD; Fri, 12 Apr 2024 03:21:52 +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=1712892114; cv=none; b=KdmLnbMPu/JNNpEjo63hDsMDVes0r26lgK09BVfdcn34cftbrSaBC20OC78sERnOHiknBQ6WdASCyh9A2vf+hnULe+YCuwDaYVU3+RMiP2kXM3KxMrbhL/ovEu8eNWFNL7ImAAzogZQKJ/I3or1CvgFE0+7+M3V6ikGtVDRgCko= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712892114; c=relaxed/simple; bh=l5A4vxQ7tsKU2pvs1CtcYasieAlxi0kY2xAYz2jv4z8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fHT7npybOw2twjlTuTo/WjtqnTTg07RQRJKCw/K+sfoaBUyg8HxMNQIBQnMWOLssa+Hf7suKCHREGFWtUHxaoc/zmuhDM38sKJPUyUC9xIzPW+SS4rpBy0GfsT+JOHi15vS7Boc2Z3TfD48jsNFLzDZqTn7NYi8M/8pxW5SAg2g= 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=FJ44YAlC; 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="FJ44YAlC" Received: from pps.filterd (m0375855.ppops.net [127.0.0.1]) by mx0b-00128a01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 43C33Clc013858; Thu, 11 Apr 2024 23:21:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s=DKIM; bh=0FpVZp5rgKR3BFnV+2O0H0nhcKqHXyxleMBi+/JGkBo=; b=FJ44YAlCnQeU JCbheJCOgVlDlv+24VB3sfWXuOeQAv88T8Y9qsqcJNFaPX1zFGZMt+eMSeRBwXkW uHVbwysr05rzmrcEq4+tlsDR6eNb4oPRCZkQWCM3Fjzg9APV+tcqmKEMlsjV1LYA jnf7qrRZk/CePgHln4m/74YH/qddV2XODDSLo1iktVxFM+w/cVtRXQhKu+Zyt9a0 mnV+T4xa3m35TxEW5saMAPYNOZeOdRINlA0vzuw3TiMO1qCGgo0gsuORIG0yEbXP hl6T4HHiMQgMjQQgiB0o5huCM4ZnDpZfdloRMJfySJpj3TgT/C/ojg5VMY4Ml5x5 D/bhvVpHPg== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0b-00128a01.pphosted.com (PPS) with ESMTPS id 3xek1f27nq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Apr 2024 23:21:37 -0400 (EDT) Received: from ASHBMBX8.ad.analog.com (ASHBMBX8.ad.analog.com [10.64.17.5]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 43C3LZIk021581 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Apr 2024 23:21:35 -0400 Received: from ASHBCASHYB5.ad.analog.com (10.64.17.133) 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; Thu, 11 Apr 2024 23:21:35 -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; Thu, 11 Apr 2024 23:21:34 -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; Thu, 11 Apr 2024 23:21:34 -0400 Received: from kim-VirtualBox.ad.analog.com (KPALLER2-L03.ad.analog.com [10.117.220.36]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 43C3L8ph021230; Thu, 11 Apr 2024 23:21:28 -0400 From: Kim Seer Paller To: , , CC: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , "Liam Girdwood" , Mark Brown , "David Lechner" , Michael Hennerich Subject: [PATCH 3/4] iio: ABI: add ABI file for the LTC2672 DAC Date: Fri, 12 Apr 2024 11:21:01 +0800 Message-ID: <20240412032102.136071-4-kimseer.paller@analog.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412032102.136071-1-kimseer.paller@analog.com> References: <20240412032102.136071-1-kimseer.paller@analog.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-GUID: QB7jeWZ8gygj_1Mbw2bdSfiS5i9maYyn X-Proofpoint-ORIG-GUID: QB7jeWZ8gygj_1Mbw2bdSfiS5i9maYyn X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-04-11_14,2024-04-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 impostorscore=0 lowpriorityscore=0 mlxlogscore=999 suspectscore=0 phishscore=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2404010003 definitions=main-2404120023 Define the sysfs interface for toggle capable channels. Toggle enabled channels will have: * out_currentY_toggle_en * out_currentY_raw0 * out_currentY_raw1 * out_currentY_symbol The common interface present in all channels is: * out_currentY_raw (not present in toggle enabled channels) * out_currentY_raw_available * out_currentY_powerdown * out_currentY_scale * out_currentY_offset Co-developed-by: Michael Hennerich Signed-off-by: Michael Hennerich Signed-off-by: Kim Seer Paller --- .../ABI/testing/sysfs-bus-iio-dac-ltc2672 | 30 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 31 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2672 diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2672 b/Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2672 new file mode 100644 index 000000000..b984d92f7 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2672 @@ -0,0 +1,30 @@ +What: /sys/bus/iio/devices/iio:deviceX/out_currentY_toggle_en +KernelVersion: 5.18 +Contact: linux-iio@vger.kernel.org +Description: + Toggle enable. Write 1 to enable toggle or 0 to disable it. This is + useful when one wants to change the DAC output codes. The way it should + be done is: + + - disable toggle operation; + - change out_currentY_raw0 and out_currentY_raw1; + - enable toggle operation. + +What: /sys/bus/iio/devices/iio:deviceX/out_currentY_raw0 +What: /sys/bus/iio/devices/iio:deviceX/out_currentY_raw1 +KernelVersion: 5.18 +Contact: linux-iio@vger.kernel.org +Description: + It has the same meaning as out_currentY_raw. This attribute is + specific to toggle enabled channels and refers to the DAC output + code in INPUT_A (_raw0) and INPUT_B (_raw1). The same scale and offset + as in out_currentY_raw applies. + +What: /sys/bus/iio/devices/iio:deviceX/out_currentY_symbol +KernelVersion: 5.18 +Contact: linux-iio@vger.kernel.org +Description: + Performs a SW toggle. This attribute is specific to toggle + enabled channels and allows to toggle between out_currentY_raw0 + and out_currentY_raw1 through software. Writing 0 will select + out_currentY_raw0 while 1 selects out_currentY_raw1. diff --git a/MAINTAINERS b/MAINTAINERS index 9ed00b364..fba8bacc0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12843,6 +12843,7 @@ L: linux-iio@vger.kernel.org S: Supported W: https://ez.analog.com/linux-software-drivers F: Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2664 +F: Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2672 F: Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml LTC2688 IIO DAC DRIVER From patchwork Fri Apr 12 03:21:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kim Seer Paller X-Patchwork-Id: 13626739 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 BFE771C29F; Fri, 12 Apr 2024 03:21:57 +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=1712892119; cv=none; b=mnCyRct8+oCC7I0nllOH1v7I83jbxdof8egFgercdcfi3fV91fe8uJ8gm7pnRNAWe9sV/qfEuGIEj/vGSqXqM6ApxDZpzpkqsHOLQmuK04xceDKOgdrx33xzLWIXbc87lB/Zf8J2gm11j5bYsfIUnHwVQ0I3g3Cr/mohWXau7cU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712892119; c=relaxed/simple; bh=AKPe30Lkkb2ALaF3MpW3QAR6qGafn8d626/Wc/B6FjI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=iLWsg9xMXFOBSgt+bbZULd0e9fC6wxntsLAdgUHPM19hyGhN6bWvPvW03fba1bV/8Jg1d6RsN8BpZKtpYTMxDC0C6fVvlAlsr7AFweJPxqMyhrFdHc0JARVcBJSHH8ZrJ+YPJWoVPS0J+z4FAcQ/Cnp1uVIJ5N3esFOcu7lYrUY= 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=Yy0K3BTg; 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="Yy0K3BTg" Received: from pps.filterd (m0167089.ppops.net [127.0.0.1]) by mx0a-00128a01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 43C2Ov8t017716; Thu, 11 Apr 2024 23:21:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=analog.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; s=DKIM; bh=a4Mul6E1bdinbHUPpudcNBMMnS1YS7YiBaHomYCsbY0=; b=Yy0K3BTgsNhs Vc6ZF9Jus/XQ5ZhDtyA+WuHB7ljf2MkyeaDHXxzYDuKsOnnr9E5B9/B9jfhTqaQW UHXwl9EviZy1jdC+m+BN380exYA//i5it1Hu96AFx7UB/pEtyMz3/oP+4FG0rb0n rnapq6bFD46pPstbYJvB0Uws87b6r8MTj/77+je3m99ozlL74bePfajx/f7OJiNx qZ+qsL1oYK4KZwdQ/88LBOIIqr4QXDEBsb7DimjwciA+IRvbx5+SurIrsW+DKLKN /i0IhZ48Y8tEuJAgK4FiNIVmx1wXJpT79BetcrPLAgMtSkM4APx4pG1lmPvNoXr0 CgkCzx9Ysw== Received: from nwd2mta3.analog.com ([137.71.173.56]) by mx0a-00128a01.pphosted.com (PPS) with ESMTPS id 3xek1et81e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 11 Apr 2024 23:21:40 -0400 (EDT) Received: from ASHBMBX9.ad.analog.com (ASHBMBX9.ad.analog.com [10.64.17.10]) by nwd2mta3.analog.com (8.14.7/8.14.7) with ESMTP id 43C3LdKH021590 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Apr 2024 23:21:39 -0400 Received: from ASHBCASHYB4.ad.analog.com (10.64.17.132) 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; Thu, 11 Apr 2024 23:21:38 -0400 Received: from ASHBMBX8.ad.analog.com (10.64.17.5) 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; Thu, 11 Apr 2024 23:21:38 -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; Thu, 11 Apr 2024 23:21:38 -0400 Received: from kim-VirtualBox.ad.analog.com (KPALLER2-L03.ad.analog.com [10.117.220.36]) by zeus.spd.analog.com (8.15.1/8.15.1) with ESMTP id 43C3L8pi021230; Thu, 11 Apr 2024 23:21:32 -0400 From: Kim Seer Paller To: , , CC: Jonathan Cameron , Lars-Peter Clausen , Rob Herring , Krzysztof Kozlowski , Conor Dooley , "Liam Girdwood" , Mark Brown , "David Lechner" , Michael Hennerich Subject: [PATCH 4/4] iio: dac: ltc2664: Add driver for LTC2664 and LTC2672 Date: Fri, 12 Apr 2024 11:21:02 +0800 Message-ID: <20240412032102.136071-5-kimseer.paller@analog.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240412032102.136071-1-kimseer.paller@analog.com> References: <20240412032102.136071-1-kimseer.paller@analog.com> Precedence: bulk X-Mailing-List: linux-iio@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ADIRuleOP-NewSCL: Rule Triggered X-Proofpoint-ORIG-GUID: wPLmqIIC7UZmU9zH3468uIz8zTZU-xQ9 X-Proofpoint-GUID: wPLmqIIC7UZmU9zH3468uIz8zTZU-xQ9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-04-11_14,2024-04-09_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 impostorscore=0 bulkscore=0 mlxscore=0 clxscore=1015 suspectscore=0 phishscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2404010003 definitions=main-2404120023 LTC2664 4 channel, 16 bit Voltage Output SoftSpan DAC LTC2672 5 channel, 16 bit Current Output Softspan DAC Co-developed-by: Michael Hennerich Signed-off-by: Michael Hennerich Signed-off-by: Kim Seer Paller --- MAINTAINERS | 1 + drivers/iio/dac/Kconfig | 11 + drivers/iio/dac/Makefile | 1 + drivers/iio/dac/ltc2664.c | 785 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 798 insertions(+) create mode 100644 drivers/iio/dac/ltc2664.c diff --git a/MAINTAINERS b/MAINTAINERS index fba8bacc0..9b5c3d6d1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12845,6 +12845,7 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2664 F: Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2672 F: Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml +F: drivers/iio/dac/ltc2664.c LTC2688 IIO DAC DRIVER M: Nuno Sá diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 34eb40bb9..79b7a547e 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -333,6 +333,17 @@ config LTC2632 To compile this driver as a module, choose M here: the module will be called ltc2632. +config LTC2664 + tristate "Analog Devices LTC2664 and LTC2672 DAC SPI driver" + depends on SPI + select REGMAP + help + Say yes here to build support for Analog Devices + LTC2664 and LTC2672 converters (DAC). + + To compile this driver as a module, choose M here: the + module will be called ltc2664. + config M62332 tristate "Mitsubishi M62332 DAC driver" depends on I2C diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 55bf89739..62df8d7e4 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_DS4424) += ds4424.o obj-$(CONFIG_LPC18XX_DAC) += lpc18xx_dac.o obj-$(CONFIG_LTC1660) += ltc1660.o obj-$(CONFIG_LTC2632) += ltc2632.o +obj-$(CONFIG_LTC2664) += ltc2664.o obj-$(CONFIG_LTC2688) += ltc2688.o obj-$(CONFIG_M62332) += m62332.o obj-$(CONFIG_MAX517) += max517.o diff --git a/drivers/iio/dac/ltc2664.c b/drivers/iio/dac/ltc2664.c new file mode 100644 index 000000000..70c43fe17 --- /dev/null +++ b/drivers/iio/dac/ltc2664.c @@ -0,0 +1,785 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * LTC2664 4 channel, 16 bit Voltage Output SoftSpan DAC driver + * LTC2672 5 channel, 16 bit Current Output Softspan DAC driver + * + * Copyright 2024 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LTC2664_CMD_WRITE_N(n) (0x00 + (n)) +#define LTC2664_CMD_UPDATE_N(n) (0x10 + (n)) +#define LTC2664_CMD_WRITE_N_UPDATE_ALL 0x20 +#define LTC2664_CMD_WRITE_N_UPDATE_N(n) (0x30 + (n)) +#define LTC2664_CMD_POWER_DOWN_N(n) (0x40 + (n)) +#define LTC2664_CMD_POWER_DOWN_ALL 0x50 +#define LTC2664_CMD_SPAN_N(n) (0x60 + (n)) +#define LTC2664_CMD_CONFIG 0x70 +#define LTC2664_CMD_MUX 0xB0 +#define LTC2664_CMD_TOGGLE_SEL 0xC0 +#define LTC2664_CMD_GLOBAL_TOGGLE 0xD0 +#define LTC2664_CMD_NO_OPERATION 0xF0 +#define LTC2664_REF_DISABLE 0x0001 +#define LTC2664_MSPAN_SOFTSPAN 7 + +#define LTC2672_MAX_CHANNEL 5 +#define LTC2672_MAX_SPAN 7 +#define LTC2672_OFFSET_CODE 384 +#define LTC2672_SCALE_MULTIPLIER(n) (50 * BIT(n)) + +enum ltc2664_ids { + LTC2664, + LTC2672, +}; + +enum { + LTC2664_SPAN_RANGE_0V_5V, + LTC2664_SPAN_RANGE_0V_10V, + LTC2664_SPAN_RANGE_M5V_5V, + LTC2664_SPAN_RANGE_M10V_10V, + LTC2664_SPAN_RANGE_M2V5_2V5, +}; + +enum { + LTC2664_INPUT_A, + LTC2664_INPUT_B, + LTC2664_INPUT_B_AVAIL, + LTC2664_POWERDOWN, + LTC2664_TOGGLE_EN, + LTC2664_GLOBAL_TOGGLE, +}; + +static const u16 ltc2664_mspan_lut[8][2] = { + {LTC2664_SPAN_RANGE_M10V_10V, 32768}, /* MPS2=0, MPS1=0, MSP0=0 (0)*/ + {LTC2664_SPAN_RANGE_M5V_5V, 32768}, /* MPS2=0, MPS1=0, MSP0=1 (1)*/ + {LTC2664_SPAN_RANGE_M2V5_2V5, 32768}, /* MPS2=0, MPS1=1, MSP0=0 (2)*/ + {LTC2664_SPAN_RANGE_0V_10V, 0}, /* MPS2=0, MPS1=1, MSP0=1 (3)*/ + {LTC2664_SPAN_RANGE_0V_10V, 32768}, /* MPS2=1, MPS1=0, MSP0=0 (4)*/ + {LTC2664_SPAN_RANGE_0V_5V, 0}, /* MPS2=1, MPS1=0, MSP0=1 (5)*/ + {LTC2664_SPAN_RANGE_0V_5V, 32768}, /* MPS2=1, MPS1=1, MSP0=0 (6)*/ + {LTC2664_SPAN_RANGE_0V_5V, 0} /* MPS2=1, MPS1=1, MSP0=1 (7)*/ +}; + +struct ltc2664_chip_info { + enum ltc2664_ids id; + const char *name; + unsigned int num_channels; + const struct iio_chan_spec *iio_chan; + const int (*span_helper)[2]; + unsigned int num_span; +}; + +struct ltc2664_chan { + bool toggle_chan; + bool powerdown; + u8 span; + u16 raw[2]; /* A/B */ +}; + +struct ltc2664_state { + struct spi_device *spi; + struct regmap *regmap; + struct ltc2664_chan channels[LTC2672_MAX_CHANNEL]; + /* lock to protect against multiple access to the device and shared data */ + struct mutex lock; + const struct ltc2664_chip_info *chip_info; + struct iio_chan_spec *iio_channels; + int vref; + u32 toggle_sel; + u32 global_toggle; + u32 rfsadj; +}; + +static const int ltc2664_span_helper[][2] = { + {0, 5000}, {0, 10000}, {-5000, 5000}, {-10000, 10000}, {-2500, 2500}, +}; + +static const int ltc2672_span_helper[][2] = { + {0, 3125}, {0, 6250}, {0, 12500}, {0, 25000}, {0, 50000}, {0, 100000}, + {0, 200000}, {0, 300000}, +}; + +static int ltc2664_scale_get(const struct ltc2664_state *st, int c, int *val) +{ + const struct ltc2664_chan *chan = &st->channels[c]; + const int (*span_helper)[2] = st->chip_info->span_helper; + int span, fs; + + span = chan->span; + if (span < 0) + return span; + + switch (st->chip_info->id) { + case LTC2664: + fs = span_helper[span][1] - span_helper[span][0]; + + if (st->vref) + *val = (fs / 2500) * st->vref; + else + *val = fs; + + return 0; + case LTC2672: + if (span == LTC2672_MAX_SPAN) + *val = 4800 * (1000 * st->vref / st->rfsadj); + else + *val = LTC2672_SCALE_MULTIPLIER(span) * + (1000 * st->vref / st->rfsadj); + + return 0; + default: + return -EINVAL; + } +} + +static int ltc2664_offset_get(const struct ltc2664_state *st, int c, int *val) +{ + const struct ltc2664_chan *chan = &st->channels[c]; + int span; + + span = chan->span; + if (span < 0) + return span; + + if (st->chip_info->span_helper[span][0] < 0) + *val = -32768; + else if (chan->raw[0] >= LTC2672_OFFSET_CODE || + chan->raw[1] >= LTC2672_OFFSET_CODE) + *val = st->chip_info->span_helper[1][span] / 250; + else + *val = 0; + + return 0; +} + +static int ltc2664_dac_code_write(struct ltc2664_state *st, u32 chan, u32 input, + u16 code) +{ + struct ltc2664_chan *c = &st->channels[chan]; + int ret, reg; + + guard(mutex)(&st->lock); + /* select the correct input register to write to */ + if (c->toggle_chan) { + ret = regmap_write(st->regmap, LTC2664_CMD_TOGGLE_SEL, + input << chan); + if (ret) + return ret; + } + /* + * If in toggle mode the dac should be updated by an + * external signal (or sw toggle) and not here. + */ + if (st->toggle_sel & BIT(chan)) + reg = LTC2664_CMD_WRITE_N(chan); + else + reg = LTC2664_CMD_WRITE_N_UPDATE_N(chan); + + ret = regmap_write(st->regmap, reg, code); + if (ret) + return ret; + + c->raw[input] = code; + + if (c->toggle_chan) { + ret = regmap_write(st->regmap, LTC2664_CMD_TOGGLE_SEL, + st->toggle_sel); + if (ret) + return ret; + } + + return ret; +} + +static int ltc2664_dac_code_read(struct ltc2664_state *st, u32 chan, u32 input, + u32 *code) +{ + guard(mutex)(&st->lock); + *code = st->channels[chan].raw[input]; + + return 0; +} + +static const int ltc2664_raw_range[] = {0, 1, U16_MAX}; + +static int ltc2664_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long info) +{ + switch (info) { + case IIO_CHAN_INFO_RAW: + *vals = ltc2664_raw_range; + *type = IIO_VAL_INT; + + return IIO_AVAIL_RANGE; + default: + return -EINVAL; + } +} + +static int ltc2664_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long info) +{ + struct ltc2664_state *st = iio_priv(indio_dev); + int ret; + + switch (info) { + case IIO_CHAN_INFO_RAW: + ret = ltc2664_dac_code_read(st, chan->channel, + LTC2664_INPUT_A, val); + if (ret) + return ret; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_OFFSET: + ret = ltc2664_offset_get(st, chan->channel, val); + if (ret) + return ret; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + ret = ltc2664_scale_get(st, chan->channel, val); + if (ret) + return ret; + + *val2 = 16; + + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; + } +} + +static int ltc2664_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, + int val2, long info) +{ + struct ltc2664_state *st = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_RAW: + if (val > U16_MAX || val < 0) + return -EINVAL; + + return ltc2664_dac_code_write(st, chan->channel, + LTC2664_INPUT_A, val); + default: + return -EINVAL; + } +} + +static ssize_t ltc2664_reg_bool_get(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + struct ltc2664_state *st = iio_priv(indio_dev); + u32 val; + + guard(mutex)(&st->lock); + switch (private) { + case LTC2664_POWERDOWN: + val = st->channels[chan->channel].powerdown; + + return sysfs_emit(buf, "%u\n", val); + case LTC2664_TOGGLE_EN: + val = !!(st->toggle_sel & BIT(chan->channel)); + + return sysfs_emit(buf, "%u\n", val); + case LTC2664_GLOBAL_TOGGLE: + val = st->global_toggle; + + return sysfs_emit(buf, "%u\n", val); + default: + return -EINVAL; + } +} + +static ssize_t ltc2664_reg_bool_set(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct ltc2664_state *st = iio_priv(indio_dev); + int ret; + bool en; + + ret = kstrtobool(buf, &en); + if (ret) + return ret; + + guard(mutex)(&st->lock); + switch (private) { + case LTC2664_POWERDOWN: + ret = regmap_write(st->regmap, + en ? LTC2664_CMD_POWER_DOWN_N(chan->channel) : + LTC2664_CMD_UPDATE_N(chan->channel), en); + if (ret) + return ret; + + st->channels[chan->channel].powerdown = en; + + return len; + case LTC2664_TOGGLE_EN: + if (en) + st->toggle_sel |= BIT(chan->channel); + else + st->toggle_sel &= ~BIT(chan->channel); + + ret = regmap_write(st->regmap, LTC2664_CMD_TOGGLE_SEL, + st->toggle_sel); + if (ret) + return ret; + + return len; + case LTC2664_GLOBAL_TOGGLE: + ret = regmap_write(st->regmap, LTC2664_CMD_GLOBAL_TOGGLE, en); + if (ret) + return ret; + + st->global_toggle = en; + + return len; + default: + return -EINVAL; + } +} + +static ssize_t ltc2664_dac_input_read(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + struct ltc2664_state *st = iio_priv(indio_dev); + int ret; + u32 val; + + if (private == LTC2664_INPUT_B_AVAIL) + return sysfs_emit(buf, "[%u %u %u]\n", ltc2664_raw_range[0], + ltc2664_raw_range[1], + ltc2664_raw_range[2] / 4); + + ret = ltc2664_dac_code_read(st, chan->channel, private, &val); + if (ret) + return ret; + + return sysfs_emit(buf, "%u\n", val); +} + +static ssize_t ltc2664_dac_input_write(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct ltc2664_state *st = iio_priv(indio_dev); + int ret; + u16 val; + + if (private == LTC2664_INPUT_B_AVAIL) + return -EINVAL; + + ret = kstrtou16(buf, 10, &val); + if (ret) + return ret; + + ret = ltc2664_dac_code_write(st, chan->channel, private, val); + if (ret) + return ret; + + return len; +} + +static int ltc2664_reg_access(struct iio_dev *indio_dev, + unsigned int reg, + unsigned int writeval, + unsigned int *readval) +{ + struct ltc2664_state *st = iio_priv(indio_dev); + + if (readval) + return -EOPNOTSUPP; + + return regmap_write(st->regmap, reg, writeval); +} + +#define LTC2664_CHAN_EXT_INFO(_name, _what, _shared, _read, _write) { \ + .name = _name, \ + .read = (_read), \ + .write = (_write), \ + .private = (_what), \ + .shared = (_shared), \ +} + +/* + * For toggle mode we only expose the symbol attr (sw_toggle) in case a TGPx is + * not provided in dts. + */ +static const struct iio_chan_spec_ext_info ltc2664_toggle_sym_ext_info[] = { + LTC2664_CHAN_EXT_INFO("raw0", LTC2664_INPUT_A, IIO_SEPARATE, + ltc2664_dac_input_read, ltc2664_dac_input_write), + LTC2664_CHAN_EXT_INFO("raw1", LTC2664_INPUT_B, IIO_SEPARATE, + ltc2664_dac_input_read, ltc2664_dac_input_write), + LTC2664_CHAN_EXT_INFO("powerdown", LTC2664_POWERDOWN, IIO_SEPARATE, + ltc2664_reg_bool_get, ltc2664_reg_bool_set), + LTC2664_CHAN_EXT_INFO("symbol", LTC2664_GLOBAL_TOGGLE, IIO_SEPARATE, + ltc2664_reg_bool_get, ltc2664_reg_bool_set), + LTC2664_CHAN_EXT_INFO("toggle_en", LTC2664_TOGGLE_EN, + IIO_SEPARATE, ltc2664_reg_bool_get, + ltc2664_reg_bool_set), + {} +}; + +static const struct iio_chan_spec_ext_info ltc2664_ext_info[] = { + LTC2664_CHAN_EXT_INFO("powerdown", LTC2664_POWERDOWN, IIO_SEPARATE, + ltc2664_reg_bool_get, ltc2664_reg_bool_set), + {} +}; + +#define LTC2664_CHANNEL(_chan) { \ + .indexed = 1, \ + .output = 1, \ + .channel = (_chan), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW), \ + .ext_info = ltc2664_ext_info, \ +} + +static const struct iio_chan_spec ltc2664_channels[] = { + LTC2664_CHANNEL(0), + LTC2664_CHANNEL(1), + LTC2664_CHANNEL(2), + LTC2664_CHANNEL(3), +}; + +static const struct iio_chan_spec ltc2672_channels[] = { + LTC2664_CHANNEL(0), + LTC2664_CHANNEL(1), + LTC2664_CHANNEL(2), + LTC2664_CHANNEL(3), + LTC2664_CHANNEL(4), +}; + +static const struct ltc2664_chip_info ltc2664_chip = { + .id = LTC2664, + .name = "ltc2664", + .num_channels = ARRAY_SIZE(ltc2664_channels), + .iio_chan = ltc2664_channels, + .span_helper = ltc2664_span_helper, + .num_span = ARRAY_SIZE(ltc2664_span_helper), +}; + +static const struct ltc2664_chip_info ltc2672_chip = { + .id = LTC2672, + .name = "ltc2672", + .num_channels = ARRAY_SIZE(ltc2672_channels), + .iio_chan = ltc2672_channels, + .span_helper = ltc2672_span_helper, + .num_span = ARRAY_SIZE(ltc2672_span_helper), +}; + +static int ltc2664_span_lookup(const struct ltc2664_state *st, int min, int max) +{ + const int (*span_helper)[2] = st->chip_info->span_helper; + int span; + + for (span = 0; span < st->chip_info->num_span; span++) { + if (min == span_helper[span][0] && max == span_helper[span][1]) + return span; + } + + return -EINVAL; +} + +static int ltc2664_channel_config(struct ltc2664_state *st) +{ + const struct ltc2664_chip_info *chip_info = st->chip_info; + struct device *dev = &st->spi->dev; + u32 reg, tmp[2], mspan; + int ret, span; + + mspan = LTC2664_MSPAN_SOFTSPAN; + ret = device_property_read_u32(dev, "adi,manual-span-operation-config", + &mspan); + if (!ret) { + if (chip_info->id != LTC2664) + return dev_err_probe(dev, -EINVAL, + "adi,manual-span-operation-config not supported\n"); + + if (mspan > ARRAY_SIZE(ltc2664_mspan_lut)) + return dev_err_probe(dev, -EINVAL, + "adi,manual-span-operation-config not in range\n"); + } + + st->rfsadj = 20000; + ret = device_property_read_u32(dev, "adi,rfsadj-ohms", &st->rfsadj); + if (!ret) { + if (chip_info->id != LTC2672) + return dev_err_probe(dev, -EINVAL, + "adi,rfsadj-ohms not supported\n"); + + if ((st->rfsadj < 19000 || st->rfsadj > 41000) || + chip_info->id != LTC2672) + return dev_err_probe(dev, -EINVAL, + "adi,rfsadj-ohms not in range\n"); + } + + device_for_each_child_node_scoped(dev, child) { + struct ltc2664_chan *chan; + + ret = fwnode_property_read_u32(child, "reg", ®); + if (ret) + return dev_err_probe(dev, ret, + "Failed to get reg property\n"); + + if (reg >= chip_info->num_channels) + return dev_err_probe(dev, -EINVAL, + "reg bigger than: %d\n", + chip_info->num_channels); + + chan = &st->channels[reg]; + + if (fwnode_property_read_bool(child, "adi,toggle-mode")) { + chan->toggle_chan = true; + /* assume sw toggle ABI */ + st->iio_channels[reg].ext_info = ltc2664_toggle_sym_ext_info; + /* + * Clear IIO_CHAN_INFO_RAW bit as toggle channels expose + * out_voltage/current_raw{0|1} files. + */ + __clear_bit(IIO_CHAN_INFO_RAW, + &st->iio_channels[reg].info_mask_separate); + } + + chan->raw[0] = ltc2664_mspan_lut[mspan][1]; + chan->raw[1] = ltc2664_mspan_lut[mspan][1]; + + chan->span = ltc2664_mspan_lut[mspan][0]; + + ret = fwnode_property_read_u32_array(child, "adi,output-range-microvolt", + tmp, ARRAY_SIZE(tmp)); + if (!ret && mspan == LTC2664_MSPAN_SOFTSPAN) { + /* voltage type measurement */ + st->iio_channels[reg].type = IIO_VOLTAGE; + + span = ltc2664_span_lookup(st, (int)tmp[0] / 1000, + tmp[1] / 1000); + if (span < 0) + return dev_err_probe(dev, -EINVAL, + "output range not valid"); + + ret = regmap_write(st->regmap, + LTC2664_CMD_SPAN_N(reg), + span); + if (ret) + return dev_err_probe(dev, -EINVAL, + "failed to set chan settings\n"); + + chan->span = span; + } + + ret = fwnode_property_read_u32(child, + "adi,output-range-microamp", + &tmp[0]); + if (!ret) { + /* current type measurement */ + st->iio_channels[reg].type = IIO_CURRENT; + + span = ltc2664_span_lookup(st, 0, + (int)tmp[0] / 1000); + if (span < 0) + return dev_err_probe(dev, -EINVAL, + "output range not valid"); + + ret = regmap_write(st->regmap, + LTC2664_CMD_SPAN_N(reg), + span + 1); + if (ret) + return dev_err_probe(dev, -EINVAL, + "failed to set chan settings\n"); + + chan->span = span; + } + } + + return 0; +} + +static int ltc2664_setup(struct ltc2664_state *st, struct regulator *vref) +{ + const struct ltc2664_chip_info *chip_info = st->chip_info; + struct gpio_desc *gpio; + int ret; + + /* + * If we have a clr/reset pin, use that to reset the chip. + */ + gpio = devm_gpiod_get_optional(&st->spi->dev, "clr", GPIOD_OUT_HIGH); + if (IS_ERR(gpio)) + return dev_err_probe(&st->spi->dev, PTR_ERR(gpio), + "Failed to get reset gpio"); + if (gpio) { + usleep_range(1000, 1200); + /* bring device out of reset */ + gpiod_set_value_cansleep(gpio, 0); + } + + /* + * Duplicate the default channel configuration as it can change during + * @ltc2664_channel_config() + */ + st->iio_channels = devm_kmemdup(&st->spi->dev, chip_info->iio_chan, + chip_info->num_channels * + sizeof(*chip_info->iio_chan), + GFP_KERNEL); + + ret = ltc2664_channel_config(st); + if (ret) + return ret; + + if (!vref) + return 0; + + return regmap_set_bits(st->regmap, LTC2664_CMD_CONFIG, LTC2664_REF_DISABLE); +} + +static void ltc2664_disable_regulator(void *regulator) +{ + regulator_disable(regulator); +} + +static const struct regmap_config ltc2664_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .max_register = LTC2664_CMD_NO_OPERATION, +}; + +static const struct iio_info ltc2664_info = { + .write_raw = ltc2664_write_raw, + .read_raw = ltc2664_read_raw, + .read_avail = ltc2664_read_avail, + .debugfs_reg_access = ltc2664_reg_access, +}; + +static int ltc2664_probe(struct spi_device *spi) +{ + static const char * const regulators[] = { "vcc", "iovcc" }; + const struct ltc2664_chip_info *chip_info; + struct device *dev = &spi->dev; + struct regulator *vref_reg; + struct iio_dev *indio_dev; + struct ltc2664_state *st; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->spi = spi; + + chip_info = spi_get_device_match_data(spi); + if (!chip_info) + return -ENOMEM; + + st->chip_info = chip_info; + + mutex_init(&st->lock); + + st->regmap = devm_regmap_init_spi(spi, <c2664_regmap_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(dev, PTR_ERR(st->regmap), + "Failed to init regmap"); + + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators), + regulators); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable regulators\n"); + + vref_reg = devm_regulator_get_optional(dev, "vref"); + if (IS_ERR(vref_reg)) { + if (PTR_ERR(vref_reg) != -ENODEV) + return dev_err_probe(dev, PTR_ERR(vref_reg), + "Failed to get vref regulator"); + + vref_reg = NULL; + + /* internal reference */ + if (chip_info->id == LTC2664) + st->vref = 2500; + else + st->vref = 1250; + } else { + ret = regulator_enable(vref_reg); + if (ret) + return dev_err_probe(dev, ret, + "Failed to enable vref regulators\n"); + + ret = devm_add_action_or_reset(dev, ltc2664_disable_regulator, + vref_reg); + if (ret) + return ret; + + ret = regulator_get_voltage(vref_reg); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to get vref\n"); + + st->vref = ret / 1000; + } + + ret = ltc2664_setup(st, vref_reg); + if (ret) + return ret; + + indio_dev->name = chip_info->name; + indio_dev->info = <c2664_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->iio_channels; + indio_dev->num_channels = chip_info->num_channels; + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct spi_device_id ltc2664_id[] = { + { "ltc2664", (kernel_ulong_t)<c2664_chip }, + { "ltc2672", (kernel_ulong_t)<c2672_chip }, + { }, +}; +MODULE_DEVICE_TABLE(spi, ltc2664_id); + +static const struct of_device_id ltc2664_of_id[] = { + { .compatible = "adi,ltc2664", .data = <c2664_chip }, + { .compatible = "adi,ltc2672", .data = <c2672_chip }, + { }, +}; +MODULE_DEVICE_TABLE(of, ltc2664_of_id); + +static struct spi_driver ltc2664_driver = { + .driver = { + .name = "ltc2664", + .of_match_table = ltc2664_of_id, + }, + .probe = ltc2664_probe, + .id_table = ltc2664_id, +}; +module_spi_driver(ltc2664_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_AUTHOR("Kim Seer Paller "); +MODULE_DESCRIPTION("Analog Devices LTC2664 and LTC2672 DAC"); +MODULE_LICENSE("GPL");