2024-05-23 03:20:07

by Paller, Kim Seer

[permalink] [raw]
Subject: [PATCH v2 0/5] Add driver for LTC2664 and LTC2672

Generalize the ABI documentation for DAC. The ABI defined for toggle mode
channels:

LTC2664:
* out_voltageY_toggle_en
* out_voltageY_raw0
* out_voltageY_raw1
* out_voltageY_symbol

LTC2672:
* out_currentY_toggle_en
* out_currentY_raw0
* out_currentY_raw1
* out_currentY_symbol

Default channels won't have any of the above ABIs. A channel is toggle capable
if the devicetree 'adi,toggle-mode' flag is set.

changes in v2:

ltc2664:
* Updated struct ltc2664_chip_info to include device-specific data for scale,
offset, measurement type, internal vref, manual span support, and rfsadj
support.
* Added a read-only extended info attribute powerdown_mode to indicate the
state that the DAC output enters when the device is powered down.
* Refactored code for setting the span into separate function and directly
returning the span.
* Adjusted memory allocation for st->iio_channels to include null terminator.
* Spaces have been added after { and before }. Each pair of values is now
placed on a separate line.

ABI:
* Generalized the ABI documentation for DAC.
* Added DAC 42kohm_to_gnd powerdown mode.

Bindings:
* Created separate bindings for ltc2664 and ltc2672.
* Added v-pos-supply and v-neg-supply regulator properties.
* Renamed vref-supply to ref-supply based on the datasheet.
* Added io-channels property and specifying the pin for multiplexer output.
* Added vdd0-vdd4 supply properties for ltc2672, although they are not
currently supported in the driver.
* Changed clr-gpios description based on the datasheet.
* Used 4 spaces for example indentation.

Kim Seer Paller (5):
iio: ABI: Generalize ABI documentation for DAC
iio: ABI: add DAC 42kohm_to_gnd powerdown mode
dt-bindings: iio: dac: Add adi,ltc2664.yaml
dt-bindings: iio: dac: Add adi,ltc2672.yaml
iio: dac: ltc2664: Add driver for LTC2664 and LTC2672

Documentation/ABI/testing/sysfs-bus-iio | 1 +
Documentation/ABI/testing/sysfs-bus-iio-dac | 61 ++
.../ABI/testing/sysfs-bus-iio-dac-ltc2688 | 31 -
.../bindings/iio/dac/adi,ltc2664.yaml | 167 ++++
.../bindings/iio/dac/adi,ltc2672.yaml | 159 ++++
MAINTAINERS | 11 +
drivers/iio/dac/Kconfig | 11 +
drivers/iio/dac/Makefile | 1 +
drivers/iio/dac/ltc2664.c | 802 ++++++++++++++++++
9 files changed, 1213 insertions(+), 31 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-dac
create mode 100644 Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml
create mode 100644 Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml
create mode 100644 drivers/iio/dac/ltc2664.c


base-commit: 827dca3129708a8465bde90c86c2e3c38e62dd4f
--
2.34.1



2024-05-23 03:20:18

by Paller, Kim Seer

[permalink] [raw]
Subject: [PATCH v2 2/5] iio: ABI: add DAC 42kohm_to_gnd powerdown mode

Co-developed-by: Michael Hennerich <[email protected]>
Signed-off-by: Michael Hennerich <[email protected]>
Signed-off-by: Kim Seer Paller <[email protected]>
---
Documentation/ABI/testing/sysfs-bus-iio | 1 +
1 file changed, 1 insertion(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 7cee78ad4108..6ee58f59065b 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -708,6 +708,7 @@ Description:
2.5kohm_to_gnd: connected to ground via a 2.5kOhm resistor,
6kohm_to_gnd: connected to ground via a 6kOhm resistor,
20kohm_to_gnd: connected to ground via a 20kOhm resistor,
+ 42kohm_to_gnd: connected to ground via a 42kOhm resistor,
90kohm_to_gnd: connected to ground via a 90kOhm resistor,
100kohm_to_gnd: connected to ground via an 100kOhm resistor,
125kohm_to_gnd: connected to ground via an 125kOhm resistor,
--
2.34.1


2024-05-23 03:20:59

by Paller, Kim Seer

[permalink] [raw]
Subject: [PATCH v2 3/5] dt-bindings: iio: dac: Add adi,ltc2664.yaml

Add documentation for ltc2664.

Co-developed-by: Michael Hennerich <[email protected]>
Signed-off-by: Michael Hennerich <[email protected]>
Signed-off-by: Kim Seer Paller <[email protected]>
---
.../bindings/iio/dac/adi,ltc2664.yaml | 167 ++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 168 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 000000000000..517a96808ee0
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml
@@ -0,0 +1,167 @@
+# 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 DAC
+
+maintainers:
+ - Michael Hennerich <[email protected]>
+ - Kim Seer Paller <[email protected]>
+
+description: |
+ Analog Devices LTC2664 4 channel, 16 bit, +-10V DAC
+ https://www.analog.com/media/en/technical-documentation/data-sheets/2664fa.pdf
+
+properties:
+ compatible:
+ enum:
+ - adi,ltc2664
+
+ reg:
+ maxItems: 1
+
+ spi-max-frequency:
+ maximum: 50000000
+
+ vcc-supply:
+ description: Analog Supply Voltage Input.
+
+ v-pos-supply:
+ description: Positive Supply Voltage Input.
+
+ v-neg-supply:
+ description: Negative Supply Voltage Input.
+
+ iovcc-supply:
+ description: Digital Input/Output Supply Voltage.
+
+ ref-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:
+ Active-low Asynchronous Clear Input. A logic low at this level-triggered
+ input clears the part to the reset code and range determined by the
+ hardwired option chosen using the MSPAN pins. The control registers are
+ cleared to zero.
+ maxItems: 1
+
+ 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
+
+ io-channels:
+ description:
+ Analog multiplexer output. VOUT0-VOUT3, MUXIN0-MUXIN3, REFLO, REF, V+, V-,
+ and a temperature monitor output can be internally routed to the MUXOUT pin.
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+patternProperties:
+ "^channel@[0-3]$":
+ type: object
+ additionalProperties: false
+
+ properties:
+ reg:
+ description: The channel number representing the DAC output channel.
+ maximum: 3
+
+ 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
+
+ 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:
+ - reg
+ - adi,output-range-microvolt
+
+required:
+ - compatible
+ - reg
+ - spi-max-frequency
+ - vcc-supply
+ - iovcc-supply
+ - v-pos-supply
+ - v-neg-supply
+
+allOf:
+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+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>;
+ ref-supply = <&vref>;
+ v-pos-supply = <&vpos>;
+ v-neg-supply = <&vneg>;
+
+ io-channels = <&adc 0>;
+
+ #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>;
+ };
+ };
+ };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index b3be54c09159..7becbdf7d1df 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12857,6 +12857,7 @@ L: [email protected]
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/ABI/testing/sysfs-bus-iio-dac
+F: Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml

