From b4d971656407a888df111c8334e46f35cee0368d Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Wed, 3 Jan 2024 13:08:52 +0100 Subject: dt-bindings: iio: light: as73211: add support for as7331 This device has the same properties and I2C addresses as the as73211. The only difference between them is the photodiodes they use internally, which in this case is irrelevant for the bindings. Acked-by: Conor Dooley Signed-off-by: Javier Carrasco Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/light/ams,as73211.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/light/ams,as73211.yaml b/Documentation/devicetree/bindings/iio/light/ams,as73211.yaml index 0e8cd02759b3..062a038aa0ff 100644 --- a/Documentation/devicetree/bindings/iio/light/ams,as73211.yaml +++ b/Documentation/devicetree/bindings/iio/light/ams,as73211.yaml @@ -4,19 +4,22 @@ $id: http://devicetree.org/schemas/iio/light/ams,as73211.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: AMS AS73211 JENCOLOR(R) Digital XYZ Sensor +title: AMS AS73211 JENCOLOR(R) Digital XYZ Sensor and AMS AS7331 UV Sensor maintainers: - Christian Eggers description: | - XYZ True Color Sensor with I2C Interface + AMS AS73211 XYZ True Color Sensor with I2C Interface https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf/a65474c0-b302-c2fd-e30a-c98df87616df + AMS AS7331 UVA, UVB and UVC Sensor with I2C Interface + https://ams.com/documents/20143/9106314/AS7331_DS001047_4-00.pdf properties: compatible: enum: - ams,as73211 + - ams,as7331 reg: description: -- cgit v1.2.3 From 7b34e1e330298cc47985de2e71498ec71f933931 Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Fri, 29 Dec 2023 11:24:29 +0200 Subject: dt-bindings: iio: pressure: honeywell,mprls0025pa.yaml improvements Define enum inside the honeywell,transfer-function property block. Set the correct irq edge in the example block. Based on the datasheet, in table 13 on page 11: "End-of-conversion indicator: This pin is set high when a measurement and calculation have been completed and the data is ready to be clocked out" Add description on End-of-conversion interrupt. Acked-by: Krzysztof Kozlowski Co-developed-by: Andreas Klinger Signed-off-by: Andreas Klinger Signed-off-by: Petre Rodan Link: https://lore.kernel.org/r/20231229092445.30180-2-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml b/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml index d9e903fbfd99..84ced4e5a7da 100644 --- a/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml @@ -42,6 +42,10 @@ properties: maxItems: 1 interrupts: + description: + Optional interrupt for indicating End-of-conversion. + If not present, the driver loops for a while until the received status + byte indicates correct measurement. maxItems: 1 reset-gpios: @@ -65,6 +69,7 @@ properties: 1 - A, 10% to 90% of 2^24 (1677722 .. 15099494) 2 - B, 2.5% to 22.5% of 2^24 (419430 .. 3774874) 3 - C, 20% to 80% of 2^24 (3355443 .. 13421773) + enum: [1, 2, 3] $ref: /schemas/types.yaml#/definitions/uint32 vdd-supply: @@ -93,7 +98,7 @@ examples: reg = <0x18>; reset-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; interrupt-parent = <&gpio3>; - interrupts = <21 IRQ_TYPE_EDGE_FALLING>; + interrupts = <21 IRQ_TYPE_EDGE_RISING>; honeywell,pmin-pascal = <0>; honeywell,pmax-pascal = <172369>; honeywell,transfer-function = <1>; -- cgit v1.2.3 From 0181749d4e0e8f11403f9441b1aa1880f42c2226 Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Fri, 29 Dec 2023 11:24:30 +0200 Subject: dt-bindings: iio: pressure: honeywell,mprls0025pa.yaml add pressure-triplet Change order of properties in order for the end user to hopefully ignore pmin-pascal and pmax-pascal which are superseded by pressure-triplet. Add pressure-triplet property which automatically initializes pmin-pascal and pmax-pascal inside the driver. Rework honeywell,pmXX-pascal requirements based on feedback from Jonathan and Conor. Co-developed-by: Andreas Klinger Signed-off-by: Andreas Klinger Signed-off-by: Petre Rodan Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20231229092445.30180-3-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- .../iio/pressure/honeywell,mprls0025pa.yaml | 64 ++++++++++++++++------ 1 file changed, 46 insertions(+), 18 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml b/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml index 84ced4e5a7da..6643e51c481d 100644 --- a/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml @@ -19,14 +19,17 @@ description: | calls them "mpr series". All of them have the identical programming model and differ in the pressure range, unit and transfer function. - To support different models one need to specify the pressure range as well as - the transfer function. Pressure range needs to be converted from its unit to - pascal. + To support different models one need to specify its pressure triplet as well + as the transfer function. + + For custom silicon chips not covered by the Honeywell MPR series datasheet, + the pressure values can be specified manually via honeywell,pmin-pascal and + honeywell,pmax-pascal. + The minimal range value stands for the minimum pressure and the maximum value + also for the maximum pressure with linear relation inside the range. The transfer function defines the ranges of numerical values delivered by the - sensor. The minimal range value stands for the minimum pressure and the - maximum value also for the maximum pressure with linear relation inside the - range. + sensor. Specifications about the devices can be found at: https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/ @@ -54,14 +57,6 @@ properties: If not present the device is not reset during the probe. maxItems: 1 - honeywell,pmin-pascal: - description: - Minimum pressure value the sensor can measure in pascal. - - honeywell,pmax-pascal: - description: - Maximum pressure value the sensor can measure in pascal. - honeywell,transfer-function: description: | Transfer function which defines the range of valid values delivered by the @@ -72,17 +67,50 @@ properties: enum: [1, 2, 3] $ref: /schemas/types.yaml#/definitions/uint32 + honeywell,pressure-triplet: + description: | + Case-sensitive five character string that defines pressure range, unit + and type as part of the device nomenclature. In the unlikely case of a + custom chip, unset and provide pmin-pascal and pmax-pascal instead. + enum: [0001BA, 01.6BA, 02.5BA, 0060MG, 0100MG, 0160MG, 0250MG, 0400MG, + 0600MG, 0001BG, 01.6BG, 02.5BG, 0100KA, 0160KA, 0250KA, 0006KG, + 0010KG, 0016KG, 0025KG, 0040KG, 0060KG, 0100KG, 0160KG, 0250KG, + 0015PA, 0025PA, 0030PA, 0001PG, 0005PG, 0015PG, 0030PG, 0300YG] + $ref: /schemas/types.yaml#/definitions/string + + honeywell,pmin-pascal: + description: + Minimum pressure value the sensor can measure in pascal. + + honeywell,pmax-pascal: + description: + Maximum pressure value the sensor can measure in pascal. + vdd-supply: description: provide VDD power to the sensor. required: - compatible - reg - - honeywell,pmin-pascal - - honeywell,pmax-pascal - honeywell,transfer-function - vdd-supply +oneOf: + - required: + - honeywell,pressure-triplet + - required: + - honeywell,pmin-pascal + - honeywell,pmax-pascal + +allOf: + - if: + required: + - honeywell,pressure-triplet + then: + properties: + honeywell,pmin-pascal: false + honeywell,pmax-pascal: false + additionalProperties: false examples: @@ -99,8 +127,8 @@ examples: reset-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; interrupt-parent = <&gpio3>; interrupts = <21 IRQ_TYPE_EDGE_RISING>; - honeywell,pmin-pascal = <0>; - honeywell,pmax-pascal = <172369>; + + honeywell,pressure-triplet = "0025PA"; honeywell,transfer-function = <1>; vdd-supply = <&vcc_3v3>; }; -- cgit v1.2.3 From f088491661012c444f8754d3c46a4aa780ff8ae4 Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Fri, 29 Dec 2023 11:24:31 +0200 Subject: dt-bindings: iio: pressure: honeywell,mprls0025pa.yaml add spi bus Add spi based example. Add spi-max-frequency property required by chip specifications. Add additional maintainer. Co-developed-by: Andreas Klinger Signed-off-by: Andreas Klinger Signed-off-by: Petre Rodan Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20231229092445.30180-4-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- .../iio/pressure/honeywell,mprls0025pa.yaml | 27 ++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml b/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml index 6643e51c481d..6994b30015bd 100644 --- a/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.yaml @@ -8,12 +8,12 @@ title: Honeywell mprls0025pa pressure sensor maintainers: - Andreas Klinger + - Petre Rodan description: | Honeywell pressure sensor of model mprls0025pa. - This sensor has an I2C and SPI interface. Only the I2C interface is - implemented. + This sensor has an I2C and SPI interface. There are many models with different pressure ranges available. The vendor calls them "mpr series". All of them have the identical programming model and @@ -86,6 +86,9 @@ properties: description: Maximum pressure value the sensor can measure in pascal. + spi-max-frequency: + maximum: 800000 + vdd-supply: description: provide VDD power to the sensor. @@ -103,6 +106,7 @@ oneOf: - honeywell,pmax-pascal allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml - if: required: - honeywell,pressure-triplet @@ -133,3 +137,22 @@ examples: vdd-supply = <&vcc_3v3>; }; }; + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + pressure@0 { + compatible = "honeywell,mprls0025pa"; + reg = <0>; + spi-max-frequency = <800000>; + reset-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; + interrupt-parent = <&gpio0>; + interrupts = <30 IRQ_TYPE_EDGE_RISING>; + + honeywell,pressure-triplet = "0015PA"; + honeywell,transfer-function = <1>; + vdd-supply = <&vcc_3v3>; + }; + }; +... -- cgit v1.2.3 From 41b5684e58b1286ae0fa180bc50b661a27efee33 Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Mon, 8 Jan 2024 09:47:27 +0800 Subject: dt-bindings: iio: adc: rtq6056: add support for the whole RTQ6056 family Add compatible support for RTQ6053 and RTQ6059. Signed-off-by: ChiYuan Huang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/c1abb261bb00846f456eb8fe9b5919f59f287c24.1704676198.git.cy_huang@richtek.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/adc/richtek,rtq6056.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/richtek,rtq6056.yaml b/Documentation/devicetree/bindings/iio/adc/richtek,rtq6056.yaml index 88e008629ea8..af2c3a67f888 100644 --- a/Documentation/devicetree/bindings/iio/adc/richtek,rtq6056.yaml +++ b/Documentation/devicetree/bindings/iio/adc/richtek,rtq6056.yaml @@ -25,7 +25,14 @@ description: | properties: compatible: - const: richtek,rtq6056 + oneOf: + - enum: + - richtek,rtq6056 + - richtek,rtq6059 + - items: + - enum: + - richtek,rtq6053 + - const: richtek,rtq6056 reg: maxItems: 1 -- cgit v1.2.3 From 47878b451216cf5e5a23bb3f931a9f932464e93d Mon Sep 17 00:00:00 2001 From: Adam Skladowski Date: Wed, 20 Dec 2023 11:38:49 +0100 Subject: dt-bindings: interconnect: Add Qualcomm MSM8909 DT bindings Add bindings for Qualcomm MSM8909 Network-On-Chip interconnect devices. [Stephan: Drop separate mm-snoc that exists downstream since it's actually the same NoC as SNoC in hardware] Signed-off-by: Adam Skladowski Reviewed-by: Krzysztof Kozlowski Signed-off-by: Stephan Gerhold Link: https://lore.kernel.org/r/20231220-icc-msm8909-v2-1-3b68bbed2891@kernkonzept.com Signed-off-by: Georgi Djakov --- .../devicetree/bindings/interconnect/qcom,rpm.yaml | 3 + include/dt-bindings/interconnect/qcom,msm8909.h | 93 ++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 include/dt-bindings/interconnect/qcom,msm8909.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml index 08c1c6b9d7cf..5aaa92a7cef7 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml @@ -23,6 +23,9 @@ properties: compatible: enum: + - qcom,msm8909-bimc + - qcom,msm8909-pcnoc + - qcom,msm8909-snoc - qcom,msm8916-bimc - qcom,msm8916-pcnoc - qcom,msm8916-snoc diff --git a/include/dt-bindings/interconnect/qcom,msm8909.h b/include/dt-bindings/interconnect/qcom,msm8909.h new file mode 100644 index 000000000000..76365d8aec21 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,msm8909.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Qualcomm MSM8909 interconnect IDs + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_MSM8909_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_MSM8909_H + +/* BIMC fabric */ +#define MAS_APPS_PROC 0 +#define MAS_OXILI 1 +#define MAS_SNOC_BIMC_0 2 +#define MAS_SNOC_BIMC_1 3 +#define MAS_TCU_0 4 +#define MAS_TCU_1 5 +#define SLV_EBI 6 +#define SLV_BIMC_SNOC 7 + +/* PCNOC fabric */ +#define MAS_AUDIO 0 +#define MAS_SPDM 1 +#define MAS_DEHR 2 +#define MAS_QPIC 3 +#define MAS_BLSP_1 4 +#define MAS_USB_HS 5 +#define MAS_CRYPTO 6 +#define MAS_SDCC_1 7 +#define MAS_SDCC_2 8 +#define MAS_SNOC_PCNOC 9 +#define PCNOC_M_0 10 +#define PCNOC_M_1 11 +#define PCNOC_INT_0 12 +#define PCNOC_INT_1 13 +#define PCNOC_S_0 14 +#define PCNOC_S_1 15 +#define PCNOC_S_2 16 +#define PCNOC_S_3 17 +#define PCNOC_S_4 18 +#define PCNOC_S_5 19 +#define PCNOC_S_7 20 +#define SLV_TCSR 21 +#define SLV_SDCC_1 22 +#define SLV_BLSP_1 23 +#define SLV_CRYPTO_0_CFG 24 +#define SLV_MESSAGE_RAM 25 +#define SLV_PDM 26 +#define SLV_PRNG 27 +#define SLV_USB_HS 28 +#define SLV_QPIC 29 +#define SLV_SPDM 30 +#define SLV_SDCC_2 31 +#define SLV_AUDIO 32 +#define SLV_DEHR_CFG 33 +#define SLV_SNOC_CFG 34 +#define SLV_QDSS_CFG 35 +#define SLV_USB_PHY 36 +#define SLV_CAMERA_SS_CFG 37 +#define SLV_DISP_SS_CFG 38 +#define SLV_VENUS_CFG 39 +#define SLV_TLMM 40 +#define SLV_GPU_CFG 41 +#define SLV_IMEM_CFG 42 +#define SLV_BIMC_CFG 43 +#define SLV_PMIC_ARB 44 +#define SLV_TCU 45 +#define SLV_PCNOC_SNOC 46 + +/* SNOC fabric */ +#define MAS_QDSS_BAM 0 +#define MAS_BIMC_SNOC 1 +#define MAS_MDP 2 +#define MAS_PCNOC_SNOC 3 +#define MAS_VENUS 4 +#define MAS_VFE 5 +#define MAS_QDSS_ETR 6 +#define MM_INT_0 7 +#define MM_INT_1 8 +#define MM_INT_2 9 +#define MM_INT_BIMC 10 +#define QDSS_INT 11 +#define SNOC_INT_0 12 +#define SNOC_INT_1 13 +#define SNOC_INT_BIMC 14 +#define SLV_KPSS_AHB 15 +#define SLV_SNOC_BIMC_0 16 +#define SLV_SNOC_BIMC_1 17 +#define SLV_IMEM 18 +#define SLV_SNOC_PCNOC 19 +#define SLV_QDSS_STM 20 +#define SLV_CATS_0 21 +#define SLV_CATS_1 22 + +#endif /* __DT_BINDINGS_INTERCONNECT_QCOM_MSM8909_H */ -- cgit v1.2.3 From 4ed57f75898ce466ed60ce3c146290742985aa95 Mon Sep 17 00:00:00 2001 From: Tao Zhang Date: Sun, 4 Feb 2024 13:30:34 +0800 Subject: dt-bindings: arm: qcom,coresight-tpdm: Add support for CMB element size Add property "qcom,cmb-elem-bits" to support CMB(Continuous Multi-Bit) element for TPDM. The associated aggregator will read this size before it is enabled. CMB element size currently only supports 8-bit, 32-bit and 64-bit. Because the existing example tpdm "tpdm@684c000" which only supports dsb sub-unit, I introduce a new example "tpdm@6c29000" to describe the usage of this new property. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Tao Zhang Signed-off-by: Mao Jinlong Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/1707024641-22460-4-git-send-email-quic_taozha@quicinc.com --- .../bindings/arm/qcom,coresight-tpdm.yaml | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml index 61ddc3b5b247..2320b5445900 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml @@ -52,6 +52,14 @@ properties: $ref: /schemas/types.yaml#/definitions/uint8 enum: [32, 64] + qcom,cmb-element-bits: + description: + Specifies the CMB(Continuous Multi-Bit) element size supported by + the monitor. The associated aggregator will read this size before it + is enabled. CMB element size currently only supports 8-bit, 32-bit + and 64-bit. + enum: [8, 32, 64] + qcom,dsb-msrs-num: description: Specifies the number of DSB(Discrete Single Bit) MSR(mux select register) @@ -110,4 +118,21 @@ examples: }; }; + tpdm@6c29000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x06c29000 0x1000>; + + qcom,cmb-element-bits = <64>; + + clocks = <&aoss_qmp>; + clock-names = "apb_pclk"; + + out-ports { + port { + tpdm_ipcc_out_funnel_center: endpoint { + remote-endpoint = <&funnel_center_in_tpdm_ipcc>; + }; + }; + }; + }; ... -- cgit v1.2.3 From 2d9ab11c262e39f3bc829d0679257ab942d5878f Mon Sep 17 00:00:00 2001 From: Tao Zhang Date: Sun, 4 Feb 2024 13:30:37 +0800 Subject: coresight-tpdm: Add support to configure CMB TPDM CMB subunits support two forms of CMB data set element creation: continuous and trace-on-change collection mode. Continuous change creates CMB data set elements on every CMBCLK edge. Trace-on-change creates CMB data set elements only when a new data set element differs in value from the previous element in a CMB data set. Set CMB_CR.MODE to 0 for continuous CMB collection mode. Set CMB_CR.MODE to 1 for trace-on-change CMB collection mode. Reviewed-by: James Clark Signed-off-by: Tao Zhang Signed-off-by: Jinlong Mao Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/1707024641-22460-7-git-send-email-quic_taozha@quicinc.com --- .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 14 +++++ drivers/hwtracing/coresight/coresight-tpdm.c | 60 ++++++++++++++++++++++ drivers/hwtracing/coresight/coresight-tpdm.h | 12 +++++ 3 files changed, 86 insertions(+) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm index 4dd49b159543..6dfb18d6d64a 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm @@ -170,3 +170,17 @@ Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) /cmb_mode +Date: January 2024 +KernelVersion 6.9 +Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Description: (Write) Set the data collection mode of CMB tpdm. Continuous + change creates CMB data set elements on every CMBCLK edge. + Trace-on-change creates CMB data set elements only when a new + data set element differs in value from the previous element + in a CMB data set. + + Accepts only one of the 2 values - 0 or 1. + 0 : Continuous CMB collection mode. + 1 : Trace-on-change CMB collection mode. diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c index 1bb1d8e83501..b20071460375 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.c +++ b/drivers/hwtracing/coresight/coresight-tpdm.c @@ -137,6 +137,18 @@ static umode_t tpdm_dsb_is_visible(struct kobject *kobj, return 0; } +static umode_t tpdm_cmb_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (drvdata && tpdm_has_cmb_dataset(drvdata)) + return attr->mode; + + return 0; +} + static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { @@ -161,6 +173,9 @@ static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata) drvdata->dsb->trig_ts = true; drvdata->dsb->trig_type = false; } + + if (drvdata->cmb) + memset(drvdata->cmb, 0, sizeof(struct cmb_dataset)); } static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val) @@ -391,6 +406,12 @@ static int tpdm_datasets_setup(struct tpdm_drvdata *drvdata) if (!drvdata->dsb) return -ENOMEM; } + if (tpdm_has_cmb_dataset(drvdata) && (!drvdata->cmb)) { + drvdata->cmb = devm_kzalloc(drvdata->dev, + sizeof(*drvdata->cmb), GFP_KERNEL); + if (!drvdata->cmb) + return -ENOMEM; + } tpdm_reset_datasets(drvdata); return 0; @@ -729,6 +750,34 @@ static ssize_t dsb_trig_ts_store(struct device *dev, } static DEVICE_ATTR_RW(dsb_trig_ts); +static ssize_t cmb_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return sysfs_emit(buf, "%x\n", drvdata->cmb->trace_mode); + +} + +static ssize_t cmb_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long trace_mode; + + if (kstrtoul(buf, 0, &trace_mode) || (trace_mode & ~1UL)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + drvdata->cmb->trace_mode = trace_mode; + spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_RW(cmb_mode); + static struct attribute *tpdm_dsb_edge_attrs[] = { &dev_attr_ctrl_idx.attr, &dev_attr_ctrl_val.attr, @@ -845,6 +894,11 @@ static struct attribute *tpdm_dsb_attrs[] = { NULL, }; +static struct attribute *tpdm_cmb_attrs[] = { + &dev_attr_cmb_mode.attr, + NULL, +}; + static struct attribute_group tpdm_dsb_attr_grp = { .attrs = tpdm_dsb_attrs, .is_visible = tpdm_dsb_is_visible, @@ -874,6 +928,11 @@ static struct attribute_group tpdm_dsb_msr_grp = { .name = "dsb_msr", }; +static struct attribute_group tpdm_cmb_attr_grp = { + .attrs = tpdm_cmb_attrs, + .is_visible = tpdm_cmb_is_visible, +}; + static const struct attribute_group *tpdm_attr_grps[] = { &tpdm_attr_grp, &tpdm_dsb_attr_grp, @@ -881,6 +940,7 @@ static const struct attribute_group *tpdm_attr_grps[] = { &tpdm_dsb_trig_patt_grp, &tpdm_dsb_patt_grp, &tpdm_dsb_msr_grp, + &tpdm_cmb_attr_grp, NULL, }; diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h index a442d9c6e4ac..2af92c270ed1 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.h +++ b/drivers/hwtracing/coresight/coresight-tpdm.h @@ -14,6 +14,8 @@ /* Enable bit for CMB subunit */ #define TPDM_CMB_CR_ENA BIT(0) +/* Trace collection mode for CMB subunit */ +#define TPDM_CMB_CR_MODE BIT(1) /* DSB Subunit Registers */ #define TPDM_DSB_CR (0x780) @@ -181,6 +183,14 @@ struct dsb_dataset { bool trig_type; }; +/** + * struct cmb_dataset + * @trace_mode: Dataset collection mode + */ +struct cmb_dataset { + u32 trace_mode; +}; + /** * struct tpdm_drvdata - specifics associated to an TPDM component * @base: memory mapped base address for this component. @@ -190,6 +200,7 @@ struct dsb_dataset { * @enable: enable status of the component. * @datasets: The datasets types present of the TPDM. * @dsb Specifics associated to TPDM DSB. + * @cmb Specifics associated to TPDM CMB. * @dsb_msr_num Number of MSR supported by DSB TPDM */ @@ -201,6 +212,7 @@ struct tpdm_drvdata { bool enable; unsigned long datasets; struct dsb_dataset *dsb; + struct cmb_dataset *cmb; u32 dsb_msr_num; }; -- cgit v1.2.3 From 53d4a017a52458d835a1f9524df09c65c2208400 Mon Sep 17 00:00:00 2001 From: Tao Zhang Date: Sun, 4 Feb 2024 13:30:38 +0800 Subject: coresight-tpdm: Add pattern registers support for CMB Timestamps are requested if the monitor’s CMB data set unit input data matches the value in the Monitor CMB timestamp pattern and mask registers (M_CMB_TPR and M_CMB_TPMR) when CMB timestamp enabled via the timestamp insertion enable register bit(CMB_TIER.PATT_TSENAB). The pattern match trigger output is achieved via setting values into the CMB trigger pattern and mask registers (CMB_XPR and CMB_XPMR). After configuring a pattern through these registers, the TPDM subunit will assert an output trigger every time it receives new input data that matches the configured pattern value. Values in a given bit number of the mask register correspond to the same bit number in the corresponding pattern register. Reviewed-by: James Clark Signed-off-by: Tao Zhang Signed-off-by: Jinlong Mao Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/1707024641-22460-8-git-send-email-quic_taozha@quicinc.com --- .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 30 +++++++ drivers/hwtracing/coresight/coresight-tpdm.c | 96 +++++++++++++++++++++- drivers/hwtracing/coresight/coresight-tpdm.h | 39 +++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm index 6dfb18d6d64a..b6cf050861ed 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm @@ -184,3 +184,33 @@ Description: (Write) Set the data collection mode of CMB tpdm. Continuous Accepts only one of the 2 values - 0 or 1. 0 : Continuous CMB collection mode. 1 : Trace-on-change CMB collection mode. + +What: /sys/bus/coresight/devices//cmb_trig_patt/xpr[0:1] +Date: January 2024 +KernelVersion 6.9 +Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Description: + (RW) Set/Get the value of the trigger pattern for the CMB + subunit TPDM. + +What: /sys/bus/coresight/devices//cmb_trig_patt/xpmr[0:1] +Date: January 2024 +KernelVersion 6.9 +Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Description: + (RW) Set/Get the mask of the trigger pattern for the CMB + subunit TPDM. + +What: /sys/bus/coresight/devices//dsb_patt/tpr[0:1] +Date: January 2024 +KernelVersion 6.9 +Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Description: + (RW) Set/Get the value of the pattern for the CMB subunit TPDM. + +What: /sys/bus/coresight/devices//dsb_patt/tpmr[0:1] +Date: January 2024 +KernelVersion 6.9 +Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Description: + (RW) Set/Get the mask of the pattern for the CMB subunit TPDM. diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c index b20071460375..07587287d9fa 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.c +++ b/drivers/hwtracing/coresight/coresight-tpdm.c @@ -66,6 +66,26 @@ static ssize_t tpdm_simple_dataset_show(struct device *dev, return -EINVAL; return sysfs_emit(buf, "0x%x\n", drvdata->dsb->msr[tpdm_attr->idx]); + case CMB_TRIG_PATT: + if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) + return -EINVAL; + return sysfs_emit(buf, "0x%x\n", + drvdata->cmb->trig_patt[tpdm_attr->idx]); + case CMB_TRIG_PATT_MASK: + if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) + return -EINVAL; + return sysfs_emit(buf, "0x%x\n", + drvdata->cmb->trig_patt_mask[tpdm_attr->idx]); + case CMB_PATT: + if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) + return -EINVAL; + return sysfs_emit(buf, "0x%x\n", + drvdata->cmb->patt_val[tpdm_attr->idx]); + case CMB_PATT_MASK: + if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT) + return -EINVAL; + return sysfs_emit(buf, "0x%x\n", + drvdata->cmb->patt_mask[tpdm_attr->idx]); } return -EINVAL; } @@ -118,6 +138,30 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev, ret = size; } break; + case CMB_TRIG_PATT: + if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { + drvdata->cmb->trig_patt[tpdm_attr->idx] = val; + ret = size; + } + break; + case CMB_TRIG_PATT_MASK: + if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { + drvdata->cmb->trig_patt_mask[tpdm_attr->idx] = val; + ret = size; + } + break; + case CMB_PATT: + if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { + drvdata->cmb->patt_val[tpdm_attr->idx] = val; + ret = size; + } + break; + case CMB_PATT_MASK: + if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) { + drvdata->cmb->patt_mask[tpdm_attr->idx] = val; + ret = size; + } + break; default: break; } @@ -280,12 +324,32 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata) { - u32 val; + u32 val, i; if (!tpdm_has_cmb_dataset(drvdata)) return; + /* Configure pattern registers */ + for (i = 0; i < TPDM_CMB_MAX_PATT; i++) { + writel_relaxed(drvdata->cmb->patt_val[i], + drvdata->base + TPDM_CMB_TPR(i)); + writel_relaxed(drvdata->cmb->patt_mask[i], + drvdata->base + TPDM_CMB_TPMR(i)); + writel_relaxed(drvdata->cmb->trig_patt[i], + drvdata->base + TPDM_CMB_XPR(i)); + writel_relaxed(drvdata->cmb->trig_patt_mask[i], + drvdata->base + TPDM_CMB_XPMR(i)); + } + val = readl_relaxed(drvdata->base + TPDM_CMB_CR); + /* + * Set to 0 for continuous CMB collection mode, + * 1 for trace-on-change CMB collection mode. + */ + if (drvdata->cmb->trace_mode) + val |= TPDM_CMB_CR_MODE; + else + val &= ~TPDM_CMB_CR_MODE; /* Set the enable bit of CMB control register to 1 */ val |= TPDM_CMB_CR_ENA; writel_relaxed(val, drvdata->base + TPDM_CMB_CR); @@ -887,6 +951,22 @@ static struct attribute *tpdm_dsb_msr_attrs[] = { NULL, }; +static struct attribute *tpdm_cmb_trig_patt_attrs[] = { + CMB_TRIG_PATT_ATTR(0), + CMB_TRIG_PATT_ATTR(1), + CMB_TRIG_PATT_MASK_ATTR(0), + CMB_TRIG_PATT_MASK_ATTR(1), + NULL, +}; + +static struct attribute *tpdm_cmb_patt_attrs[] = { + CMB_PATT_ATTR(0), + CMB_PATT_ATTR(1), + CMB_PATT_MASK_ATTR(0), + CMB_PATT_MASK_ATTR(1), + NULL, +}; + static struct attribute *tpdm_dsb_attrs[] = { &dev_attr_dsb_mode.attr, &dev_attr_dsb_trig_ts.attr, @@ -933,6 +1013,18 @@ static struct attribute_group tpdm_cmb_attr_grp = { .is_visible = tpdm_cmb_is_visible, }; +static struct attribute_group tpdm_cmb_trig_patt_grp = { + .attrs = tpdm_cmb_trig_patt_attrs, + .is_visible = tpdm_cmb_is_visible, + .name = "cmb_trig_patt", +}; + +static struct attribute_group tpdm_cmb_patt_grp = { + .attrs = tpdm_cmb_patt_attrs, + .is_visible = tpdm_cmb_is_visible, + .name = "cmb_patt", +}; + static const struct attribute_group *tpdm_attr_grps[] = { &tpdm_attr_grp, &tpdm_dsb_attr_grp, @@ -941,6 +1033,8 @@ static const struct attribute_group *tpdm_attr_grps[] = { &tpdm_dsb_patt_grp, &tpdm_dsb_msr_grp, &tpdm_cmb_attr_grp, + &tpdm_cmb_trig_patt_grp, + &tpdm_cmb_patt_grp, NULL, }; diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h index 2af92c270ed1..e5d4c22cd38c 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.h +++ b/drivers/hwtracing/coresight/coresight-tpdm.h @@ -11,12 +11,23 @@ /* CMB Subunit Registers */ #define TPDM_CMB_CR (0xA00) +/* CMB subunit timestamp pattern registers */ +#define TPDM_CMB_TPR(n) (0xA08 + (n * 4)) +/* CMB subunit timestamp pattern mask registers */ +#define TPDM_CMB_TPMR(n) (0xA10 + (n * 4)) +/* CMB subunit trigger pattern registers */ +#define TPDM_CMB_XPR(n) (0xA18 + (n * 4)) +/* CMB subunit trigger pattern mask registers */ +#define TPDM_CMB_XPMR(n) (0xA20 + (n * 4)) /* Enable bit for CMB subunit */ #define TPDM_CMB_CR_ENA BIT(0) /* Trace collection mode for CMB subunit */ #define TPDM_CMB_CR_MODE BIT(1) +/* Patten register number */ +#define TPDM_CMB_MAX_PATT 2 + /* DSB Subunit Registers */ #define TPDM_DSB_CR (0x780) #define TPDM_DSB_TIER (0x784) @@ -151,6 +162,22 @@ tpdm_simple_dataset_rw(msr##nr, \ DSB_MSR, nr) +#define CMB_TRIG_PATT_ATTR(nr) \ + tpdm_simple_dataset_rw(xpr##nr, \ + CMB_TRIG_PATT, nr) + +#define CMB_TRIG_PATT_MASK_ATTR(nr) \ + tpdm_simple_dataset_rw(xpmr##nr, \ + CMB_TRIG_PATT_MASK, nr) + +#define CMB_PATT_ATTR(nr) \ + tpdm_simple_dataset_rw(tpr##nr, \ + CMB_PATT, nr) + +#define CMB_PATT_MASK_ATTR(nr) \ + tpdm_simple_dataset_rw(tpmr##nr, \ + CMB_PATT_MASK, nr) + /** * struct dsb_dataset - specifics associated to dsb dataset * @mode: DSB programming mode @@ -186,9 +213,17 @@ struct dsb_dataset { /** * struct cmb_dataset * @trace_mode: Dataset collection mode + * @patt_val: Save value for pattern + * @patt_mask: Save value for pattern mask + * @trig_patt: Save value for trigger pattern + * @trig_patt_mask: Save value for trigger pattern mask */ struct cmb_dataset { u32 trace_mode; + u32 patt_val[TPDM_CMB_MAX_PATT]; + u32 patt_mask[TPDM_CMB_MAX_PATT]; + u32 trig_patt[TPDM_CMB_MAX_PATT]; + u32 trig_patt_mask[TPDM_CMB_MAX_PATT]; }; /** @@ -225,6 +260,10 @@ enum dataset_mem { DSB_PATT, DSB_PATT_MASK, DSB_MSR, + CMB_TRIG_PATT, + CMB_TRIG_PATT_MASK, + CMB_PATT, + CMB_PATT_MASK }; /** -- cgit v1.2.3 From dc6ce57e2aa0b10b0b78517245ea0ba47eed75b1 Mon Sep 17 00:00:00 2001 From: Tao Zhang Date: Sun, 4 Feb 2024 13:30:39 +0800 Subject: coresight-tpdm: Add timestamp control register support for the CMB CMB_TIER register is CMB subunit timestamp insertion enable register. Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit. Set this bit to 1 to request a timestamp following a CMB CTI timestamp request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp for all packets. Reviewed-by: James Clark Signed-off-by: Tao Zhang Signed-off-by: Jinlong Mao Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/1707024641-22460-9-git-send-email-quic_taozha@quicinc.com --- .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 35 ++++++ drivers/hwtracing/coresight/coresight-tpdm.c | 121 +++++++++++++++++++-- drivers/hwtracing/coresight/coresight-tpdm.h | 31 ++++++ 3 files changed, 180 insertions(+), 7 deletions(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm index b6cf050861ed..e8c76ce4dd15 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm @@ -214,3 +214,38 @@ KernelVersion 6.9 Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) Description: (RW) Set/Get the mask of the pattern for the CMB subunit TPDM. + +What: /sys/bus/coresight/devices//cmb_patt/enable_ts +Date: January 2024 +KernelVersion 6.9 +Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Description: + (Write) Set the pattern timestamp of CMB tpdm. Read + the pattern timestamp of CMB tpdm. + + Accepts only one of the 2 values - 0 or 1. + 0 : Disable CMB pattern timestamp. + 1 : Enable CMB pattern timestamp. + +What: /sys/bus/coresight/devices//cmb_trig_ts +Date: January 2024 +KernelVersion 6.9 +Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Description: + (RW) Set/Get the trigger timestamp of the CMB for tpdm. + + Accepts only one of the 2 values - 0 or 1. + 0 : Set the CMB trigger type to false + 1 : Set the CMB trigger type to true + +What: /sys/bus/coresight/devices//cmb_ts_all +Date: January 2024 +KernelVersion 6.9 +Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Description: + (RW) Read or write the status of timestamp upon all interface. + Only value 0 and 1 can be written to this node. Set this node to 1 to requeset + timestamp to all trace packet. + Accepts only one of the 2 values - 0 or 1. + 0 : Disable the timestamp of all trace packets. + 1 : Enable the timestamp of all trace packets. diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c index 07587287d9fa..22966d541230 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.c +++ b/drivers/hwtracing/coresight/coresight-tpdm.c @@ -322,6 +322,31 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata) writel_relaxed(val, drvdata->base + TPDM_DSB_CR); } +static void set_cmb_tier(struct tpdm_drvdata *drvdata) +{ + u32 val; + + val = readl_relaxed(drvdata->base + TPDM_CMB_TIER); + + /* Clear all relevant fields */ + val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL | + TPDM_CMB_TIER_XTRIG_TSENAB); + + /* Set pattern timestamp type and enablement */ + if (drvdata->cmb->patt_ts) + val |= TPDM_CMB_TIER_PATT_TSENAB; + + /* Set trigger timestamp */ + if (drvdata->cmb->trig_ts) + val |= TPDM_CMB_TIER_XTRIG_TSENAB; + + /* Set all timestamp enablement*/ + if (drvdata->cmb->ts_all) + val |= TPDM_CMB_TIER_TS_ALL; + + writel_relaxed(val, drvdata->base + TPDM_CMB_TIER); +} + static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata) { u32 val, i; @@ -341,6 +366,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata) drvdata->base + TPDM_CMB_XPMR(i)); } + set_cmb_tier(drvdata); + val = readl_relaxed(drvdata->base + TPDM_CMB_CR); /* * Set to 0 for continuous CMB collection mode, @@ -687,9 +714,18 @@ static ssize_t enable_ts_show(struct device *dev, char *buf) { struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct tpdm_dataset_attribute *tpdm_attr = + container_of(attr, struct tpdm_dataset_attribute, attr); + ssize_t size = -EINVAL; - return sysfs_emit(buf, "%u\n", - (unsigned int)drvdata->dsb->patt_ts); + if (tpdm_attr->mem == DSB_PATT) + size = sysfs_emit(buf, "%u\n", + (unsigned int)drvdata->dsb->patt_ts); + else if (tpdm_attr->mem == CMB_PATT) + size = sysfs_emit(buf, "%u\n", + (unsigned int)drvdata->cmb->patt_ts); + + return size; } /* @@ -701,17 +737,23 @@ static ssize_t enable_ts_store(struct device *dev, size_t size) { struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct tpdm_dataset_attribute *tpdm_attr = + container_of(attr, struct tpdm_dataset_attribute, attr); unsigned long val; if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) return -EINVAL; - spin_lock(&drvdata->spinlock); - drvdata->dsb->patt_ts = !!val; - spin_unlock(&drvdata->spinlock); + guard(spinlock)(&drvdata->spinlock); + if (tpdm_attr->mem == DSB_PATT) + drvdata->dsb->patt_ts = !!val; + else if (tpdm_attr->mem == CMB_PATT) + drvdata->cmb->patt_ts = !!val; + else + return -EINVAL; + return size; } -static DEVICE_ATTR_RW(enable_ts); static ssize_t set_type_show(struct device *dev, struct device_attribute *attr, @@ -842,6 +884,68 @@ static ssize_t cmb_mode_store(struct device *dev, } static DEVICE_ATTR_RW(cmb_mode); +static ssize_t cmb_ts_all_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return sysfs_emit(buf, "%u\n", + (unsigned int)drvdata->cmb->ts_all); +} + +static ssize_t cmb_ts_all_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + if (val) + drvdata->cmb->ts_all = true; + else + drvdata->cmb->ts_all = false; + + return size; +} +static DEVICE_ATTR_RW(cmb_ts_all); + +static ssize_t cmb_trig_ts_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + return sysfs_emit(buf, "%u\n", + (unsigned int)drvdata->cmb->trig_ts); +} + +static ssize_t cmb_trig_ts_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if ((kstrtoul(buf, 0, &val)) || (val & ~1UL)) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + if (val) + drvdata->cmb->trig_ts = true; + else + drvdata->cmb->trig_ts = false; + + return size; +} +static DEVICE_ATTR_RW(cmb_trig_ts); + static struct attribute *tpdm_dsb_edge_attrs[] = { &dev_attr_ctrl_idx.attr, &dev_attr_ctrl_val.attr, @@ -910,7 +1014,7 @@ static struct attribute *tpdm_dsb_patt_attrs[] = { DSB_PATT_MASK_ATTR(5), DSB_PATT_MASK_ATTR(6), DSB_PATT_MASK_ATTR(7), - &dev_attr_enable_ts.attr, + DSB_PATT_ENABLE_TS, &dev_attr_set_type.attr, NULL, }; @@ -964,6 +1068,7 @@ static struct attribute *tpdm_cmb_patt_attrs[] = { CMB_PATT_ATTR(1), CMB_PATT_MASK_ATTR(0), CMB_PATT_MASK_ATTR(1), + CMB_PATT_ENABLE_TS, NULL, }; @@ -976,6 +1081,8 @@ static struct attribute *tpdm_dsb_attrs[] = { static struct attribute *tpdm_cmb_attrs[] = { &dev_attr_cmb_mode.attr, + &dev_attr_cmb_ts_all.attr, + &dev_attr_cmb_trig_ts.attr, NULL, }; diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h index e5d4c22cd38c..6d1fe4aed7d0 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.h +++ b/drivers/hwtracing/coresight/coresight-tpdm.h @@ -11,6 +11,8 @@ /* CMB Subunit Registers */ #define TPDM_CMB_CR (0xA00) +/* CMB subunit timestamp insertion enable register */ +#define TPDM_CMB_TIER (0xA04) /* CMB subunit timestamp pattern registers */ #define TPDM_CMB_TPR(n) (0xA08 + (n * 4)) /* CMB subunit timestamp pattern mask registers */ @@ -24,6 +26,12 @@ #define TPDM_CMB_CR_ENA BIT(0) /* Trace collection mode for CMB subunit */ #define TPDM_CMB_CR_MODE BIT(1) +/* Timestamp control for pattern match */ +#define TPDM_CMB_TIER_PATT_TSENAB BIT(0) +/* CMB CTI timestamp request */ +#define TPDM_CMB_TIER_XTRIG_TSENAB BIT(1) +/* For timestamp fo all trace */ +#define TPDM_CMB_TIER_TS_ALL BIT(2) /* Patten register number */ #define TPDM_CMB_MAX_PATT 2 @@ -134,6 +142,15 @@ } \ })[0].attr.attr) +#define tpdm_patt_enable_ts(name, mem) \ + (&((struct tpdm_dataset_attribute[]) { \ + { \ + __ATTR(name, 0644, enable_ts_show, \ + enable_ts_store), \ + mem, \ + } \ + })[0].attr.attr) + #define DSB_EDGE_CTRL_ATTR(nr) \ tpdm_simple_dataset_ro(edcr##nr, \ DSB_EDGE_CTRL, nr) @@ -158,6 +175,10 @@ tpdm_simple_dataset_rw(tpmr##nr, \ DSB_PATT_MASK, nr) +#define DSB_PATT_ENABLE_TS \ + tpdm_patt_enable_ts(enable_ts, \ + DSB_PATT) + #define DSB_MSR_ATTR(nr) \ tpdm_simple_dataset_rw(msr##nr, \ DSB_MSR, nr) @@ -178,6 +199,10 @@ tpdm_simple_dataset_rw(tpmr##nr, \ CMB_PATT_MASK, nr) +#define CMB_PATT_ENABLE_TS \ + tpdm_patt_enable_ts(enable_ts, \ + CMB_PATT) + /** * struct dsb_dataset - specifics associated to dsb dataset * @mode: DSB programming mode @@ -217,6 +242,9 @@ struct dsb_dataset { * @patt_mask: Save value for pattern mask * @trig_patt: Save value for trigger pattern * @trig_patt_mask: Save value for trigger pattern mask + * @patt_ts: Indicates if pattern match for timestamp is enabled. + * @trig_ts: Indicates if CTI trigger for timestamp is enabled. + * @ts_all: Indicates if timestamp is enabled for all packets. */ struct cmb_dataset { u32 trace_mode; @@ -224,6 +252,9 @@ struct cmb_dataset { u32 patt_mask[TPDM_CMB_MAX_PATT]; u32 trig_patt[TPDM_CMB_MAX_PATT]; u32 trig_patt_mask[TPDM_CMB_MAX_PATT]; + bool patt_ts; + bool trig_ts; + bool ts_all; }; /** -- cgit v1.2.3 From 19bfaff3845727f354079a140f092336d97e5c1e Mon Sep 17 00:00:00 2001 From: Tao Zhang Date: Sun, 4 Feb 2024 13:30:40 +0800 Subject: dt-bindings: arm: qcom,coresight-tpdm: Add support for TPDM CMB MSR register Add property "qcom,cmb_msr_num" to support CMB MSR(mux select register) for TPDM. It specifies the number of CMB MSR registers supported by the TDPM. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Tao Zhang Signed-off-by: Mao Jinlong Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/1707024641-22460-10-git-send-email-quic_taozha@quicinc.com --- Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml index 2320b5445900..d0647ffaed71 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml @@ -69,6 +69,15 @@ properties: minimum: 0 maximum: 32 + qcom,cmb-msrs-num: + description: + Specifies the number of CMB MSR(mux select register) registers supported + by the monitor. If this property is not configured or set to 0, it means + this TPDM doesn't support CMB MSR. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 32 + clocks: maxItems: 1 @@ -123,6 +132,7 @@ examples: reg = <0x06c29000 0x1000>; qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <32>; clocks = <&aoss_qmp>; clock-names = "apb_pclk"; -- cgit v1.2.3 From 8e8804145a46e092c5207bb1258d29236a2cbcaa Mon Sep 17 00:00:00 2001 From: Tao Zhang Date: Sun, 4 Feb 2024 13:30:41 +0800 Subject: coresight-tpdm: Add msr register support for CMB Add the nodes for CMB subunit MSR(mux select register) support. CMB MSRs(mux select registers) is to separate mux, arbitration, interleaving,data packing control from stream filtering control. Reviewed-by: James Clark Signed-off-by: Tao Zhang Signed-off-by: Mao Jinlong Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/1707024641-22460-11-git-send-email-quic_taozha@quicinc.com --- .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 8 ++ drivers/hwtracing/coresight/coresight-tpdm.c | 85 ++++++++++++++++++++++ drivers/hwtracing/coresight/coresight-tpdm.h | 16 +++- 3 files changed, 108 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm index e8c76ce4dd15..b4d0fc8d319d 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm @@ -249,3 +249,11 @@ Description: Accepts only one of the 2 values - 0 or 1. 0 : Disable the timestamp of all trace packets. 1 : Enable the timestamp of all trace packets. + +What: /sys/bus/coresight/devices//cmb_msr/msr[0:31] +Date: January 2024 +KernelVersion 6.9 +Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Description: + (RW) Set/Get the MSR(mux select register) for the CMB subunit + TPDM. diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c index 22966d541230..a9708ab0d488 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.c +++ b/drivers/hwtracing/coresight/coresight-tpdm.c @@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct device *dev, return -EINVAL; return sysfs_emit(buf, "0x%x\n", drvdata->cmb->patt_mask[tpdm_attr->idx]); + case CMB_MSR: + if (tpdm_attr->idx >= drvdata->cmb_msr_num) + return -EINVAL; + return sysfs_emit(buf, "0x%x\n", + drvdata->cmb->msr[tpdm_attr->idx]); } return -EINVAL; } @@ -162,6 +167,12 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev, ret = size; } break; + case CMB_MSR: + if (tpdm_attr->idx < drvdata->cmb_msr_num) { + drvdata->cmb->msr[tpdm_attr->idx] = val; + ret = size; + } + break; default: break; } @@ -209,6 +220,23 @@ static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj, return 0; } +static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); + + struct device_attribute *dev_attr = + container_of(attr, struct device_attribute, attr); + struct tpdm_dataset_attribute *tpdm_attr = + container_of(dev_attr, struct tpdm_dataset_attribute, attr); + + if (tpdm_attr->idx < drvdata->cmb_msr_num) + return attr->mode; + + return 0; +} + static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata) { if (tpdm_has_dsb_dataset(drvdata)) { @@ -347,6 +375,15 @@ static void set_cmb_tier(struct tpdm_drvdata *drvdata) writel_relaxed(val, drvdata->base + TPDM_CMB_TIER); } +static void set_cmb_msr(struct tpdm_drvdata *drvdata) +{ + int i; + + for (i = 0; i < drvdata->cmb_msr_num; i++) + writel_relaxed(drvdata->cmb->msr[i], + drvdata->base + TPDM_CMB_MSR(i)); +} + static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata) { u32 val, i; @@ -367,6 +404,7 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata) } set_cmb_tier(drvdata); + set_cmb_msr(drvdata); val = readl_relaxed(drvdata->base + TPDM_CMB_CR); /* @@ -1072,6 +1110,42 @@ static struct attribute *tpdm_cmb_patt_attrs[] = { NULL, }; +static struct attribute *tpdm_cmb_msr_attrs[] = { + CMB_MSR_ATTR(0), + CMB_MSR_ATTR(1), + CMB_MSR_ATTR(2), + CMB_MSR_ATTR(3), + CMB_MSR_ATTR(4), + CMB_MSR_ATTR(5), + CMB_MSR_ATTR(6), + CMB_MSR_ATTR(7), + CMB_MSR_ATTR(8), + CMB_MSR_ATTR(9), + CMB_MSR_ATTR(10), + CMB_MSR_ATTR(11), + CMB_MSR_ATTR(12), + CMB_MSR_ATTR(13), + CMB_MSR_ATTR(14), + CMB_MSR_ATTR(15), + CMB_MSR_ATTR(16), + CMB_MSR_ATTR(17), + CMB_MSR_ATTR(18), + CMB_MSR_ATTR(19), + CMB_MSR_ATTR(20), + CMB_MSR_ATTR(21), + CMB_MSR_ATTR(22), + CMB_MSR_ATTR(23), + CMB_MSR_ATTR(24), + CMB_MSR_ATTR(25), + CMB_MSR_ATTR(26), + CMB_MSR_ATTR(27), + CMB_MSR_ATTR(28), + CMB_MSR_ATTR(29), + CMB_MSR_ATTR(30), + CMB_MSR_ATTR(31), + NULL, +}; + static struct attribute *tpdm_dsb_attrs[] = { &dev_attr_dsb_mode.attr, &dev_attr_dsb_trig_ts.attr, @@ -1132,6 +1206,12 @@ static struct attribute_group tpdm_cmb_patt_grp = { .name = "cmb_patt", }; +static struct attribute_group tpdm_cmb_msr_grp = { + .attrs = tpdm_cmb_msr_attrs, + .is_visible = tpdm_cmb_msr_is_visible, + .name = "cmb_msr", +}; + static const struct attribute_group *tpdm_attr_grps[] = { &tpdm_attr_grp, &tpdm_dsb_attr_grp, @@ -1142,6 +1222,7 @@ static const struct attribute_group *tpdm_attr_grps[] = { &tpdm_cmb_attr_grp, &tpdm_cmb_trig_patt_grp, &tpdm_cmb_patt_grp, + &tpdm_cmb_msr_grp, NULL, }; @@ -1180,6 +1261,10 @@ static int tpdm_probe(struct amba_device *adev, const struct amba_id *id) of_property_read_u32(drvdata->dev->of_node, "qcom,dsb-msrs-num", &drvdata->dsb_msr_num); + if (drvdata && tpdm_has_cmb_dataset(drvdata)) + of_property_read_u32(drvdata->dev->of_node, + "qcom,cmb-msrs-num", &drvdata->cmb_msr_num); + /* Set up coresight component description */ desc.name = coresight_alloc_device_name(&tpdm_devs, dev); if (!desc.name) diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h index 6d1fe4aed7d0..f3a8f56d0fe7 100644 --- a/drivers/hwtracing/coresight/coresight-tpdm.h +++ b/drivers/hwtracing/coresight/coresight-tpdm.h @@ -21,6 +21,8 @@ #define TPDM_CMB_XPR(n) (0xA18 + (n * 4)) /* CMB subunit trigger pattern mask registers */ #define TPDM_CMB_XPMR(n) (0xA20 + (n * 4)) +/* CMB MSR register */ +#define TPDM_CMB_MSR(n) (0xA80 + (n * 4)) /* Enable bit for CMB subunit */ #define TPDM_CMB_CR_ENA BIT(0) @@ -36,6 +38,9 @@ /* Patten register number */ #define TPDM_CMB_MAX_PATT 2 +/* MAX number of DSB MSR */ +#define TPDM_CMB_MAX_MSR 32 + /* DSB Subunit Registers */ #define TPDM_DSB_CR (0x780) #define TPDM_DSB_TIER (0x784) @@ -203,6 +208,10 @@ tpdm_patt_enable_ts(enable_ts, \ CMB_PATT) +#define CMB_MSR_ATTR(nr) \ + tpdm_simple_dataset_rw(msr##nr, \ + CMB_MSR, nr) + /** * struct dsb_dataset - specifics associated to dsb dataset * @mode: DSB programming mode @@ -242,6 +251,7 @@ struct dsb_dataset { * @patt_mask: Save value for pattern mask * @trig_patt: Save value for trigger pattern * @trig_patt_mask: Save value for trigger pattern mask + * @msr Save value for MSR * @patt_ts: Indicates if pattern match for timestamp is enabled. * @trig_ts: Indicates if CTI trigger for timestamp is enabled. * @ts_all: Indicates if timestamp is enabled for all packets. @@ -252,6 +262,7 @@ struct cmb_dataset { u32 patt_mask[TPDM_CMB_MAX_PATT]; u32 trig_patt[TPDM_CMB_MAX_PATT]; u32 trig_patt_mask[TPDM_CMB_MAX_PATT]; + u32 msr[TPDM_CMB_MAX_MSR]; bool patt_ts; bool trig_ts; bool ts_all; @@ -268,6 +279,7 @@ struct cmb_dataset { * @dsb Specifics associated to TPDM DSB. * @cmb Specifics associated to TPDM CMB. * @dsb_msr_num Number of MSR supported by DSB TPDM + * @cmb_msr_num Number of MSR supported by CMB TPDM */ struct tpdm_drvdata { @@ -280,6 +292,7 @@ struct tpdm_drvdata { struct dsb_dataset *dsb; struct cmb_dataset *cmb; u32 dsb_msr_num; + u32 cmb_msr_num; }; /* Enumerate members of various datasets */ @@ -294,7 +307,8 @@ enum dataset_mem { CMB_TRIG_PATT, CMB_TRIG_PATT_MASK, CMB_PATT, - CMB_PATT_MASK + CMB_PATT_MASK, + CMB_MSR }; /** -- cgit v1.2.3 From 7b5f651127550f2506aae7aac6b78ff6568f5725 Mon Sep 17 00:00:00 2001 From: Kim Seer Paller Date: Tue, 23 Jan 2024 16:10:58 +0800 Subject: dt-bindings: iio: frequency: add admfm2000 Dual microwave down converter module with input RF and LO frequency ranges from 0.5 to 32 GHz and an output IF frequency range from 0.1 to 8 GHz. It consists of a LNA, mixer, IF filter, DSA, and IF amplifier for each down conversion path. Signed-off-by: Kim Seer Paller Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/20240123081059.5746-1-kimseer.paller@analog.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/frequency/adi,admfm2000.yaml | 127 +++++++++++++++++++++ MAINTAINERS | 7 ++ 2 files changed, 134 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/frequency/adi,admfm2000.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,admfm2000.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,admfm2000.yaml new file mode 100644 index 000000000000..2bcf4bbc12e4 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/frequency/adi,admfm2000.yaml @@ -0,0 +1,127 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2024 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/frequency/adi,admfm2000.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ADMFM2000 Dual Microwave Down Converter + +maintainers: + - Kim Seer Paller + +description: + Dual microwave down converter module with input RF and LO frequency ranges + from 0.5 to 32 GHz and an output IF frequency range from 0.1 to 8 GHz. + It consists of a LNA, mixer, IF filter, DSA, and IF amplifier for each down + conversion path. + +properties: + compatible: + enum: + - adi,admfm2000 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +patternProperties: + "^channel@[0-1]$": + type: object + description: Represents a channel of the device. + + additionalProperties: false + + properties: + reg: + description: + The channel number. + minimum: 0 + maximum: 1 + + adi,mixer-mode: + description: + Enable mixer mode for the channel. It downconverts RF between 5 GHz + and 32 GHz to IF between 0.5 GHz and 8 GHz. If not present, the channel + is in direct IF mode which bypasses the mixer and downconverts RF + between 2 GHz and 8 GHz to IF between 0.5 GHz and 8 GHz. + type: boolean + + switch-gpios: + description: | + GPIOs to select the RF path for the channel. The same state of CTRL-A + and CTRL-B GPIOs is not permitted. + CTRL-A CTRL-B CH1 Status CH2 Status + 1 0 Direct IF mode Mixer mode + 0 1 Mixer mode Direct IF mode + + items: + - description: CTRL-A GPIO + - description: CTRL-B GPIO + + attenuation-gpios: + description: | + Choice of attenuation: + DSA-V4 DSA-V3 DSA-V2 DSA-V1 DSA-V0 + 1 1 1 1 1 0 dB + 1 1 1 1 0 -1 dB + 1 1 1 0 1 -2 dB + 1 1 0 1 1 -4 dB + 1 0 1 1 1 -8 dB + 0 1 1 1 1 -16 dB + 0 0 0 0 0 -31 dB + + items: + - description: DSA-V0 GPIO + - description: DSA-V1 GPIO + - description: DSA-V2 GPIO + - description: DSA-V3 GPIO + - description: DSA-V4 GPIO + + required: + - reg + - switch-gpios + - attenuation-gpios + +required: + - compatible + +additionalProperties: false + +examples: + - | + #include + converter { + compatible = "adi,admfm2000"; + + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + switch-gpios = <&gpio 1 GPIO_ACTIVE_LOW>, + <&gpio 2 GPIO_ACTIVE_HIGH>; + + attenuation-gpios = <&gpio 17 GPIO_ACTIVE_LOW>, + <&gpio 22 GPIO_ACTIVE_LOW>, + <&gpio 23 GPIO_ACTIVE_LOW>, + <&gpio 24 GPIO_ACTIVE_LOW>, + <&gpio 25 GPIO_ACTIVE_LOW>; + }; + + channel@1 { + reg = <1>; + adi,mixer-mode; + switch-gpios = <&gpio 3 GPIO_ACTIVE_LOW>, + <&gpio 4 GPIO_ACTIVE_HIGH>; + + attenuation-gpios = <&gpio 0 GPIO_ACTIVE_LOW>, + <&gpio 5 GPIO_ACTIVE_LOW>, + <&gpio 6 GPIO_ACTIVE_LOW>, + <&gpio 16 GPIO_ACTIVE_LOW>, + <&gpio 26 GPIO_ACTIVE_LOW>; + }; + }; +... diff --git a/MAINTAINERS b/MAINTAINERS index 421520e192fc..e650f65996c0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1267,6 +1267,13 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/hwmon/adi,adm1177.yaml F: drivers/hwmon/adm1177.c +ANALOG DEVICES INC ADMFM2000 DRIVER +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/frequency/adi,admfm2000.yaml + ANALOG DEVICES INC ADMV1013 DRIVER M: Antoniu Miclaus L: linux-iio@vger.kernel.org -- cgit v1.2.3 From 7c28226cd03746c7e87409ee75d45e42f1687d89 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 3 Feb 2024 13:01:38 +0100 Subject: dt-bindings: iio: imu: st_lsm6dsx: add asm330lhhxg1 Add device bindings for asm330lhhxg1 IMU sensor. The lsm6dsr supports the features and functionality provided by the asm330lhhxg1 via identical interfaces and so is a suitable fallback compatible. Signed-off-by: Lorenzo Bianconi Acked-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/942452ec9626bc1166501cec0fa88c369e28ec6f.1706961432.git.lorenzo@kernel.org Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml index 28b667a9cb76..c48a96d17f51 100644 --- a/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml +++ b/Documentation/devicetree/bindings/iio/imu/st,lsm6dsx.yaml @@ -35,7 +35,9 @@ properties: - st,lsm6dsv - st,lsm6dso16is - items: - - const: st,asm330lhhx + - enum: + - st,asm330lhhx + - st,asm330lhhxg1 - const: st,lsm6dsr - items: - const: st,lsm6dstx -- cgit v1.2.3 From f1f99fcbf997b50a32844c31523ed41da0428f08 Mon Sep 17 00:00:00 2001 From: Naresh Solanki Date: Tue, 6 Feb 2024 16:25:01 +0530 Subject: dt-bindings: iio: afe: voltage-divider: Add io-channel-cells Enable the voltage divider to both receive and provide measurement services by adding #io-channel-cells. This is especially valuable in scenarios where an ADC has an analog frontend, like a voltage divider, and obtaining its raw value isn't interesting. It is desired to get the real voltage before the voltage divider. Signed-off-by: Naresh Solanki Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/20240206105502.648255-1-naresh.solanki@9elements.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/afe/voltage-divider.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/afe/voltage-divider.yaml b/Documentation/devicetree/bindings/iio/afe/voltage-divider.yaml index dddf97b50549..4151f99b42aa 100644 --- a/Documentation/devicetree/bindings/iio/afe/voltage-divider.yaml +++ b/Documentation/devicetree/bindings/iio/afe/voltage-divider.yaml @@ -39,6 +39,17 @@ properties: description: | Channel node of a voltage io-channel. + '#io-channel-cells': + description: + In addition to consuming the measurement services of a voltage + output channel, the voltage divider can act as a provider of + measurement services to other devices. This is particularly + useful in scenarios wherein an ADC has an analog frontend, + such as a voltage divider, and then consuming its raw value + isn't interesting. In this case, the voltage before the divider + is desired. + const: 1 + output-ohms: description: Resistance Rout over which the output voltage is measured. See full-ohms. -- cgit v1.2.3 From 9f9bfae410e6cdfa454e779c9ef3b737a213ce2c Mon Sep 17 00:00:00 2001 From: Dimitri Fedrau Date: Wed, 14 Feb 2024 09:53:44 +0100 Subject: dt-bindings: iio: humidity: hdc3020: add interrupt bindings in example Add interrupt bindings in example. Signed-off-by: Dimitri Fedrau Acked-by: Rob Herring Link: https://lore.kernel.org/r/20240214085350.19382-3-dima.fedrau@gmail.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/humidity/ti,hdc3020.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/humidity/ti,hdc3020.yaml b/Documentation/devicetree/bindings/iio/humidity/ti,hdc3020.yaml index 7f6d0f9edc75..8b5dedd1a598 100644 --- a/Documentation/devicetree/bindings/iio/humidity/ti,hdc3020.yaml +++ b/Documentation/devicetree/bindings/iio/humidity/ti,hdc3020.yaml @@ -43,6 +43,7 @@ additionalProperties: false examples: - | + #include i2c { #address-cells = <1>; #size-cells = <0>; @@ -51,5 +52,7 @@ examples: compatible = "ti,hdc3021", "ti,hdc3020"; reg = <0x47>; vdd-supply = <&vcc_3v3>; + interrupt-parent = <&gpio3>; + interrupts = <23 IRQ_TYPE_EDGE_RISING>; }; }; -- cgit v1.2.3 From 64eec95820c19d5e1dbb65913d3473b3cf679940 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Mon, 19 Feb 2024 10:16:28 +0200 Subject: dt-bindings: interconnect: qcom,rpmh: Fix bouncing @codeaurora address The servers for the @codeaurora domain have long been retired and any messages sent there will bounce. Fix Odelu's address in the binding to match the .mailmap entry so that folks see the correct address when looking at the documentation. Signed-off-by: Jeffrey Hugo Acked-by: Rob Herring Link: https://lore.kernel.org/r/20240202181748.4124411-1-quic_jhugo@quicinc.com Signed-off-by: Georgi Djakov --- Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml index 74ab080249ff..9318b845ec35 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpmh.yaml @@ -8,7 +8,7 @@ title: Qualcomm RPMh Network-On-Chip Interconnect maintainers: - Georgi Djakov - - Odelu Kukatla + - Odelu Kukatla description: | RPMh interconnect providers support system bandwidth requirements through -- cgit v1.2.3 From 49bb3839e0153b1f48aaa8dd502ea66b8b56db8a Mon Sep 17 00:00:00 2001 From: Nuno Sa Date: Sat, 10 Feb 2024 21:57:13 +0100 Subject: dt-bindings: adc: ad9467: add new io-backend property The ad9467 will make use of the new IIO backend framework which is a provider - consumer interface where IIO backends provide services to consumers. As such, and being this device a consumer, add the new generic io-backend property to the bindings. Reviewed-by: Rob Herring Signed-off-by: Nuno Sa Link: https://lore.kernel.org/r/20240210-iio-backend-v11-1-f5242a5fb42a@analog.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml index 7aa748d6b7a0..eecd5fbab695 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml @@ -44,6 +44,9 @@ properties: Pin that controls the powerdown mode of the device. maxItems: 1 + io-backends: + maxItems: 1 + reset-gpios: description: Reset pin for the device. @@ -68,6 +71,7 @@ examples: reg = <0>; clocks = <&adc_clk>; clock-names = "adc-clk"; + io-backends = <&iio_backend>; }; }; ... -- cgit v1.2.3 From a032b921bdeba2274866daafc8e791edd609eb13 Mon Sep 17 00:00:00 2001 From: Nuno Sa Date: Sat, 10 Feb 2024 21:57:14 +0100 Subject: dt-bindings: adc: axi-adc: update bindings for backend framework 'adi,adc-dev' is now deprecated and must not be used anymore. Hence, also remove it from being required. The reason why it's being deprecated is because the axi-adc CORE is now an IIO service provider hardware (IIO backends) for consumers to make use of. Before, the logic with 'adi,adc-dev' was the opposite (it was kind of consumer referencing other nodes/devices) and that proved to be wrong and to not scale. Now, IIO consumers of this hardware are expected to reference it using the io-backends property. Hence, the new '#io-backend-cells' is being added so the device is easily identified as a provider. Reviewed-by: Rob Herring Signed-off-by: Nuno Sa Link: https://lore.kernel.org/r/20240210-iio-backend-v11-2-f5242a5fb42a@analog.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml index 9996dd93f84b..3d49d21ad33d 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml @@ -39,12 +39,15 @@ properties: $ref: /schemas/types.yaml#/definitions/phandle description: A reference to a the actual ADC to which this FPGA ADC interfaces to. + deprecated: true + + '#io-backend-cells': + const: 0 required: - compatible - dmas - reg - - adi,adc-dev additionalProperties: false @@ -55,7 +58,6 @@ examples: reg = <0x44a00000 0x10000>; dmas = <&rx_dma 0>; dma-names = "rx"; - - adi,adc-dev = <&spi_adc>; + #io-backend-cells = <0>; }; ... -- cgit v1.2.3 From 158b48c8648b105577179122734280e2c3abe6e1 Mon Sep 17 00:00:00 2001 From: Petre Rodan Date: Sun, 11 Feb 2024 09:56:32 +0200 Subject: dt-bindings: iio: pressure: honeywell,hsc030pa.yaml add spi props Add spi-peripheral-props.yaml requirement needed by the spi-max-frequency property. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Petre Rodan Link: https://lore.kernel.org/r/20240211075645.28777-2-petre.rodan@subdimension.ro Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/pressure/honeywell,hsc030pa.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/pressure/honeywell,hsc030pa.yaml b/Documentation/devicetree/bindings/iio/pressure/honeywell,hsc030pa.yaml index 65a24ed67b3c..89977b9f01cf 100644 --- a/Documentation/devicetree/bindings/iio/pressure/honeywell,hsc030pa.yaml +++ b/Documentation/devicetree/bindings/iio/pressure/honeywell,hsc030pa.yaml @@ -99,6 +99,9 @@ required: - honeywell,transfer-function - honeywell,pressure-triplet +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml + additionalProperties: false dependentSchemas: -- cgit v1.2.3 From bc4d251ee8442fa23758bf13de0bda603da01e22 Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Fri, 16 Feb 2024 16:30:19 +0100 Subject: dt-bindings: iio: adc: ti-ads1298: Add bindings Bindings for the TI ADS1298 medical ADC. This device is typically used for ECG and similar measurements. Supports data acquisition at configurable scale and sampling frequency. The device has so many options for connecting stuff, at this point the bindings aren't nearly complete but partial bindings are better than no bindings at all. Signed-off-by: Mike Looijmans Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/20240216153020.485201-1-mike.looijmans@topic.nl Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/adc/ti,ads1298.yaml | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/ti,ads1298.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads1298.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads1298.yaml new file mode 100644 index 000000000000..bf5a43a81d59 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads1298.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,ads1298.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments' ads1298 medical ADC chips + +description: | + Datasheet at: https://www.ti.com/product/ADS1298 + Bindings for this chip aren't complete. + +maintainers: + - Mike Looijmans + +properties: + compatible: + enum: + - ti,ads1298 + + reg: + maxItems: 1 + + spi-cpha: true + + reset-gpios: + maxItems: 1 + + avdd-supply: + description: + Analog power supply, voltage between AVDD and AVSS. When providing a + symmetric +/- 2.5V, the regulator should report 5V. + + vref-supply: + description: + Optional reference voltage. If omitted, internal reference is used, + which is 2.4V when analog supply is below 4.4V, 4V otherwise. + + clocks: + description: Optional 2.048 MHz external source clock on CLK pin + maxItems: 1 + + interrupts: + description: Interrupt on DRDY pin, triggers on falling edge + maxItems: 1 + + label: true + +required: + - compatible + - reg + - avdd-supply + - interrupts + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@1 { + reg = <1>; + compatible = "ti,ads1298"; + label = "ads1298-1-ecg"; + avdd-supply = <®_iso_5v_a>; + clocks = <&clk_ads1298>; + interrupt-parent = <&gpio0>; + interrupts = <78 IRQ_TYPE_EDGE_FALLING>; + spi-max-frequency = <20000000>; + spi-cpha; + }; + }; +... -- cgit v1.2.3 From 7f6860e856062fc927127fa731288b909af797bc Mon Sep 17 00:00:00 2001 From: Mao Jinlong Date: Sun, 18 Feb 2024 01:43:19 -0800 Subject: dt-bindings: arm: qcom,coresight-tpdm: Rename qcom,dsb-element-size The unit for TPDM DSB element size is bits. So rename the property: qcom,dsb-element-size => qcom,dsb-element-bits This also makes it consistent with the naming for the CMB element size property. There is no tpdm node in any DT as of now. Make this change before any tpdm node is added to DT. Fixes: 2a8d9b371566 ("dt-bindings: arm: Add support for DSB element size") Signed-off-by: Mao Jinlong Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240218094322.22470-2-quic_jinlmao@quicinc.com [ Reworded commit description to explain why we change this ] Signed-off-by: Suzuki K Poulose --- Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml index d0647ffaed71..8eec07d9d454 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml @@ -44,12 +44,11 @@ properties: minItems: 1 maxItems: 2 - qcom,dsb-element-size: + qcom,dsb-element-bits: description: Specifies the DSB(Discrete Single Bit) element size supported by the monitor. The associated aggregator will read this size before it is enabled. DSB element size currently only supports 32-bit and 64-bit. - $ref: /schemas/types.yaml#/definitions/uint8 enum: [32, 64] qcom,cmb-element-bits: @@ -111,7 +110,7 @@ examples: compatible = "qcom,coresight-tpdm", "arm,primecell"; reg = <0x0684c000 0x1000>; - qcom,dsb-element-size = /bits/ 8 <32>; + qcom,dsb-element-bits = <32>; qcom,dsb-msrs-num = <16>; clocks = <&aoss_qmp>; -- cgit v1.2.3 From 7d87c9b94a44bed97637199a62e99c702f8469d0 Mon Sep 17 00:00:00 2001 From: Thomas Haemmerle Date: Mon, 19 Feb 2024 14:11:13 +0100 Subject: dt-bindings: iio: ti,tmp117: add vcc supply binding Add the binding to specify the vcc supply. We can't make it required since this would break the backward compatibility. Reviewed-by: Conor Dooley Signed-off-by: Thomas Haemmerle Signed-off-by: Marco Felsch Link: https://lore.kernel.org/r/20240219131114.134607-1-m.felsch@pengutronix.de Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml b/Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml index 8c6d7735e875..33f2e9c5bd81 100644 --- a/Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml @@ -24,9 +24,13 @@ properties: reg: maxItems: 1 + vcc-supply: + description: provide VCC power to the sensor. + required: - compatible - reg + - vcc-supply additionalProperties: false @@ -39,5 +43,6 @@ examples: tmp117@48 { compatible = "ti,tmp117"; reg = <0x48>; + vcc-supply = <&pmic_reg_3v3>; }; }; -- cgit v1.2.3 From 506d7e3acec6b09c5b598c2bf84db79456bd0606 Mon Sep 17 00:00:00 2001 From: Josua Mayer Date: Mon, 19 Feb 2024 15:48:21 +0100 Subject: dt-bindings: iio: humidity: hdc20x0: add optional interrupts property HDC2010 and HDC2080 humidity sensors both have an interrupt / data-ready signal which can be used for signaling to the host. Add binding for "interrupts" property so that boards wiring this signal may describe the connection. Acked-by: Rob Herring Signed-off-by: Josua Mayer Link: https://lore.kernel.org/r/20240219-iio-hdc20x0-interrupt-binding-v7-1-c8ffb39c3768@solid-run.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml b/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml index 79e75a8675cb..e3eca8917517 100644 --- a/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml +++ b/Documentation/devicetree/bindings/iio/humidity/ti,hdc2010.yaml @@ -27,6 +27,9 @@ properties: reg: maxItems: 1 + interrupts: + maxItems: 1 + required: - compatible - reg -- cgit v1.2.3 From 5c7403abf9da656f5827cb9081c2ad7bfab0d673 Mon Sep 17 00:00:00 2001 From: Dumitru Ceclan Date: Tue, 20 Feb 2024 17:34:50 +0200 Subject: dt-bindings: iio: hmc425a: add conditional GPIO array size constraints ADRF5740 and HMC540S have a 4 bit parallel interface. Update ctrl-gpios description and min/maxItems values depending on the matched compatible to correctly reflect the hardware properties. Fixes: 79f2ff6461e7 ("dt-bindings: iio: hmc425a: add entry for ADRF5740 Attenuator") Fixes: 20f87a9a26be ("dt-bindings: iio: hmc425a: add entry for HMC540S") Acked-by: Conor Dooley Signed-off-by: Dumitru Ceclan Link: https://lore.kernel.org/r/20240220153553.2432-3-mitrutzceclan@gmail.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/amplifiers/adi,hmc425a.yaml | 33 ++++++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml b/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml index 67de9d4e3a1d..a434cb8ddcc9 100644 --- a/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml +++ b/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml @@ -33,11 +33,38 @@ properties: ctrl-gpios: description: - Must contain an array of 6 GPIO specifiers, referring to the GPIO pins - connected to the control pins V1-V6. - minItems: 6 + Must contain an array of GPIO specifiers, referring to the GPIO pins + connected to the control pins. + ADRF5740 - 4 GPIO connected to D2-D5 + HMC540S - 4 GPIO connected to V1-V4 + HMC425A - 6 GPIO connected to V1-V6 + minItems: 1 maxItems: 6 +allOf: + - if: + properties: + compatible: + contains: + const: adi,hmc425a + then: + properties: + ctrl-gpios: + minItems: 6 + maxItems: 6 + - if: + properties: + compatible: + contains: + anyOf: + - const: adi,adrf5740 + - const: adi,hmc540s + then: + properties: + ctrl-gpios: + minItems: 4 + maxItems: 4 + required: - compatible - ctrl-gpios -- cgit v1.2.3 From ff96eb45baf2803f3c529fe79c76659c9af1a3fc Mon Sep 17 00:00:00 2001 From: Dumitru Ceclan Date: Tue, 20 Feb 2024 17:34:52 +0200 Subject: dt-bindings: iio: hmc425a: add entry for LTC6373 The LTC6373 is a silicon, 3-bit Fully-Differential digital instrumentation amplifier that supports the following programmable gains (Vout/Vin): G = 0.25, 0.5, 1, 2, 4, 8, 16 + Shutdown. Acked-by: Conor Dooley Signed-off-by: Dumitru Ceclan Link: https://lore.kernel.org/r/20240220153553.2432-5-mitrutzceclan@gmail.com Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml b/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml index a434cb8ddcc9..3a470459b965 100644 --- a/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml +++ b/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml @@ -21,6 +21,8 @@ description: | HMC540S 1 dB LSB Silicon MMIC 4-Bit Digital Positive Control Attenuator, 0.1 - 8 GHz https://www.analog.com/media/en/technical-documentation/data-sheets/hmc540s.pdf + LTC6373 is a 3-Bit precision instrumentation amplifier with fully differential outputs + https://www.analog.com/media/en/technical-documentation/data-sheets/ltc6373.pdf properties: compatible: @@ -28,6 +30,7 @@ properties: - adi,adrf5740 - adi,hmc425a - adi,hmc540s + - adi,ltc6373 vcc-supply: true @@ -38,6 +41,7 @@ properties: ADRF5740 - 4 GPIO connected to D2-D5 HMC540S - 4 GPIO connected to V1-V4 HMC425A - 6 GPIO connected to V1-V6 + LTC6373 - 3 GPIO connected to A0-A2 minItems: 1 maxItems: 6 @@ -64,6 +68,16 @@ allOf: ctrl-gpios: minItems: 4 maxItems: 4 + - if: + properties: + compatible: + contains: + const: adi,ltc6373 + then: + properties: + ctrl-gpios: + minItems: 3 + maxItems: 3 required: - compatible -- cgit v1.2.3 From a3e58e4aa986c54e5fa26b9556acc3a507d3706a Mon Sep 17 00:00:00 2001 From: Ramona Gradinariu Date: Wed, 21 Feb 2024 10:58:46 +0200 Subject: docs: iio: Refactor index.rst Refactor index.rst such that it contains a section for generic documentation and a section for Kernel Drivers documentation. Signed-off-by: Ramona Gradinariu Link: https://lore.kernel.org/r/20240221085848.991413-2-ramona.gradinariu@analog.com Signed-off-by: Jonathan Cameron --- Documentation/iio/index.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index 1b7292c58cd0..db341b45397f 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -9,6 +9,11 @@ Industrial I/O iio_configfs - ep93xx_adc +Industrial I/O Kernel Drivers +============================= + +.. toctree:: + :maxdepth: 1 bno055 + ep93xx_adc -- cgit v1.2.3 From d5422a85ed2956fc85ee198ac8faf89ab02ba318 Mon Sep 17 00:00:00 2001 From: Ramona Gradinariu Date: Wed, 21 Feb 2024 10:58:47 +0200 Subject: docs: iio: add documentation for device buffers Add documentation for IIO device buffers describing buffer attributes and how data is structured in buffers using scan elements. Signed-off-by: Ramona Gradinariu Link: https://lore.kernel.org/r/20240221085848.991413-3-ramona.gradinariu@analog.com Signed-off-by: Jonathan Cameron --- Documentation/iio/iio_devbuf.rst | 152 +++++++++++++++++++++++++++++++++++++++ Documentation/iio/index.rst | 1 + 2 files changed, 153 insertions(+) create mode 100644 Documentation/iio/iio_devbuf.rst (limited to 'Documentation') diff --git a/Documentation/iio/iio_devbuf.rst b/Documentation/iio/iio_devbuf.rst new file mode 100644 index 000000000000..9919e4792d0e --- /dev/null +++ b/Documentation/iio/iio_devbuf.rst @@ -0,0 +1,152 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============================= +Industrial IIO device buffers +============================= + +1. Overview +=========== + +The Industrial I/O core offers a way for continuous data capture based on a +trigger source. Multiple data channels can be read at once from +``/dev/iio:deviceX`` character device node, thus reducing the CPU load. + +Devices with buffer support feature an additional sub-directory in the +``/sys/bus/iio/devices/iio:deviceX/`` directory hierarchy, called bufferY, where +Y defaults to 0, for devices with a single buffer. + +2. Buffer attributes +==================== + +An IIO buffer has an associated attributes directory under +``/sys/bus/iio/iio:deviceX/bufferY/``. The attributes are described below. + +``length`` +---------- + +Read / Write attribute which states the total number of data samples (capacity) +that can be stored by the buffer. + +``enable`` +---------- + +Read / Write attribute which starts / stops the buffer capture. This file should +be written last, after length and selection of scan elements. Writing a non-zero +value may result in an error, such as EINVAL, if, for example, an unsupported +combination of channels is given. + +``watermark`` +------------- + +Read / Write positive integer attribute specifying the maximum number of scan +elements to wait for. + +Poll will block until the watermark is reached. + +Blocking read will wait until the minimum between the requested read amount or +the low watermark is available. + +Non-blocking read will retrieve the available samples from the buffer even if +there are less samples than the watermark level. This allows the application to +block on poll with a timeout and read the available samples after the timeout +expires and thus have a maximum delay guarantee. + +Data available +-------------- + +Read-only attribute indicating the bytes of data available in the buffer. In the +case of an output buffer, this indicates the amount of empty space available to +write data to. In the case of an input buffer, this indicates the amount of data +available for reading. + +Scan elements +------------- + +The meta information associated with a channel data placed in a buffer is called +a scan element. The scan elements attributes are presented below. + +**_en** + +Read / Write attribute used for enabling a channel. If and only if its value +is non-zero, then a triggered capture will contain data samples for this +channel. + +**_index** + +Read-only unsigned integer attribute specifying the position of the channel in +the buffer. Note these are not dependent on what is enabled and may not be +contiguous. Thus for userspace to establish the full layout these must be used +in conjunction with all _en attributes to establish which channels are present, +and the relevant _type attributes to establish the data storage format. + +**_type** + +Read-only attribute containing the description of the scan element data storage +within the buffer and hence the form in which it is read from userspace. Format +is [be|le]:[s|u]bits/storagebits[Xrepeat][>>shift], where: + +- **be** or **le** specifies big or little-endian. +- **s** or **u** specifies if signed (2's complement) or unsigned. +- **bits** is the number of valid data bits. +- **storagebits** is the number of bits (after padding) that it occupies in the + buffer. +- **repeat** specifies the number of bits/storagebits repetitions. When the + repeat element is 0 or 1, then the repeat value is omitted. +- **shift** if specified, is the shift that needs to be applied prior to + masking out unused bits. + +For example, a driver for a 3-axis accelerometer with 12-bit resolution where +data is stored in two 8-bit registers is as follows:: + + 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+ + |D3 |D2 |D1 |D0 | X | X | X | X | (LOW byte, address 0x06) + +---+---+---+---+---+---+---+---+ + + 7 6 5 4 3 2 1 0 + +---+---+---+---+---+---+---+---+ + |D11|D10|D9 |D8 |D7 |D6 |D5 |D4 | (HIGH byte, address 0x07) + +---+---+---+---+---+---+---+---+ + +will have the following scan element type for each axis: + +.. code-block:: bash + + $ cat /sys/bus/iio/devices/iio:device0/buffer0/in_accel_y_type + le:s12/16>>4 + +A userspace application will interpret data samples read from the buffer as +two-byte little-endian signed data, that needs a 4 bits right shift before +masking out the 12 valid bits of data. + +It is also worth mentioning that the data in the buffer will be naturally +aligned, so the userspace application has to handle the buffers accordingly. + +Take for example, a driver with four channels with the following description: +- channel0: index: 0, type: be:u16/16>>0 +- channel1: index: 1, type: be:u32/32>>0 +- channel2: index: 2, type: be:u32/32>>0 +- channel3: index: 3, type: be:u64/64>>0 + +If all channels are enabled, the data will be aligned in the buffer as follows:: + + 0-1 2 3 4-7 8-11 12 13 14 15 16-23 -> buffer byte number + +-----+---+---+-----+-----+---+---+---+---+-----+ + |CHN_0|PAD|PAD|CHN_1|CHN_2|PAD|PAD|PAD|PAD|CHN_3| -> buffer content + +-----+---+---+-----+-----+---+---+---+---+-----+ + +If only channel0 and channel3 are enabled, the data will be aligned in the +buffer as follows:: + + 0-1 2 3 4 5 6 7 8-15 -> buffer byte number + +-----+---+---+---+---+---+---+-----+ + |CHN_0|PAD|PAD|PAD|PAD|PAD|PAD|CHN_3| -> buffer content + +-----+---+---+---+---+---+---+-----+ + +Typically the buffered data is found in raw format (unscaled with no offset +applied), however there are corner cases in which the buffered data may be found +in a processed form. Please note that these corner cases are not addressed by +this documentation. + +Please see ``Documentation/ABI/testing/sysfs-bus-iio`` for a complete +description of the attributes. diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index db341b45397f..206a0aff5ca1 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -8,6 +8,7 @@ Industrial I/O :maxdepth: 1 iio_configfs + iio_devbuf Industrial I/O Kernel Drivers ============================= -- cgit v1.2.3 From 8243b2877eefe92f1022013601b8dfeb892b707a Mon Sep 17 00:00:00 2001 From: Ramona Gradinariu Date: Wed, 21 Feb 2024 10:58:48 +0200 Subject: docs: iio: add documentation for adis16475 driver Add documentation for adis16475 driver which describes the driver device files and shows how the user may use the ABI for various scenarios (configuration, measurement, etc.). Signed-off-by: Ramona Gradinariu Link: https://lore.kernel.org/r/20240221085848.991413-4-ramona.gradinariu@analog.com Signed-off-by: Jonathan Cameron --- Documentation/iio/adis16475.rst | 407 ++++++++++++++++++++++++++++++++++++++++ Documentation/iio/index.rst | 1 + 2 files changed, 408 insertions(+) create mode 100644 Documentation/iio/adis16475.rst (limited to 'Documentation') diff --git a/Documentation/iio/adis16475.rst b/Documentation/iio/adis16475.rst new file mode 100644 index 000000000000..91cabb7d8d05 --- /dev/null +++ b/Documentation/iio/adis16475.rst @@ -0,0 +1,407 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================ +ADIS16475 driver +================ + +This driver supports Analog Device's IMUs on SPI bus. + +1. Supported devices +==================== + +* `ADIS16465 `_ +* `ADIS16467 `_ +* `ADIS16470 `_ +* `ADIS16475 `_ +* `ADIS16477 `_ +* `ADIS16500 `_ +* `ADIS16505 `_ +* `ADIS16507 `_ + +Each supported device is a precision, miniature microelectromechanical system +(MEMS) inertial measurement unit (IMU) that includes a triaxial gyroscope and a +triaxial accelerometer. Each inertial sensor in the IMU device combines with +signal conditioning that optimizes dynamic performance. The factory calibration +characterizes each sensor for sensitivity, bias, alignment, linear acceleration +(gyroscope bias), and point of percussion (accelerometer location). As a result, +each sensor has dynamic compensation formulas that provide accurate sensor +measurements over a broad set of conditions. + +2. Device attributes +==================== + +Accelerometer, gyroscope measurements are always provided. Furthermore, the +driver offers the capability to retrieve the delta angle and the delta velocity +measurements computed by the device. + +The delta angle measurements represent a calculation of angular displacement +between each sample update, while the delta velocity measurements represent a +calculation of linear velocity change between each sample update. + +Finally, temperature data are provided which show a coarse measurement of +the temperature inside of the IMU device. This data is most useful for +monitoring relative changes in the thermal environment. + +The signal chain of each inertial sensor (accelerometers and gyroscopes) +includes the application of unique correction formulas, which are derived from +extensive characterization of bias, sensitivity, alignment, response to linear +acceleration (gyroscopes), and point of percussion (accelerometer location) +over a temperature range of −40°C to +85°C, for each ADIS device. These +correction formulas are not accessible, but users do have the opportunity to +adjust the bias for each sensor individually through the calibbias attribute. + +Each IIO device, has a device folder under ``/sys/bus/iio/devices/iio:deviceX``, +where X is the IIO index of the device. Under these folders reside a set of +device files, depending on the characteristics and features of the hardware +device in questions. These files are consistently generalized and documented in +the IIO ABI documentation. + +The following tables show the adis16475 related device files, found in the +specific device folder path ``/sys/bus/iio/devices/iio:deviceX``. + ++-------------------------------------------+----------------------------------------------------------+ +| 3-Axis Accelerometer related device files | Description | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_scale | Scale for the accelerometer channels. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_x_calibbias | Calibration offset for the X-axis accelerometer channel. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_calibbias_x | x-axis acceleration offset correction | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_x_raw | Raw X-axis accelerometer channel value. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_calibbias_y | y-axis acceleration offset correction | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_y_raw | Raw Y-axis accelerometer channel value. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_z_calibbias | Calibration offset for the Z-axis accelerometer channel. | ++-------------------------------------------+----------------------------------------------------------+ +| in_accel_z_raw | Raw Z-axis accelerometer channel value. | ++-------------------------------------------+----------------------------------------------------------+ +| in_deltavelocity_scale | Scale for delta velocity channels. | ++-------------------------------------------+----------------------------------------------------------+ +| in_deltavelocity_x_raw | Raw X-axis delta velocity channel value. | ++-------------------------------------------+----------------------------------------------------------+ +| in_deltavelocity_y_raw | Raw Y-axis delta velocity channel value. | ++-------------------------------------------+----------------------------------------------------------+ +| in_deltavelocity_z_raw | Raw Z-axis delta velocity channel value. | ++-------------------------------------------+----------------------------------------------------------+ + ++---------------------------------------+------------------------------------------------------+ +| 3-Axis Gyroscope related device files | Description | ++---------------------------------------+------------------------------------------------------+ +| in_anglvel_scale | Scale for the gyroscope channels. | ++---------------------------------------+------------------------------------------------------+ +| in_anglvel_x_calibbias | Calibration offset for the X-axis gyroscope channel. | ++---------------------------------------+------------------------------------------------------+ +| in_anglvel_calibbias_x | x-axis gyroscope offset correction | ++---------------------------------------+------------------------------------------------------+ +| in_anglvel_x_raw | Raw X-axis gyroscope channel value. | ++---------------------------------------+------------------------------------------------------+ +| in_anglvel_calibbias_y | y-axis gyroscope offset correction | ++---------------------------------------+------------------------------------------------------+ +| in_anglvel_y_raw | Raw Y-axis gyroscope channel value. | ++---------------------------------------+------------------------------------------------------+ +| in_anglvel_z_calibbias | Calibration offset for the Z-axis gyroscope channel. | ++---------------------------------------+------------------------------------------------------+ +| in_anglvel_z_raw | Raw Z-axis gyroscope channel value. | ++---------------------------------------+------------------------------------------------------+ +| in_deltaangl_scale | Scale for delta angle channels. | ++---------------------------------------+------------------------------------------------------+ +| in_deltaangl_x_raw | Raw X-axis delta angle channel value. | ++---------------------------------------+------------------------------------------------------+ +| in_deltaangl_y_raw | Raw Y-axis delta angle channel value. | ++---------------------------------------+------------------------------------------------------+ +| in_deltaangl_z_raw | Raw Z-axis delta angle channel value. | ++---------------------------------------+------------------------------------------------------+ + ++----------------------------------+-------------------------------------------+ +| Temperature sensor related files | Description | ++----------------------------------+-------------------------------------------+ +| in_temp0_raw | Raw temperature channel value. | ++----------------------------------+-------------------------------------------+ +| in_temp0_scale | Scale for the temperature sensor channel. | ++----------------------------------+-------------------------------------------+ + ++-------------------------------+---------------------------------------------------------+ +| Miscellaneous device files | Description | ++-------------------------------+---------------------------------------------------------+ +| name | Name of the IIO device. | ++-------------------------------+---------------------------------------------------------+ +| sampling_frequency | Currently selected sample rate. | ++-------------------------------+---------------------------------------------------------+ +| filter_low_pass_3db_frequency | Bandwidth for the accelerometer and gyroscope channels. | ++-------------------------------+---------------------------------------------------------+ + +The following table shows the adis16475 related device debug files, found in the +specific device debug folder path ``/sys/kernel/debug/iio/iio:deviceX``. + ++----------------------+-------------------------------------------------------------------------+ +| Debugfs device files | Description | ++----------------------+-------------------------------------------------------------------------+ +| serial_number | The serial number of the chip in hexadecimal format. | ++----------------------+-------------------------------------------------------------------------+ +| product_id | Chip specific product id (e.g. 16475, 16500, 16505, etc.). | ++----------------------+-------------------------------------------------------------------------+ +| flash_count | The number of flash writes performed on the device. | ++----------------------+-------------------------------------------------------------------------+ +| firmware_revision | String containing the firmware revision in the following format ##.##. | ++----------------------+-------------------------------------------------------------------------+ +| firmware_date | String containing the firmware date in the following format mm-dd-yyyy. | ++----------------------+-------------------------------------------------------------------------+ + +Channels processed values +------------------------- + +A channel value can be read from its _raw attribute. The value returned is the +raw value as reported by the devices. To get the processed value of the channel, +apply the following formula: + +.. code-block:: bash + + processed value = (_raw + _offset) * _scale + +Where _offset and _scale are device attributes. If no _offset attribute is +present, simply assume its value is 0. + +The adis16475 driver offers data for 5 types of channels, the table below shows +the measurement units for the processed value, which are defined by the IIO +framework: + ++-------------------------------------+---------------------------+ +| Channel type | Measurement unit | ++-------------------------------------+---------------------------+ +| Acceleration on X, Y, and Z axis | Meters per Second squared | ++-------------------------------------+---------------------------+ +| Angular velocity on X, Y and Z axis | Radians per second | ++-------------------------------------+---------------------------+ +| Delta velocity on X. Y, and Z axis | Meters per Second | ++-------------------------------------+---------------------------+ +| Delta angle on X, Y, and Z axis | Radians | ++-------------------------------------+---------------------------+ +| Temperature | Millidegrees Celsius | ++-------------------------------------+---------------------------+ + +Usage examples +-------------- + +Show device name: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat name + adis16505-2 + +Show accelerometer channels value: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_raw + -275924 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_y_raw + -30142222 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_z_raw + 261265769 + root:/sys/bus/iio/devices/iio:device0> cat in_accel_scale + 0.000000037 + +- X-axis acceleration = in_accel_x_raw * in_accel_scale = −0.010209188 m/s^2 +- Y-axis acceleration = in_accel_y_raw * in_accel_scale = −1.115262214 m/s^2 +- Z-axis acceleration = in_accel_z_raw * in_accel_scale = 9.666833453 m/s^2 + +Show gyroscope channels value: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_anglvel_x_raw + -3324626 + root:/sys/bus/iio/devices/iio:device0> cat in_anglvel_y_raw + 1336980 + root:/sys/bus/iio/devices/iio:device0> cat in_anglvel_z_raw + -602983 + root:/sys/bus/iio/devices/iio:device0> cat in_anglvel_scale + 0.000000006 + +- X-axis angular velocity = in_anglvel_x_raw * in_anglvel_scale = −0.019947756 rad/s +- Y-axis angular velocity = in_anglvel_y_raw * in_anglvel_scale = 0.00802188 rad/s +- Z-axis angular velocity = in_anglvel_z_raw * in_anglvel_scale = −0.003617898 rad/s + +Set calibration offset for accelerometer channels: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_calibbias + 0 + + root:/sys/bus/iio/devices/iio:device0> echo 5000 > in_accel_x_calibbias + root:/sys/bus/iio/devices/iio:device0> cat in_accel_x_calibbias + 5000 + +Set calibration offset for gyroscope channels: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat in_anglvel_y_calibbias + 0 + + root:/sys/bus/iio/devices/iio:device0> echo -5000 > in_anglvel_y_calibbias + root:/sys/bus/iio/devices/iio:device0> cat in_anglvel_y_calibbias + -5000 + +Set sampling frequency: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat sampling_frequency + 2000.000000 + + root:/sys/bus/iio/devices/iio:device0> echo 1000 > sampling_frequency + 1000.000000 + +Set bandwidth for accelerometer and gyroscope: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat filter_low_pass_3db_frequency + 720 + + root:/sys/bus/iio/devices/iio:device0> echo 360 > filter_low_pass_3db_frequency + root:/sys/bus/iio/devices/iio:device0> cat filter_low_pass_3db_frequency + 360 + +Show serial number: + +.. code-block:: bash + + root:/sys/kernel/debug/iio/iio:device0> cat serial_number + 0x04f9 + +Show product id: + +.. code-block:: bash + + root:/sys/kernel/debug/iio/iio:device0> cat product_id + 16505 + +Show flash count: + +.. code-block:: bash + + root:/sys/kernel/debug/iio/iio:device0> cat flash_count + 150 + +Show firmware revision: + +.. code-block:: bash + + root:/sys/kernel/debug/iio/iio:device0> cat firmware_revision + 1.6 + +Show firmware date: + +.. code-block:: bash + + root:/sys/kernel/debug/iio/iio:device0> cat firmware_date + 06-27-2019 + +3. Device buffers +================= + +This driver supports IIO buffers. + +All devices support retrieving the raw acceleration, gyroscope and temperature +measurements using buffers. + +The following device families also support retrieving the delta velocity, delta +angle and temperature measurements using buffers: + +- ADIS16477 +- ADIS16500 +- ADIS16505 +- ADIS16507 + +However, when retrieving acceleration or gyroscope data using buffers, delta +readings will not be available and vice versa. + +Usage examples +-------------- + +Set device trigger in current_trigger, if not already set: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> cat trigger/current_trigger + + root:/sys/bus/iio/devices/iio:device0> echo adis16505-2-dev0 > trigger/current_trigger + root:/sys/bus/iio/devices/iio:device0> cat trigger/current_trigger + adis16505-2-dev0 + +Select channels for buffer read: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_deltavelocity_x_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_deltavelocity_y_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_deltavelocity_z_en + root:/sys/bus/iio/devices/iio:device0> echo 1 > scan_elements/in_temp0_en + +Set the number of samples to be stored in the buffer: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 10 > buffer/length + +Enable buffer readings: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> echo 1 > buffer/enable + +Obtain buffered data: + +.. code-block:: bash + + root:/sys/bus/iio/devices/iio:device0> hexdump -C /dev/iio\:device0 + ... + 00001680 01 1f 00 00 ff ff fe ef 00 00 47 bf 00 03 35 55 |..........G...5U| + 00001690 01 1f 00 00 ff ff ff d9 00 00 46 f1 00 03 35 35 |..........F...55| + 000016a0 01 1f 00 00 ff ff fe fc 00 00 46 cb 00 03 35 7b |..........F...5{| + 000016b0 01 1f 00 00 ff ff fe 41 00 00 47 0d 00 03 35 8b |.......A..G...5.| + 000016c0 01 1f 00 00 ff ff fe 37 00 00 46 b4 00 03 35 90 |.......7..F...5.| + 000016d0 01 1d 00 00 ff ff fe 5a 00 00 45 d7 00 03 36 08 |.......Z..E...6.| + 000016e0 01 1b 00 00 ff ff fe fb 00 00 45 e7 00 03 36 60 |..........E...6`| + 000016f0 01 1a 00 00 ff ff ff 17 00 00 46 bc 00 03 36 de |..........F...6.| + 00001700 01 1a 00 00 ff ff fe 59 00 00 46 d7 00 03 37 b8 |.......Y..F...7.| + 00001710 01 1a 00 00 ff ff fe ae 00 00 46 95 00 03 37 ba |..........F...7.| + 00001720 01 1a 00 00 ff ff fe c5 00 00 46 63 00 03 37 9f |..........Fc..7.| + 00001730 01 1a 00 00 ff ff fe 55 00 00 46 89 00 03 37 c1 |.......U..F...7.| + 00001740 01 1a 00 00 ff ff fe 31 00 00 46 aa 00 03 37 f7 |.......1..F...7.| + ... + +See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered +data is structured. + +4. IIO Interfacing Tools +======================== + +Linux Kernel Tools +------------------ + +Linux Kernel provides some userspace tools that can be used to retrieve data +from IIO sysfs: + +* lsiio: example application that provides a list of IIO devices and triggers +* iio_event_monitor: example application that reads events from an IIO device + and prints them +* iio_generic_buffer: example application that reads data from buffer +* iio_utils: set of APIs, typically used to access sysfs files. + +LibIIO +------ + +LibIIO is a C/C++ library that provides generic access to IIO devices. The +library abstracts the low-level details of the hardware, and provides a simple +yet complete programming interface that can be used for advanced projects. + +For more information about LibIIO, please see: +https://github.com/analogdevicesinc/libiio diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index 206a0aff5ca1..30b09eefe75e 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -16,5 +16,6 @@ Industrial I/O Kernel Drivers .. toctree:: :maxdepth: 1 + adis16475 bno055 ep93xx_adc -- cgit v1.2.3 From a8ce0b4e5653c3aafd602be1e3aaf5d08cb00923 Mon Sep 17 00:00:00 2001 From: Marius Cristea Date: Thu, 22 Feb 2024 18:42:05 +0200 Subject: dt-bindings: iio: adc: adding support for PAC193X This is the device tree schema for iio driver for Microchip PAC193X series of Power Monitors with Accumulator. Signed-off-by: Marius Cristea Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/20240222164206.65700-2-marius.cristea@microchip.com Signed-off-by: Jonathan Cameron --- .../bindings/iio/adc/microchip,pac1934.yaml | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/adc/microchip,pac1934.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/microchip,pac1934.yaml b/Documentation/devicetree/bindings/iio/adc/microchip,pac1934.yaml new file mode 100644 index 000000000000..47a11a9ac95e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/microchip,pac1934.yaml @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/microchip,pac1934.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip PAC1934 Power Monitors with Accumulator + +maintainers: + - Marius Cristea + +description: | + This device is part of the Microchip family of Power Monitors with + Accumulator. + The datasheet for PAC1931, PAC1932, PAC1933 and PAC1934 can be found here: + https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/PAC1931-Family-Data-Sheet-DS20005850E.pdf + +properties: + compatible: + enum: + - microchip,pac1931 + - microchip,pac1932 + - microchip,pac1933 + - microchip,pac1934 + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + interrupts: + maxItems: 1 + + slow-io-gpios: + description: + A GPIO used to trigger a change is sampling rate (lowering the chip power + consumption). If configured in SLOW mode, if this pin is forced high, + sampling rate is forced to eight samples/second. When it is forced low, + the sampling rate is 1024 samples/second unless a different sample rate + has been programmed. + +patternProperties: + "^channel@[1-4]+$": + type: object + $ref: adc.yaml + description: + Represents the external channels which are connected to the ADC. + + properties: + reg: + items: + minimum: 1 + maximum: 4 + + shunt-resistor-micro-ohms: + description: + Value in micro Ohms of the shunt resistor connected between + the SENSE+ and SENSE- inputs, across which the current is measured. + Value is needed to compute the scaling of the measured current. + + required: + - reg + - shunt-resistor-micro-ohms + + unevaluatedProperties: false + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + power-monitor@10 { + compatible = "microchip,pac1934"; + reg = <0x10>; + + #address-cells = <1>; + #size-cells = <0>; + + channel@1 { + reg = <0x1>; + shunt-resistor-micro-ohms = <24900000>; + label = "CPU"; + }; + + channel@2 { + reg = <0x2>; + shunt-resistor-micro-ohms = <49900000>; + label = "GPU"; + }; + + channel@3 { + reg = <0x3>; + shunt-resistor-micro-ohms = <75000000>; + label = "MEM"; + bipolar; + }; + + channel@4 { + reg = <0x4>; + shunt-resistor-micro-ohms = <100000000>; + label = "NET"; + bipolar; + }; + }; + }; + +... -- cgit v1.2.3 From 0fb528c8255bd2de6a2fba26ed28d75a7f0cb630 Mon Sep 17 00:00:00 2001 From: Marius Cristea Date: Thu, 22 Feb 2024 18:42:06 +0200 Subject: iio: adc: adding support for PAC193x This is the iio driver for Microchip PAC193X series of Power Monitor with Accumulator chip family. Signed-off-by: Marius Cristea Link: https://lore.kernel.org/r/20240222164206.65700-3-marius.cristea@microchip.com Signed-off-by: Jonathan Cameron --- .../ABI/testing/sysfs-bus-iio-adc-pac1934 | 9 + MAINTAINERS | 7 + drivers/iio/adc/Kconfig | 11 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/pac1934.c | 1636 ++++++++++++++++++++ 5 files changed, 1664 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-adc-pac1934 create mode 100644 drivers/iio/adc/pac1934.c (limited to 'Documentation') diff --git a/Documentation/ABI/testing/sysfs-bus-iio-adc-pac1934 b/Documentation/ABI/testing/sysfs-bus-iio-adc-pac1934 new file mode 100644 index 000000000000..625b7f867847 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-adc-pac1934 @@ -0,0 +1,9 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_shunt_resistorY +KernelVersion: 6.7 +Contact: linux-iio@vger.kernel.org +Description: + The value of the shunt resistor may be known only at runtime + and set by a client application. This attribute allows to + set its value in micro-ohms. X is the IIO index of the device. + Y is the channel number. The value is used to calculate + current, power and accumulated energy. diff --git a/MAINTAINERS b/MAINTAINERS index d59d52ec8b06..031600dd6c2a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14426,6 +14426,13 @@ F: Documentation/devicetree/bindings/nvmem/microchip,sama7g5-otpc.yaml F: drivers/nvmem/microchip-otpc.c F: include/dt-bindings/nvmem/microchip,sama7g5-otpc.h +MICROCHIP PAC1934 POWER/ENERGY MONITOR DRIVER +M: Marius Cristea +L: linux-iio@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/iio/adc/microchip,pac1934.yaml +F: drivers/iio/adc/pac1934.c + MICROCHIP PCI1XXXX GP DRIVER M: Vaibhaav Ram T.L M: Kumaravel Thiagarajan diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index d4462c202784..0d9282fa67f5 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -930,6 +930,17 @@ config NPCM_ADC This driver can also be built as a module. If so, the module will be called npcm_adc. +config PAC1934 + tristate "Microchip Technology PAC1934 driver" + depends on I2C + help + Say yes here to build support for Microchip Technology's PAC1931, + PAC1932, PAC1933, PAC1934 Single/Multi-Channel Power Monitor with + Accumulator. + + This driver can also be built as a module. If so, the module + will be called pac1934. + config PALMAS_GPADC tristate "TI Palmas General Purpose ADC" depends on MFD_PALMAS diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index a64326f40fcb..b3c434722364 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -86,6 +86,7 @@ obj-$(CONFIG_MP2629_ADC) += mp2629_adc.o obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o obj-$(CONFIG_NAU7802) += nau7802.o obj-$(CONFIG_NPCM_ADC) += npcm_adc.o +obj-$(CONFIG_PAC1934) += pac1934.o obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o obj-$(CONFIG_QCOM_SPMI_ADC5) += qcom-spmi-adc5.o obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o diff --git a/drivers/iio/adc/pac1934.c b/drivers/iio/adc/pac1934.c new file mode 100644 index 000000000000..e0c2742da523 --- /dev/null +++ b/drivers/iio/adc/pac1934.c @@ -0,0 +1,1636 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * IIO driver for PAC1934 Multi-Channel DC Power/Energy Monitor + * + * Copyright (C) 2017-2024 Microchip Technology Inc. and its subsidiaries + * + * Author: Bogdan Bolocan + * Author: Victor Tudose + * Author: Marius Cristea + * + * Datasheet for PAC1931, PAC1932, PAC1933 and PAC1934 can be found here: + * https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/PAC1931-Family-Data-Sheet-DS20005850E.pdf + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * maximum accumulation time should be (17 * 60 * 1000) around 17 minutes@1024 sps + * till PAC1934 accumulation registers starts to saturate + */ +#define PAC1934_MAX_RFSH_LIMIT_MS 60000 +/* 50msec is the timeout for validity of the cached registers */ +#define PAC1934_MIN_POLLING_TIME_MS 50 +/* + * 1000usec is the minimum wait time for normal conversions when sample + * rate doesn't change + */ +#define PAC1934_MIN_UPDATE_WAIT_TIME_US 1000 + +/* 32000mV */ +#define PAC1934_VOLTAGE_MILLIVOLTS_MAX 32000 +/* voltage bits resolution when set for unsigned values */ +#define PAC1934_VOLTAGE_U_RES 16 +/* voltage bits resolution when set for signed values */ +#define PAC1934_VOLTAGE_S_RES 15 + +/* + * max signed value that can be stored on 32 bits and 8 digits fractional value + * (2^31 - 1) * 10^8 + 99999999 + */ +#define PAC_193X_MAX_POWER_ACC 214748364799999999LL +/* + * min signed value that can be stored on 32 bits and 8 digits fractional value + * -(2^31) * 10^8 - 99999999 + */ +#define PAC_193X_MIN_POWER_ACC -214748364899999999LL + +#define PAC1934_MAX_NUM_CHANNELS 4 + +#define PAC1934_MEAS_REG_LEN 76 +#define PAC1934_CTRL_REG_LEN 12 + +#define PAC1934_DEFAULT_CHIP_SAMP_SPEED_HZ 1024 + +/* I2C address map */ +#define PAC1934_REFRESH_REG_ADDR 0x00 +#define PAC1934_CTRL_REG_ADDR 0x01 +#define PAC1934_ACC_COUNT_REG_ADDR 0x02 +#define PAC1934_VPOWER_ACC_1_ADDR 0x03 +#define PAC1934_VPOWER_ACC_2_ADDR 0x04 +#define PAC1934_VPOWER_ACC_3_ADDR 0x05 +#define PAC1934_VPOWER_ACC_4_ADDR 0x06 +#define PAC1934_VBUS_1_ADDR 0x07 +#define PAC1934_VBUS_2_ADDR 0x08 +#define PAC1934_VBUS_3_ADDR 0x09 +#define PAC1934_VBUS_4_ADDR 0x0A +#define PAC1934_VSENSE_1_ADDR 0x0B +#define PAC1934_VSENSE_2_ADDR 0x0C +#define PAC1934_VSENSE_3_ADDR 0x0D +#define PAC1934_VSENSE_4_ADDR 0x0E +#define PAC1934_VBUS_AVG_1_ADDR 0x0F +#define PAC1934_VBUS_AVG_2_ADDR 0x10 +#define PAC1934_VBUS_AVG_3_ADDR 0x11 +#define PAC1934_VBUS_AVG_4_ADDR 0x12 +#define PAC1934_VSENSE_AVG_1_ADDR 0x13 +#define PAC1934_VSENSE_AVG_2_ADDR 0x14 +#define PAC1934_VSENSE_AVG_3_ADDR 0x15 +#define PAC1934_VSENSE_AVG_4_ADDR 0x16 +#define PAC1934_VPOWER_1_ADDR 0x17 +#define PAC1934_VPOWER_2_ADDR 0x18 +#define PAC1934_VPOWER_3_ADDR 0x19 +#define PAC1934_VPOWER_4_ADDR 0x1A +#define PAC1934_REFRESH_V_REG_ADDR 0x1F +#define PAC1934_CTRL_STAT_REGS_ADDR 0x1C +#define PAC1934_PID_REG_ADDR 0xFD +#define PAC1934_MID_REG_ADDR 0xFE +#define PAC1934_RID_REG_ADDR 0xFF + +/* PRODUCT ID REGISTER + MANUFACTURER ID REGISTER + REVISION ID REGISTER */ +#define PAC1934_ID_REG_LEN 3 +#define PAC1934_PID_IDX 0 +#define PAC1934_MID_IDX 1 +#define PAC1934_RID_IDX 2 + +#define PAC1934_ACPI_GET_NAMES_AND_MOHMS_VALS 1 +#define PAC1934_ACPI_GET_UOHMS_VALS 2 +#define PAC1934_ACPI_GET_BIPOLAR_SETTINGS 4 +#define PAC1934_ACPI_GET_SAMP 5 + +#define PAC1934_SAMPLE_RATE_SHIFT 6 + +#define PAC1934_VBUS_SENSE_REG_LEN 2 +#define PAC1934_ACC_REG_LEN 3 +#define PAC1934_VPOWER_REG_LEN 4 +#define PAC1934_VPOWER_ACC_REG_LEN 6 +#define PAC1934_MAX_REGISTER_LENGTH 6 + +#define PAC1934_CUSTOM_ATTR_FOR_CHANNEL 1 + +/* + * relative offsets when using multi-byte reads/writes even though these + * bytes are read one after the other, they are not at adjacent memory + * locations within the I2C memory map. The chip can skip some addresses + */ +#define PAC1934_CHANNEL_DIS_REG_OFF 0 +#define PAC1934_NEG_PWR_REG_OFF 1 + +/* + * when reading/writing multiple bytes from offset PAC1934_CHANNEL_DIS_REG_OFF, + * the chip jumps over the 0x1E (REFRESH_G) and 0x1F (REFRESH_V) offsets + */ +#define PAC1934_SLOW_REG_OFF 2 +#define PAC1934_CTRL_ACT_REG_OFF 3 +#define PAC1934_CHANNEL_DIS_ACT_REG_OFF 4 +#define PAC1934_NEG_PWR_ACT_REG_OFF 5 +#define PAC1934_CTRL_LAT_REG_OFF 6 +#define PAC1934_CHANNEL_DIS_LAT_REG_OFF 7 +#define PAC1934_NEG_PWR_LAT_REG_OFF 8 +#define PAC1934_PID_REG_OFF 9 +#define PAC1934_MID_REG_OFF 10 +#define PAC1934_REV_REG_OFF 11 +#define PAC1934_CTRL_STATUS_INFO_LEN 12 + +#define PAC1934_MID 0x5D +#define PAC1931_PID 0x58 +#define PAC1932_PID 0x59 +#define PAC1933_PID 0x5A +#define PAC1934_PID 0x5B + +/* Scale constant = (10^3 * 3.2 * 10^9 / 2^28) for mili Watt-second */ +#define PAC1934_SCALE_CONSTANT 11921 + +#define PAC1934_MAX_VPOWER_RSHIFTED_BY_28B 11921 +#define PAC1934_MAX_VSENSE_RSHIFTED_BY_16B 1525 + +#define PAC1934_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr) + +#define PAC1934_CRTL_SAMPLE_RATE_MASK GENMASK(7, 6) +#define PAC1934_CHAN_SLEEP_MASK BIT(5) +#define PAC1934_CHAN_SLEEP_SET BIT(5) +#define PAC1934_CHAN_SINGLE_MASK BIT(4) +#define PAC1934_CHAN_SINGLE_SHOT_SET BIT(4) +#define PAC1934_CHAN_ALERT_MASK BIT(3) +#define PAC1934_CHAN_ALERT_EN BIT(3) +#define PAC1934_CHAN_ALERT_CC_MASK BIT(2) +#define PAC1934_CHAN_ALERT_CC_EN BIT(2) +#define PAC1934_CHAN_OVF_ALERT_MASK BIT(1) +#define PAC1934_CHAN_OVF_ALERT_EN BIT(1) +#define PAC1934_CHAN_OVF_MASK BIT(0) + +#define PAC1934_CHAN_DIS_CH1_OFF_MASK BIT(7) +#define PAC1934_CHAN_DIS_CH2_OFF_MASK BIT(6) +#define PAC1934_CHAN_DIS_CH3_OFF_MASK BIT(5) +#define PAC1934_CHAN_DIS_CH4_OFF_MASK BIT(4) +#define PAC1934_SMBUS_TIMEOUT_MASK BIT(3) +#define PAC1934_SMBUS_BYTECOUNT_MASK BIT(2) +#define PAC1934_SMBUS_NO_SKIP_MASK BIT(1) + +#define PAC1934_NEG_PWR_CH1_BIDI_MASK BIT(7) +#define PAC1934_NEG_PWR_CH2_BIDI_MASK BIT(6) +#define PAC1934_NEG_PWR_CH3_BIDI_MASK BIT(5) +#define PAC1934_NEG_PWR_CH4_BIDI_MASK BIT(4) +#define PAC1934_NEG_PWR_CH1_BIDV_MASK BIT(3) +#define PAC1934_NEG_PWR_CH2_BIDV_MASK BIT(2) +#define PAC1934_NEG_PWR_CH3_BIDV_MASK BIT(1) +#define PAC1934_NEG_PWR_CH4_BIDV_MASK BIT(0) + +/* + * Universal Unique Identifier (UUID), + * 033771E0-1705-47B4-9535-D1BBE14D9A09, + * is reserved to Microchip for the PAC1934. + */ +#define PAC1934_DSM_UUID "033771E0-1705-47B4-9535-D1BBE14D9A09" + +enum pac1934_ids { + PAC1931, + PAC1932, + PAC1933, + PAC1934 +}; + +enum pac1934_samps { + PAC1934_SAMP_1024SPS, + PAC1934_SAMP_256SPS, + PAC1934_SAMP_64SPS, + PAC1934_SAMP_8SPS +}; + +/* + * these indexes are exactly describing the element order within a single + * PAC1934 phys channel IIO channel descriptor; see the static const struct + * iio_chan_spec pac1934_single_channel[] declaration + */ +enum pac1934_ch_idx { + PAC1934_CH_ENERGY, + PAC1934_CH_POWER, + PAC1934_CH_VOLTAGE, + PAC1934_CH_CURRENT, + PAC1934_CH_VOLTAGE_AVERAGE, + PAC1934_CH_CURRENT_AVERAGE +}; + +/** + * struct pac1934_features - features of a pac1934 instance + * @phys_channels: number of physical channels supported by the chip + * @name: chip's name + */ +struct pac1934_features { + u8 phys_channels; + const char *name; +}; + +struct samp_rate_mapping { + u16 samp_rate; + u8 shift2value; +}; + +static const unsigned int samp_rate_map_tbl[] = { + [PAC1934_SAMP_1024SPS] = 1024, + [PAC1934_SAMP_256SPS] = 256, + [PAC1934_SAMP_64SPS] = 64, + [PAC1934_SAMP_8SPS] = 8, +}; + +static const struct pac1934_features pac1934_chip_config[] = { + [PAC1931] = { + .phys_channels = 1, + .name = "pac1931", + }, + [PAC1932] = { + .phys_channels = 2, + .name = "pac1932", + }, + [PAC1933] = { + .phys_channels = 3, + .name = "pac1933", + }, + [PAC1934] = { + .phys_channels = 4, + .name = "pac1934", + }, +}; + +/** + * struct reg_data - data from the registers + * @meas_regs: snapshot of raw measurements registers + * @ctrl_regs: snapshot of control registers + * @energy_sec_acc: snapshot of energy values + * @vpower_acc: accumulated vpower values + * @vpower: snapshot of vpower registers + * @vbus: snapshot of vbus registers + * @vbus_avg: averages of vbus registers + * @vsense: snapshot of vsense registers + * @vsense_avg: averages of vsense registers + * @num_enabled_channels: count of how many chip channels are currently enabled + */ +struct reg_data { + u8 meas_regs[PAC1934_MEAS_REG_LEN]; + u8 ctrl_regs[PAC1934_CTRL_REG_LEN]; + s64 energy_sec_acc[PAC1934_MAX_NUM_CHANNELS]; + s64 vpower_acc[PAC1934_MAX_NUM_CHANNELS]; + s32 vpower[PAC1934_MAX_NUM_CHANNELS]; + s32 vbus[PAC1934_MAX_NUM_CHANNELS]; + s32 vbus_avg[PAC1934_MAX_NUM_CHANNELS]; + s32 vsense[PAC1934_MAX_NUM_CHANNELS]; + s32 vsense_avg[PAC1934_MAX_NUM_CHANNELS]; + u8 num_enabled_channels; +}; + +/** + * struct pac1934_chip_info - information about the chip + * @client: the i2c-client attached to the device + * @lock: synchronize access to driver's state members + * @work_chip_rfsh: work queue used for refresh commands + * @phys_channels: phys channels count + * @active_channels: array of values, true means that channel is active + * @enable_energy: array of values, true means that channel energy is measured + * @bi_dir: array of bools, true means that channel is bidirectional + * @chip_variant: chip variant + * @chip_revision: chip revision + * @shunts: shunts + * @chip_reg_data: chip reg data + * @sample_rate_value: sampling frequency + * @labels: table with channels labels + * @iio_info: iio_info + * @tstamp: chip's uptime + */ +struct pac1934_chip_info { + struct i2c_client *client; + struct mutex lock; /* synchronize access to driver's state members */ + struct delayed_work work_chip_rfsh; + u8 phys_channels; + bool active_channels[PAC1934_MAX_NUM_CHANNELS]; + bool enable_energy[PAC1934_MAX_NUM_CHANNELS]; + bool bi_dir[PAC1934_MAX_NUM_CHANNELS]; + u8 chip_variant; + u8 chip_revision; + u32 shunts[PAC1934_MAX_NUM_CHANNELS]; + struct reg_data chip_reg_data; + s32 sample_rate_value; + char *labels[PAC1934_MAX_NUM_CHANNELS]; + struct iio_info iio_info; + unsigned long tstamp; +}; + +#define TO_PAC1934_CHIP_INFO(d) container_of(d, struct pac1934_chip_info, work_chip_rfsh) + +#define PAC1934_VPOWER_ACC_CHANNEL(_index, _si, _address) { \ + .type = IIO_ENERGY, \ + .address = (_address), \ + .indexed = 1, \ + .channel = (_index), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_ENABLE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = (_si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 48, \ + .storagebits = 64, \ + .endianness = IIO_CPU, \ + } \ +} + +#define PAC1934_VBUS_CHANNEL(_index, _si, _address) { \ + .type = IIO_VOLTAGE, \ + .address = (_address), \ + .indexed = 1, \ + .channel = (_index), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = (_si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + } \ +} + +#define PAC1934_VBUS_AVG_CHANNEL(_index, _si, _address) { \ + .type = IIO_VOLTAGE, \ + .address = (_address), \ + .indexed = 1, \ + .channel = (_index), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_AVERAGE_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = (_si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + } \ +} + +#define PAC1934_VSENSE_CHANNEL(_index, _si, _address) { \ + .type = IIO_CURRENT, \ + .address = (_address), \ + .indexed = 1, \ + .channel = (_index), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = (_si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + } \ +} + +#define PAC1934_VSENSE_AVG_CHANNEL(_index, _si, _address) { \ + .type = IIO_CURRENT, \ + .address = (_address), \ + .indexed = 1, \ + .channel = (_index), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_AVERAGE_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = (_si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + } \ +} + +#define PAC1934_VPOWER_CHANNEL(_index, _si, _address) { \ + .type = IIO_POWER, \ + .address = (_address), \ + .indexed = 1, \ + .channel = (_index), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = (_si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 28, \ + .storagebits = 32, \ + .shift = 4, \ + .endianness = IIO_CPU, \ + } \ +} + +static const struct iio_chan_spec pac1934_single_channel[] = { + PAC1934_VPOWER_ACC_CHANNEL(0, 0, PAC1934_VPOWER_ACC_1_ADDR), + PAC1934_VPOWER_CHANNEL(0, 0, PAC1934_VPOWER_1_ADDR), + PAC1934_VBUS_CHANNEL(0, 0, PAC1934_VBUS_1_ADDR), + PAC1934_VSENSE_CHANNEL(0, 0, PAC1934_VSENSE_1_ADDR), + PAC1934_VBUS_AVG_CHANNEL(0, 0, PAC1934_VBUS_AVG_1_ADDR), + PAC1934_VSENSE_AVG_CHANNEL(0, 0, PAC1934_VSENSE_AVG_1_ADDR), +}; + +/* Low-level I2c functions used to transfer up to 76 bytes at once */ +static int pac1934_i2c_read(struct i2c_client *client, u8 reg_addr, + void *databuf, u8 len) +{ + int ret; + struct i2c_msg msgs[2] = { + { + .addr = client->addr, + .len = 1, + .buf = (u8 *)®_addr, + }, + { + .addr = client->addr, + .len = len, + .buf = databuf, + .flags = I2C_M_RD + } + }; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret < 0) + return ret; + + return 0; +} + +static int pac1934_get_samp_rate_idx(struct pac1934_chip_info *info, + u32 new_samp_rate) +{ + int cnt; + + for (cnt = 0; cnt < ARRAY_SIZE(samp_rate_map_tbl); cnt++) + if (new_samp_rate == samp_rate_map_tbl[cnt]) + return cnt; + + /* not a valid sample rate value */ + return -EINVAL; +} + +static ssize_t pac1934_shunt_value_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct pac1934_chip_info *info = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + return sysfs_emit(buf, "%u\n", info->shunts[this_attr->address]); +} + +static ssize_t pac1934_shunt_value_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct pac1934_chip_info *info = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int sh_val; + + if (kstrtouint(buf, 10, &sh_val)) { + dev_err(dev, "Shunt value is not valid\n"); + return -EINVAL; + } + + scoped_guard(mutex, &info->lock) + info->shunts[this_attr->address] = sh_val; + + return count; +} + +static int pac1934_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *channel, + const int **vals, int *type, int *length, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *type = IIO_VAL_INT; + *vals = samp_rate_map_tbl; + *length = ARRAY_SIZE(samp_rate_map_tbl); + return IIO_AVAIL_LIST; + } + + return -EINVAL; +} + +static int pac1934_send_refresh(struct pac1934_chip_info *info, + u8 refresh_cmd, u32 wait_time) +{ + /* this function only sends REFRESH or REFRESH_V */ + struct i2c_client *client = info->client; + int ret; + u8 bidir_reg; + bool revision_bug = false; + + if (info->chip_revision == 2 || info->chip_revision == 3) { + /* + * chip rev 2 and 3 bug workaround + * see: PAC1934 Family Data Sheet Errata DS80000836A.pdf + */ + revision_bug = true; + + bidir_reg = + FIELD_PREP(PAC1934_NEG_PWR_CH1_BIDI_MASK, info->bi_dir[0]) | + FIELD_PREP(PAC1934_NEG_PWR_CH2_BIDI_MASK, info->bi_dir[1]) | + FIELD_PREP(PAC1934_NEG_PWR_CH3_BIDI_MASK, info->bi_dir[2]) | + FIELD_PREP(PAC1934_NEG_PWR_CH4_BIDI_MASK, info->bi_dir[3]) | + FIELD_PREP(PAC1934_NEG_PWR_CH1_BIDV_MASK, info->bi_dir[0]) | + FIELD_PREP(PAC1934_NEG_PWR_CH2_BIDV_MASK, info->bi_dir[1]) | + FIELD_PREP(PAC1934_NEG_PWR_CH3_BIDV_MASK, info->bi_dir[2]) | + FIELD_PREP(PAC1934_NEG_PWR_CH4_BIDV_MASK, info->bi_dir[3]); + + ret = i2c_smbus_write_byte_data(client, + PAC1934_CTRL_STAT_REGS_ADDR + + PAC1934_NEG_PWR_REG_OFF, + bidir_reg); + if (ret) + return ret; + } + + ret = i2c_smbus_write_byte(client, refresh_cmd); + if (ret) { + dev_err(&client->dev, "%s - cannot send 0x%02X\n", + __func__, refresh_cmd); + return ret; + } + + if (revision_bug) { + /* + * chip rev 2 and 3 bug workaround - write again the same + * register write the updated registers back + */ + ret = i2c_smbus_write_byte_data(client, + PAC1934_CTRL_STAT_REGS_ADDR + + PAC1934_NEG_PWR_REG_OFF, bidir_reg); + if (ret) + return ret; + } + + /* register data retrieval timestamp */ + info->tstamp = jiffies; + + /* wait till the data is available */ + usleep_range(wait_time, wait_time + 100); + + return ret; +} + +static int pac1934_reg_snapshot(struct pac1934_chip_info *info, + bool do_refresh, u8 refresh_cmd, u32 wait_time) +{ + int ret; + struct i2c_client *client = info->client; + u8 samp_shift, ctrl_regs_tmp; + u8 *offset_reg_data_p; + u16 tmp_value; + u32 samp_rate, cnt, tmp; + s64 curr_energy, inc; + u64 tmp_energy; + struct reg_data *reg_data; + + guard(mutex)(&info->lock); + + if (do_refresh) { + ret = pac1934_send_refresh(info, refresh_cmd, wait_time); + if (ret < 0) { + dev_err(&client->dev, + "%s - cannot send refresh\n", + __func__); + return ret; + } + } + + ret = i2c_smbus_read_i2c_block_data(client, PAC1934_CTRL_STAT_REGS_ADDR, + PAC1934_CTRL_REG_LEN, + (u8 *)info->chip_reg_data.ctrl_regs); + if (ret < 0) { + dev_err(&client->dev, + "%s - cannot read ctrl/status registers\n", + __func__); + return ret; + } + + reg_data = &info->chip_reg_data; + + /* read the data registers */ + ret = pac1934_i2c_read(client, PAC1934_ACC_COUNT_REG_ADDR, + (u8 *)reg_data->meas_regs, PAC1934_MEAS_REG_LEN); + if (ret) { + dev_err(&client->dev, + "%s - cannot read ACC_COUNT register: %d:%d\n", + __func__, ret, PAC1934_MEAS_REG_LEN); + return ret; + } + + /* see how much shift is required by the sample rate */ + samp_rate = samp_rate_map_tbl[((reg_data->ctrl_regs[PAC1934_CTRL_LAT_REG_OFF]) >> 6)]; + samp_shift = get_count_order(samp_rate); + + ctrl_regs_tmp = reg_data->ctrl_regs[PAC1934_CHANNEL_DIS_LAT_REG_OFF]; + offset_reg_data_p = ®_data->meas_regs[PAC1934_ACC_REG_LEN]; + + /* start with VPOWER_ACC */ + for (cnt = 0; cnt < info->phys_channels; cnt++) { + /* check if the channel is active, skip all fields if disabled */ + if ((ctrl_regs_tmp << cnt) & 0x80) + continue; + + /* skip if the energy accumulation is disabled */ + if (info->enable_energy[cnt]) { + curr_energy = info->chip_reg_data.energy_sec_acc[cnt]; + + tmp_energy = get_unaligned_be48(offset_reg_data_p); + + if (info->bi_dir[cnt]) + reg_data->vpower_acc[cnt] = sign_extend64(tmp_energy, 47); + else + reg_data->vpower_acc[cnt] = tmp_energy; + + /* + * compute the scaled to 1 second accumulated energy value; + * energy accumulator scaled to 1sec = VPOWER_ACC/2^samp_shift + * the chip's sampling rate is 2^samp_shift samples/sec + */ + inc = (reg_data->vpower_acc[cnt] >> samp_shift); + + /* add the power_acc field */ + curr_energy += inc; + + clamp(curr_energy, PAC_193X_MIN_POWER_ACC, PAC_193X_MAX_POWER_ACC); + + reg_data->energy_sec_acc[cnt] = curr_energy; + } + + offset_reg_data_p += PAC1934_VPOWER_ACC_REG_LEN; + } + + /* continue with VBUS */ + for (cnt = 0; cnt < info->phys_channels; cnt++) { + if ((ctrl_regs_tmp << cnt) & 0x80) + continue; + + tmp_value = get_unaligned_be16(offset_reg_data_p); + + if (info->bi_dir[cnt]) + reg_data->vbus[cnt] = sign_extend32((u32)(tmp_value), 15); + else + reg_data->vbus[cnt] = tmp_value; + + offset_reg_data_p += PAC1934_VBUS_SENSE_REG_LEN; + } + + /* VSENSE */ + for (cnt = 0; cnt < info->phys_channels; cnt++) { + if ((ctrl_regs_tmp << cnt) & 0x80) + continue; + + tmp_value = get_unaligned_be16(offset_reg_data_p); + + if (info->bi_dir[cnt]) + reg_data->vsense[cnt] = sign_extend32((u32)(tmp_value), 15); + else + reg_data->vsense[cnt] = tmp_value; + + offset_reg_data_p += PAC1934_VBUS_SENSE_REG_LEN; + } + + /* VBUS_AVG */ + for (cnt = 0; cnt < info->phys_channels; cnt++) { + if ((ctrl_regs_tmp << cnt) & 0x80) + continue; + + tmp_value = get_unaligned_be16(offset_reg_data_p); + + if (info->bi_dir[cnt]) + reg_data->vbus_avg[cnt] = sign_extend32((u32)(tmp_value), 15); + else + reg_data->vbus_avg[cnt] = tmp_value; + + offset_reg_data_p += PAC1934_VBUS_SENSE_REG_LEN; + } + + /* VSENSE_AVG */ + for (cnt = 0; cnt < info->phys_channels; cnt++) { + if ((ctrl_regs_tmp << cnt) & 0x80) + continue; + + tmp_value = get_unaligned_be16(offset_reg_data_p); + + if (info->bi_dir[cnt]) + reg_data->vsense_avg[cnt] = sign_extend32((u32)(tmp_value), 15); + else + reg_data->vsense_avg[cnt] = tmp_value; + + offset_reg_data_p += PAC1934_VBUS_SENSE_REG_LEN; + } + + /* VPOWER */ + for (cnt = 0; cnt < info->phys_channels; cnt++) { + if ((ctrl_regs_tmp << cnt) & 0x80) + continue; + + tmp = get_unaligned_be32(offset_reg_data_p) >> 4; + + if (info->bi_dir[cnt]) + reg_data->vpower[cnt] = sign_extend32(tmp, 27); + else + reg_data->vpower[cnt] = tmp; + + offset_reg_data_p += PAC1934_VPOWER_REG_LEN; + } + + return 0; +} + +static int pac1934_retrieve_data(struct pac1934_chip_info *info, + u32 wait_time) +{ + int ret = 0; + + /* + * check if the minimal elapsed time has passed and if so, + * re-read the chip, otherwise the cached info is just fine + */ + if (time_after(jiffies, info->tstamp + msecs_to_jiffies(PAC1934_MIN_POLLING_TIME_MS))) { + ret = pac1934_reg_snapshot(info, true, PAC1934_REFRESH_REG_ADDR, + wait_time); + + /* + * Re-schedule the work for the read registers on timeout + * (to prevent chip registers saturation) + */ + mod_delayed_work(system_wq, &info->work_chip_rfsh, + msecs_to_jiffies(PAC1934_MAX_RFSH_LIMIT_MS)); + } + + return ret; +} + +static int pac1934_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct pac1934_chip_info *info = iio_priv(indio_dev); + s64 curr_energy; + int ret, channel = chan->channel - 1; + + ret = pac1934_retrieve_data(info, PAC1934_MIN_UPDATE_WAIT_TIME_US); + if (ret < 0) + return ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_VOLTAGE: + *val = info->chip_reg_data.vbus[channel]; + return IIO_VAL_INT; + case IIO_CURRENT: + *val = info->chip_reg_data.vsense[channel]; + return IIO_VAL_INT; + case IIO_POWER: + *val = info->chip_reg_data.vpower[channel]; + return IIO_VAL_INT; + case IIO_ENERGY: + curr_energy = info->chip_reg_data.energy_sec_acc[channel]; + *val = (u32)curr_energy; + *val2 = (u32)(curr_energy >> 32); + return IIO_VAL_INT_64; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_AVERAGE_RAW: + switch (chan->type) { + case IIO_VOLTAGE: + *val = info->chip_reg_data.vbus_avg[channel]; + return IIO_VAL_INT; + case IIO_CURRENT: + *val = info->chip_reg_data.vsense_avg[channel]; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SCALE: + switch (chan->address) { + /* Voltages - scale for millivolts */ + case PAC1934_VBUS_1_ADDR: + case PAC1934_VBUS_2_ADDR: + case PAC1934_VBUS_3_ADDR: + case PAC1934_VBUS_4_ADDR: + case PAC1934_VBUS_AVG_1_ADDR: + case PAC1934_VBUS_AVG_2_ADDR: + case PAC1934_VBUS_AVG_3_ADDR: + case PAC1934_VBUS_AVG_4_ADDR: + *val = PAC1934_VOLTAGE_MILLIVOLTS_MAX; + if (chan->scan_type.sign == 'u') + *val2 = PAC1934_VOLTAGE_U_RES; + else + *val2 = PAC1934_VOLTAGE_S_RES; + return IIO_VAL_FRACTIONAL_LOG2; + /* + * Currents - scale for mA - depends on the + * channel's shunt value + * (100mV * 1000000) / (2^16 * shunt(uohm)) + */ + case PAC1934_VSENSE_1_ADDR: + case PAC1934_VSENSE_2_ADDR: + case PAC1934_VSENSE_3_ADDR: + case PAC1934_VSENSE_4_ADDR: + case PAC1934_VSENSE_AVG_1_ADDR: + case PAC1934_VSENSE_AVG_2_ADDR: + case PAC1934_VSENSE_AVG_3_ADDR: + case PAC1934_VSENSE_AVG_4_ADDR: + *val = PAC1934_MAX_VSENSE_RSHIFTED_BY_16B; + if (chan->scan_type.sign == 'u') + *val2 = info->shunts[channel]; + else + *val2 = info->shunts[channel] >> 1; + return IIO_VAL_FRACTIONAL; + /* + * Power - uW - it will use the combined scale + * for current and voltage + * current(mA) * voltage(mV) = power (uW) + */ + case PAC1934_VPOWER_1_ADDR: + case PAC1934_VPOWER_2_ADDR: + case PAC1934_VPOWER_3_ADDR: + case PAC1934_VPOWER_4_ADDR: + *val = PAC1934_MAX_VPOWER_RSHIFTED_BY_28B; + if (chan->scan_type.sign == 'u') + *val2 = info->shunts[channel]; + else + *val2 = info->shunts[channel] >> 1; + return IIO_VAL_FRACTIONAL; + case PAC1934_VPOWER_ACC_1_ADDR: + case PAC1934_VPOWER_ACC_2_ADDR: + case PAC1934_VPOWER_ACC_3_ADDR: + case PAC1934_VPOWER_ACC_4_ADDR: + /* + * expresses the 32 bit scale value here compute + * the scale for energy (miliWatt-second or miliJoule) + */ + *val = PAC1934_SCALE_CONSTANT; + + if (chan->scan_type.sign == 'u') + *val2 = info->shunts[channel]; + else + *val2 = info->shunts[channel] >> 1; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SAMP_FREQ: + *val = info->sample_rate_value; + return IIO_VAL_INT; + case IIO_CHAN_INFO_ENABLE: + *val = info->enable_energy[channel]; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int pac1934_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct pac1934_chip_info *info = iio_priv(indio_dev); + struct i2c_client *client = info->client; + int ret = -EINVAL; + s32 old_samp_rate; + u8 ctrl_reg; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + ret = pac1934_get_samp_rate_idx(info, val); + if (ret < 0) + return ret; + + /* write the new sampling value and trigger a snapshot(incl refresh) */ + scoped_guard(mutex, &info->lock) { + ctrl_reg = FIELD_PREP(PAC1934_CRTL_SAMPLE_RATE_MASK, ret); + ret = i2c_smbus_write_byte_data(client, PAC1934_CTRL_REG_ADDR, ctrl_reg); + if (ret) { + dev_err(&client->dev, + "%s - can't update sample rate\n", + __func__); + return ret; + } + } + + old_samp_rate = info->sample_rate_value; + info->sample_rate_value = val; + + /* + * now, force a snapshot with refresh - call retrieve + * data in order to update the refresh timer + * alter the timestamp in order to force trigger a + * register snapshot and a timestamp update + */ + info->tstamp -= msecs_to_jiffies(PAC1934_MIN_POLLING_TIME_MS); + ret = pac1934_retrieve_data(info, (1024 / old_samp_rate) * 1000); + if (ret < 0) { + dev_err(&client->dev, + "%s - cannot snapshot ctrl and measurement regs\n", + __func__); + return ret; + } + + return 0; + case IIO_CHAN_INFO_ENABLE: + scoped_guard(mutex, &info->lock) { + info->enable_energy[chan->channel - 1] = val ? true : false; + if (!val) + info->chip_reg_data.energy_sec_acc[chan->channel - 1] = 0; + } + + return 0; + default: + return -EINVAL; + } +} + +static int pac1934_read_label(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, char *label) +{ + struct pac1934_chip_info *info = iio_priv(indio_dev); + + switch (chan->address) { + case PAC1934_VBUS_1_ADDR: + case PAC1934_VBUS_2_ADDR: + case PAC1934_VBUS_3_ADDR: + case PAC1934_VBUS_4_ADDR: + return sysfs_emit(label, "%s_VBUS_%d\n", + info->labels[chan->scan_index], + chan->scan_index + 1); + case PAC1934_VBUS_AVG_1_ADDR: + case PAC1934_VBUS_AVG_2_ADDR: + case PAC1934_VBUS_AVG_3_ADDR: + case PAC1934_VBUS_AVG_4_ADDR: + return sysfs_emit(label, "%s_VBUS_AVG_%d\n", + info->labels[chan->scan_index], + chan->scan_index + 1); + case PAC1934_VSENSE_1_ADDR: + case PAC1934_VSENSE_2_ADDR: + case PAC1934_VSENSE_3_ADDR: + case PAC1934_VSENSE_4_ADDR: + return sysfs_emit(label, "%s_IBUS_%d\n", + info->labels[chan->scan_index], + chan->scan_index + 1); + case PAC1934_VSENSE_AVG_1_ADDR: + case PAC1934_VSENSE_AVG_2_ADDR: + case PAC1934_VSENSE_AVG_3_ADDR: + case PAC1934_VSENSE_AVG_4_ADDR: + return sysfs_emit(label, "%s_IBUS_AVG_%d\n", + info->labels[chan->scan_index], + chan->scan_index + 1); + case PAC1934_VPOWER_1_ADDR: + case PAC1934_VPOWER_2_ADDR: + case PAC1934_VPOWER_3_ADDR: + case PAC1934_VPOWER_4_ADDR: + return sysfs_emit(label, "%s_POWER_%d\n", + info->labels[chan->scan_index], + chan->scan_index + 1); + case PAC1934_VPOWER_ACC_1_ADDR: + case PAC1934_VPOWER_ACC_2_ADDR: + case PAC1934_VPOWER_ACC_3_ADDR: + case PAC1934_VPOWER_ACC_4_ADDR: + return sysfs_emit(label, "%s_ENERGY_%d\n", + info->labels[chan->scan_index], + chan->scan_index + 1); + } + + return 0; +} + +static void pac1934_work_periodic_rfsh(struct work_struct *work) +{ + struct pac1934_chip_info *info = TO_PAC1934_CHIP_INFO((struct delayed_work *)work); + struct device *dev = &info->client->dev; + + dev_dbg(dev, "%s - Periodic refresh\n", __func__); + + /* do a REFRESH, then read */ + pac1934_reg_snapshot(info, true, PAC1934_REFRESH_REG_ADDR, + PAC1934_MIN_UPDATE_WAIT_TIME_US); + + schedule_delayed_work(&info->work_chip_rfsh, + msecs_to_jiffies(PAC1934_MAX_RFSH_LIMIT_MS)); +} + +static int pac1934_read_revision(struct pac1934_chip_info *info, u8 *buf) +{ + int ret; + struct i2c_client *client = info->client; + + ret = i2c_smbus_read_i2c_block_data(client, PAC1934_PID_REG_ADDR, + PAC1934_ID_REG_LEN, + buf); + if (ret < 0) { + dev_err(&client->dev, "cannot read revision\n"); + return ret; + } + + return 0; +} + +static int pac1934_chip_identify(struct pac1934_chip_info *info) +{ + u8 rev_info[PAC1934_ID_REG_LEN]; + struct device *dev = &info->client->dev; + int ret = 0; + + ret = pac1934_read_revision(info, (u8 *)rev_info); + if (ret) + return ret; + + info->chip_variant = rev_info[PAC1934_PID_IDX]; + info->chip_revision = rev_info[PAC1934_RID_IDX]; + + dev_dbg(dev, "Chip variant: 0x%02X\n", info->chip_variant); + dev_dbg(dev, "Chip revision: 0x%02X\n", info->chip_revision); + + switch (info->chip_variant) { + case PAC1934_PID: + return PAC1934; + case PAC1933_PID: + return PAC1933; + case PAC1932_PID: + return PAC1932; + case PAC1931_PID: + return PAC1931; + default: + return -EINVAL; + } +} + +/* + * documentation related to the ACPI device definition + * https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ApplicationNotes/ApplicationNotes/PAC1934-Integration-Notes-for-Microsoft-Windows-10-and-Windows-11-Driver-Support-DS00002534.pdf + */ +static bool pac1934_acpi_parse_channel_config(struct i2c_client *client, + struct pac1934_chip_info *info) +{ + acpi_handle handle; + union acpi_object *rez; + struct device *dev = &client->dev; + unsigned short bi_dir_mask; + int idx, i; + guid_t guid; + + handle = ACPI_HANDLE(dev); + + guid_parse(PAC1934_DSM_UUID, &guid); + + rez = acpi_evaluate_dsm(handle, &guid, 0, PAC1934_ACPI_GET_NAMES_AND_MOHMS_VALS, NULL); + if (!rez) + return false; + + for (i = 0; i < rez->package.count; i += 2) { + idx = i / 2; + info->labels[idx] = + devm_kmemdup(dev, rez->package.elements[i].string.pointer, + (size_t)rez->package.elements[i].string.length + 1, + GFP_KERNEL); + info->labels[idx][rez->package.elements[i].string.length] = '\0'; + info->shunts[idx] = rez->package.elements[i + 1].integer.value * 1000; + info->active_channels[idx] = (info->shunts[idx] != 0); + } + + ACPI_FREE(rez); + + rez = acpi_evaluate_dsm(handle, &guid, 1, PAC1934_ACPI_GET_UOHMS_VALS, NULL); + if (!rez) { + /* + * initializing with default values + * we assume all channels are unidirectional(the mask is zero) + * and assign the default sampling rate + */ + info->sample_rate_value = PAC1934_DEFAULT_CHIP_SAMP_SPEED_HZ; + return true; + } + + for (i = 0; i < rez->package.count; i++) { + idx = i; + info->shunts[idx] = rez->package.elements[i].integer.value; + info->active_channels[idx] = (info->shunts[idx] != 0); + } + + ACPI_FREE(rez); + + rez = acpi_evaluate_dsm(handle, &guid, 1, PAC1934_ACPI_GET_BIPOLAR_SETTINGS, NULL); + if (!rez) + return false; + + bi_dir_mask = rez->package.elements[0].integer.value; + info->bi_dir[0] = ((bi_dir_mask & (1 << 3)) | (bi_dir_mask & (1 << 7))) != 0; + info->bi_dir[1] = ((bi_dir_mask & (1 << 2)) | (bi_dir_mask & (1 << 6))) != 0; + info->bi_dir[2] = ((bi_dir_mask & (1 << 1)) | (bi_dir_mask & (1 << 5))) != 0; + info->bi_dir[3] = ((bi_dir_mask & (1 << 0)) | (bi_dir_mask & (1 << 4))) != 0; + + ACPI_FREE(rez); + + rez = acpi_evaluate_dsm(handle, &guid, 1, PAC1934_ACPI_GET_SAMP, NULL); + if (!rez) + return false; + + info->sample_rate_value = rez->package.elements[0].integer.value; + + ACPI_FREE(rez); + + return true; +} + +static bool pac1934_of_parse_channel_config(struct i2c_client *client, + struct pac1934_chip_info *info) +{ + struct fwnode_handle *node, *fwnode; + struct device *dev = &client->dev; + unsigned int current_channel; + int idx, ret; + + info->sample_rate_value = 1024; + current_channel = 1; + + fwnode = dev_fwnode(dev); + fwnode_for_each_available_child_node(fwnode, node) { + ret = fwnode_property_read_u32(node, "reg", &idx); + if (ret) { + dev_err_probe(dev, ret, + "reading invalid channel index\n"); + goto err_fwnode; + } + /* adjust idx to match channel index (1 to 4) from the datasheet */ + idx--; + + if (current_channel >= (info->phys_channels + 1) || + idx >= info->phys_channels || idx < 0) { + dev_err_probe(dev, -EINVAL, + "%s: invalid channel_index %d value\n", + fwnode_get_name(node), idx); + goto err_fwnode; + } + + /* enable channel */ + info->active_channels[idx] = true; + + ret = fwnode_property_read_u32(node, "shunt-resistor-micro-ohms", + &info->shunts[idx]); + if (ret) { + dev_err_probe(dev, ret, + "%s: invalid shunt-resistor value: %d\n", + fwnode_get_name(node), info->shunts[idx]); + goto err_fwnode; + } + + if (fwnode_property_present(node, "label")) { + ret = fwnode_property_read_string(node, "label", + (const char **)&info->labels[idx]); + if (ret) { + dev_err_probe(dev, ret, + "%s: invalid rail-name value\n", + fwnode_get_name(node)); + goto err_fwnode; + } + } + + info->bi_dir[idx] = fwnode_property_read_bool(node, "bipolar"); + + current_channel++; + } + + return true; + +err_fwnode: + fwnode_handle_put(node); + + return false; +} + +static void pac1934_cancel_delayed_work(void *dwork) +{ + cancel_delayed_work_sync(dwork); +} + +static int pac1934_chip_configure(struct pac1934_chip_info *info) +{ + int cnt, ret; + struct i2c_client *client = info->client; + u8 regs[PAC1934_CTRL_STATUS_INFO_LEN], idx, ctrl_reg; + u32 wait_time; + + info->chip_reg_data.num_enabled_channels = 0; + for (cnt = 0; cnt < info->phys_channels; cnt++) { + if (info->active_channels[cnt]) + info->chip_reg_data.num_enabled_channels++; + } + + /* + * read whatever information was gathered before the driver was loaded + * establish which channels are enabled/disabled and then establish the + * information retrieval mode (using SKIP or no). + * Read the chip ID values + */ + ret = i2c_smbus_read_i2c_block_data(client, PAC1934_CTRL_STAT_REGS_ADDR, + ARRAY_SIZE(regs), + (u8 *)regs); + if (ret < 0) { + dev_err_probe(&client->dev, ret, + "%s - cannot read regs from 0x%02X\n", + __func__, PAC1934_CTRL_STAT_REGS_ADDR); + return ret; + } + + /* write the CHANNEL_DIS and the NEG_PWR registers */ + regs[PAC1934_CHANNEL_DIS_REG_OFF] = + FIELD_PREP(PAC1934_CHAN_DIS_CH1_OFF_MASK, info->active_channels[0] ? 0 : 1) | + FIELD_PREP(PAC1934_CHAN_DIS_CH2_OFF_MASK, info->active_channels[1] ? 0 : 1) | + FIELD_PREP(PAC1934_CHAN_DIS_CH3_OFF_MASK, info->active_channels[2] ? 0 : 1) | + FIELD_PREP(PAC1934_CHAN_DIS_CH4_OFF_MASK, info->active_channels[3] ? 0 : 1) | + FIELD_PREP(PAC1934_SMBUS_TIMEOUT_MASK, 0) | + FIELD_PREP(PAC1934_SMBUS_BYTECOUNT_MASK, 0) | + FIELD_PREP(PAC1934_SMBUS_NO_SKIP_MASK, 0); + + regs[PAC1934_NEG_PWR_REG_OFF] = + FIELD_PREP(PAC1934_NEG_PWR_CH1_BIDI_MASK, info->bi_dir[0]) | + FIELD_PREP(PAC1934_NEG_PWR_CH2_BIDI_MASK, info->bi_dir[1]) | + FIELD_PREP(PAC1934_NEG_PWR_CH3_BIDI_MASK, info->bi_dir[2]) | + FIELD_PREP(PAC1934_NEG_PWR_CH4_BIDI_MASK, info->bi_dir[3]) | + FIELD_PREP(PAC1934_NEG_PWR_CH1_BIDV_MASK, info->bi_dir[0]) | + FIELD_PREP(PAC1934_NEG_PWR_CH2_BIDV_MASK, info->bi_dir[1]) | + FIELD_PREP(PAC1934_NEG_PWR_CH3_BIDV_MASK, info->bi_dir[2]) | + FIELD_PREP(PAC1934_NEG_PWR_CH4_BIDV_MASK, info->bi_dir[3]); + + /* no SLOW triggered REFRESH, clear POR */ + regs[PAC1934_SLOW_REG_OFF] = 0; + + ret = i2c_smbus_write_block_data(client, PAC1934_CTRL_STAT_REGS_ADDR, + ARRAY_SIZE(regs), (u8 *)regs); + if (ret) + return ret; + + /* Default sampling rate */ + ctrl_reg = FIELD_PREP(PAC1934_CRTL_SAMPLE_RATE_MASK, PAC1934_SAMP_1024SPS); + + ret = i2c_smbus_write_byte_data(client, PAC1934_CTRL_REG_ADDR, ctrl_reg); + if (ret) + return ret; + + /* + * send a REFRESH to the chip, so the new settings take place + * as well as resetting the accumulators + */ + ret = i2c_smbus_write_byte(client, PAC1934_REFRESH_REG_ADDR); + if (ret) { + dev_err(&client->dev, + "%s - cannot send 0x%02X\n", + __func__, PAC1934_REFRESH_REG_ADDR); + return ret; + } + + /* + * get the current(in the chip) sampling speed and compute the + * required timeout based on its value + * the timeout is 1/sampling_speed + */ + idx = regs[PAC1934_CTRL_ACT_REG_OFF] >> PAC1934_SAMPLE_RATE_SHIFT; + wait_time = (1024 / samp_rate_map_tbl[idx]) * 1000; + + /* + * wait the maximum amount of time to be on the safe side + * the maximum wait time is for 8sps + */ + usleep_range(wait_time, wait_time + 100); + + INIT_DELAYED_WORK(&info->work_chip_rfsh, pac1934_work_periodic_rfsh); + /* Setup the latest moment for reading the regs before saturation */ + schedule_delayed_work(&info->work_chip_rfsh, + msecs_to_jiffies(PAC1934_MAX_RFSH_LIMIT_MS)); + + return devm_add_action_or_reset(&client->dev, pac1934_cancel_delayed_work, + &info->work_chip_rfsh); +} + +static int pac1934_prep_iio_channels(struct pac1934_chip_info *info, struct iio_dev *indio_dev) +{ + struct iio_chan_spec *ch_sp; + int channel_size, attribute_count, cnt; + void *dyn_ch_struct, *tmp_data; + struct device *dev = &info->client->dev; + + /* find out dynamically how many IIO channels we need */ + attribute_count = 0; + channel_size = 0; + for (cnt = 0; cnt < info->phys_channels; cnt++) { + if (!info->active_channels[cnt]) + continue; + + /* add the size of the properties of one chip physical channel */ + channel_size += sizeof(pac1934_single_channel); + /* count how many enabled channels we have */ + attribute_count += ARRAY_SIZE(pac1934_single_channel); + dev_dbg(dev, ":%s: Channel %d active\n", __func__, cnt + 1); + } + + dyn_ch_struct = devm_kzalloc(dev, channel_size, GFP_KERNEL); + if (!dyn_ch_struct) + return -EINVAL; + + tmp_data = dyn_ch_struct; + + /* populate the dynamic channels and make all the adjustments */ + for (cnt = 0; cnt < info->phys_channels; cnt++) { + if (!info->active_channels[cnt]) + continue; + + memcpy(tmp_data, pac1934_single_channel, sizeof(pac1934_single_channel)); + ch_sp = (struct iio_chan_spec *)tmp_data; + ch_sp[PAC1934_CH_ENERGY].channel = cnt + 1; + ch_sp[PAC1934_CH_ENERGY].scan_index = cnt; + ch_sp[PAC1934_CH_ENERGY].address = cnt + PAC1934_VPOWER_ACC_1_ADDR; + ch_sp[PAC1934_CH_POWER].channel = cnt + 1; + ch_sp[PAC1934_CH_POWER].scan_index = cnt; + ch_sp[PAC1934_CH_POWER].address = cnt + PAC1934_VPOWER_1_ADDR; + ch_sp[PAC1934_CH_VOLTAGE].channel = cnt + 1; + ch_sp[PAC1934_CH_VOLTAGE].scan_index = cnt; + ch_sp[PAC1934_CH_VOLTAGE].address = cnt + PAC1934_VBUS_1_ADDR; + ch_sp[PAC1934_CH_CURRENT].channel = cnt + 1; + ch_sp[PAC1934_CH_CURRENT].scan_index = cnt; + ch_sp[PAC1934_CH_CURRENT].address = cnt + PAC1934_VSENSE_1_ADDR; + + /* + * In order to be able to use labels for PAC1934_CH_VOLTAGE, and + * PAC1934_CH_VOLTAGE_AVERAGE,respectively PAC1934_CH_CURRENT + * and PAC1934_CH_CURRENT_AVERAGE we need to use different + * channel numbers. We will add +5 (+1 to maximum PAC channels). + */ + ch_sp[PAC1934_CH_VOLTAGE_AVERAGE].channel = cnt + 5; + ch_sp[PAC1934_CH_VOLTAGE_AVERAGE].scan_index = cnt; + ch_sp[PAC1934_CH_VOLTAGE_AVERAGE].address = cnt + PAC1934_VBUS_AVG_1_ADDR; + ch_sp[PAC1934_CH_CURRENT_AVERAGE].channel = cnt + 5; + ch_sp[PAC1934_CH_CURRENT_AVERAGE].scan_index = cnt; + ch_sp[PAC1934_CH_CURRENT_AVERAGE].address = cnt + PAC1934_VSENSE_AVG_1_ADDR; + + /* + * now modify the parameters in all channels if the + * whole chip rail(channel) is bi-directional + */ + if (info->bi_dir[cnt]) { + ch_sp[PAC1934_CH_ENERGY].scan_type.sign = 's'; + ch_sp[PAC1934_CH_ENERGY].scan_type.realbits = 47; + ch_sp[PAC1934_CH_POWER].scan_type.sign = 's'; + ch_sp[PAC1934_CH_POWER].scan_type.realbits = 27; + ch_sp[PAC1934_CH_VOLTAGE].scan_type.sign = 's'; + ch_sp[PAC1934_CH_VOLTAGE].scan_type.realbits = 15; + ch_sp[PAC1934_CH_CURRENT].scan_type.sign = 's'; + ch_sp[PAC1934_CH_CURRENT].scan_type.realbits = 15; + ch_sp[PAC1934_CH_VOLTAGE_AVERAGE].scan_type.sign = 's'; + ch_sp[PAC1934_CH_VOLTAGE_AVERAGE].scan_type.realbits = 15; + ch_sp[PAC1934_CH_CURRENT_AVERAGE].scan_type.sign = 's'; + ch_sp[PAC1934_CH_CURRENT_AVERAGE].scan_type.realbits = 15; + } + tmp_data += sizeof(pac1934_single_channel); + } + + /* + * send the updated dynamic channel structure information towards IIO + * prepare the required field for IIO class registration + */ + indio_dev->num_channels = attribute_count; + indio_dev->channels = (const struct iio_chan_spec *)dyn_ch_struct; + + return 0; +} + +static IIO_DEVICE_ATTR(in_shunt_resistor1, 0644, + pac1934_shunt_value_show, pac1934_shunt_value_store, 0); +static IIO_DEVICE_ATTR(in_shunt_resistor2, 0644, + pac1934_shunt_value_show, pac1934_shunt_value_store, 1); +static IIO_DEVICE_ATTR(in_shunt_resistor3, 0644, + pac1934_shunt_value_show, pac1934_shunt_value_store, 2); +static IIO_DEVICE_ATTR(in_shunt_resistor4, 0644, + pac1934_shunt_value_show, pac1934_shunt_value_store, 3); + +static int pac1934_prep_custom_attributes(struct pac1934_chip_info *info, + struct iio_dev *indio_dev) +{ + int i, active_channels_count = 0; + struct attribute **pac1934_custom_attr; + struct attribute_group *pac1934_group; + struct device *dev = &info->client->dev; + + for (i = 0 ; i < info->phys_channels; i++) + if (info->active_channels[i]) + active_channels_count++; + + pac1934_group = devm_kzalloc(dev, sizeof(*pac1934_group), GFP_KERNEL); + if (!pac1934_group) + return -ENOMEM; + + pac1934_custom_attr = devm_kzalloc(dev, + (PAC1934_CUSTOM_ATTR_FOR_CHANNEL * + active_channels_count) + * sizeof(*pac1934_group) + 1, + GFP_KERNEL); + if (!pac1934_custom_attr) + return -ENOMEM; + + i = 0; + if (info->active_channels[0]) + pac1934_custom_attr[i++] = PAC1934_DEV_ATTR(in_shunt_resistor1); + + if (info->active_channels[1]) + pac1934_custom_attr[i++] = PAC1934_DEV_ATTR(in_shunt_resistor2); + + if (info->active_channels[2]) + pac1934_custom_attr[i++] = PAC1934_DEV_ATTR(in_shunt_resistor3); + + if (info->active_channels[3]) + pac1934_custom_attr[i] = PAC1934_DEV_ATTR(in_shunt_resistor4); + + pac1934_group->attrs = pac1934_custom_attr; + info->iio_info.attrs = pac1934_group; + + return 0; +} + +static void pac1934_mutex_destroy(void *data) +{ + struct mutex *lock = data; + + mutex_destroy(lock); +} + +static const struct iio_info pac1934_info = { + .read_raw = pac1934_read_raw, + .write_raw = pac1934_write_raw, + .read_avail = pac1934_read_avail, + .read_label = pac1934_read_label, +}; + +static int pac1934_probe(struct i2c_client *client) +{ + struct pac1934_chip_info *info; + const struct pac1934_features *chip; + struct iio_dev *indio_dev; + int cnt, ret; + bool match = false; + struct device *dev = &client->dev; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*info)); + if (!indio_dev) + return -ENOMEM; + + info = iio_priv(indio_dev); + + info->client = client; + + /* always start with energy accumulation enabled */ + for (cnt = 0; cnt < PAC1934_MAX_NUM_CHANNELS; cnt++) + info->enable_energy[cnt] = true; + + ret = pac1934_chip_identify(info); + if (ret < 0) { + /* + * If failed to identify the hardware based on internal + * registers, try using fallback compatible in device tree + * to deal with some newer part number. + */ + chip = i2c_get_match_data(client); + if (!chip) + return -EINVAL; + + info->phys_channels = chip->phys_channels; + indio_dev->name = chip->name; + } else { + info->phys_channels = pac1934_chip_config[ret].phys_channels; + indio_dev->name = pac1934_chip_config[ret].name; + } + + if (acpi_match_device(dev->driver->acpi_match_table, dev)) + match = pac1934_acpi_parse_channel_config(client, info); + else + /* + * This makes it possible to use also ACPI PRP0001 for + * registering the device using device tree properties. + */ + match = pac1934_of_parse_channel_config(client, info); + + if (!match) + return dev_err_probe(dev, -EINVAL, + "parameter parsing returned an error\n"); + + mutex_init(&info->lock); + ret = devm_add_action_or_reset(dev, pac1934_mutex_destroy, + &info->lock); + if (ret < 0) + return ret; + + /* + * do now any chip specific initialization (e.g. read/write + * some registers), enable/disable certain channels, change the sampling + * rate to the requested value + */ + ret = pac1934_chip_configure(info); + if (ret < 0) + return ret; + + /* prepare the channel information */ + ret = pac1934_prep_iio_channels(info, indio_dev); + if (ret < 0) + return ret; + + info->iio_info = pac1934_info; + indio_dev->info = &info->iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = pac1934_prep_custom_attributes(info, indio_dev); + if (ret < 0) + return dev_err_probe(dev, ret, + "Can't configure custom attributes for PAC1934 device\n"); + + /* + * read whatever has been accumulated in the chip so far + * and reset the accumulators + */ + ret = pac1934_reg_snapshot(info, true, PAC1934_REFRESH_REG_ADDR, + PAC1934_MIN_UPDATE_WAIT_TIME_US); + if (ret < 0) + return ret; + + ret = devm_iio_device_register(dev, indio_dev); + if (ret < 0) + return dev_err_probe(dev, ret, + "Can't register IIO device\n"); + + return 0; +} + +static const struct i2c_device_id pac1934_id[] = { + { .name = "pac1931", .driver_data = (kernel_ulong_t)&pac1934_chip_config[PAC1931] }, + { .name = "pac1932", .driver_data = (kernel_ulong_t)&pac1934_chip_config[PAC1932] }, + { .name = "pac1933", .driver_data = (kernel_ulong_t)&pac1934_chip_config[PAC1933] }, + { .name = "pac1934", .driver_data = (kernel_ulong_t)&pac1934_chip_config[PAC1934] }, + {} +}; +MODULE_DEVICE_TABLE(i2c, pac1934_id); + +static const struct of_device_id pac1934_of_match[] = { + { + .compatible = "microchip,pac1931", + .data = &pac1934_chip_config[PAC1931] + }, + { + .compatible = "microchip,pac1932", + .data = &pac1934_chip_config[PAC1932] + }, + { + .compatible = "microchip,pac1933", + .data = &pac1934_chip_config[PAC1933] + }, + { + .compatible = "microchip,pac1934", + .data = &pac1934_chip_config[PAC1934] + }, + {} +}; +MODULE_DEVICE_TABLE(of, pac1934_of_match); + +/* + * using MCHP1930 to be compatible with BIOS ACPI. See example: + * https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ApplicationNotes/ApplicationNotes/PAC1934-Integration-Notes-for-Microsoft-Windows-10-and-Windows-11-Driver-Support-DS00002534.pdf + */ +static const struct acpi_device_id pac1934_acpi_match[] = { + { "MCHP1930", .driver_data = (kernel_ulong_t)&pac1934_chip_config[PAC1934] }, + {} +}; +MODULE_DEVICE_TABLE(acpi, pac1934_acpi_match); + +static struct i2c_driver pac1934_driver = { + .driver = { + .name = "pac1934", + .of_match_table = pac1934_of_match, + .acpi_match_table = pac1934_acpi_match + }, + .probe = pac1934_probe, + .id_table = pac1934_id, +}; + +module_i2c_driver(pac1934_driver); + +MODULE_AUTHOR("Bogdan Bolocan "); +MODULE_AUTHOR("Victor Tudose"); +MODULE_AUTHOR("Marius Cristea "); +MODULE_DESCRIPTION("IIO driver for PAC1934 Multi-Channel DC Power/Energy Monitor"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From b8b393348ad8eb1b96681dd155cd30d6184f61d3 Mon Sep 17 00:00:00 2001 From: Javier Carrasco Date: Fri, 23 Feb 2024 14:01:33 +0100 Subject: dt-bindings: iio: light: vishay,veml6075: make vdd-supply required The VEML6075 requires a single supply to operate. The property already exists in the bindings and it is used in the example, but it is still not on the list of required properties. Signed-off-by: Javier Carrasco Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20240223-veml6075_vdd-v1-1-ac76509b1998@gmail.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/light/vishay,veml6075.yaml | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/light/vishay,veml6075.yaml b/Documentation/devicetree/bindings/iio/light/vishay,veml6075.yaml index abee04cd126e..91c318746bf3 100644 --- a/Documentation/devicetree/bindings/iio/light/vishay,veml6075.yaml +++ b/Documentation/devicetree/bindings/iio/light/vishay,veml6075.yaml @@ -21,6 +21,7 @@ properties: required: - compatible - reg + - vdd-supply additionalProperties: false -- cgit v1.2.3 From 14166bac93b2cd16789368bef74a24cab6e81825 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 22 Feb 2024 02:13:35 +0100 Subject: dt-bindings: vendor-prefix: Add prefix for Voltafield Voltafile Technology Corp. is a company that produces MEMS sensors. Add a DT vendor prefix for it. Signed-off-by: Icenowy Zheng Signed-off-by: Ondřej Jirman Acked-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240222011341.3232645-2-megi@xff.cz Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 1a0dc04f1db4..82e9f64c90ff 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1534,6 +1534,8 @@ patternProperties: description: VoCore Studio "^voipac,.*": description: Voipac Technologies s.r.o. + "^voltafield,.*": + description: Voltafield Technology Corp. "^vot,.*": description: Vision Optical Technology Co., Ltd. "^vxt,.*": -- cgit v1.2.3 From 3b2eaffd2bd2ce9c6c0e7f9e210135475e9a46ec Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 22 Feb 2024 02:13:36 +0100 Subject: dt-bindings: iio: magnetometer: Add Voltafield AF8133J Voltafield AF8133J is a simple magnetometer sensor produced by Voltafield Technology Corp, with dual power supplies (one for core and one for I/O) and active-low reset pin. The sensor has configurable range 1.2 - 2.2 mT and a software controlled standby mode. Add a device tree binding for it. Signed-off-by: Icenowy Zheng Signed-off-by: Ondřej Jirman Reviewed-by: Conor Dooley Link: https://lore.kernel.org/r/20240222011341.3232645-3-megi@xff.cz Signed-off-by: Jonathan Cameron --- .../iio/magnetometer/voltafield,af8133j.yaml | 60 ++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/magnetometer/voltafield,af8133j.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/magnetometer/voltafield,af8133j.yaml b/Documentation/devicetree/bindings/iio/magnetometer/voltafield,af8133j.yaml new file mode 100644 index 000000000000..b6ab01a6914a --- /dev/null +++ b/Documentation/devicetree/bindings/iio/magnetometer/voltafield,af8133j.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/magnetometer/voltafield,af8133j.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Voltafield AF8133J magnetometer sensor + +maintainers: + - Ondřej Jirman + +properties: + compatible: + const: voltafield,af8133j + + reg: + maxItems: 1 + + reset-gpios: + description: + A signal for active low reset input of the sensor. (optional; if not + used, software reset over I2C will be used instead) + + avdd-supply: + description: + A regulator that provides AVDD power (Working power, usually 3.3V) to + the sensor. + + dvdd-supply: + description: + A regulator that provides DVDD power (Digital IO power, 1.8V - AVDD) + to the sensor. + + mount-matrix: + description: An optional 3x3 mounting rotation matrix. + +required: + - compatible + - reg + - avdd-supply + - dvdd-supply + +additionalProperties: false + +examples: + - | + #include + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + magnetometer@1c { + compatible = "voltafield,af8133j"; + reg = <0x1c>; + avdd-supply = <®_dldo1>; + dvdd-supply = <®_dldo1>; + reset-gpios = <&pio 1 1 GPIO_ACTIVE_LOW>; + }; + }; -- cgit v1.2.3 From de42d339553d39d1ab1f0ef9d4f1338c725b7019 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Mon, 26 Feb 2024 13:12:33 +0100 Subject: dt-bindings: iio: ti,tmp117: add optional label property Add the support to provide an optional label like we do for ADC channels to identify the device more easily. Signed-off-by: Marco Felsch Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240226121234.545662-1-m.felsch@pengutronix.de Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml b/Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml index 33f2e9c5bd81..58aa1542776b 100644 --- a/Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml +++ b/Documentation/devicetree/bindings/iio/temperature/ti,tmp117.yaml @@ -27,6 +27,9 @@ properties: vcc-supply: description: provide VCC power to the sensor. + label: + description: Unique name to identify which device this is. + required: - compatible - reg -- cgit v1.2.3 From 513ea6b7b4fe7eb58b9e32dad6ee43f36c2c5f24 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 26 Feb 2024 13:30:04 +0100 Subject: dt-bindings: iio: adc: drop redundant type from label dtschema defines label as string, so $ref in other bindings is redundant. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240226123004.91061-1-krzysztof.kozlowski@linaro.org Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/adc/adc.yaml | 1 - Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml | 1 - 2 files changed, 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/adc.yaml b/Documentation/devicetree/bindings/iio/adc/adc.yaml index 261601729745..36775f8f71df 100644 --- a/Documentation/devicetree/bindings/iio/adc/adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adc.yaml @@ -22,7 +22,6 @@ properties: maxItems: 1 label: - $ref: /schemas/types.yaml#/definitions/string description: Unique name to identify which channel this is. bipolar: diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml index 40fa0710f1f0..c28db0d635a0 100644 --- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml @@ -75,7 +75,6 @@ patternProperties: in the PMIC-specific files in include/dt-bindings/iio/. label: - $ref: /schemas/types.yaml#/definitions/string description: | ADC input of the platform as seen in the schematics. For thermistor inputs connected to generic AMUX or GPIO inputs -- cgit v1.2.3 From ca1e2b91baa38a0641b8b2ff9473f38232986ecc Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 26 Feb 2024 21:08:25 +0800 Subject: dt-bindings: iio: adc: imx93: drop the 4th interrupt Per i.MX93 Reference Mannual Rev.4, 12/2013, there is no interrupt 268, so drop it. Signed-off-by: Peng Fan Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20240226130826.3824251-1-peng.fan@oss.nxp.com Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml b/Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml index dacc526dc695..dfc3f512918f 100644 --- a/Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml @@ -31,7 +31,6 @@ properties: - description: normal conversion, include EOC (End of Conversion), ECH (End of Chain), JEOC (End of Injected Conversion) and JECH (End of injected Chain). - - description: Self-testing Interrupts. clocks: maxItems: 1 @@ -70,8 +69,7 @@ examples: reg = <0x44530000 0x10000>; interrupts = , , - , - ; + ; clocks = <&clk IMX93_CLK_ADC1_GATE>; clock-names = "ipg"; vref-supply = <®_vref_1v8>; -- cgit v1.2.3 From 6b61aae323e30ba363616e1da23f591b164aca3f Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Wed, 21 Feb 2024 18:43:05 +0100 Subject: dt-bindings: iio: gyroscope: bosch,bmg160: add spi-max-frequency Make use of the common spi-peripheral-props.yaml to pull in the common spi device properties and limit the spi-max-frequency to 10 MHz as this is the max. frequency if VDDIO >= 1.62V. Note all listed devices can either operate in I2C or in SPI mode. Signed-off-by: Marco Felsch Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240221174305.3423039-1-m.felsch@pengutronix.de Signed-off-by: Jonathan Cameron --- Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml b/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml index 1414ba9977c1..3c6fe74af0b8 100644 --- a/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml +++ b/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml @@ -22,6 +22,9 @@ properties: vdd-supply: true vddio-supply: true + spi-max-frequency: + maximum: 10000000 + interrupts: minItems: 1 maxItems: 2 @@ -33,7 +36,10 @@ required: - compatible - reg -additionalProperties: false +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false examples: - | -- cgit v1.2.3 From 9c4058493b62f5ee7a0620e21d21592283c8f8f5 Mon Sep 17 00:00:00 2001 From: Danila Tikhonov Date: Thu, 22 Feb 2024 20:42:49 +0300 Subject: dt-bindings: interconnect: Add Qualcomm SM7150 DT bindings The Qualcomm SM7150 platform has several bus fabrics that could be controlled and tuned dynamically according to the bandwidth demand. Signed-off-by: Danila Tikhonov Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240222174250.80493-2-danila@jiaxyga.com Signed-off-by: Georgi Djakov --- .../bindings/interconnect/qcom,sm7150-rpmh.yaml | 84 ++++++++++++ .../dt-bindings/interconnect/qcom,sm7150-rpmh.h | 150 +++++++++++++++++++++ 2 files changed, 234 insertions(+) create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,sm7150-rpmh.yaml create mode 100644 include/dt-bindings/interconnect/qcom,sm7150-rpmh.h (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/interconnect/qcom,sm7150-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,sm7150-rpmh.yaml new file mode 100644 index 000000000000..b565d1a382f6 --- /dev/null +++ b/Documentation/devicetree/bindings/interconnect/qcom,sm7150-rpmh.yaml @@ -0,0 +1,84 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/interconnect/qcom,sm7150-rpmh.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm RPMh Network-On-Chip Interconnect on SM7150 + +maintainers: + - Danila Tikhonov + +description: | + RPMh interconnect providers support system bandwidth requirements through + RPMh hardware accelerators known as Bus Clock Manager (BCM). + + See also:: include/dt-bindings/interconnect/qcom,sm7150-rpmh.h + +allOf: + - $ref: qcom,rpmh-common.yaml# + +properties: + compatible: + enum: + - qcom,sm7150-aggre1-noc + - qcom,sm7150-aggre2-noc + - qcom,sm7150-compute-noc + - qcom,sm7150-config-noc + - qcom,sm7150-dc-noc + - qcom,sm7150-gem-noc + - qcom,sm7150-mc-virt + - qcom,sm7150-mmss-noc + - qcom,sm7150-system-noc + + reg: + maxItems: 1 + +# Child node's properties +patternProperties: + '^interconnect-[0-9]+$': + type: object + description: + The interconnect providers do not have a separate QoS register space, + but share parent's space. + + allOf: + - $ref: qcom,rpmh-common.yaml# + + properties: + compatible: + enum: + - qcom,sm7150-camnoc-virt + + required: + - compatible + + unevaluatedProperties: false + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + mc_virt: interconnect@1380000 { + compatible = "qcom,sm7150-mc-virt"; + reg = <0x01380000 0x40000>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + system_noc: interconnect@1620000 { + compatible = "qcom,sm7150-system-noc"; + reg = <0x01620000 0x40000>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + + camnoc_virt: interconnect-0 { + compatible = "qcom,sm7150-camnoc-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + }; diff --git a/include/dt-bindings/interconnect/qcom,sm7150-rpmh.h b/include/dt-bindings/interconnect/qcom,sm7150-rpmh.h new file mode 100644 index 000000000000..1f610eb832aa --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,sm7150-rpmh.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* + * Qualcomm SM7150 interconnect IDs + * + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Danila Tikhonov + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_SM7150_H +#define __DT_BINDINGS_INTERCONNECT_QCOM_SM7150_H + +#define MASTER_A1NOC_CFG 0 +#define MASTER_QUP_0 1 +#define MASTER_TSIF 2 +#define MASTER_EMMC 3 +#define MASTER_SDCC_2 4 +#define MASTER_SDCC_4 5 +#define MASTER_UFS_MEM 6 +#define A1NOC_SNOC_SLV 7 +#define SLAVE_SERVICE_A1NOC 8 + +#define MASTER_A2NOC_CFG 0 +#define MASTER_QDSS_BAM 1 +#define MASTER_QUP_1 2 +#define MASTER_CNOC_A2NOC 3 +#define MASTER_CRYPTO_CORE_0 4 +#define MASTER_IPA 5 +#define MASTER_PCIE 6 +#define MASTER_QDSS_ETR 7 +#define MASTER_USB3 8 +#define A2NOC_SNOC_SLV 9 +#define SLAVE_ANOC_PCIE_GEM_NOC 10 +#define SLAVE_SERVICE_A2NOC 11 + +#define MASTER_CAMNOC_HF0_UNCOMP 0 +#define MASTER_CAMNOC_RT_UNCOMP 1 +#define MASTER_CAMNOC_SF_UNCOMP 2 +#define MASTER_CAMNOC_NRT_UNCOMP 3 +#define SLAVE_CAMNOC_UNCOMP 4 + +#define MASTER_NPU 0 +#define SLAVE_CDSP_GEM_NOC 1 + +#define MASTER_SPDM 0 +#define SNOC_CNOC_MAS 1 +#define MASTER_QDSS_DAP 2 +#define SLAVE_A1NOC_CFG 3 +#define SLAVE_A2NOC_CFG 4 +#define SLAVE_AHB2PHY_NORTH 5 +#define SLAVE_AHB2PHY_SOUTH 6 +#define SLAVE_AHB2PHY_WEST 7 +#define SLAVE_AOP 8 +#define SLAVE_AOSS 9 +#define SLAVE_CAMERA_CFG 10 +#define SLAVE_CAMERA_NRT_THROTTLE_CFG 11 +#define SLAVE_CAMERA_RT_THROTTLE_CFG 12 +#define SLAVE_CLK_CTL 13 +#define SLAVE_CDSP_CFG 14 +#define SLAVE_RBCPR_CX_CFG 15 +#define SLAVE_RBCPR_MX_CFG 16 +#define SLAVE_CRYPTO_0_CFG 17 +#define SLAVE_CNOC_DDRSS 18 +#define SLAVE_DISPLAY_CFG 19 +#define SLAVE_DISPLAY_THROTTLE_CFG 20 +#define SLAVE_EMMC_CFG 21 +#define SLAVE_GLM 22 +#define SLAVE_GRAPHICS_3D_CFG 23 +#define SLAVE_IMEM_CFG 24 +#define SLAVE_IPA_CFG 25 +#define SLAVE_CNOC_MNOC_CFG 26 +#define SLAVE_PCIE_CFG 27 +#define SLAVE_PDM 28 +#define SLAVE_PIMEM_CFG 29 +#define SLAVE_PRNG 30 +#define SLAVE_QDSS_CFG 31 +#define SLAVE_QUP_0 32 +#define SLAVE_QUP_1 33 +#define SLAVE_SDCC_2 34 +#define SLAVE_SDCC_4 35 +#define SLAVE_SNOC_CFG 36 +#define SLAVE_SPDM_WRAPPER 37 +#define SLAVE_TCSR 38 +#define SLAVE_TLMM_NORTH 39 +#define SLAVE_TLMM_SOUTH 40 +#define SLAVE_TLMM_WEST 41 +#define SLAVE_TSIF 42 +#define SLAVE_UFS_MEM_CFG 43 +#define SLAVE_USB3 44 +#define SLAVE_VENUS_CFG 45 +#define SLAVE_VENUS_CVP_THROTTLE_CFG 46 +#define SLAVE_VENUS_THROTTLE_CFG 47 +#define SLAVE_VSENSE_CTRL_CFG 48 +#define SLAVE_CNOC_A2NOC 49 +#define SLAVE_SERVICE_CNOC 50 + +#define MASTER_CNOC_DC_NOC 0 +#define SLAVE_GEM_NOC_CFG 1 +#define SLAVE_LLCC_CFG 2 + +#define MASTER_AMPSS_M0 0 +#define MASTER_SYS_TCU 1 +#define MASTER_GEM_NOC_CFG 2 +#define MASTER_COMPUTE_NOC 3 +#define MASTER_MNOC_HF_MEM_NOC 4 +#define MASTER_MNOC_SF_MEM_NOC 5 +#define MASTER_GEM_NOC_PCIE_SNOC 6 +#define MASTER_SNOC_GC_MEM_NOC 7 +#define MASTER_SNOC_SF_MEM_NOC 8 +#define MASTER_GRAPHICS_3D 9 +#define SLAVE_MSS_PROC_MS_MPU_CFG 10 +#define SLAVE_GEM_NOC_SNOC 11 +#define SLAVE_LLCC 12 +#define SLAVE_SERVICE_GEM_NOC 13 + + +#define MASTER_LLCC 0 +#define SLAVE_EBI_CH0 1 + +#define MASTER_CNOC_MNOC_CFG 0 +#define MASTER_CAMNOC_HF0 1 +#define MASTER_CAMNOC_NRT 2 +#define MASTER_CAMNOC_RT 3 +#define MASTER_CAMNOC_SF 4 +#define MASTER_MDP_PORT0 5 +#define MASTER_MDP_PORT1 6 +#define MASTER_ROTATOR 7 +#define MASTER_VIDEO_P0 8 +#define MASTER_VIDEO_P1 9 +#define MASTER_VIDEO_PROC 10 +#define SLAVE_MNOC_SF_MEM_NOC 11 +#define SLAVE_MNOC_HF_MEM_NOC 12 +#define SLAVE_SERVICE_MNOC 13 + +#define MASTER_SNOC_CFG 0 +#define A1NOC_SNOC_MAS 1 +#define A2NOC_SNOC_MAS 2 +#define MASTER_GEM_NOC_SNOC 3 +#define MASTER_PIMEM 4 +#define MASTER_GIC 5 +#define SLAVE_APPSS 6 +#define SNOC_CNOC_SLV 7 +#define SLAVE_SNOC_GEM_NOC_GC 8 +#define SLAVE_SNOC_GEM_NOC_SF 9 +#define SLAVE_OCIMEM 10 +#define SLAVE_PIMEM 11 +#define SLAVE_SERVICE_SNOC 12 +#define SLAVE_QDSS_STM 13 +#define SLAVE_TCU 14 + +#endif -- cgit v1.2.3 From 508ecc78b6c983a7921bee2f4bd22682f9f0396e Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Sat, 24 Feb 2024 11:45:06 +0000 Subject: nvmem: fixed-cell: Simplify nested if/then schema There's no reason to have a nested if/then schema as checking for compatible being present and containing 'mac-base' can all be done in one 'if' schema. Signed-off-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20240224114516.86365-2-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- .../bindings/nvmem/layouts/fixed-cell.yaml | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml b/Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml index ac2381e66027..8b3826243ddd 100644 --- a/Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml +++ b/Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml @@ -36,20 +36,18 @@ properties: allOf: - if: + properties: + compatible: + contains: + const: mac-base required: [ compatible ] then: - if: - properties: - compatible: - contains: - const: mac-base - then: - properties: - "#nvmem-cell-cells": - description: The first argument is a MAC address offset. - const: 1 - required: - - "#nvmem-cell-cells" + properties: + "#nvmem-cell-cells": + description: The first argument is a MAC address offset. + const: 1 + required: + - "#nvmem-cell-cells" required: - reg -- cgit v1.2.3 From c7f99cd8fb6b3997bc634ad6ae6e709f49898cbe Mon Sep 17 00:00:00 2001 From: Praveen Teja Kundanala Date: Sat, 24 Feb 2024 11:45:08 +0000 Subject: dt-bindings: nvmem: Convert xlnx,zynqmp-nvmem.txt to yaml Convert the xlnx,zynqmp-nvmem.txt to yaml. Signed-off-by: Praveen Teja Kundanala Reviewed-by: Krzysztof Kozlowski Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20240224114516.86365-4-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- .../bindings/nvmem/xlnx,zynqmp-nvmem.txt | 46 ---------------------- .../bindings/nvmem/xlnx,zynqmp-nvmem.yaml | 42 ++++++++++++++++++++ 2 files changed, 42 insertions(+), 46 deletions(-) delete mode 100644 Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.txt create mode 100644 Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.txt b/Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.txt deleted file mode 100644 index 4881561b3a02..000000000000 --- a/Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.txt +++ /dev/null @@ -1,46 +0,0 @@ --------------------------------------------------------------------------- -= Zynq UltraScale+ MPSoC nvmem firmware driver binding = --------------------------------------------------------------------------- -The nvmem_firmware node provides access to the hardware related data -like soc revision, IDCODE... etc, By using the firmware interface. - -Required properties: -- compatible: should be "xlnx,zynqmp-nvmem-fw" - -= Data cells = -Are child nodes of silicon id, bindings of which as described in -bindings/nvmem/nvmem.txt - -------- - Example -------- -firmware { - zynqmp_firmware: zynqmp-firmware { - compatible = "xlnx,zynqmp-firmware"; - method = "smc"; - - nvmem_firmware { - compatible = "xlnx,zynqmp-nvmem-fw"; - #address-cells = <1>; - #size-cells = <1>; - - /* Data cells */ - soc_revision: soc_revision { - reg = <0x0 0x4>; - }; - }; - }; -}; - -= Data consumers = -Are device nodes which consume nvmem data cells. - -For example: - pcap { - ... - - nvmem-cells = <&soc_revision>; - nvmem-cell-names = "soc_revision"; - - ... - }; diff --git a/Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.yaml b/Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.yaml new file mode 100644 index 000000000000..917c40d5c382 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/xlnx,zynqmp-nvmem.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/xlnx,zynqmp-nvmem.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Zynq UltraScale+ MPSoC Non Volatile Memory interface + +description: | + The ZynqMP MPSoC provides access to the hardware related data + like SOC revision, IDCODE and specific purpose efuses. + +maintainers: + - Kalyani Akula + - Praveen Teja Kundanala + +allOf: + - $ref: nvmem.yaml# + +properties: + compatible: + const: xlnx,zynqmp-nvmem-fw + +required: + - compatible + +unevaluatedProperties: false + +examples: + - | + nvmem { + compatible = "xlnx,zynqmp-nvmem-fw"; + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + soc_revision: soc-revision@0 { + reg = <0x0 0x4>; + }; + }; + }; -- cgit v1.2.3 From d28c853b32b868f25545ce0c08b4b6a17f5d8767 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 24 Feb 2024 11:45:09 +0000 Subject: dt-bindings: nvmem: add common definition of nvmem-cell-cells Linux kernel NVMEM consumer bindings define phandle to NVMEM cells ("nvmem-cells"), thus we also want the common definition of property defining number of cells encoding that specifier, so the Suggested-by: Rob Herring Reported-by: Michael Walle Closes: https://github.com/devicetree-org/dt-schema/pull/89 Reported-by: Rafał Miłecki Closes: https://lore.kernel.org/linux-arm-kernel/20221121105830.7411-1-zajec5@gmail.com/#r Closes: https://lore.kernel.org/all/bdf7751b-0421-485d-8382-26c084f09d7d@gmail.com/ Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20240224114516.86365-5-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/nvmem/nvmem-provider.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Documentation/devicetree/bindings/nvmem/nvmem-provider.yaml (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/nvmem/nvmem-provider.yaml b/Documentation/devicetree/bindings/nvmem/nvmem-provider.yaml new file mode 100644 index 000000000000..4009a9a03841 --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/nvmem-provider.yaml @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/nvmem-provider.yaml# +$schema: http://devicetree.org/meta-schemas/base.yaml# + +title: NVMEM (Non Volatile Memory) Provider + +maintainers: + - Srinivas Kandagatla + +select: true + +properties: + '#nvmem-cell-cells': + enum: [0, 1] + +additionalProperties: true -- cgit v1.2.3