LTC2688 IIO DAC DRIVER
M: Nuno Sá <[email protected]>
--
2.34.1


2024-05-23 03:21:21

by Paller, Kim Seer

[permalink] [raw]
Subject: [PATCH v2 4/5] dt-bindings: iio: dac: Add adi,ltc2672.yaml

Add documentation for ltc2672.

Co-developed-by: Michael Hennerich <[email protected]>
Signed-off-by: Michael Hennerich <[email protected]>
Signed-off-by: Kim Seer Paller <[email protected]>
---
.../bindings/iio/dac/adi,ltc2672.yaml | 159 ++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 160 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml

diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml
new file mode 100644
index 000000000000..996aae315640
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml
@@ -0,0 +1,159 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/dac/adi,ltc2672.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices LTC2672 DAC
+
+maintainers:
+ - Michael Hennerich <[email protected]>
+ - Kim Seer Paller <[email protected]>
+
+description: |
+ Analog Devices LTC2672 5 channel, 16 bit, 300mA DAC
+ https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2672.pdf
+
+properties:
+ compatible:
+ enum:
+ - adi,ltc2672
+
+ reg:
+ maxItems: 1
+
+ spi-max-frequency:
+ maximum: 50000000
+
+ vcc-supply:
+ description: Analog Supply Voltage Input.
+
+ v-neg-supply:
+ description: Negative Supply Voltage Input.
+
+ vdd0-supply:
+ description: Positive Supply Voltage Input for DAC OUT0.
+
+ vdd1-supply:
+ description: Positive Supply Voltage Input for DAC OUT1.
+
+ vdd2-supply:
+ description: Positive Supply Voltage Input for DAC OUT2.
+
+ vdd3-supply:
+ description: Positive Supply Voltage Input for DAC OUT3.
+
+ vdd4-supply:
+ description: Positive Supply Voltage Input for DAC OUT4.
+
+ iovcc-supply:
+ description: Digital Input/Output Supply Voltage.
+
+ ref-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:
+ Active Low Asynchronous Clear Input. A logic low at this level triggered
+ input clears the device to the default reset code and output range, which
+ is zero-scale with the outputs off. The control registers are cleared to
+ zero.
+ maxItems: 1
+
+ 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
+
+ io-channels:
+ description:
+ Analog multiplexer output. Pin voltages and currents can be monitored by
+ measuring the voltage at MUX.
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+patternProperties:
+ "^channel@[0-4]$":
+ type: object
+ additionalProperties: false
+
+ properties:
+ reg:
+ description: The channel number representing the DAC output channel.
+ 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
+
+ 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:
+ - reg
+ - adi,output-range-microamp
+
+required:
+ - compatible
+ - reg
+ - spi-max-frequency
+ - vcc-supply
+ - iovcc-supply
+ - v-neg-supply
+
+allOf:
+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+additionalProperties: false
+
+examples:
+ - |
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ dac@0 {
+ compatible = "adi,ltc2672";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ vcc-supply = <&vcc>;
+ iovcc-supply = <&vcc>;
+ ref-supply = <&vref>;
+ v-neg-supply = <&vneg>;
+
+ io-channels = <&adc 0>;
+
+ #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 7becbdf7d1df..3320b7af4c0b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12858,6 +12858,7 @@ S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/ABI/testing/sysfs-bus-iio-dac
F: Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml
+F: Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml

LTC2688 IIO DAC DRIVER
M: Nuno Sá <[email protected]>
--
2.34.1


2024-05-23 03:27:25

by Paller, Kim Seer

[permalink] [raw]
Subject: [PATCH v2 5/5] iio: dac: ltc2664: Add driver for LTC2664 and LTC2672

LTC2664 4 channel, 16 bit Voltage Output SoftSpan DAC
LTC2672 5 channel, 16 bit Current Output Softspan DAC

Co-developed-by: Michael Hennerich <[email protected]>
Signed-off-by: Michael Hennerich <[email protected]>
Signed-off-by: Kim Seer Paller <[email protected]>
---
MAINTAINERS | 1 +
drivers/iio/dac/Kconfig | 11 +
drivers/iio/dac/Makefile | 1 +
drivers/iio/dac/ltc2664.c | 802 ++++++++++++++++++++++++++++++++++++++
4 files changed, 815 insertions(+)
create mode 100644 drivers/iio/dac/ltc2664.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3320b7af4c0b..2997f65247e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12859,6 +12859,7 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/ABI/testing/sysfs-bus-iio-dac
F: Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml
F: Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml
+F: drivers/iio/dac/ltc2664.c

LTC2688 IIO DAC DRIVER
M: Nuno Sá <[email protected]>
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index 3c2bf620f00f..3d065c157605 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -370,6 +370,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 8432a81a19dc..2cf148f16306 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -37,6 +37,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 000000000000..488b841e6c66
--- /dev/null
+++ b/drivers/iio/dac/ltc2664.c
@@ -0,0 +1,802 @@
+// 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 <linux/bitfield.h>
+#include <linux/cleanup.h>
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/iio/iio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+
+#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_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_POWERDOWN_MODE,
+ 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_state;
+
+struct ltc2664_chip_info {
+ enum ltc2664_ids id;
+ const char *name;
+ int (*scale_get)(const struct ltc2664_state *st, int c);
+ int (*offset_get)(const struct ltc2664_state *st, int c);
+ int measurement_type;
+ unsigned int num_channels;
+ const struct iio_chan_spec *iio_chan;
+ const int (*span_helper)[2];
+ unsigned int num_span;
+ unsigned int internal_vref;
+ bool manual_span_support;
+ bool rfsadj_support;
+};
+
+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)
+{
+ 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;
+
+ fs = span_helper[span][1] - span_helper[span][0];
+
+ return (fs / 2500) * st->vref;
+}
+
+static int ltc2672_scale_get(const struct ltc2664_state *st, int c)
+{
+ const struct ltc2664_chan *chan = &st->channels[c];
+ int span, fs;
+
+ span = chan->span;
+ if (span < 0)
+ return span;
+
+ fs = 1000 * st->vref / st->rfsadj;
+
+ if (span == LTC2672_MAX_SPAN)
+ return 4800 * fs;
+
+ return LTC2672_SCALE_MULTIPLIER(span) * fs;
+}
+
+static int ltc2664_offset_get(const struct ltc2664_state *st, int c)
+{
+ 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)
+ return -32768;
+
+ return 0;
+}
+
+static int ltc2672_offset_get(const struct ltc2664_state *st, int c)
+{
+ 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][1] < 0)
+ return -32768;
+
+ return st->chip_info->span_helper[span][1] / 250;
+}
+
+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:
+ *val = st->chip_info->offset_get(st, chan->channel);
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = st->chip_info->scale_get(st, chan->channel);
+
+ *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_POWERDOWN_MODE:
+ return sysfs_emit(buf, "42kohm_to_gnd\n");
+ 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("powerdown_mode", LTC2664_POWERDOWN_MODE,
+ IIO_SEPARATE, ltc2664_reg_bool_get, NULL),
+ 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),
+ LTC2664_CHAN_EXT_INFO("powerdown_mode", LTC2664_POWERDOWN_MODE,
+ IIO_SEPARATE, ltc2664_reg_bool_get, NULL),
+ { }
+};
+
+#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",
+ .scale_get = ltc2664_scale_get,
+ .offset_get = ltc2664_offset_get,
+ .measurement_type = IIO_VOLTAGE,
+ .num_channels = ARRAY_SIZE(ltc2664_channels),
+ .iio_chan = ltc2664_channels,
+ .span_helper = ltc2664_span_helper,
+ .num_span = ARRAY_SIZE(ltc2664_span_helper),
+ .internal_vref = 2500,
+ .manual_span_support = true,
+ .rfsadj_support = false,
+};
+
+static const struct ltc2664_chip_info ltc2672_chip = {
+ .id = LTC2672,
+ .name = "ltc2672",
+ .scale_get = ltc2672_scale_get,
+ .offset_get = ltc2672_offset_get,
+ .measurement_type = IIO_CURRENT,
+ .num_channels = ARRAY_SIZE(ltc2672_channels),
+ .iio_chan = ltc2672_channels,
+ .span_helper = ltc2672_span_helper,
+ .num_span = ARRAY_SIZE(ltc2672_span_helper),
+ .internal_vref = 1250,
+ .manual_span_support = false,
+ .rfsadj_support = true,
+};
+
+static int ltc2664_set_span(const struct ltc2664_state *st, int min, int max,
+ int chan)
+{
+ const struct ltc2664_chip_info *chip_info = st->chip_info;
+ const int (*span_helper)[2] = chip_info->span_helper;
+ int span, ret;
+
+ st->iio_channels[chan].type = chip_info->measurement_type;
+
+ for (span = 0; span < chip_info->num_span; span++) {
+ if (min == span_helper[span][0] && max == span_helper[span][1])
+ break;
+ }
+
+ ret = regmap_write(st->regmap, LTC2664_CMD_SPAN_N(chan),
+ (chip_info->id == LTC2672) ? span + 1 : span);
+ if (ret)
+ return ret;
+
+ return span;
+}
+
+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->manual_span_support)
+ 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->rfsadj_support)
+ return dev_err_probe(dev, -EINVAL,
+ "adi,rfsadj-ohms not supported\n");
+
+ if (st->rfsadj < 19000 || st->rfsadj > 41000)
+ 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", &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) {
+ chan->span = ltc2664_set_span(st, tmp[0] / 1000,
+ tmp[1] / 1000, reg);
+ if (span < 0)
+ return dev_err_probe(dev, span,
+ "Failed to set span\n");
+
+ }
+
+ ret = fwnode_property_read_u32(child,
+ "adi,output-range-microamp",
+ &tmp[0]);
+ if (!ret) {
+ chan->span = ltc2664_set_span(st, 0, tmp[0] / 1000, reg);
+ if (span < 0)
+ return dev_err_probe(dev, span,
+ "Failed to set span\n");
+ }
+ }
+
+ 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);
+ 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 + 1) *
+ 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", "v-neg" };
+ 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, &ltc2664_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, "ref");
+ if (IS_ERR(vref_reg)) {
+ if (PTR_ERR(vref_reg) != -ENODEV)
+ return dev_err_probe(dev, PTR_ERR(vref_reg),
+ "Failed to get ref regulator");
+
+ vref_reg = NULL;
+
+ st->vref = chip_info->internal_vref;
+ } else {
+ ret = regulator_enable(vref_reg);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to enable ref 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 ref\n");
+
+ st->vref = ret / 1000;
+ }
+
+ ret = ltc2664_setup(st, vref_reg);
+ if (ret)
+ return ret;
+
+ indio_dev->name = chip_info->name;
+ indio_dev->info = &ltc2664_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)&ltc2664_chip },
+ { "ltc2672", (kernel_ulong_t)&ltc2672_chip },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, ltc2664_id);
+
+static const struct of_device_id ltc2664_of_id[] = {
+ { .compatible = "adi,ltc2664", .data = &ltc2664_chip },
+ { .compatible = "adi,ltc2672", .data = &ltc2672_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 <[email protected]>");
+MODULE_AUTHOR("Kim Seer Paller <[email protected]>");
+MODULE_DESCRIPTION("Analog Devices LTC2664 and LTC2672 DAC");
+MODULE_LICENSE("GPL");
--
2.34.1


2024-05-23 03:28:00

by Paller, Kim Seer

[permalink] [raw]
Subject: [PATCH v2 1/5] iio: ABI: Generalize ABI documentation for DAC

Introduces a more generalized ABI documentation for DAC. Instead of
having separate ABI files for each DAC, we now have a single ABI file
that covers the common sysfs interface for all DAC.

Co-developed-by: Michael Hennerich <[email protected]>
Signed-off-by: Michael Hennerich <[email protected]>
Signed-off-by: Kim Seer Paller <[email protected]>
---
Documentation/ABI/testing/sysfs-bus-iio-dac | 61 +++++++++++++++++++
.../ABI/testing/sysfs-bus-iio-dac-ltc2688 | 31 ----------
MAINTAINERS | 8 +++
3 files changed, 69 insertions(+), 31 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-dac

diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dac b/Documentation/ABI/testing/sysfs-bus-iio-dac
new file mode 100644
index 000000000000..53d5213520c6
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-dac
@@ -0,0 +1,61 @@
+What: /sys/bus/iio/devices/iio:deviceX/out_currentY_toggle_en
+KernelVersion: 5.18
+Contact: [email protected]
+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: [email protected]
+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: [email protected]
+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.
+
+What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_toggle_en
+KernelVersion: 5.18
+Contact: [email protected]
+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: [email protected]
+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: [email protected]
+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/Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2688 b/Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2688
index 1c35971277ba..ae95a5477382 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2688
+++ b/Documentation/ABI/testing/sysfs-bus-iio-dac-ltc2688
@@ -53,34 +53,3 @@ KernelVersion: 5.18
Contact: [email protected]
Description:
Returns the available values for the dither phase.
-
-What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_toggle_en
-KernelVersion: 5.18
-Contact: [email protected]
-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: [email protected]
-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: [email protected]
-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 758c202ec712..b3be54c09159 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12850,6 +12850,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 <[email protected]>
+M: Kim Seer Paller <[email protected]>
+L: [email protected]
+S: Supported
+W: https://ez.analog.com/linux-software-drivers
+F: Documentation/ABI/testing/sysfs-bus-iio-dac
+
LTC2688 IIO DAC DRIVER
M: Nuno Sá <[email protected]>
L: [email protected]
--
2.34.1


2024-05-23 04:24:25

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v2 4/5] dt-bindings: iio: dac: Add adi,ltc2672.yaml


On Thu, 23 May 2024 11:19:08 +0800, Kim Seer Paller wrote:
> Add documentation for ltc2672.
>
> Co-developed-by: Michael Hennerich <[email protected]>
> Signed-off-by: Michael Hennerich <[email protected]>
> Signed-off-by: Kim Seer Paller <[email protected]>
> ---
> .../bindings/iio/dac/adi,ltc2672.yaml | 159 ++++++++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 160 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml
>

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml: patternProperties:^channel@[0-4]$:properties:adi,output-range-microamp: '$ref' should not be valid under {'const': '$ref'}
hint: Standard unit suffix properties don't need a type $ref
from schema $id: http://devicetree.org/meta-schemas/core.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/[email protected]

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


2024-05-23 06:39:52

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v2 3/5] dt-bindings: iio: dac: Add adi,ltc2664.yaml

On 23/05/2024 05:19, Kim Seer Paller wrote:
> Add documentation for ltc2664.
>


> +
> + ref-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:
> + Active-low Asynchronous Clear Input. A logic low at this level-triggered
> + input clears the part to the reset code and range determined by the
> + hardwired option chosen using the MSPAN pins. The control registers are
> + cleared to zero.

So this is a reset gpio?

> + maxItems: 1
> +
> + 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
> +
> + io-channels:
> + description:
> + Analog multiplexer output. VOUT0-VOUT3, MUXIN0-MUXIN3, REFLO, REF, V+, V-,

That's not output but input.

> + and a temperature monitor output can be internally routed to the MUXOUT pin.

Needs maxItems

> +
> + '#address-cells':
> + const: 1
> +
> + '#size-cells':
> + const: 0
> +


Best regards,
Krzysztof


2024-05-23 12:34:02

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v2 4/5] dt-bindings: iio: dac: Add adi,ltc2672.yaml

On Thu, May 23, 2024 at 11:19:08AM +0800, Kim Seer Paller wrote:
> Add documentation for ltc2672.
>
> Co-developed-by: Michael Hennerich <[email protected]>
> Signed-off-by: Michael Hennerich <[email protected]>
> Signed-off-by: Kim Seer Paller <[email protected]>
> ---
> .../bindings/iio/dac/adi,ltc2672.yaml | 159 ++++++++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 160 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml
>
> diff --git a/Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml b/Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml
> new file mode 100644
> index 000000000000..996aae315640
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml
> @@ -0,0 +1,159 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/iio/dac/adi,ltc2672.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Analog Devices LTC2672 DAC
> +
> +maintainers:
> + - Michael Hennerich <[email protected]>
> + - Kim Seer Paller <[email protected]>
> +
> +description: |
> + Analog Devices LTC2672 5 channel, 16 bit, 300mA DAC
> + https://www.analog.com/media/en/technical-documentation/data-sheets/ltc2672.pdf
> +
> +properties:
> + compatible:
> + enum:
> + - adi,ltc2672
> +
> + reg:
> + maxItems: 1
> +
> + spi-max-frequency:
> + maximum: 50000000
> +
> + vcc-supply:
> + description: Analog Supply Voltage Input.
> +
> + v-neg-supply:
> + description: Negative Supply Voltage Input.
> +
> + vdd0-supply:
> + description: Positive Supply Voltage Input for DAC OUT0.
> +
> + vdd1-supply:
> + description: Positive Supply Voltage Input for DAC OUT1.
> +
> + vdd2-supply:
> + description: Positive Supply Voltage Input for DAC OUT2.
> +
> + vdd3-supply:
> + description: Positive Supply Voltage Input for DAC OUT3.
> +
> + vdd4-supply:
> + description: Positive Supply Voltage Input for DAC OUT4.
> +
> + iovcc-supply:
> + description: Digital Input/Output Supply Voltage.
> +
> + ref-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:
> + Active Low Asynchronous Clear Input. A logic low at this level triggered
> + input clears the device to the default reset code and output range, which
> + is zero-scale with the outputs off. The control registers are cleared to
> + zero.
> + maxItems: 1
> +
> + 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
> +
> + io-channels:
> + description:
> + Analog multiplexer output. Pin voltages and currents can be monitored by
> + measuring the voltage at MUX.

You need constraints for how many entries and what is each one.

> +
> + '#address-cells':
> + const: 1
> +
> + '#size-cells':
> + const: 0
> +
> +patternProperties:
> + "^channel@[0-4]$":
> + type: object
> + additionalProperties: false
> +
> + properties:
> + reg:
> + description: The channel number representing the DAC output channel.
> + 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
> +
> + 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:
> + - reg
> + - adi,output-range-microamp
> +
> +required:
> + - compatible
> + - reg
> + - spi-max-frequency
> + - vcc-supply
> + - iovcc-supply
> + - v-neg-supply
> +
> +allOf:
> + - $ref: /schemas/spi/spi-peripheral-props.yaml#
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + spi {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + dac@0 {
> + compatible = "adi,ltc2672";
> + reg = <0>;
> + spi-max-frequency = <10000000>;
> +
> + vcc-supply = <&vcc>;
> + iovcc-supply = <&vcc>;
> + ref-supply = <&vref>;
> + v-neg-supply = <&vneg>;
> +
> + io-channels = <&adc 0>;
> +
> + #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 7becbdf7d1df..3320b7af4c0b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -12858,6 +12858,7 @@ S: Supported
> W: https://ez.analog.com/linux-software-drivers
> F: Documentation/ABI/testing/sysfs-bus-iio-dac
> F: Documentation/devicetree/bindings/iio/dac/adi,ltc2664.yaml
> +F: Documentation/devicetree/bindings/iio/dac/adi,ltc2672.yaml
>
> LTC2688 IIO DAC DRIVER
> M: Nuno Sá <[email protected]>
> --
> 2.34.1
>

2024-05-24 03:28:51

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 5/5] iio: dac: ltc2664: Add driver for LTC2664 and LTC2672

Hi Kim,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 827dca3129708a8465bde90c86c2e3c38e62dd4f]

url: https://github.com/intel-lab-lkp/linux/commits/Kim-Seer-Paller/iio-ABI-Generalize-ABI-documentation-for-DAC/20240523-112246
base: 827dca3129708a8465bde90c86c2e3c38e62dd4f
patch link: https://lore.kernel.org/r/20240523031909.19427-6-kimseer.paller%40analog.com
patch subject: [PATCH v2 5/5] iio: dac: ltc2664: Add driver for LTC2664 and LTC2672
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20240524/[email protected]/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 7aa382fd7257d9bd4f7fc50bb7078a3c26a1628c)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240524/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

In file included from drivers/iio/dac/ltc2664.c:20:
In file included from include/linux/regulator/consumer.h:35:
In file included from include/linux/suspend.h:5:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:21:
In file included from include/linux/mm.h:2208:
include/linux/vmstat.h:508:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
508 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
509 | item];
| ~~~~
include/linux/vmstat.h:515:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
515 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
516 | NR_VM_NUMA_EVENT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmstat.h:522:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
522 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
| ~~~~~~~~~~~ ^ ~~~
include/linux/vmstat.h:527:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
527 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
528 | NR_VM_NUMA_EVENT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~~
include/linux/vmstat.h:536:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion]
536 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~ ^
537 | NR_VM_NUMA_EVENT_ITEMS +
| ~~~~~~~~~~~~~~~~~~~~~~
>> drivers/iio/dac/ltc2664.c:627:8: warning: variable 'span' is uninitialized when used here [-Wuninitialized]
627 | if (span < 0)
| ^~~~
drivers/iio/dac/ltc2664.c:563:15: note: initialize the variable 'span' to silence this warning
563 | int ret, span;
| ^
| = 0
6 warnings generated.


vim +/span +627 drivers/iio/dac/ltc2664.c

557
558 static int ltc2664_channel_config(struct ltc2664_state *st)
559 {
560 const struct ltc2664_chip_info *chip_info = st->chip_info;
561 struct device *dev = &st->spi->dev;
562 u32 reg, tmp[2], mspan;
563 int ret, span;
564
565 mspan = LTC2664_MSPAN_SOFTSPAN;
566 ret = device_property_read_u32(dev, "adi,manual-span-operation-config",
567 &mspan);
568 if (!ret) {
569 if (!chip_info->manual_span_support)
570 return dev_err_probe(dev, -EINVAL,
571 "adi,manual-span-operation-config not supported\n");
572
573 if (mspan > ARRAY_SIZE(ltc2664_mspan_lut))
574 return dev_err_probe(dev, -EINVAL,
575 "adi,manual-span-operation-config not in range\n");
576 }
577
578 st->rfsadj = 20000;
579 ret = device_property_read_u32(dev, "adi,rfsadj-ohms", &st->rfsadj);
580 if (!ret) {
581 if (!chip_info->rfsadj_support)
582 return dev_err_probe(dev, -EINVAL,
583 "adi,rfsadj-ohms not supported\n");
584
585 if (st->rfsadj < 19000 || st->rfsadj > 41000)
586 return dev_err_probe(dev, -EINVAL,
587 "adi,rfsadj-ohms not in range\n");
588 }
589
590 device_for_each_child_node_scoped(dev, child) {
591 struct ltc2664_chan *chan;
592
593 ret = fwnode_property_read_u32(child, "reg", &reg);
594 if (ret)
595 return dev_err_probe(dev, ret,
596 "Failed to get reg property\n");
597
598 if (reg >= chip_info->num_channels)
599 return dev_err_probe(dev, -EINVAL,
600 "reg bigger than: %d\n",
601 chip_info->num_channels);
602
603 chan = &st->channels[reg];
604
605 if (fwnode_property_read_bool(child, "adi,toggle-mode")) {
606 chan->toggle_chan = true;
607 /* assume sw toggle ABI */
608 st->iio_channels[reg].ext_info = ltc2664_toggle_sym_ext_info;
609 /*
610 * Clear IIO_CHAN_INFO_RAW bit as toggle channels expose
611 * out_voltage/current_raw{0|1} files.
612 */
613 __clear_bit(IIO_CHAN_INFO_RAW,
614 &st->iio_channels[reg].info_mask_separate);
615 }
616
617 chan->raw[0] = ltc2664_mspan_lut[mspan][1];
618 chan->raw[1] = ltc2664_mspan_lut[mspan][1];
619
620 chan->span = ltc2664_mspan_lut[mspan][0];
621
622 ret = fwnode_property_read_u32_array(child, "adi,output-range-microvolt",
623 tmp, ARRAY_SIZE(tmp));
624 if (!ret && mspan == LTC2664_MSPAN_SOFTSPAN) {
625 chan->span = ltc2664_set_span(st, tmp[0] / 1000,
626 tmp[1] / 1000, reg);
> 627 if (span < 0)
628 return dev_err_probe(dev, span,
629 "Failed to set span\n");
630
631 }
632
633 ret = fwnode_property_read_u32(child,
634 "adi,output-range-microamp",
635 &tmp[0]);
636 if (!ret) {
637 chan->span = ltc2664_set_span(st, 0, tmp[0] / 1000, reg);
638 if (span < 0)
639 return dev_err_probe(dev, span,
640 "Failed to set span\n");
641 }
642 }
643
644 return 0;
645 }
646

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

2024-05-24 06:28:41

by Paller, Kim Seer

[permalink] [raw]
Subject: RE: [PATCH v2 3/5] dt-bindings: iio: dac: Add adi,ltc2664.yaml


> -----Original Message-----
> From: Krzysztof Kozlowski <[email protected]>
> Sent: Thursday, May 23, 2024 2:40 PM
> To: Paller, Kim Seer <[email protected]>; linux-
> [email protected]; [email protected]; [email protected]
> Cc: Jonathan Cameron <[email protected]>; David Lechner
> <[email protected]>; Lars-Peter Clausen <[email protected]>; Liam
> Girdwood <[email protected]>; Mark Brown <[email protected]>;
> Dimitri Fedrau <[email protected]>; Krzysztof Kozlowski
> <[email protected]>; Rob Herring <[email protected]>; Conor Dooley
> <[email protected]>; Hennerich, Michael
> <[email protected]>; Nuno Sá <[email protected]>
> Subject: Re: [PATCH v2 3/5] dt-bindings: iio: dac: Add adi,ltc2664.yaml
>
> [External]
>
> On 23/05/2024 05:19, Kim Seer Paller wrote:
> > Add documentation for ltc2664.
> >
>
>
> > +
> > + ref-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:
> > + Active-low Asynchronous Clear Input. A logic low at this level-triggered
> > + input clears the part to the reset code and range determined by the
> > + hardwired option chosen using the MSPAN pins. The control registers are
> > + cleared to zero.
>
> So this is a reset gpio?

Yes, this is a reset gpio.

Kim

>
> > + maxItems: 1
> > +
> > + 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
> > +
> > + io-channels:
> > + description:
> > + Analog multiplexer output. VOUT0-VOUT3, MUXIN0-MUXIN3, REFLO,
> REF, V+, V-,
>
> That's not output but input.
>
> > + and a temperature monitor output can be internally routed to the
> MUXOUT pin.
>
> Needs maxItems
>
> > +
> > + '#address-cells':
> > + const: 1
> > +
> > + '#size-cells':
> > + const: 0
> > +
>
>
> Best regards,
> Krzysztof

2024-05-25 16:49:58

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v2 3/5] dt-bindings: iio: dac: Add adi,ltc2664.yaml

On 24/05/2024 08:28, Paller, Kim Seer wrote:
>
>> -----Original Message-----
>> From: Krzysztof Kozlowski <[email protected]>
>> Sent: Thursday, May 23, 2024 2:40 PM
>> To: Paller, Kim Seer <[email protected]>; linux-
>> [email protected]; [email protected]; [email protected]
>> Cc: Jonathan Cameron <[email protected]>; David Lechner
>> <[email protected]>; Lars-Peter Clausen <[email protected]>; Liam
>> Girdwood <[email protected]>; Mark Brown <[email protected]>;
>> Dimitri Fedrau <[email protected]>; Krzysztof Kozlowski
>> <[email protected]>; Rob Herring <[email protected]>; Conor Dooley
>> <[email protected]>; Hennerich, Michael
>> <[email protected]>; Nuno Sá <[email protected]>
>> Subject: Re: [PATCH v2 3/5] dt-bindings: iio: dac: Add adi,ltc2664.yaml
>>
>> [External]
>>
>> On 23/05/2024 05:19, Kim Seer Paller wrote:
>>> Add documentation for ltc2664.
>>>
>>
>>
>>> +
>>> + ref-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:
>>> + Active-low Asynchronous Clear Input. A logic low at this level-triggered
>>> + input clears the part to the reset code and range determined by the
>>> + hardwired option chosen using the MSPAN pins. The control registers are
>>> + cleared to zero.
>>
>> So this is a reset gpio?
>
> Yes, this is a reset gpio.

Then call it that - reset-gpios (see gpio-consumer-common).

Best regards,
Krzysztof


2024-05-25 17:17:54

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v2 3/5] dt-bindings: iio: dac: Add adi,ltc2664.yaml


A few comments inline.

> + 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)
Could you add to the description to say what results of the entries are
(like you have done for 7)
e.g.
0 - MSP2=GND, MPS1=GND, MSP0=GND (+-10V, reset to 0V)
at least I think that's what reset to mid scale means.

This seems like a reasonable level of information to convey here.

I was going to suggest making this a 3 value array, but that would
make ti hard to add such docs, so perhaps what you have here
is the right approach.


> + $ref: /schemas/types.yaml#/definitions/uint32
> + enum: [0, 1, 2, 3, 4, 5, 6, 7]
> + default: 7
> +
> + io-channels:
> + description:
> + Analog multiplexer output. VOUT0-VOUT3, MUXIN0-MUXIN3, REFLO, REF, V+, V-,
> + and a temperature monitor output can be internally routed to the MUXOUT pin.
> +
That's a little confusing. What you are specifying here is the ADC
channels that is connected to. This description sort of suggests it's about
what is routed there.




2024-06-02 13:14:01

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v2 5/5] iio: dac: ltc2664: Add driver for LTC2664 and LTC2672

On Tue, 28 May 2024 05:53:11 +0000
"Paller, Kim Seer" <[email protected]> wrote:

> > -----Original Message-----
> > From: Jonathan Cameron <[email protected]>
> > Sent: Friday, May 24, 2024 1:02 AM
> > To: Paller, Kim Seer <[email protected]>
> > Cc: [email protected]; [email protected];
> > [email protected]; Jonathan Cameron <[email protected]>; David
> > Lechner <[email protected]>; Lars-Peter Clausen <[email protected]>;
> > Liam Girdwood <[email protected]>; Mark Brown <[email protected]>;
> > Dimitri Fedrau <[email protected]>; Krzysztof Kozlowski
> > <[email protected]>; Rob Herring <[email protected]>; Conor Dooley
> > <[email protected]>; Hennerich, Michael
> > <[email protected]>; Nuno Sá <[email protected]>
> > Subject: Re: [PATCH v2 5/5] iio: dac: ltc2664: Add driver for LTC2664 and
> > LTC2672
> >
> > [External]
> >
> > On Thu, 23 May 2024 11:19:09 +0800
> > Kim Seer Paller <[email protected]> wrote:
> >
> > > LTC2664 4 channel, 16 bit Voltage Output SoftSpan DAC
> > > LTC2672 5 channel, 16 bit Current Output Softspan DAC
> > >
> > > Co-developed-by: Michael Hennerich <[email protected]>
> > > Signed-off-by: Michael Hennerich <[email protected]>
> > > Signed-off-by: Kim Seer Paller <[email protected]>
> > Hi Kim,
> >
> > A few minor things inline,
> >
> > Jonathan
> >
> > > diff --git a/drivers/iio/dac/ltc2664.c b/drivers/iio/dac/ltc2664.c
> > > new file mode 100644
> > > index 000000000000..488b841e6c66
> > > --- /dev/null
> > > +++ b/drivers/iio/dac/ltc2664.c
> > > @@ -0,0 +1,802 @@
> >
> >
> > > +static int ltc2664_set_span(const struct ltc2664_state *st, int min, int max,
> > > + int chan)
> > > +{
> > > + const struct ltc2664_chip_info *chip_info = st->chip_info;
> > > + const int (*span_helper)[2] = chip_info->span_helper;
> > > + int span, ret;
> > > +
> > > + st->iio_channels[chan].type = chip_info->measurement_type;
> > > +
> > > + for (span = 0; span < chip_info->num_span; span++) {
> > > + if (min == span_helper[span][0] && max ==
> > span_helper[span][1])
> > > + break;
> > > + }
> >
> > Sanity check for no match?
> >
> > > +
> > > + ret = regmap_write(st->regmap, LTC2664_CMD_SPAN_N(chan),
> > > + (chip_info->id == LTC2672) ? span + 1 : span);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + return span;
> > > +}
> > > +
> > > +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->manual_span_support)
> > > + 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->rfsadj_support)
> > > + return dev_err_probe(dev, -EINVAL,
> > > + "adi,rfsadj-ohms not supported\n");
> > > +
> > > + if (st->rfsadj < 19000 || st->rfsadj > 41000)
> > > + 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", &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;
> >
> > chan->ext_info = ...
>
> Hi Jonathan,
>
> I noticed that the struct ltc2664_chan does not currently have an ext_info field.
> Based on your comment, I'm considering adding this field to the structure yet
> I'd like to understand how this would interact with the iio_chan_spec. I'd see this
> by adding 'st->iio_channels[reg].ext_info = chan->ext_info' after that. Is that right
> approach? I'd appreciate more details on how you picture this. Thanks
Ah. Was a misread on my part. I confused channels and iio_channels.
Ignore that comment.

Sorry for the waste of time!

Jonathan

>
> Kim
>
>
>


2024-06-03 18:46:21

by David Lechner

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] iio: ABI: add DAC 42kohm_to_gnd powerdown mode

On 5/22/24 10:19 PM, Kim Seer Paller wrote:

It is always helpful to have a commit message that explains why we need
this change.

> Co-developed-by: Michael Hennerich <[email protected]>
> Signed-off-by: Michael Hennerich <[email protected]>
> Signed-off-by: Kim Seer Paller <[email protected]>
> ---
> Documentation/ABI/testing/sysfs-bus-iio | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
> index 7cee78ad4108..6ee58f59065b 100644
> --- a/Documentation/ABI/testing/sysfs-bus-iio
> +++ b/Documentation/ABI/testing/sysfs-bus-iio
> @@ -708,6 +708,7 @@ Description:
> 2.5kohm_to_gnd: connected to ground via a 2.5kOhm resistor,
> 6kohm_to_gnd: connected to ground via a 6kOhm resistor,
> 20kohm_to_gnd: connected to ground via a 20kOhm resistor,
> + 42kohm_to_gnd: connected to ground via a 42kOhm resistor,
> 90kohm_to_gnd: connected to ground via a 90kOhm resistor,
> 100kohm_to_gnd: connected to ground via an 100kOhm resistor,
> 125kohm_to_gnd: connected to ground via an 125kOhm resistor,