diff options
144 files changed, 2382 insertions, 1818 deletions
@@ -1942,6 +1942,10 @@ S: Post Office Box 611311 S: San Jose, California 95161-1311 S: USA +N: Hartmut Knaack +E: knaack.h@gmx.de +D: IIO subsystem and drivers + N: Thorsten Knabe E: Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de> E: Thorsten Knabe <tek01@hrzpub.tu-darmstadt.de> diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index c20334454dbf..a9d51810a3ba 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -1758,6 +1758,14 @@ Contact: linux-iio@vger.kernel.org Description: One of the following thermocouple types: B, E, J, K, N, R, S, T. +What: /sys/bus/iio/devices/iio:deviceX/in_temp_object_calibambient +What: /sys/bus/iio/devices/iio:deviceX/in_tempX_object_calibambient +KernelVersion: 5.10 +Contact: linux-iio@vger.kernel.org +Description: + Calibrated ambient temperature for object temperature + calculation in milli degrees Celsius. + What: /sys/bus/iio/devices/iio:deviceX/in_intensity_x_raw What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_raw What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_raw diff --git a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x b/Documentation/ABI/testing/sysfs-bus-iio-light-tsl2772 index b2798b258bf7..b2798b258bf7 100644 --- a/drivers/staging/iio/Documentation/light/sysfs-bus-iio-light-tsl2x7x +++ b/Documentation/ABI/testing/sysfs-bus-iio-light-tsl2772 diff --git a/Documentation/devicetree/bindings/iio/adc/ad7949.txt b/Documentation/devicetree/bindings/iio/adc/ad7949.txt deleted file mode 100644 index c7f5057356b1..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ad7949.txt +++ /dev/null @@ -1,16 +0,0 @@ -* Analog Devices AD7949/AD7682/AD7689 - -Required properties: - - compatible: Should be one of - * "adi,ad7949" - * "adi,ad7682" - * "adi,ad7689" - - reg: spi chip select number for the device - - vref-supply: The regulator supply for ADC reference voltage - -Example: -adc@0 { - compatible = "adi,ad7949"; - reg = <0>; - vref-supply = <&vdd_supply>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt deleted file mode 100644 index 9f5b88cf680d..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt +++ /dev/null @@ -1,41 +0,0 @@ -Analog Devices AD7768-1 ADC device driver - -Required properties for the AD7768-1: - -- compatible: Must be "adi,ad7768-1" -- reg: SPI chip select number for the device -- spi-max-frequency: Max SPI frequency to use - see: Documentation/devicetree/bindings/spi/spi-bus.txt -- clocks: phandle to the master clock (mclk) - see: Documentation/devicetree/bindings/clock/clock-bindings.txt -- clock-names: Must be "mclk". -- interrupts: IRQ line for the ADC - see: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt -- vref-supply: vref supply can be used as reference for conversion -- adi,sync-in-gpios: must be the device tree identifier of the SYNC-IN pin. Enables - synchronization of multiple devices that require simultaneous sampling. - A pulse is always required if the configuration is changed in any way, for example - if the filter decimation rate changes. As the line is active low, it should - be marked GPIO_ACTIVE_LOW. - -Optional properties: - - - reset-gpios : GPIO spec for the RESET pin. If specified, it will be asserted during - driver probe. As the line is active low, it should be marked GPIO_ACTIVE_LOW. - -Example: - - adc@0 { - compatible = "adi,ad7768-1"; - reg = <0>; - spi-max-frequency = <2000000>; - spi-cpol; - spi-cpha; - vref-supply = <&adc_vref>; - interrupts = <25 IRQ_TYPE_EDGE_RISING>; - interrupt-parent = <&gpio>; - adi,sync-in-gpios = <&gpio 22 GPIO_ACTIVE_LOW>; - reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>; - clocks = <&ad7768_mclk>; - clock-names = "mclk"; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml new file mode 100644 index 000000000000..d3733ad8785a --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad7768-1.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD7768-1 ADC device driver + +maintainers: + - Michael Hennerich <michael.hennerich@analog.com> + +description: | + Datasheet at: + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7768-1.pdf + +properties: + compatible: + const: adi,ad7768-1 + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: mclk + + interrupts: + maxItems: 1 + + vref-supply: + description: + ADC reference voltage supply + + adi,sync-in-gpios: + description: + Enables synchronization of multiple devices that require simultaneous + sampling. A pulse is always required if the configuration is changed + in any way, for example if the filter decimation rate changes. + As the line is active low, it should be marked GPIO_ACTIVE_LOW. + + reset-gpios: + maxItems: 1 + + spi-max-frequency: true + + spi-cpol: true + spi-cpha : true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - vref-supply + - spi-cpol + - spi-cpha + - adi,sync-in-gpios + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/gpio/gpio.h> + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad7768-1"; + reg = <0>; + spi-max-frequency = <2000000>; + spi-cpol; + spi-cpha; + vref-supply = <&adc_vref>; + interrupts = <25 IRQ_TYPE_EDGE_RISING>; + interrupt-parent = <&gpio>; + adi,sync-in-gpios = <&gpio 22 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>; + clocks = <&ad7768_mclk>; + clock-names = "mclk"; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7949.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7949.yaml new file mode 100644 index 000000000000..9b56bd4d5510 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7949.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad7949.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD7949/AD7682/AD7689 analog to digital converters + +maintainers: + - Charles-Antoine Couret <charles-antoine.couret@essensium.com> + +description: | + Specifications on the converters can be found at: + AD7949: + https://www.analog.com/media/en/technical-documentation/data-sheets/AD7949.pdf + AD7682/AD7698: + https://www.analog.com/media/en/technical-documentation/data-sheets/AD7682_7689.pdf + +properties: + compatible: + enum: + - adi,ad7682 + - adi,ad7689 + - adi,ad7949 + + reg: + maxItems: 1 + + vref-supply: + description: + ADC reference voltage supply + + spi-max-frequency: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad7949"; + reg = <0>; + vref-supply = <&vdd_supply>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ads1015.txt b/Documentation/devicetree/bindings/iio/adc/ads1015.txt deleted file mode 100644 index 918a507d1159..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ads1015.txt +++ /dev/null @@ -1,73 +0,0 @@ -ADS1015 (I2C) - -This device is a 12-bit A-D converter with 4 inputs. - -The inputs can be used single ended or in certain differential combinations. - -For configuration all possible combinations are mapped to 8 channels: - 0: Voltage over AIN0 and AIN1. - 1: Voltage over AIN0 and AIN3. - 2: Voltage over AIN1 and AIN3. - 3: Voltage over AIN2 and AIN3. - 4: Voltage over AIN0 and GND. - 5: Voltage over AIN1 and GND. - 6: Voltage over AIN2 and GND. - 7: Voltage over AIN3 and GND. - -Each channel can be configured individually: - - pga is the programmable gain amplifier (values are full scale) - 0: +/- 6.144 V - 1: +/- 4.096 V - 2: +/- 2.048 V (default) - 3: +/- 1.024 V - 4: +/- 0.512 V - 5: +/- 0.256 V - - data_rate in samples per second - 0: 128 - 1: 250 - 2: 490 - 3: 920 - 4: 1600 (default) - 5: 2400 - 6: 3300 - -1) The /ads1015 node - - Required properties: - - - compatible : must be "ti,ads1015" - - reg : I2C bus address of the device - - #address-cells : must be <1> - - #size-cells : must be <0> - - The node contains child nodes for each channel that the platform uses. - - Example ADS1015 node: - - ads1015@49 { - compatible = "ti,ads1015"; - reg = <0x49>; - #address-cells = <1>; - #size-cells = <0>; - - [ child node definitions... ] - } - -2) channel nodes - - Required properties: - - - reg : the channel number - - Optional properties: - - - ti,gain : the programmable gain amplifier setting - - ti,datarate : the converter data rate - - Example ADS1015 channel node: - - channel@4 { - reg = <4>; - ti,gain = <3>; - ti,datarate = <5>; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml new file mode 100644 index 000000000000..7f534a933e92 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2400-adc.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2400-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ADC that forms part of an ASPEED server management processor. + +maintainers: + - Joel Stanley <joel@jms.id.au> + +description: + This device is a 10-bit converter for 16 voltage channels. All inputs are + single ended. + +properties: + compatible: + enum: + - aspeed,ast2400-adc + - aspeed,ast2500-adc + + reg: + maxItems: 1 + + clocks: + description: + Input clock used to derive the sample clock. Expected to be the + SoC's APB clock. + + resets: + maxItems: 1 + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - resets + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/aspeed-clock.h> + adc@1e6e9000 { + compatible = "aspeed,ast2400-adc"; + reg = <0x1e6e9000 0xb0>; + clocks = <&syscon ASPEED_CLK_APB>; + resets = <&syscon ASPEED_RESET_ADC>; + #io-channel-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt b/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt deleted file mode 100644 index 034fc2ba100e..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt +++ /dev/null @@ -1,22 +0,0 @@ -Aspeed ADC - -This device is a 10-bit converter for 16 voltage channels. All inputs are -single ended. - -Required properties: -- compatible: Should be "aspeed,ast2400-adc" or "aspeed,ast2500-adc" -- reg: memory window mapping address and length -- clocks: Input clock used to derive the sample clock. Expected to be the - SoC's APB clock. -- resets: Reset controller phandle -- #io-channel-cells: Must be set to <1> to indicate channels are selected - by index. - -Example: - adc@1e6e9000 { - compatible = "aspeed,ast2400-adc"; - reg = <0x1e6e9000 0xb0>; - clocks = <&syscon ASPEED_CLK_APB>; - resets = <&syscon ASPEED_RESET_ADC>; - #io-channel-cells = <1>; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/berlin2_adc.txt b/Documentation/devicetree/bindings/iio/adc/berlin2_adc.txt deleted file mode 100644 index 908334c6b07f..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/berlin2_adc.txt +++ /dev/null @@ -1,19 +0,0 @@ -* Berlin Analog to Digital Converter (ADC) - -The Berlin ADC has 8 channels, with one connected to a temperature sensor. -It is part of the system controller register set. The ADC node should be a -sub-node of the system controller node. - -Required properties: -- compatible: must be "marvell,berlin2-adc" -- interrupts: the interrupts for the ADC and the temperature sensor -- interrupt-names: should be "adc" and "tsen" - -Example: - -adc: adc { - compatible = "marvell,berlin2-adc"; - interrupt-parent = <&sic>; - interrupts = <12>, <14>; - interrupt-names = "adc", "tsen"; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt b/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt deleted file mode 100644 index 904f76de9055..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt +++ /dev/null @@ -1,22 +0,0 @@ -* Cosmic Circuits - Analog to Digital Converter (CC-10001-ADC) - -Required properties: - - compatible: Should be "cosmic,10001-adc" - - reg: Should contain adc registers location and length. - - clock-names: Should contain "adc". - - clocks: Should contain a clock specifier for each entry in clock-names - - vref-supply: The regulator supply ADC reference voltage. - -Optional properties: - - adc-reserved-channels: Bitmask of reserved channels, - i.e. channels that cannot be used by the OS. - -Example: -adc: adc@18101600 { - compatible = "cosmic,10001-adc"; - reg = <0x18101600 0x24>; - adc-reserved-channels = <0x2>; - clocks = <&adc_clk>; - clock-names = "adc"; - vref-supply = <®_1v8>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/cosmic,10001-adc.yaml b/Documentation/devicetree/bindings/iio/adc/cosmic,10001-adc.yaml new file mode 100644 index 000000000000..5d92b477e23f --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/cosmic,10001-adc.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/cosmic,10001-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cosmic Circuits CC-10001 ADC + +maintainers: + - Jonathan Cameron <jic23@kernel.org> + +description: + Cosmic Circuits 10001 10-bit ADC device. + +properties: + compatible: + const: cosmic,10001-adc + + reg: + maxItems: 1 + + adc-reserved-channels: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Bitmask of reserved channels, i.e. channels that cannot be + used by the OS. + + clocks: + maxItems: 1 + + clock-names: + const: adc + + vref-supply: true + + "#io-channel-cells": + const: 1 + + +required: + - compatible + - reg + - clocks + - clock-names + - vref-supply + +additionalProperties: false + +examples: + - | + adc@18101600 { + compatible = "cosmic,10001-adc"; + reg = <0x18101600 0x24>; + adc-reserved-channels = <0x2>; + clocks = <&adc_clk>; + clock-names = "adc"; + vref-supply = <®_1v8>; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/cpcap-adc.txt b/Documentation/devicetree/bindings/iio/adc/cpcap-adc.txt deleted file mode 100644 index ec04008e8f4f..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/cpcap-adc.txt +++ /dev/null @@ -1,17 +0,0 @@ -Motorola CPCAP PMIC ADC binding - -Required properties: -- compatible: Should be "motorola,cpcap-adc" or "motorola,mapphone-cpcap-adc" -- interrupts: The interrupt number for the ADC device -- interrupt-names: Should be "adcdone" -- #io-channel-cells: Number of cells in an IIO specifier - -Example: - -cpcap_adc: adc { - compatible = "motorola,mapphone-cpcap-adc"; - interrupt-parent = <&cpcap>; - interrupts = <8 IRQ_TYPE_NONE>; - interrupt-names = "adcdone"; - #io-channel-cells = <1>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt b/Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt deleted file mode 100644 index c07228da92ac..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt +++ /dev/null @@ -1,16 +0,0 @@ -Dialog Semiconductor DA9150 IIO GPADC bindings - -Required properties: -- compatible: "dlg,da9150-gpadc" for DA9150 IIO GPADC -- #io-channel-cells: Should be set to <1> - (See Documentation/devicetree/bindings/iio/iio-bindings.txt for further info) - -For further information on GPADC channels, see device datasheet. - - -Example: - - gpadc: da9150-gpadc { - compatible = "dlg,da9150-gpadc"; - #io-channel-cells = <1>; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/dlg,da9150-gpadc.yaml b/Documentation/devicetree/bindings/iio/adc/dlg,da9150-gpadc.yaml new file mode 100644 index 000000000000..cc29a2f2111a --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/dlg,da9150-gpadc.yaml @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/dlg,da9150-gpadc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Dialog Semiconductor DA9150 IIO GPADC + +maintainers: + - Adam Thomson <Adam.Thomson.Opensource@diasemi.com> + +description: + This patch adds support for general purpose ADC within the + DA9150 Charger & Fuel-Gauge IC. + +properties: + compatible: + const: dlg,da9150-gpadc + + "#io-channel-cells": + const: 1 + +required: + - compatible + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + adc { + compatible = "dlg,da9150-gpadc"; + #io-channel-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt deleted file mode 100644 index eebdcec3dab5..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt +++ /dev/null @@ -1,57 +0,0 @@ -Freescale i.MX25 ADC GCQ device - -This is a generic conversion queue device that can convert any of the -analog inputs using the ADC unit of the i.MX25. - -Required properties: - - compatible: Should be "fsl,imx25-gcq". - - reg: Should be the register range of the module. - - interrupts: Should be the interrupt number of the module. - Typically this is <1>. - - #address-cells: Should be <1> (setting for the subnodes) - - #size-cells: Should be <0> (setting for the subnodes) - -Optional properties: - - vref-ext-supply: The regulator supplying the ADC reference voltage. - Required when at least one subnode uses the this reference. - - vref-xp-supply: The regulator supplying the ADC reference voltage on pin XP. - Required when at least one subnode uses this reference. - - vref-yp-supply: The regulator supplying the ADC reference voltage on pin YP. - Required when at least one subnode uses this reference. - -Sub-nodes: -Optionally you can define subnodes which define the reference voltage -for the analog inputs. - -Required properties for subnodes: - - reg: Should be the number of the analog input. - 0: xp - 1: yp - 2: xn - 3: yn - 4: wiper - 5: inaux0 - 6: inaux1 - 7: inaux2 -Optional properties for subnodes: - - fsl,adc-refp: specifies the positive reference input as defined in - <dt-bindings/iio/adc/fsl-imx25-gcq.h> - - fsl,adc-refn: specifies the negative reference input as defined in - <dt-bindings/iio/adc/fsl-imx25-gcq.h> - -Example: - - adc: adc@50030800 { - compatible = "fsl,imx25-gcq"; - reg = <0x50030800 0x60>; - interrupt-parent = <&tscadc>; - interrupts = <1>; - #address-cells = <1>; - #size-cells = <0>; - - inaux@5 { - reg = <5>; - fsl,adc-refp = <MX25_ADC_REFP_INT>; - fsl,adc-refn = <MX25_ADC_REFN_NGND>; - }; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.yaml b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.yaml new file mode 100644 index 000000000000..e9103497e3a4 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.yaml @@ -0,0 +1,131 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/fsl,imx25-gcq.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale ADC GCQ device + +description: + This is a generic conversion queue device that can convert any of the + analog inputs using the ADC unit of the i.MX25. + +maintainers: + - Jonathan Cameron <jic23@kernel.org> + +properties: + compatible: + const: fsl,imx25-gcq + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + vref-ext-supply: + description: + The regulator supplying the ADC reference voltage. + Required when at least one subnode uses the this reference. + + vref-xp-supply: + description: + The regulator supplying the ADC reference voltage on pin XP. + Required when at least one subnode uses this reference. + + vref-yp-supply: + description: + The regulator supplying the ADC reference voltage on pin YP. + Required when at least one subnode uses this reference. + + "#io-channel-cells": + const: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +required: + - compatible + - reg + - interrupts + - "#address-cells" + - "#size-cells" + +patternProperties: + "[a-z][a-z0-9]+@[0-9a-f]+$": + type: object + description: + Child nodes used to define the reference voltages used for each channel + + properties: + reg: + description: | + Number of the analog input. + 0: xp + 1: yp + 2: xn + 3: yn + 4: wiper + 5: inaux0 + 6: inaux1 + 7: inaux2 + items: + - minimum: 0 + maximum: 7 + + fsl,adc-refp: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Specifies the positive reference input as defined in + <dt-bindings/iio/adc/fsl-imx25-gcq.h> + 0: YP voltage reference + 1: XP voltage reference + 2: External voltage reference + 3: Internal voltage reference (default) + minimum: 0 + maximum: 3 + + fsl,adc-refn: + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + Specifies the negative reference input as defined in + <dt-bindings/iio/adc/fsl-imx25-gcq.h> + 0: XN ground reference + 1: YN ground reference + 2: Internal ground reference + 3: External ground reference (default) + minimum: 0 + maximum: 3 + + required: + - reg + + additionalProperties: false + +additionalProperties: false + +examples: + - | + #include <dt-bindings/iio/adc/fsl-imx25-gcq.h> + soc { + #address-cells = <1>; + #size-cells = <1>; + adc@50030800 { + compatible = "fsl,imx25-gcq"; + reg = <0x50030800 0x60>; + interrupt-parent = <&tscadc>; + interrupts = <1>; + #address-cells = <1>; + #size-cells = <0>; + + inaux@5 { + reg = <5>; + fsl,adc-refp = <MX25_ADC_REFP_INT>; + fsl,adc-refn = <MX25_ADC_REFN_NGND>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,imx7d-adc.yaml b/Documentation/devicetree/bindings/iio/adc/fsl,imx7d-adc.yaml new file mode 100644 index 000000000000..afc5cc48a0ce --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/fsl,imx7d-adc.yaml @@ -0,0 +1,62 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/fsl,imx7d-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale ADC found on the imx7d SoC + +maintainers: + - Haibo Chen <haibo.chen@nxp.com> + +properties: + compatible: + const: fsl,imx7d-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: adc + + vref-supply: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - vref-supply + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/clock/imx7d-clock.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + soc { + #address-cells = <1>; + #size-cells = <1>; + adc@30610000 { + compatible = "fsl,imx7d-adc"; + reg = <0x30610000 0x10000>; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX7D_ADC_ROOT_CLK>; + clock-names = "adc"; + vref-supply = <®_vcc_3v3_mcu>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,vf610-adc.yaml b/Documentation/devicetree/bindings/iio/adc/fsl,vf610-adc.yaml new file mode 100644 index 000000000000..1ca571056ea9 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/fsl,vf610-adc.yaml @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/fsl,vf610-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ADC found on Freescale vf610 and similar SoCs + +maintainers: + - Fugang Duan <fugang.duan@nxp.com> + +description: + ADCs found on vf610/i.MX6slx and upward SoCs from Freescale. + +properties: + compatible: + const: fsl,vf610-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + description: ADC source clock (ipg clock) + maxItems: 1 + + clock-names: + const: adc + + vref-supply: + description: ADC reference voltage supply. + + fsl,adck-max-frequency: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 3 + maxItems: 3 + description: | + Maximum frequencies from datasheet operating requirements. + Three values necessary to cover the 3 conversion modes. + * Frequency in normal mode (ADLPC=0, ADHSC=0) + * Frequency in high-speed mode (ADLPC=0, ADHSC=1) + * Frequency in low-power mode (ADLPC=1, ADHSC=0) + + min-sample-time: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Minimum sampling time in nanoseconds. This value has + to be chosen according to the conversion mode and the connected analog + source resistance (R_as) and capacitance (C_as). Refer the datasheet's + operating requirements. A safe default across a wide range of R_as and + C_as as well as conversion modes is 1000ns. + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - vref-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/vf610-clock.h> + adc@4003b000 { + compatible = "fsl,vf610-adc"; + reg = <0x4003b000 0x1000>; + interrupts = <0 53 0x04>; + clocks = <&clks VF610_CLK_ADC0>; + clock-names = "adc"; + fsl,adck-max-frequency = <30000000>, <40000000>, <20000000>; + vref-supply = <®_vcc_3v3_mcu>; + min-sample-time = <10000>; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/hi8435.txt b/Documentation/devicetree/bindings/iio/adc/hi8435.txt deleted file mode 100644 index 3b0348c5e516..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/hi8435.txt +++ /dev/null @@ -1,21 +0,0 @@ -Holt Integrated Circuits HI-8435 threshold detector bindings - -Required properties: - - compatible: should be "holt,hi8435" - - reg: spi chip select number for the device - -Recommended properties: - - spi-max-frequency: definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Optional properties: - - gpios: GPIO used for controlling the reset pin - -Example: -sensor@0 { - compatible = "holt,hi8435"; - reg = <0>; - gpios = <&gpio6 1 0>; - - spi-max-frequency = <1000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/holt,hi8435.yaml b/Documentation/devicetree/bindings/iio/adc/holt,hi8435.yaml new file mode 100644 index 000000000000..9514c3381c42 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/holt,hi8435.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/holt,hi8435.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Holt Integrated Circuits HI-8435 SPI threshold detector + +maintainers: + - Vladimir Barinov <vladimir.barinov@cogentembedded.com> + +description: | + Datasheet: http://www.holtic.com/documents/427-hi-8435_v-rev-lpdf.do + +properties: + compatible: + const: holt,hi8435 + + reg: + maxItems: 1 + + gpios: + description: + GPIO used for controlling the reset pin + maxItems: 1 + + spi-max-frequency: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + threshold-detector@0 { + compatible = "holt,hi8435"; + reg = <0>; + gpios = <&gpio6 1 0>; + spi-max-frequency = <1000000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/imx7d-adc.txt b/Documentation/devicetree/bindings/iio/adc/imx7d-adc.txt deleted file mode 100644 index f1f3a552459b..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/imx7d-adc.txt +++ /dev/null @@ -1,24 +0,0 @@ -Freescale imx7d ADC bindings - -The devicetree bindings are for the ADC driver written for -imx7d SoC. - -Required properties: -- compatible: Should be "fsl,imx7d-adc" -- reg: Offset and length of the register set for the ADC device -- interrupts: The interrupt number for the ADC device -- clocks: The root clock of the ADC controller -- clock-names: Must contain "adc", matching entry in the clocks property -- vref-supply: The regulator supply ADC reference voltage -- #io-channel-cells: Must be 1 as per ../iio-bindings.txt - -Example: -adc1: adc@30610000 { - compatible = "fsl,imx7d-adc"; - reg = <0x30610000 0x10000>; - interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMX7D_ADC_ROOT_CLK>; - clock-names = "adc"; - vref-supply = <®_vcc_3v3_mcu>; - #io-channel-cells = <1>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt b/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt deleted file mode 100644 index 9ada5abd45fa..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/lpc1850-adc.txt +++ /dev/null @@ -1,20 +0,0 @@ -NXP LPC1850 ADC bindings - -Required properties: -- compatible: Should be "nxp,lpc1850-adc" -- reg: Offset and length of the register set for the ADC device -- interrupts: The interrupt number for the ADC device -- clocks: The root clock of the ADC controller -- vref-supply: The regulator supply ADC reference voltage -- resets: phandle to reset controller and line specifier - -Example: - -adc0: adc@400e3000 { - compatible = "nxp,lpc1850-adc"; - reg = <0x400e3000 0x1000>; - interrupts = <17>; - clocks = <&ccu1 CLK_APB3_ADC0>; - vref-supply = <®_vdda>; - resets = <&rgu 40>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/lpc32xx-adc.txt b/Documentation/devicetree/bindings/iio/adc/lpc32xx-adc.txt deleted file mode 100644 index 3a1bc669bd51..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/lpc32xx-adc.txt +++ /dev/null @@ -1,21 +0,0 @@ -* NXP LPC32xx SoC ADC controller - -Required properties: -- compatible: must be "nxp,lpc3220-adc" -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: The ADC interrupt - -Optional: - - vref-supply: The regulator supply ADC reference voltage, optional - for legacy reason, but highly encouraging to us in new device tree - -Example: - - adc@40048000 { - compatible = "nxp,lpc3220-adc"; - reg = <0x40048000 0x1000>; - interrupt-parent = <&mic>; - interrupts = <39 0>; - vref-supply = <&vcc>; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/marvell,berlin2-adc.yaml b/Documentation/devicetree/bindings/iio/adc/marvell,berlin2-adc.yaml new file mode 100644 index 000000000000..b3b292fb1c59 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/marvell,berlin2-adc.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/marvell,berlin2-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Berlin 2 Analog to Digital Converter (ADC) + +maintainers: + - Antoine Tenart <antoine.tenart@free-electrons.com> + +description: + The Berlin ADC has 8 channels, with one connected to a temperature sensor. + It is part of the system controller register set. The ADC node should be a + sub-node of the system controller node. + +properties: + compatible: + const: marvell,berlin2-adc + + interrupts: + minItems: 2 + maxItems: 2 + + interrupt-names: + items: + - const: adc + - const: tsen + + "#io-channel-cells": + const: 1 + +required: + - compatible + - interrupts + - interrupt-names + +additionalProperties: false + +examples: + - | + sysctrl { + adc { + compatible = "marvell,berlin2-adc"; + interrupt-parent = <&sic>; + interrupts = <12>, <14>; + interrupt-names = "adc", "tsen"; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml b/Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml new file mode 100644 index 000000000000..a6cb857a232d --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/motorola,cpcap-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Motorola CPCAP PMIC ADC binding + +maintainers: + - Tony Lindgren <tony@atomide.com> + +description: + On Motorola phones like droid 4 there is a custom CPCAP PMIC. This PMIC + has ADCs that are used for battery charging and USB PHY VBUS and ID pin + detection. + +properties: + compatible: + enum: + - motorola,cpcap-adc + - motorola,mapphone-cpcap-adc + + interrupts: + maxItems: 1 + + interrupt-names: + const: adcdone + + "#io-channel-cells": + const: 1 + +required: + - compatible + - interrupts + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + pmic { + #address-cells = <1>; + #size-cells = <0>; + adc { + compatible = "motorola,mapphone-cpcap-adc"; + interrupt-parent = <&cpcap>; + interrupts = <8 IRQ_TYPE_NONE>; + interrupt-names = "adcdone"; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,nau7802.yaml b/Documentation/devicetree/bindings/iio/adc/nuvoton,nau7802.yaml new file mode 100644 index 000000000000..04566ff02eb6 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,nau7802.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/nuvoton,nau7802.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton NAU7802 I2c Analog to Digital Converter (ADC) + +maintainers: + - Alexandre Belloni <alexandre.belloni@bootlin.com> + - Maxime Ripard <mripard@kernel.org> + +properties: + compatible: + const: nuvoton,nau7802 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + nuvoton,vldo: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Internal reference voltage in millivolts to be configured. + minimum: 2400 + maximum: 4500 + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + nau7802@2a { + compatible = "nuvoton,nau7802"; + reg = <0x2a>; + nuvoton,vldo = <3000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt deleted file mode 100644 index ef8eeec1a997..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm-adc.txt +++ /dev/null @@ -1,26 +0,0 @@ -Nuvoton NPCM Analog to Digital Converter (ADC) - -The NPCM ADC is a 10-bit converter for eight channel inputs. - -Required properties: -- compatible: "nuvoton,npcm750-adc" for the NPCM7XX BMC. -- reg: specifies physical base address and size of the registers. -- interrupts: Contain the ADC interrupt with flags for falling edge. -- resets : phandle to the reset control for this device. - -Optional properties: -- clocks: phandle of ADC reference clock, in case the clock is not - added the ADC will use the default ADC sample rate. -- vref-supply: The regulator supply ADC reference voltage, in case the - vref-supply is not added the ADC will use internal voltage - reference. - -Example: - -adc: adc@f000c000 { - compatible = "nuvoton,npcm750-adc"; - reg = <0xf000c000 0x8>; - interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk NPCM7XX_CLK_ADC>; - resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm750-adc.yaml b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm750-adc.yaml new file mode 100644 index 000000000000..001cf263b7d5 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,npcm750-adc.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/nuvoton,npcm750-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nuvoton NPCM BMC Analog to Digital Converter (ADC) + +maintainers: + - Tomer Maimon <tmaimon77@gmail.com> + +description: + The NPCM ADC is a 10-bit converter for eight channel inputs. + +properties: + compatible: + const: nuvoton,npcm750-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + description: ADC interrupt, should be set for falling edge. + + resets: + maxItems: 1 + + clocks: + maxItems: 1 + description: If not provided the defulat ADC sample rate will be used. + + vref-supply: + description: If not supplied, the internal voltage reference will be used. + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - resets + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/clock/nuvoton,npcm7xx-clock.h> + #include <dt-bindings/reset/nuvoton,npcm7xx-reset.h> + soc { + #address-cells = <1>; + #size-cells = <1>; + adc@f000c000 { + compatible = "nuvoton,npcm750-adc"; + reg = <0xf000c000 0x8>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM7XX_CLK_ADC>; + resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt b/Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt deleted file mode 100644 index e9582e6fe350..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/nuvoton-nau7802.txt +++ /dev/null @@ -1,18 +0,0 @@ -* Nuvoton NAU7802 Analog to Digital Converter (ADC) - -Required properties: - - compatible: Should be "nuvoton,nau7802" - - reg: Should contain the ADC I2C address - -Optional properties: - - nuvoton,vldo: Internal reference voltage in millivolts to be - configured valid values are between 2400 mV and 4500 mV. - - interrupts: IRQ line for the ADC. If not used the driver will use - polling. - -Example: -adc2: nau7802@2a { - compatible = "nuvoton,nau7802"; - reg = <0x2a>; - nuvoton,vldo = <3000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/nxp,lpc1850-adc.yaml b/Documentation/devicetree/bindings/iio/adc/nxp,lpc1850-adc.yaml new file mode 100644 index 000000000000..6404fb73f8ed --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nxp,lpc1850-adc.yaml @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/nxp,lpc1850-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP LPC1850 ADC bindings + +maintainers: + - Joachim Eastwood <manabian@gmail.com> + +description: + Supports the ADC found on the LPC1850 SoC. + +properties: + compatible: + const: nxp,lpc1850-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + vref-supply: true + + resets: + maxItems: 1 + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - vref-supply + - resets + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/lpc18xx-ccu.h> + soc { + #address-cells = <1>; + #size-cells = <1>; + adc@400e3000 { + compatible = "nxp,lpc1850-adc"; + reg = <0x400e3000 0x1000>; + interrupts = <17>; + clocks = <&ccu1 CLK_APB3_ADC0>; + vref-supply = <®_vdda>; + resets = <&rgu 40>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/nxp,lpc3220-adc.yaml b/Documentation/devicetree/bindings/iio/adc/nxp,lpc3220-adc.yaml new file mode 100644 index 000000000000..2c5032be83bd --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nxp,lpc3220-adc.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/nxp,lpc3220-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP LPC3220 SoC ADC controller + +maintainers: + - Gregory Clement <gregory.clement@bootlin.com> + +description: + This hardware block has been used on several LPC32XX SoCs. + +properties: + compatible: + const: nxp,lpc3220-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + vref-supply: true + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + soc { + #address-cells = <1>; + #size-cells = <1>; + adc@40048000 { + compatible = "nxp,lpc3220-adc"; + reg = <0x40048000 0x1000>; + interrupt-parent = <&mic>; + interrupts = <39 0>; + vref-supply = <&vcc>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml index cc3c8ea6a894..37d6591ff78c 100644 --- a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml @@ -41,7 +41,10 @@ properties: maxItems: 2 interrupts: - maxItems: 1 + description: + ADC interrupt followed by optional touchscreen interrupt. + minItems: 1 + maxItems: 2 "#io-channel-cells": const: 1 @@ -78,7 +81,6 @@ allOf: - samsung,exynos-adc-v2 - samsung,exynos3250-adc - samsung,exynos4212-adc - - samsung,s5pv210-adc then: required: - samsung,syscon-phandle @@ -107,6 +109,15 @@ allOf: items: - const: adc + - if: + required: + - has-touchscreen + then: + properties: + interrupts: + minItems: 2 + maxItems: 2 + examples: - | adc: adc@12d10000 { diff --git a/Documentation/devicetree/bindings/iio/adc/sprd,sc2720-adc.yaml b/Documentation/devicetree/bindings/iio/adc/sprd,sc2720-adc.yaml new file mode 100644 index 000000000000..caa3ee0b4b8c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/sprd,sc2720-adc.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/sprd,sc2720-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Spreadtrum SC27XX series PMICs ADC binding + +maintainers: + - Baolin Wang <baolin.wang7@gmail.com> + +description: + Supports the ADC found on these PMICs. + +properties: + compatible: + enum: + - sprd,sc2720-adc + - sprd,sc2721-adc + - sprd,sc2723-adc + - sprd,sc2730-adc + - sprd,sc2731-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + "#io-channel-cells": + const: 1 + + hwlocks: + maxItems: 1 + + nvmem-cells: + maxItems: 2 + + nvmem-cell-names: + items: + - const: big_scale_calib + - const: small_scale_calib + +required: + - compatible + - reg + - interrupts + - "#io-channel-cells" + - hwlocks + - nvmem-cells + - nvmem-cell-names + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + pmic { + #address-cells = <1>; + #size-cells = <0>; + adc@480 { + compatible = "sprd,sc2731-adc"; + reg = <0x480>; + interrupt-parent = <&sc2731_pmic>; + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; + #io-channel-cells = <1>; + hwlocks = <&hwlock 4>; + nvmem-cells = <&adc_big_scale>, <&adc_small_scale>; + nvmem-cell-names = "big_scale_calib", "small_scale_calib"; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt b/Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt deleted file mode 100644 index b4daa15dcf15..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/sprd,sc27xx-adc.txt +++ /dev/null @@ -1,40 +0,0 @@ -Spreadtrum SC27XX series PMICs ADC binding - -Required properties: -- compatible: Should be one of the following. - "sprd,sc2720-adc" - "sprd,sc2721-adc" - "sprd,sc2723-adc" - "sprd,sc2730-adc" - "sprd,sc2731-adc" -- reg: The address offset of ADC controller. -- interrupt-parent: The interrupt controller. -- interrupts: The interrupt number for the ADC device. -- #io-channel-cells: Number of cells in an IIO specifier. -- hwlocks: Reference to a phandle of a hwlock provider node. -- nvmem-cells: A phandle to the calibration cells provided by eFuse device. -- nvmem-cell-names: Should be "big_scale_calib", "small_scale_calib". - -Example: - - sc2731_pmic: pmic@0 { - compatible = "sprd,sc2731"; - reg = <0>; - spi-max-frequency = <26000000>; - interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; - interrupt-controller; - #interrupt-cells = <2>; - #address-cells = <1>; - #size-cells = <0>; - - pmic_adc: adc@480 { - compatible = "sprd,sc2731-adc"; - reg = <0x480>; - interrupt-parent = <&sc2731_pmic>; - interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; - #io-channel-cells = <1>; - hwlocks = <&hwlock 4>; - nvmem-cells = <&adc_big_scale>, <&adc_small_scale>; - nvmem-cell-names = "big_scale_calib", "small_scale_calib"; - }; - }; diff --git a/Documentation/devicetree/bindings/iio/adc/st,stmpe-adc.yaml b/Documentation/devicetree/bindings/iio/adc/st,stmpe-adc.yaml new file mode 100644 index 000000000000..9049c699152f --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/st,stmpe-adc.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/st,stmpe-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ADC on an STMPE multifunction device. + +maintainers: + - Stefan Agner <stefan@agner.ch> + +description: + This ADC forms part of an ST microelectronics STMPE multifunction device . + The ADC is shared with the STMPE touchscreen. As a result some ADC related + settings are specified in the parent node. + The node name myst be stmpe_adc and should be a child node of the stmpe node + to which it belongs. + +properties: + compatible: + const: st,stmpe-adc + + st,norequest-mask: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Bitmask specifying which ADC channels should _not_ be + requestable due to different usage (e.g. touch). + + "#io-channel-cells": + const: 1 + +required: + - compatible + +additionalProperties: false + +examples: + - | + stmpe { + stmpe_adc { + compatible = "st,stmpe-adc"; + st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */ + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt b/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt deleted file mode 100644 index 480e66422625..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt +++ /dev/null @@ -1,21 +0,0 @@ -STMPE ADC driver ----------------- - -Required properties: - - compatible: "st,stmpe-adc" - -Optional properties: -Note that the ADC is shared with the STMPE touchscreen. ADC related settings -have to be done in the mfd. -- st,norequest-mask: bitmask specifying which ADC channels should _not_ be - requestable due to different usage (e.g. touch) - -Node name must be stmpe_adc and should be child node of stmpe node to -which it belongs. - -Example: - - stmpe_adc { - compatible = "st,stmpe-adc"; - st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */ - }; diff --git a/Documentation/devicetree/bindings/iio/adc/ti,adc12138.yaml b/Documentation/devicetree/bindings/iio/adc/ti,adc12138.yaml new file mode 100644 index 000000000000..ec3b2edf1fb7 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,adc12138.yaml @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,adc12138.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADC12138 and similar self-calibrating ADCs + +maintainers: + - Akinobu Mita <akinobu.mita@gmail.com> + +description: | + 13 bit ADCs with 1, 2 or 8 inputs and self calibrating circuitry to + correct for linearity, zero and full scale errors. + +properties: + compatible: + enum: + - ti,adc12130 + - ti,adc12132 + - ti,adc12138 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + description: End of Conversion (EOC) interrupt + + clocks: + maxItems: 1 + description: Conversion clock input. + + spi-max-frequency: true + + vref-p-supply: + description: The regulator supply for positive analog voltage reference + + vref-n-supply: + description: | + The regulator supply for negative analog voltage reference + (Note that this must not go below GND or exceed vref-p) + If not specified, this is assumed to be analog ground. + + ti,acquisition-time: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 6, 10, 18, 34 ] + description: | + The number of conversion clock periods for the S/H's acquisition time. + For high source impedances, this value can be increased to 18 or 34. + For less ADC accuracy and/or slower CCLK frequencies this value may be + decreased to 6. See section 6.0 INPUT SOURCE RESISTANCE in the + datasheet for details. + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - vref-p-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,adc12138"; + reg = <0>; + interrupts = <28 IRQ_TYPE_EDGE_RISING>; + interrupt-parent = <&gpio1>; + clocks = <&cclk>; + vref-p-supply = <&ldo4_reg>; + spi-max-frequency = <5000000>; + ti,acquisition-time = <6>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml new file mode 100644 index 000000000000..2c2d01bbc296 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads1015.yaml @@ -0,0 +1,112 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,ads1015.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI ADS1015 4 channel I2C analog to digital converter + +maintainers: + - Daniel Baluta <daniel.baluta@nxp.com> + +description: | + Datasheet at: https://www.ti.com/lit/gpn/ads1015 + Supports both single ended and differential channels. + +properties: + compatible: + const: ti,ads1015 + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + +additionalProperties: false + +patternProperties: + "^channel@[0-7]+$": + type: object + description: + Child nodes needed for each channel that the platform uses. + + properties: + reg: + description: | + 0: Voltage over AIN0 and AIN1. + 1: Voltage over AIN0 and AIN3. + 2: Voltage over AIN1 and AIN3. + 3: Voltage over AIN2 and AIN3. + 4: Voltage over AIN0 and GND. + 5: Voltage over AIN1 and GND. + 6: Voltage over AIN2 and GND. + 7: Voltage over AIN3 and GND. + items: + - minimum: 0 + maximum: 7 + + ti,gain: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 5 + description: | + pga is the programmable gain amplifier (values are full scale) + 0: +/- 6.144 V + 1: +/- 4.096 V + 2: +/- 2.048 V (default) + 3: +/- 1.024 V + 4: +/- 0.512 V + 5: +/- 0.256 V + + ti,datarate: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 6 + description: | + Data acquisition rate in samples per second + 0: 128 + 1: 250 + 2: 490 + 3: 920 + 4: 1600 (default) + 5: 2400 + 6: 3300 + + required: + - reg + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + adc@49 { + compatible = "ti,ads1015"; + reg = <0x49>; + #address-cells = <1>; + #size-cells = <0>; + channel@0 { + reg = <0>; + }; + channel@4 { + reg = <4>; + ti,gain = <3>; + ti,datarate = <5>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads7950.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads7950.yaml new file mode 100644 index 000000000000..5ab5027be97e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads7950.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,ads7950.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADS7950 and similar ADCs + +maintainers: + - David Lechner <david@lechnology.com> + +description: | + Family of 4-16 channel, 8-12 bit ADCs with SPI interface. + +properties: + compatible: + enum: + - ti,ads7950 + - ti,ads7951 + - ti,ads7952 + - ti,ads7953 + - ti,ads7954 + - ti,ads7955 + - ti,ads7956 + - ti,ads7957 + - ti,ads7958 + - ti,ads7959 + - ti,ads7960 + - ti,ads7961 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 20000000 + + vref-supply: + description: Supplies the 2.5V or 5V reference voltage + + "#io-channel-cells": + const: 1 + +required: + - compatible + - reg + - vref-supply + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,ads7957"; + reg = <0>; + vref-supply = <&refin_supply>; + spi-max-frequency = <10000000>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti,twl4030-madc.yaml b/Documentation/devicetree/bindings/iio/adc/ti,twl4030-madc.yaml new file mode 100644 index 000000000000..6781ad2f0f51 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,twl4030-madc.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,twl4030-madc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MADC subsystem in the TWL4030 power module + +maintainers: + - Sebastian Reichel <sre@kernel.org> + +description: + The MADC subsystem in the TWL4030 consists of a 10-bit ADC + combined with a 16-input analog multiplexer. + +properties: + compatible: + const: ti,twl4030-madc + + interrupts: + maxItems: 1 + + ti,system-uses-second-madc-irq: + type: boolean + description: + Set if the second madc irq register should be used, which is intended + to be used by Co-Processors (e.g. a modem). + + "#io-channel-cells": + const: 1 + +required: + - compatible + - interrupts + - "#io-channel-cells" + +additionalProperties: false + +examples: + - | + twl { + madc { + compatible = "ti,twl4030-madc"; + interrupts = <3>; + #io-channel-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt deleted file mode 100644 index 049a1d36f013..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc12138.txt +++ /dev/null @@ -1,37 +0,0 @@ -* Texas Instruments' ADC12130/ADC12132/ADC12138 - -Required properties: - - compatible: Should be one of - * "ti,adc12130" - * "ti,adc12132" - * "ti,adc12138" - - reg: SPI chip select number for the device - - interrupts: Should contain interrupt for EOC (end of conversion) - - clocks: phandle to conversion clock input - - spi-max-frequency: Definision as per - Documentation/devicetree/bindings/spi/spi-bus.txt - - vref-p-supply: The regulator supply for positive analog voltage reference - -Optional properties: - - vref-n-supply: The regulator supply for negative analog voltage reference - (Note that this must not go below GND or exceed vref-p) - If not specified, this is assumed to be analog ground. - - ti,acquisition-time: The number of conversion clock periods for the S/H's - acquisition time. Should be one of 6, 10, 18, 34. If not specified, - default value of 10 is used. - For high source impedances, this value can be increased to 18 or 34. - For less ADC accuracy and/or slower CCLK frequencies this value may be - decreased to 6. See section 6.0 INPUT SOURCE RESISTANCE in the - datasheet for details. - -Example: -adc@0 { - compatible = "ti,adc12138"; - reg = <0>; - interrupts = <28 IRQ_TYPE_EDGE_RISING>; - interrupt-parent = <&gpio1>; - clocks = <&cclk>; - vref-p-supply = <&ldo4_reg>; - spi-max-frequency = <5000000>; - ti,acquisition-time = <6>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt b/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt deleted file mode 100644 index e77a6f7e1001..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt +++ /dev/null @@ -1,23 +0,0 @@ -* Texas Instruments ADS7950 family of A/DC chips - -Required properties: - - compatible: Must be one of "ti,ads7950", "ti,ads7951", "ti,ads7952", - "ti,ads7953", "ti,ads7954", "ti,ads7955", "ti,ads7956", "ti,ads7957", - "ti,ads7958", "ti,ads7959", "ti,ads7960", or "ti,ads7961" - - reg: SPI chip select number for the device - - #io-channel-cells: Must be 1 as per ../iio-bindings.txt - - vref-supply: phandle to a regulator node that supplies the 2.5V or 5V - reference voltage - -Recommended properties: - - spi-max-frequency: Definition as per - Documentation/devicetree/bindings/spi/spi-bus.txt - -Example: -adc@0 { - compatible = "ti,ads7957"; - reg = <0>; - #io-channel-cells = <1>; - vref-supply = <&refin_supply>; - spi-max-frequency = <10000000>; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt b/Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt deleted file mode 100644 index 6bdd21404b57..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/twl4030-madc.txt +++ /dev/null @@ -1,24 +0,0 @@ -* TWL4030 Monitoring Analog to Digital Converter (MADC) - -The MADC subsystem in the TWL4030 consists of a 10-bit ADC -combined with a 16-input analog multiplexer. - -Required properties: - - compatible: Should contain "ti,twl4030-madc". - - interrupts: IRQ line for the MADC submodule. - - #io-channel-cells: Should be set to <1>. - -Optional properties: - - ti,system-uses-second-madc-irq: boolean, set if the second madc irq register - should be used, which is intended to be used - by Co-Processors (e.g. a modem). - -Example: - -&twl { - madc { - compatible = "ti,twl4030-madc"; - interrupts = <3>; - #io-channel-cells = <1>; - }; -}; diff --git a/Documentation/devicetree/bindings/iio/adc/vf610-adc.txt b/Documentation/devicetree/bindings/iio/adc/vf610-adc.txt deleted file mode 100644 index 1aad0514e647..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/vf610-adc.txt +++ /dev/null @@ -1,36 +0,0 @@ -Freescale vf610 Analog to Digital Converter bindings - -The devicetree bindings are for the new ADC driver written for -vf610/i.MX6slx and upward SoCs from Freescale. - -Required properties: -- compatible: Should contain "fsl,vf610-adc" -- reg: Offset and length of the register set for the device -- interrupts: Should contain the interrupt for the device -- clocks: The clock is needed by the ADC controller, ADC clock source is ipg clock. -- clock-names: Must contain "adc", matching entry in the clocks property. -- vref-supply: The regulator supply ADC reference voltage. - -Recommended properties: -- fsl,adck-max-frequency: Maximum frequencies according to datasheets operating - requirements. Three values are required, depending on conversion mode: - - Frequency in normal mode (ADLPC=0, ADHSC=0) - - Frequency in high-speed mode (ADLPC=0, ADHSC=1) - - Frequency in low-power mode (ADLPC=1, ADHSC=0) -- min-sample-time: Minimum sampling time in nanoseconds. This value has - to be chosen according to the conversion mode and the connected analog - source resistance (R_as) and capacitance (C_as). Refer the datasheet's - operating requirements. A safe default across a wide range of R_as and - C_as as well as conversion modes is 1000ns. - -Example: -adc0: adc@4003b000 { - compatible = "fsl,vf610-adc"; - reg = <0x4003b000 0x1000>; - interrupts = <0 53 0x04>; - clocks = <&clks VF610_CLK_ADC0>; - clock-names = "adc"; - fsl,adck-max-frequency = <30000000>, <40000000>, - <20000000>; - vref-supply = <®_vcc_3v3_mcu>; -}; diff --git a/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml b/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml index 61adb2c2454b..662ec59ca0af 100644 --- a/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml +++ b/Documentation/devicetree/bindings/iio/gyroscope/adi,adxrs290.yaml @@ -28,6 +28,9 @@ properties: spi-cpha: true + interrupts: + maxItems: 1 + required: - compatible - reg @@ -39,6 +42,7 @@ additionalProperties: false examples: - | + #include <dt-bindings/interrupt-controller/irq.h> spi { #address-cells = <1>; #size-cells = <0>; @@ -48,6 +52,8 @@ examples: spi-max-frequency = <5000000>; spi-cpol; spi-cpha; + interrupt-parent = <&gpio>; + interrupts = <25 IRQ_TYPE_EDGE_RISING>; }; }; ... diff --git a/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml b/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml index 58887a4f9c15..4d1a225e8868 100644 --- a/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml +++ b/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml @@ -24,6 +24,10 @@ properties: - vishay,vcnl4020 - vishay,vcnl4040 - vishay,vcnl4200 + + interrupts: + maxItems: 1 + reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt index aac5f621f8dc..dfe00eb961cd 100644 --- a/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt +++ b/Documentation/devicetree/bindings/iio/proximity/vl53l0x.txt @@ -4,9 +4,15 @@ Required properties: - compatible: must be "st,vl53l0x" - reg: i2c address where to find the device +Optional properties: + - interrupts: Interrupt for notifying that new measurement is ready. + If no interrupt is specified, polling is used. + Example: vl53l0x@29 { compatible = "st,vl53l0x"; reg = <0x29>; + interrupt-parent = <&gpio>; + interrupts = <23 IRQ_TYPE_EDGE_FALLING>; }; diff --git a/MAINTAINERS b/MAINTAINERS index 311f705d72d4..924616dc19ff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -950,38 +950,6 @@ S: Maintained F: Documentation/devicetree/bindings/iio/light/ams,as73211.yaml F: drivers/iio/light/as73211.c -ANALOG DEVICES INC AD5686 DRIVER -M: Michael Hennerich <Michael.Hennerich@analog.com> -L: linux-pm@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: drivers/iio/dac/ad5686* -F: drivers/iio/dac/ad5696* - -ANALOG DEVICES INC AD5758 DRIVER -M: Michael Hennerich <Michael.Hennerich@analog.com> -L: linux-iio@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/dac/ad5758.txt -F: drivers/iio/dac/ad5758.c - -ANALOG DEVICES INC AD7091R5 DRIVER -M: Beniamin Bia <beniamin.bia@analog.com> -L: linux-iio@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/adc/adi,ad7091r5.yaml -F: drivers/iio/adc/ad7091r5.c - -ANALOG DEVICES INC AD7124 DRIVER -M: Michael Hennerich <Michael.Hennerich@analog.com> -L: linux-iio@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml -F: drivers/iio/adc/ad7124.c - ANALOG DEVICES INC AD7192 DRIVER M: Alexandru Tachici <alexandru.tachici@analog.com> L: linux-iio@vger.kernel.org @@ -998,15 +966,6 @@ W: http://ez.analog.com/community/linux-device-drivers F: Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml F: drivers/iio/adc/ad7292.c -ANALOG DEVICES INC AD7606 DRIVER -M: Michael Hennerich <Michael.Hennerich@analog.com> -M: Beniamin Bia <beniamin.bia@analog.com> -L: linux-iio@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml -F: drivers/iio/adc/ad7606.c - ANALOG DEVICES INC AD7768-1 DRIVER M: Michael Hennerich <Michael.Hennerich@analog.com> L: linux-iio@vger.kernel.org @@ -1068,7 +1027,6 @@ F: drivers/iio/imu/adis16475.c F: Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml ANALOG DEVICES INC ADM1177 DRIVER -M: Beniamin Bia <beniamin.bia@analog.com> M: Michael Hennerich <Michael.Hennerich@analog.com> L: linux-hwmon@vger.kernel.org S: Supported @@ -1142,15 +1100,6 @@ S: Supported W: http://ez.analog.com/community/linux-device-drivers F: drivers/dma/dma-axi-dmac.c -ANALOG DEVICES INC HMC425A DRIVER -M: Beniamin Bia <beniamin.bia@analog.com> -M: Michael Hennerich <michael.hennerich@analog.com> -L: linux-iio@vger.kernel.org -S: Supported -W: http://ez.analog.com/community/linux-device-drivers -F: Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml -F: drivers/iio/amplifiers/hmc425a.c - ANALOG DEVICES INC IIO DRIVERS M: Lars-Peter Clausen <lars@metafoo.de> M: Michael Hennerich <Michael.Hennerich@analog.com> @@ -1159,8 +1108,11 @@ W: http://wiki.analog.com/ W: http://ez.analog.com/community/linux-device-drivers F: Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523 F: Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 +F: Documentation/devicetree/bindings/iio/*/adi,* +F: Documentation/devicetree/bindings/iio/dac/ad5758.txt F: drivers/iio/*/ad* F: drivers/iio/adc/ltc249* +F: drivers/iio/amplifiers/hmc425a.c F: drivers/staging/iio/*/ad* X: drivers/iio/*/adjd* @@ -8524,7 +8476,6 @@ F: drivers/iio/multiplexer/iio-mux.c IIO SUBSYSTEM AND DRIVERS M: Jonathan Cameron <jic23@kernel.org> -R: Hartmut Knaack <knaack.h@gmx.de> R: Lars-Peter Clausen <lars@metafoo.de> R: Peter Meerwald-Stadler <pmeerw@pmeerw.net> L: linux-iio@vger.kernel.org @@ -16515,7 +16466,6 @@ F: drivers/staging/rtl8712/ STAGING - SEPS525 LCD CONTROLLER DRIVERS M: Michael Hennerich <michael.hennerich@analog.com> -M: Beniamin Bia <beniamin.bia@analog.com> L: linux-fbdev@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml diff --git a/drivers/iio/accel/adis16201.c b/drivers/iio/accel/adis16201.c index 59a24c355a1a..f955cccb3e77 100644 --- a/drivers/iio/accel/adis16201.c +++ b/drivers/iio/accel/adis16201.c @@ -281,34 +281,15 @@ static int adis16201_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) return ret; ret = adis_initial_startup(st); if (ret) - goto error_cleanup_buffer_trigger; - - ret = iio_device_register(indio_dev); - if (ret < 0) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16201_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static struct spi_driver adis16201_driver = { @@ -316,7 +297,6 @@ static struct spi_driver adis16201_driver = { .name = "adis16201", }, .probe = adis16201_probe, - .remove = adis16201_remove, }; module_spi_driver(adis16201_driver); diff --git a/drivers/iio/accel/adis16209.c b/drivers/iio/accel/adis16209.c index 3d5538e2f76e..4a841aec6268 100644 --- a/drivers/iio/accel/adis16209.c +++ b/drivers/iio/accel/adis16209.c @@ -291,33 +291,15 @@ static int adis16209_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) return ret; ret = adis_initial_startup(st); if (ret) - goto error_cleanup_buffer_trigger; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16209_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static struct spi_driver adis16209_driver = { @@ -325,7 +307,6 @@ static struct spi_driver adis16209_driver = { .name = "adis16209", }, .probe = adis16209_probe, - .remove = adis16209_remove, }; module_spi_driver(adis16209_driver); diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 448faed001fd..6b74c2b04c15 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -673,7 +673,7 @@ static const struct iio_chan_spec_ext_info bma023_ext_info[] = { }; static const struct iio_chan_spec_ext_info bma180_ext_info[] = { - IIO_ENUM("power_mode", true, &bma180_power_mode_enum), + IIO_ENUM("power_mode", IIO_SHARED_BY_TYPE, &bma180_power_mode_enum), IIO_ENUM_AVAILABLE("power_mode", &bma180_power_mode_enum), IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma180_accel_get_mount_matrix), { } diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 406a4b00fb1f..91ae90514aff 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -863,7 +863,7 @@ config RN5T618_ADC config ROCKCHIP_SARADC tristate "Rockchip SARADC driver" - depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) + depends on ARCH_ROCKCHIP || COMPILE_TEST depends on RESET_CONTROLLER select IIO_BUFFER select IIO_TRIGGERED_BUFFER diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c index d9566a83988a..5d597e5050f6 100644 --- a/drivers/iio/adc/ad7949.c +++ b/drivers/iio/adc/ad7949.c @@ -39,7 +39,7 @@ static const struct ad7949_adc_spec ad7949_adc_spec[] = { * struct ad7949_adc_chip - AD ADC chip * @lock: protects write sequences * @vref: regulator generating Vref - * @iio_dev: reference to iio structure + * @indio_dev: reference to iio structure * @spi: reference to spi structure * @resolution: resolution of the chip * @cfg: copy of the configuration register diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index 1e8fd83b9bc2..f068256cfca9 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -324,7 +324,7 @@ static int ad9467_setup(struct ad9467_state *st, unsigned int chip_id) AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; return 0; default: - return -EINVAL; + return -ENODEV; } } @@ -390,7 +390,8 @@ static int ad9467_probe(struct spi_device *spi) id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID); if (id != conv->chip_info->id) { - dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", id); + dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", + id, conv->chip_info->id); return -ENODEV; } diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 20477b249f2a..99f4404e9fd1 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -138,6 +138,16 @@ struct exynos_adc { bool read_ts; u32 ts_x; u32 ts_y; + + /* + * Lock to protect from potential concurrent access to the + * completion callback during a manual conversion. For this driver + * a wait-callback is used to wait for the conversion result, + * so in the meantime no other read request (or conversion start) + * must be performed, otherwise it would interfere with the + * current conversion result. + */ + struct mutex lock; }; struct exynos_adc_data { @@ -542,7 +552,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev, return -EINVAL; } - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); reinit_completion(&info->completion); /* Select the channel to be used and Trigger conversion */ @@ -562,7 +572,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev, ret = IIO_VAL_INT; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } @@ -573,7 +583,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y) unsigned long timeout; int ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&info->lock); info->read_ts = true; reinit_completion(&info->completion); @@ -598,7 +608,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y) } info->read_ts = false; - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&info->lock); return ret; } @@ -868,6 +878,8 @@ static int exynos_adc_probe(struct platform_device *pdev) indio_dev->channels = exynos_adc_iio_channels; indio_dev->num_channels = info->data->num_channels; + mutex_init(&info->lock); + ret = request_irq(info->irq, exynos_adc_isr, 0, dev_name(&pdev->dev), info); if (ret < 0) { diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c index 8cb51cf7a816..ab5139e911c3 100644 --- a/drivers/iio/adc/fsl-imx25-gcq.c +++ b/drivers/iio/adc/fsl-imx25-gcq.c @@ -40,6 +40,15 @@ struct mx25_gcq_priv { int irq; struct regulator *vref[4]; u32 channel_vref_mv[MX25_NUM_CFGS]; + /* + * Lock to protect the device state during a potential concurrent + * read access from userspace. Reading a raw value requires a sequence + * of register writes, then a wait for a completion callback, + * and finally a register read, during which userspace could issue + * another read request. This lock protects a read access from + * ocurring before another one has finished. + */ + struct mutex lock; }; #define MX25_CQG_CHAN(chan, id) {\ @@ -137,9 +146,9 @@ static int mx25_gcq_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); + mutex_lock(&priv->lock); ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&priv->lock); return ret; case IIO_CHAN_INFO_SCALE: @@ -314,6 +323,8 @@ static int mx25_gcq_probe(struct platform_device *pdev) return PTR_ERR(priv->regs); } + mutex_init(&priv->lock); + init_completion(&priv->completed); ret = mx25_gcq_setup_cfgs(pdev, priv); diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 95bd187de1cb..e03988698755 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -1150,16 +1150,13 @@ static const struct of_device_id meson_sar_adc_of_match[] = { { .compatible = "amlogic,meson8-saradc", .data = &meson_sar_adc_meson8_data, - }, - { + }, { .compatible = "amlogic,meson8b-saradc", .data = &meson_sar_adc_meson8b_data, - }, - { + }, { .compatible = "amlogic,meson8m2-saradc", .data = &meson_sar_adc_meson8m2_data, - }, - { + }, { .compatible = "amlogic,meson-gxbb-saradc", .data = &meson_sar_adc_gxbb_data, }, { @@ -1175,7 +1172,7 @@ static const struct of_device_id meson_sar_adc_of_match[] = { .compatible = "amlogic,meson-g12a-saradc", .data = &meson_sar_adc_g12a_data, }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match); diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index 1ca6570be66a..889b88768b63 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -834,18 +834,7 @@ static struct platform_driver palmas_gpadc_driver = { .of_match_table = of_palmas_gpadc_match_tbl, }, }; - -static int __init palmas_gpadc_init(void) -{ - return platform_driver_register(&palmas_gpadc_driver); -} -module_init(palmas_gpadc_init); - -static void __exit palmas_gpadc_exit(void) -{ - platform_driver_unregister(&palmas_gpadc_driver); -} -module_exit(palmas_gpadc_exit); +module_platform_driver(palmas_gpadc_driver); MODULE_DESCRIPTION("palmas GPADC driver"); MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>"); diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 3f27b4817a42..6a0338d33bd8 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c @@ -595,7 +595,7 @@ static int stm32_adc_core_switches_probe(struct device *dev, if (IS_ERR(priv->booster)) { ret = PTR_ERR(priv->booster); if (ret != -ENODEV) - dev_err_probe(dev, ret, "can't get booster\n"); + return dev_err_probe(dev, ret, "can't get booster\n"); priv->booster = NULL; } diff --git a/drivers/iio/adc/ti-adc0832.c b/drivers/iio/adc/ti-adc0832.c index c7a085dce1f4..0261b3cfc92b 100644 --- a/drivers/iio/adc/ti-adc0832.c +++ b/drivers/iio/adc/ti-adc0832.c @@ -29,6 +29,12 @@ struct adc0832 { struct regulator *reg; struct mutex lock; u8 mux_bits; + /* + * Max size needed: 16x 1 byte ADC data + 8 bytes timestamp + * May be shorter if not all channels are enabled subject + * to the timestamp remaining 8 byte aligned. + */ + u8 data[24] __aligned(8); u8 tx_buf[2] ____cacheline_aligned; u8 rx_buf[2]; @@ -200,7 +206,6 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adc0832 *adc = iio_priv(indio_dev); - u8 data[24] = { }; /* 16x 1 byte ADC data + 8 bytes timestamp */ int scan_index; int i = 0; @@ -218,10 +223,10 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p) goto out; } - data[i] = ret; + adc->data[i] = ret; i++; } - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, adc->data, iio_get_time_ns(indio_dev)); out: mutex_unlock(&adc->lock); diff --git a/drivers/iio/adc/ti-adc12138.c b/drivers/iio/adc/ti-adc12138.c index e485719cd2c4..fcd5d39dd03e 100644 --- a/drivers/iio/adc/ti-adc12138.c +++ b/drivers/iio/adc/ti-adc12138.c @@ -47,6 +47,12 @@ struct adc12138 { struct completion complete; /* The number of cclk periods for the S/H's acquisition time */ unsigned int acquisition_time; + /* + * Maximum size needed: 16x 2 bytes ADC data + 8 bytes timestamp. + * Less may be need if not all channels are enabled, as long as + * the 8 byte alignment of the timestamp is maintained. + */ + __be16 data[20] __aligned(8); u8 tx_buf[2] ____cacheline_aligned; u8 rx_buf[2]; @@ -329,7 +335,6 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adc12138 *adc = iio_priv(indio_dev); - __be16 data[20] = { }; /* 16x 2 bytes ADC data + 8 bytes timestamp */ __be16 trash; int ret; int scan_index; @@ -345,7 +350,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) reinit_completion(&adc->complete); ret = adc12138_start_and_read_conv(adc, scan_chan, - i ? &data[i - 1] : &trash); + i ? &adc->data[i - 1] : &trash); if (ret) { dev_warn(&adc->spi->dev, "failed to start conversion\n"); @@ -362,7 +367,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) } if (i) { - ret = adc12138_read_conv_data(adc, &data[i - 1]); + ret = adc12138_read_conv_data(adc, &adc->data[i - 1]); if (ret) { dev_warn(&adc->spi->dev, "failed to get conversion data\n"); @@ -370,7 +375,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) } } - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, adc->data, iio_get_time_ns(indio_dev)); out: mutex_unlock(&adc->lock); diff --git a/drivers/iio/chemical/ams-iaq-core.c b/drivers/iio/chemical/ams-iaq-core.c index 8c1b64fd424a..97be3669c554 100644 --- a/drivers/iio/chemical/ams-iaq-core.c +++ b/drivers/iio/chemical/ams-iaq-core.c @@ -7,6 +7,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> #include <linux/init.h> #include <linux/i2c.h> @@ -177,7 +178,7 @@ MODULE_DEVICE_TABLE(of, ams_iaqcore_dt_ids); static struct i2c_driver ams_iaqcore_driver = { .driver = { .name = "ams-iaq-core", - .of_match_table = of_match_ptr(ams_iaqcore_dt_ids), + .of_match_table = ams_iaqcore_dt_ids, }, .probe = ams_iaqcore_probe, .id_table = ams_iaqcore_id, diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c index 43069636fcd5..cdab9d04dedd 100644 --- a/drivers/iio/chemical/atlas-sensor.c +++ b/drivers/iio/chemical/atlas-sensor.c @@ -15,7 +15,7 @@ #include <linux/irq.h> #include <linux/irq_work.h> #include <linux/i2c.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/regmap.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -620,7 +620,6 @@ static int atlas_probe(struct i2c_client *client, { struct atlas_data *data; struct atlas_device *chip; - const struct of_device_id *of_id; struct iio_trigger *trig; struct iio_dev *indio_dev; int ret; @@ -629,11 +628,10 @@ static int atlas_probe(struct i2c_client *client, if (!indio_dev) return -ENOMEM; - of_id = of_match_device(atlas_dt_ids, &client->dev); - if (!of_id) + if (!dev_fwnode(&client->dev)) chip = &atlas_devices[id->driver_data]; else - chip = &atlas_devices[(unsigned long)of_id->data]; + chip = &atlas_devices[(unsigned long)device_get_match_data(&client->dev)]; indio_dev->info = &atlas_info; indio_dev->name = ATLAS_DRV_NAME; @@ -775,7 +773,7 @@ static const struct dev_pm_ops atlas_pm_ops = { static struct i2c_driver atlas_driver = { .driver = { .name = ATLAS_DRV_NAME, - .of_match_table = of_match_ptr(atlas_dt_ids), + .of_match_table = atlas_dt_ids, .pm = &atlas_pm_ops, }, .probe = atlas_probe, diff --git a/drivers/iio/chemical/sgp30.c b/drivers/iio/chemical/sgp30.c index 2c4086c48136..1029c457be15 100644 --- a/drivers/iio/chemical/sgp30.c +++ b/drivers/iio/chemical/sgp30.c @@ -20,9 +20,9 @@ #include <linux/delay.h> #include <linux/kthread.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> #include <linux/i2c.h> -#include <linux/of_device.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -227,6 +227,7 @@ static int sgp_verify_buffer(const struct sgp_data *data, * @cmd: SGP Command to issue * @buf: Raw data buffer to use * @word_count: Num words to read, excluding CRC bytes + * @duration_us: Time taken to sensor to take a reading and data to be ready. * * Return: 0 on success, negative error otherwise. */ @@ -409,6 +410,7 @@ static int sgp_read_raw(struct iio_dev *indio_dev, static int sgp_check_compat(struct sgp_data *data, unsigned int product_id) { + struct device *dev = &data->client->dev; const struct sgp_version *supported_versions; u16 ix, num_fs; u16 product, generation, major, minor; @@ -416,21 +418,20 @@ static int sgp_check_compat(struct sgp_data *data, /* driver does not match product */ generation = SGP_VERS_GEN(data); if (generation != 0) { - dev_err(&data->client->dev, + dev_err(dev, "incompatible product generation %d != 0", generation); return -ENODEV; } product = SGP_VERS_PRODUCT(data); if (product != product_id) { - dev_err(&data->client->dev, - "sensor reports a different product: 0x%04hx\n", + dev_err(dev, "sensor reports a different product: 0x%04hx\n", product); return -ENODEV; } if (SGP_VERS_RESERVED(data)) - dev_warn(&data->client->dev, "reserved bit is set\n"); + dev_warn(dev, "reserved bit is set\n"); /* engineering samples are not supported: no interface guarantees */ if (SGP_VERS_ENG_BIT(data)) @@ -456,8 +457,7 @@ static int sgp_check_compat(struct sgp_data *data, minor >= supported_versions[ix].minor) return 0; } - dev_err(&data->client->dev, "unsupported sgp version: %d.%d\n", - major, minor); + dev_err(dev, "unsupported sgp version: %d.%d\n", major, minor); return -ENODEV; } @@ -499,19 +499,18 @@ static const struct of_device_id sgp_dt_ids[] = { static int sgp_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct device *dev = &client->dev; struct iio_dev *indio_dev; struct sgp_data *data; - const struct of_device_id *of_id; unsigned long product_id; int ret; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; - of_id = of_match_device(sgp_dt_ids, &client->dev); - if (of_id) - product_id = (unsigned long)of_id->data; + if (dev_fwnode(dev)) + product_id = (unsigned long)device_get_match_data(dev); else product_id = id->driver_data; @@ -541,9 +540,9 @@ static int sgp_probe(struct i2c_client *client, sgp_init(data); - ret = devm_iio_device_register(&client->dev, indio_dev); + ret = devm_iio_device_register(dev, indio_dev); if (ret) { - dev_err(&client->dev, "failed to register iio device\n"); + dev_err(dev, "failed to register iio device\n"); return ret; } @@ -576,7 +575,7 @@ MODULE_DEVICE_TABLE(of, sgp_dt_ids); static struct i2c_driver sgp_driver = { .driver = { .name = "sgp30", - .of_match_table = of_match_ptr(sgp_dt_ids), + .of_match_table = sgp_dt_ids, }, .probe = sgp_probe, .remove = sgp_remove, diff --git a/drivers/iio/chemical/vz89x.c b/drivers/iio/chemical/vz89x.c index 5586eb8e12cd..23b22a5f5c1c 100644 --- a/drivers/iio/chemical/vz89x.c +++ b/drivers/iio/chemical/vz89x.c @@ -10,8 +10,7 @@ #include <linux/mutex.h> #include <linux/init.h> #include <linux/i2c.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -352,12 +351,12 @@ MODULE_DEVICE_TABLE(of, vz89x_dt_ids); static int vz89x_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct device *dev = &client->dev; struct iio_dev *indio_dev; struct vz89x_data *data; - const struct of_device_id *of_id; int chip_id; - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; data = iio_priv(indio_dev); @@ -370,11 +369,10 @@ static int vz89x_probe(struct i2c_client *client, else return -EOPNOTSUPP; - of_id = of_match_device(vz89x_dt_ids, &client->dev); - if (!of_id) + if (!dev_fwnode(dev)) chip_id = id->driver_data; else - chip_id = (unsigned long)of_id->data; + chip_id = (unsigned long)device_get_match_data(dev); i2c_set_clientdata(client, indio_dev); data->client = client; @@ -383,13 +381,13 @@ static int vz89x_probe(struct i2c_client *client, mutex_init(&data->lock); indio_dev->info = &vz89x_info; - indio_dev->name = dev_name(&client->dev); + indio_dev->name = dev_name(dev); indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = data->chip->channels; indio_dev->num_channels = data->chip->num_channels; - return devm_iio_device_register(&client->dev, indio_dev); + return devm_iio_device_register(dev, indio_dev); } static const struct i2c_device_id vz89x_id[] = { @@ -402,7 +400,7 @@ MODULE_DEVICE_TABLE(i2c, vz89x_id); static struct i2c_driver vz89x_driver = { .driver = { .name = "vz89x", - .of_match_table = of_match_ptr(vz89x_dt_ids), + .of_match_table = vz89x_dt_ids, }, .probe = vz89x_probe, .id_table = vz89x_id, diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index fef503f8012d..82abd4d6886c 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -68,8 +68,8 @@ enum ad5064_regmap_type { * struct ad5064_chip_info - chip specific information * @shared_vref: whether the vref supply is shared between channels * @internal_vref: internal reference voltage. 0 if the chip has no - internal vref. - * @channel: channel specification + * internal vref. + * @channels: channel specification * @num_channels: number of channels * @regmap_type: register map layout variant */ @@ -98,6 +98,7 @@ typedef int (*ad5064_write_func)(struct ad5064_state *st, unsigned int cmd, * @use_internal_vref: set to true if the internal reference voltage should be * used. * @write: register write callback + * @lock: maintain consistency between cached and dev state * @data: i2c/spi transfer buffers */ @@ -111,7 +112,6 @@ struct ad5064_state { bool use_internal_vref; ad5064_write_func write; - /* Lock used to maintain consistency between cached and dev state */ struct mutex lock; /* diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 935a6177569f..d87e21016863 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -17,6 +17,7 @@ #include <linux/regulator/consumer.h> #include <linux/err.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -478,13 +479,11 @@ static const struct spi_device_id ad5446_spi_ids[] = { }; MODULE_DEVICE_TABLE(spi, ad5446_spi_ids); -#ifdef CONFIG_OF static const struct of_device_id ad5446_of_ids[] = { { .compatible = "ti,dac7512" }, { } }; MODULE_DEVICE_TABLE(of, ad5446_of_ids); -#endif static int ad5446_spi_probe(struct spi_device *spi) { @@ -502,7 +501,7 @@ static int ad5446_spi_remove(struct spi_device *spi) static struct spi_driver ad5446_spi_driver = { .driver = { .name = "ad5446", - .of_match_table = of_match_ptr(ad5446_of_ids), + .of_match_table = ad5446_of_ids, }, .probe = ad5446_spi_probe, .remove = ad5446_spi_remove, diff --git a/drivers/iio/dac/ad5592r-base.c b/drivers/iio/dac/ad5592r-base.c index 1fd75c02a7cd..0405e92b9e8c 100644 --- a/drivers/iio/dac/ad5592r-base.c +++ b/drivers/iio/dac/ad5592r-base.c @@ -374,36 +374,36 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, { struct ad5592r_state *st = iio_priv(iio_dev); u16 read_val; - int ret; + int ret, mult; switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&st->lock); - if (!chan->output) { + mutex_lock(&st->lock); ret = st->ops->read_adc(st, chan->channel, &read_val); + mutex_unlock(&st->lock); if (ret) - goto unlock; + return ret; if ((read_val >> 12 & 0x7) != (chan->channel & 0x7)) { dev_err(st->dev, "Error while reading channel %u\n", chan->channel); - ret = -EIO; - goto unlock; + return -EIO; } read_val &= GENMASK(11, 0); } else { + mutex_lock(&st->lock); read_val = st->cached_dac[chan->channel]; + mutex_unlock(&st->lock); } dev_dbg(st->dev, "Channel %u read: 0x%04hX\n", chan->channel, read_val); *val = (int) read_val; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = ad5592r_get_vref(st); @@ -412,24 +412,24 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, *val = div_s64_rem(tmp, 1000000000LL, val2); return IIO_VAL_INT_PLUS_MICRO; - } else { - int mult; + } - mutex_lock(&st->lock); + mutex_lock(&st->lock); - if (chan->output) - mult = !!(st->cached_gp_ctrl & - AD5592R_REG_CTRL_DAC_RANGE); - else - mult = !!(st->cached_gp_ctrl & - AD5592R_REG_CTRL_ADC_RANGE); + if (chan->output) + mult = !!(st->cached_gp_ctrl & + AD5592R_REG_CTRL_DAC_RANGE); + else + mult = !!(st->cached_gp_ctrl & + AD5592R_REG_CTRL_ADC_RANGE); - *val *= ++mult; + mutex_unlock(&st->lock); - *val2 = chan->scan_type.realbits; - ret = IIO_VAL_FRACTIONAL_LOG2; - } - break; + *val *= ++mult; + + *val2 = chan->scan_type.realbits; + + return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_OFFSET: ret = ad5592r_get_vref(st); @@ -439,15 +439,13 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, *val = (-34365 * 25) / ret; else *val = (-75365 * 25) / ret; - ret = IIO_VAL_INT; - break; + + mutex_unlock(&st->lock); + + return IIO_VAL_INT; default: return -EINVAL; } - -unlock: - mutex_unlock(&st->lock); - return ret; } static int ad5592r_write_raw_get_fmt(struct iio_dev *indio_dev, @@ -486,7 +484,7 @@ static const struct iio_chan_spec_ext_info ad5592r_ext_info[] = { { .name = "scale_available", .read = ad5592r_show_scale_available, - .shared = true, + .shared = IIO_SHARED_BY_TYPE, }, {}, }; diff --git a/drivers/iio/dac/ad5592r.c b/drivers/iio/dac/ad5592r.c index 49308ad13c4b..41f651500668 100644 --- a/drivers/iio/dac/ad5592r.c +++ b/drivers/iio/dac/ad5592r.c @@ -10,9 +10,8 @@ #include <linux/bitops.h> #include <linux/module.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/spi/spi.h> -#include <linux/acpi.h> #define AD5592R_GPIO_READBACK_EN BIT(10) #define AD5592R_LDAC_READBACK_EN BIT(6) @@ -157,8 +156,8 @@ MODULE_DEVICE_TABLE(acpi, ad5592r_acpi_match); static struct spi_driver ad5592r_spi_driver = { .driver = { .name = "ad5592r", - .of_match_table = of_match_ptr(ad5592r_of_match), - .acpi_match_table = ACPI_PTR(ad5592r_acpi_match), + .of_match_table = ad5592r_of_match, + .acpi_match_table = ad5592r_acpi_match, }, .probe = ad5592r_spi_probe, .remove = ad5592r_spi_remove, diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c index 1fbe9c019c7f..5b4df36fdc2a 100644 --- a/drivers/iio/dac/ad5593r.c +++ b/drivers/iio/dac/ad5593r.c @@ -11,8 +11,7 @@ #include <linux/bitops.h> #include <linux/i2c.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/acpi.h> +#include <linux/mod_devicetable.h> #define AD5593R_MODE_CONF (0 << 4) #define AD5593R_MODE_DAC_WRITE (1 << 4) @@ -124,8 +123,8 @@ MODULE_DEVICE_TABLE(acpi, ad5593r_acpi_match); static struct i2c_driver ad5593r_driver = { .driver = { .name = "ad5593r", - .of_match_table = of_match_ptr(ad5593r_of_match), - .acpi_match_table = ACPI_PTR(ad5593r_acpi_match), + .of_match_table = ad5593r_of_match, + .acpi_match_table = ad5593r_acpi_match, }, .probe = ad5593r_i2c_probe, .remove = ad5593r_i2c_remove, diff --git a/drivers/iio/dac/ad7303.c b/drivers/iio/dac/ad7303.c index 4460aa57a33f..2e46def9d8ee 100644 --- a/drivers/iio/dac/ad7303.c +++ b/drivers/iio/dac/ad7303.c @@ -7,6 +7,7 @@ #include <linux/err.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> @@ -29,6 +30,9 @@ * @spi: the device for this driver instance * @config: cached config register value * @dac_cache: current DAC raw value (chip does not support readback) + * @vdd_reg: reference to VDD regulator + * @vref_reg: reference to VREF regulator + * @lock: protect writes and cache updates * @data: spi transfer buffer */ @@ -287,7 +291,7 @@ MODULE_DEVICE_TABLE(spi, ad7303_spi_ids); static struct spi_driver ad7303_driver = { .driver = { .name = "ad7303", - .of_match_table = of_match_ptr(ad7303_spi_of_match), + .of_match_table = ad7303_spi_of_match, }, .probe = ad7303_probe, .remove = ad7303_remove, diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index ee174d224110..beb9a15b7c74 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -16,8 +16,8 @@ #include <linux/err.h> #include <linux/delay.h> #include <linux/regulator/consumer.h> -#include <linux/of_device.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -357,29 +357,16 @@ static const struct iio_info mcp4725_info = { .attrs = &mcp4725_attribute_group, }; -#ifdef CONFIG_OF static int mcp4725_probe_dt(struct device *dev, struct mcp4725_platform_data *pdata) { - struct device_node *np = dev->of_node; - - if (!np) - return -ENODEV; - /* check if is the vref-supply defined */ - pdata->use_vref = of_property_read_bool(np, "vref-supply"); + pdata->use_vref = device_property_read_bool(dev, "vref-supply"); pdata->vref_buffered = - of_property_read_bool(np, "microchip,vref-buffered"); + device_property_read_bool(dev, "microchip,vref-buffered"); return 0; } -#else -static int mcp4725_probe_dt(struct device *dev, - struct mcp4725_platform_data *platform_data) -{ - return -ENODEV; -} -#endif static int mcp4725_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -398,8 +385,8 @@ static int mcp4725_probe(struct i2c_client *client, data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; - if (client->dev.of_node) - data->id = (enum chip_id)of_device_get_match_data(&client->dev); + if (dev_fwnode(&client->dev)) + data->id = (enum chip_id)device_get_match_data(&client->dev); else data->id = id->driver_data; pdata = dev_get_platdata(&client->dev); @@ -519,7 +506,6 @@ static const struct i2c_device_id mcp4725_id[] = { }; MODULE_DEVICE_TABLE(i2c, mcp4725_id); -#ifdef CONFIG_OF static const struct of_device_id mcp4725_of_match[] = { { .compatible = "microchip,mcp4725", @@ -532,12 +518,11 @@ static const struct of_device_id mcp4725_of_match[] = { { } }; MODULE_DEVICE_TABLE(of, mcp4725_of_match); -#endif static struct i2c_driver mcp4725_driver = { .driver = { .name = MCP4725_DRV_NAME, - .of_match_table = of_match_ptr(mcp4725_of_match), + .of_match_table = mcp4725_of_match, .pm = &mcp4725_pm_ops, }, .probe = mcp4725_probe, diff --git a/drivers/iio/dac/stm32-dac.c b/drivers/iio/dac/stm32-dac.c index 092c796fa3d9..12dec68c16f7 100644 --- a/drivers/iio/dac/stm32-dac.c +++ b/drivers/iio/dac/stm32-dac.c @@ -26,9 +26,12 @@ /** * struct stm32_dac - private data of DAC driver * @common: reference to DAC common data + * @lock: lock to protect against potential races when reading + * and update CR, to keep it in sync with pm_runtime */ struct stm32_dac { struct stm32_dac_common *common; + struct mutex lock; }; static int stm32_dac_is_enabled(struct iio_dev *indio_dev, int channel) @@ -58,10 +61,10 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch, int ret; /* already enabled / disabled ? */ - mutex_lock(&indio_dev->mlock); + mutex_lock(&dac->lock); ret = stm32_dac_is_enabled(indio_dev, ch); if (ret < 0 || enable == !!ret) { - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&dac->lock); return ret < 0 ? ret : 0; } @@ -69,13 +72,13 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch, ret = pm_runtime_get_sync(dev); if (ret < 0) { pm_runtime_put_noidle(dev); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&dac->lock); return ret; } } ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, msk, en); - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&dac->lock); if (ret < 0) { dev_err(&indio_dev->dev, "%s failed\n", en ? "Enable" : "Disable"); @@ -327,6 +330,8 @@ static int stm32_dac_probe(struct platform_device *pdev) indio_dev->info = &stm32_dac_iio_info; indio_dev->modes = INDIO_DIRECT_MODE; + mutex_init(&dac->lock); + ret = stm32_dac_chan_of_init(indio_dev); if (ret < 0) return ret; diff --git a/drivers/iio/dac/ti-dac082s085.c b/drivers/iio/dac/ti-dac082s085.c index 86bfb1c3f9b9..de33c1fc6e0b 100644 --- a/drivers/iio/dac/ti-dac082s085.c +++ b/drivers/iio/dac/ti-dac082s085.c @@ -14,6 +14,7 @@ #include <linux/iio/iio.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> @@ -324,7 +325,6 @@ static int ti_dac_remove(struct spi_device *spi) return 0; } -#ifdef CONFIG_OF static const struct of_device_id ti_dac_of_id[] = { { .compatible = "ti,dac082s085" }, { .compatible = "ti,dac102s085" }, @@ -335,7 +335,6 @@ static const struct of_device_id ti_dac_of_id[] = { { } }; MODULE_DEVICE_TABLE(of, ti_dac_of_id); -#endif static const struct spi_device_id ti_dac_spi_id[] = { { "dac082s085", dual_8bit }, @@ -351,7 +350,7 @@ MODULE_DEVICE_TABLE(spi, ti_dac_spi_id); static struct spi_driver ti_dac_driver = { .driver = { .name = "ti-dac082s085", - .of_match_table = of_match_ptr(ti_dac_of_id), + .of_match_table = ti_dac_of_id, }, .probe = ti_dac_probe, .remove = ti_dac_remove, diff --git a/drivers/iio/dac/ti-dac5571.c b/drivers/iio/dac/ti-dac5571.c index d303b19814e7..d3295767a079 100644 --- a/drivers/iio/dac/ti-dac5571.c +++ b/drivers/iio/dac/ti-dac5571.c @@ -18,8 +18,7 @@ #include <linux/iio/iio.h> #include <linux/i2c.h> #include <linux/module.h> -#include <linux/of_device.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/regulator/consumer.h> enum chip_id { @@ -384,7 +383,6 @@ static int dac5571_remove(struct i2c_client *i2c) return 0; } -#ifdef CONFIG_OF static const struct of_device_id dac5571_of_id[] = { {.compatible = "ti,dac5571"}, {.compatible = "ti,dac6571"}, @@ -398,7 +396,6 @@ static const struct of_device_id dac5571_of_id[] = { {} }; MODULE_DEVICE_TABLE(of, dac5571_of_id); -#endif static const struct i2c_device_id dac5571_id[] = { {"dac5571", single_8bit}, @@ -417,7 +414,7 @@ MODULE_DEVICE_TABLE(i2c, dac5571_id); static struct i2c_driver dac5571_driver = { .driver = { .name = "ti-dac5571", - .of_match_table = of_match_ptr(dac5571_of_id), + .of_match_table = dac5571_of_id, }, .probe = dac5571_probe, .remove = dac5571_remove, diff --git a/drivers/iio/dac/ti-dac7612.c b/drivers/iio/dac/ti-dac7612.c index 07c9f39d54f1..4c0f4b5e9ff4 100644 --- a/drivers/iio/dac/ti-dac7612.c +++ b/drivers/iio/dac/ti-dac7612.c @@ -23,6 +23,14 @@ struct dac7612 { uint16_t cache[2]; /* + * Lock to protect the state of the device from potential concurrent + * write accesses from userspace. The write operation requires an + * SPI write, then toggling of a GPIO, so the lock aims to protect + * the sanity of the entire sequence of operation. + */ + struct mutex lock; + + /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ @@ -101,9 +109,9 @@ static int dac7612_write_raw(struct iio_dev *iio_dev, if (val == priv->cache[chan->channel]) return 0; - mutex_lock(&iio_dev->mlock); + mutex_lock(&priv->lock); ret = dac7612_cmd_single(priv, chan->channel, val); - mutex_unlock(&iio_dev->mlock); + mutex_unlock(&priv->lock); return ret; } @@ -145,6 +153,8 @@ static int dac7612_probe(struct spi_device *spi) iio_dev->num_channels = ARRAY_SIZE(priv->cache); iio_dev->name = spi_get_device_id(spi)->name; + mutex_init(&priv->lock); + for (i = 0; i < ARRAY_SIZE(priv->cache); i++) { ret = dac7612_cmd_single(priv, i, 0); if (ret) diff --git a/drivers/iio/dummy/iio_dummy_evgen.c b/drivers/iio/dummy/iio_dummy_evgen.c index ee85d596e528..5a0072727ba4 100644 --- a/drivers/iio/dummy/iio_dummy_evgen.c +++ b/drivers/iio/dummy/iio_dummy_evgen.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * Copyright (c) 2011 Jonathan Cameron * * Companion module to the iio simple dummy example driver. @@ -27,11 +27,13 @@ #define IIO_EVENTGEN_NO 10 /** + * struct iio_dummy_eventgen - event generator specific state * @regs: irq regs we are faking * @lock: protect the evgen state * @inuse: mask of which irqs are connected * @irq_sim: interrupt simulator * @base: base of irq range + * @irq_sim_domain: irq simulator domain */ struct iio_dummy_eventgen { struct iio_dummy_regs regs[IIO_EVENTGEN_NO]; diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index 409c9c47161e..82c050a3899d 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -48,6 +48,13 @@ struct adf4350_state { unsigned long regs_hw[6]; unsigned long long freq_req; /* + * Lock to protect the state of the device from potential concurrent + * writes. The device is configured via a sequence of SPI writes, + * and this lock is meant to prevent the start of another sequence + * before another one has finished. + */ + struct mutex lock; + /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ @@ -99,7 +106,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev, if (reg > ADF4350_REG5) return -EINVAL; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); if (readval == NULL) { st->regs[reg] = writeval & ~(BIT(0) | BIT(1) | BIT(2)); ret = adf4350_sync_config(st); @@ -107,7 +114,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev, *readval = st->regs_hw[reg]; ret = 0; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret; } @@ -254,7 +261,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev, if (ret) return ret; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); switch ((u32)private) { case ADF4350_FREQ: ret = adf4350_set_freq(st, readin); @@ -295,7 +302,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev, default: ret = -EINVAL; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret ? ret : len; } @@ -309,7 +316,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev, unsigned long long val; int ret = 0; - mutex_lock(&indio_dev->mlock); + mutex_lock(&st->lock); switch ((u32)private) { case ADF4350_FREQ: val = (u64)((st->r0_int * st->r1_mod) + st->r0_fract) * @@ -338,7 +345,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev, ret = -EINVAL; val = 0; } - mutex_unlock(&indio_dev->mlock); + mutex_unlock(&st->lock); return ret < 0 ? ret : sprintf(buf, "%llu\n", val); } @@ -539,6 +546,8 @@ static int adf4350_probe(struct spi_device *spi) indio_dev->channels = &adf4350_chan; indio_dev->num_channels = 1; + mutex_init(&st->lock); + st->chspc = pdata->channel_spacing; if (clk) { st->clk = clk; diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig index 024a34139875..5824f2edf975 100644 --- a/drivers/iio/gyro/Kconfig +++ b/drivers/iio/gyro/Kconfig @@ -44,6 +44,8 @@ config ADIS16260 config ADXRS290 tristate "Analog Devices ADXRS290 Dual-Axis MEMS Gyroscope SPI driver" depends on SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Analog Devices ADXRS290 programmable digital output gyroscope. diff --git a/drivers/iio/gyro/adis16080.c b/drivers/iio/gyro/adis16080.c index 6e5e2d98943c..e2f4d943e220 100644 --- a/drivers/iio/gyro/adis16080.c +++ b/drivers/iio/gyro/adis16080.c @@ -38,7 +38,7 @@ struct adis16080_chip_info { * @us: actual spi_device to write data * @info: chip specific parameters * @buf: transmit or receive buffer - * @lock lock to protect buffer during reads + * @lock: lock to protect buffer during reads **/ struct adis16080_state { struct spi_device *us; diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c index d8a96f6bbae2..a11ae9db0d11 100644 --- a/drivers/iio/gyro/adis16136.c +++ b/drivers/iio/gyro/adis16136.c @@ -523,6 +523,11 @@ static const struct adis16136_chip_info adis16136_chip_info[] = { }, }; +static void adis16136_stop(void *data) +{ + adis16136_stop_device(data); +} + static int adis16136_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); @@ -552,38 +557,23 @@ static int adis16136_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL); if (ret) return ret; ret = adis16136_initial_setup(indio_dev); if (ret) - goto error_cleanup_buffer; + return ret; - ret = iio_device_register(indio_dev); + ret = devm_add_action_or_reset(&spi->dev, adis16136_stop, indio_dev); if (ret) - goto error_stop_device; - - adis16136_debugfs_init(indio_dev); - - return 0; - -error_stop_device: - adis16136_stop_device(indio_dev); -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); - return ret; -} - -static int adis16136_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16136 *adis16136 = iio_priv(indio_dev); + return ret; - iio_device_unregister(indio_dev); - adis16136_stop_device(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); + if (ret) + return ret; - adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); + adis16136_debugfs_init(indio_dev); return 0; } @@ -603,7 +593,6 @@ static struct spi_driver adis16136_driver = { }, .id_table = adis16136_ids, .probe = adis16136_probe, - .remove = adis16136_remove, }; module_spi_driver(adis16136_driver); diff --git a/drivers/iio/gyro/adis16260.c b/drivers/iio/gyro/adis16260.c index e638d56e1574..e7c9a3e31c45 100644 --- a/drivers/iio/gyro/adis16260.c +++ b/drivers/iio/gyro/adis16260.c @@ -359,6 +359,11 @@ static const struct adis_data adis16260_data = { BIT(ADIS16260_DIAG_STAT_POWER_LOW_BIT), }; +static void adis16260_stop(void *data) +{ + adis16260_stop_device(data); +} + static int adis16260_probe(struct spi_device *spi) { const struct spi_device_id *id; @@ -390,35 +395,20 @@ static int adis16260_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL); if (ret) return ret; /* Get the device into a sane initial state */ ret = adis_initial_startup(&adis16260->adis); if (ret) - goto error_cleanup_buffer_trigger; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev); - return ret; -} - -static int adis16260_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16260 *adis16260 = iio_priv(indio_dev); + return ret; - iio_device_unregister(indio_dev); - adis16260_stop_device(indio_dev); - adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev); + ret = devm_add_action_or_reset(&spi->dev, adis16260_stop, indio_dev); + if (ret) + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } /* @@ -441,7 +431,6 @@ static struct spi_driver adis16260_driver = { .name = "adis16260", }, .probe = adis16260_probe, - .remove = adis16260_remove, .id_table = adis16260_id, }; module_spi_driver(adis16260_driver); diff --git a/drivers/iio/gyro/adxrs290.c b/drivers/iio/gyro/adxrs290.c index ff989536d2fb..ca6fc234076e 100644 --- a/drivers/iio/gyro/adxrs290.c +++ b/drivers/iio/gyro/adxrs290.c @@ -13,8 +13,12 @@ #include <linux/module.h> #include <linux/spi/spi.h> +#include <linux/iio/buffer.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> +#include <linux/iio/trigger.h> +#include <linux/iio/triggered_buffer.h> +#include <linux/iio/trigger_consumer.h> #define ADXRS290_ADI_ID 0xAD #define ADXRS290_MEMS_ID 0x1D @@ -35,7 +39,9 @@ #define ADXRS290_READ BIT(7) #define ADXRS290_TSM BIT(0) #define ADXRS290_MEASUREMENT BIT(1) -#define ADXRS290_SYNC GENMASK(1, 0) +#define ADXRS290_DATA_RDY_OUT BIT(0) +#define ADXRS290_SYNC_MASK GENMASK(1, 0) +#define ADXRS290_SYNC(x) FIELD_PREP(ADXRS290_SYNC_MASK, x) #define ADXRS290_LPF_MASK GENMASK(2, 0) #define ADXRS290_LPF(x) FIELD_PREP(ADXRS290_LPF_MASK, x) #define ADXRS290_HPF_MASK GENMASK(7, 4) @@ -50,6 +56,13 @@ enum adxrs290_mode { ADXRS290_MODE_MEASUREMENT, }; +enum adxrs290_scan_index { + ADXRS290_IDX_X, + ADXRS290_IDX_Y, + ADXRS290_IDX_TEMP, + ADXRS290_IDX_TS, +}; + struct adxrs290_state { struct spi_device *spi; /* Serialize reads and their subsequent processing */ @@ -57,6 +70,12 @@ struct adxrs290_state { enum adxrs290_mode mode; unsigned int lpf_3db_freq_idx; unsigned int hpf_3db_freq_idx; + struct iio_trigger *dready_trig; + /* Ensure correct alignment of timestamp when present */ + struct { + s16 channels[3]; + s64 ts __aligned(8); + } buffer; }; /* @@ -192,15 +211,70 @@ static int adxrs290_set_filter_freq(struct iio_dev *indio_dev, return adxrs290_spi_write_reg(st->spi, ADXRS290_REG_FILTER, val); } +static int adxrs290_set_mode(struct iio_dev *indio_dev, enum adxrs290_mode mode) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + int val, ret; + + if (st->mode == mode) + return 0; + + mutex_lock(&st->lock); + + ret = spi_w8r8(st->spi, ADXRS290_READ_REG(ADXRS290_REG_POWER_CTL)); + if (ret < 0) + goto out_unlock; + + val = ret; + + switch (mode) { + case ADXRS290_MODE_STANDBY: + val &= ~ADXRS290_MEASUREMENT; + break; + case ADXRS290_MODE_MEASUREMENT: + val |= ADXRS290_MEASUREMENT; + break; + default: + ret = -EINVAL; + goto out_unlock; + } + + ret = adxrs290_spi_write_reg(st->spi, ADXRS290_REG_POWER_CTL, val); + if (ret < 0) { + dev_err(&st->spi->dev, "unable to set mode: %d\n", ret); + goto out_unlock; + } + + /* update cached mode */ + st->mode = mode; + +out_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static void adxrs290_chip_off_action(void *data) +{ + struct iio_dev *indio_dev = data; + + adxrs290_set_mode(indio_dev, ADXRS290_MODE_STANDBY); +} + static int adxrs290_initial_setup(struct iio_dev *indio_dev) { struct adxrs290_state *st = iio_priv(indio_dev); + struct spi_device *spi = st->spi; + int ret; + + ret = adxrs290_spi_write_reg(spi, ADXRS290_REG_POWER_CTL, + ADXRS290_MEASUREMENT | ADXRS290_TSM); + if (ret < 0) + return ret; st->mode = ADXRS290_MODE_MEASUREMENT; - return adxrs290_spi_write_reg(st->spi, - ADXRS290_REG_POWER_CTL, - ADXRS290_MEASUREMENT | ADXRS290_TSM); + return devm_add_action_or_reset(&spi->dev, adxrs290_chip_off_action, + indio_dev); } static int adxrs290_read_raw(struct iio_dev *indio_dev, @@ -215,24 +289,34 @@ static int adxrs290_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + switch (chan->type) { case IIO_ANGL_VEL: ret = adxrs290_get_rate_data(indio_dev, ADXRS290_READ_REG(chan->address), val); if (ret < 0) - return ret; + break; - return IIO_VAL_INT; + ret = IIO_VAL_INT; + break; case IIO_TEMP: ret = adxrs290_get_temp_data(indio_dev, val); if (ret < 0) - return ret; + break; - return IIO_VAL_INT; + ret = IIO_VAL_INT; + break; default: - return -EINVAL; + ret = -EINVAL; + break; } + + iio_device_release_direct_mode(indio_dev); + return ret; case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_ANGL_VEL: @@ -279,34 +363,52 @@ static int adxrs290_write_raw(struct iio_dev *indio_dev, long mask) { struct adxrs290_state *st = iio_priv(indio_dev); - int lpf_idx, hpf_idx; + int ret, lpf_idx, hpf_idx; + + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; switch (mask) { case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: lpf_idx = adxrs290_find_match(adxrs290_lpf_3db_freq_hz_table, ARRAY_SIZE(adxrs290_lpf_3db_freq_hz_table), val, val2); - if (lpf_idx < 0) - return -EINVAL; + if (lpf_idx < 0) { + ret = -EINVAL; + break; + } + /* caching the updated state of the low-pass filter */ st->lpf_3db_freq_idx = lpf_idx; /* retrieving the current state of the high-pass filter */ hpf_idx = st->hpf_3db_freq_idx; - return adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx); + ret = adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx); + break; + case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY: hpf_idx = adxrs290_find_match(adxrs290_hpf_3db_freq_hz_table, ARRAY_SIZE(adxrs290_hpf_3db_freq_hz_table), val, val2); - if (hpf_idx < 0) - return -EINVAL; + if (hpf_idx < 0) { + ret = -EINVAL; + break; + } + /* caching the updated state of the high-pass filter */ st->hpf_3db_freq_idx = hpf_idx; /* retrieving the current state of the low-pass filter */ lpf_idx = st->lpf_3db_freq_idx; - return adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx); + ret = adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx); + break; + + default: + ret = -EINVAL; + break; } - return -EINVAL; + iio_device_release_direct_mode(indio_dev); + return ret; } static int adxrs290_read_avail(struct iio_dev *indio_dev, @@ -334,6 +436,97 @@ static int adxrs290_read_avail(struct iio_dev *indio_dev, } } +static int adxrs290_reg_access_rw(struct spi_device *spi, unsigned int reg, + unsigned int *readval) +{ + int ret; + + ret = spi_w8r8(spi, ADXRS290_READ_REG(reg)); + if (ret < 0) + return ret; + + *readval = ret; + + return 0; +} + +static int adxrs290_reg_access(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + + if (readval) + return adxrs290_reg_access_rw(st->spi, reg, readval); + else + return adxrs290_spi_write_reg(st->spi, reg, writeval); +} + +static int adxrs290_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct adxrs290_state *st = iio_priv(indio_dev); + int ret; + u8 val; + + val = state ? ADXRS290_SYNC(ADXRS290_DATA_RDY_OUT) : 0; + + ret = adxrs290_spi_write_reg(st->spi, ADXRS290_REG_DATA_RDY, val); + if (ret < 0) + dev_err(&st->spi->dev, "failed to start data rdy interrupt\n"); + + return ret; +} + +static int adxrs290_reset_trig(struct iio_trigger *trig) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + int val; + + /* + * Data ready interrupt is reset after a read of the data registers. + * Here, we only read the 16b DATAY registers as that marks the end of + * a read of the data registers and initiates a reset for the interrupt + * line. + */ + adxrs290_get_rate_data(indio_dev, + ADXRS290_READ_REG(ADXRS290_REG_DATAY0), &val); + + return 0; +} + +static const struct iio_trigger_ops adxrs290_trigger_ops = { + .set_trigger_state = &adxrs290_data_rdy_trigger_set_state, + .validate_device = &iio_trigger_validate_own_device, + .try_reenable = &adxrs290_reset_trig, +}; + +static irqreturn_t adxrs290_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct adxrs290_state *st = iio_priv(indio_dev); + u8 tx = ADXRS290_READ_REG(ADXRS290_REG_DATAX0); + int ret; + + mutex_lock(&st->lock); + + /* exercise a bulk data capture starting from reg DATAX0... */ + ret = spi_write_then_read(st->spi, &tx, sizeof(tx), st->buffer.channels, + sizeof(st->buffer.channels)); + if (ret < 0) + goto out_unlock_notify; + + iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer, + pf->timestamp); + +out_unlock_notify: + mutex_unlock(&st->lock); + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + #define ADXRS290_ANGL_VEL_CHANNEL(reg, axis) { \ .type = IIO_ANGL_VEL, \ .address = reg, \ @@ -346,6 +539,13 @@ static int adxrs290_read_avail(struct iio_dev *indio_dev, .info_mask_shared_by_type_available = \ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \ + .scan_index = ADXRS290_IDX_##axis, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_LE, \ + }, \ } static const struct iio_chan_spec adxrs290_channels[] = { @@ -356,15 +556,67 @@ static const struct iio_chan_spec adxrs290_channels[] = { .address = ADXRS290_REG_TEMP0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .scan_index = ADXRS290_IDX_TEMP, + .scan_type = { + .sign = 's', + .realbits = 12, + .storagebits = 16, + .endianness = IIO_LE, + }, }, + IIO_CHAN_SOFT_TIMESTAMP(ADXRS290_IDX_TS), +}; + +static const unsigned long adxrs290_avail_scan_masks[] = { + BIT(ADXRS290_IDX_X) | BIT(ADXRS290_IDX_Y) | BIT(ADXRS290_IDX_TEMP), + 0 }; static const struct iio_info adxrs290_info = { .read_raw = &adxrs290_read_raw, .write_raw = &adxrs290_write_raw, .read_avail = &adxrs290_read_avail, + .debugfs_reg_access = &adxrs290_reg_access, }; +static int adxrs290_probe_trigger(struct iio_dev *indio_dev) +{ + struct adxrs290_state *st = iio_priv(indio_dev); + int ret; + + if (!st->spi->irq) { + dev_info(&st->spi->dev, "no irq, using polling\n"); + return 0; + } + + st->dready_trig = devm_iio_trigger_alloc(&st->spi->dev, "%s-dev%d", + indio_dev->name, + indio_dev->id); + if (!st->dready_trig) + return -ENOMEM; + + st->dready_trig->dev.parent = &st->spi->dev; + st->dready_trig->ops = &adxrs290_trigger_ops; + iio_trigger_set_drvdata(st->dready_trig, indio_dev); + + ret = devm_request_irq(&st->spi->dev, st->spi->irq, + &iio_trigger_generic_data_rdy_poll, + IRQF_ONESHOT, "adxrs290_irq", st->dready_trig); + if (ret < 0) + return dev_err_probe(&st->spi->dev, ret, + "request irq %d failed\n", st->spi->irq); + + ret = devm_iio_trigger_register(&st->spi->dev, st->dready_trig); + if (ret) { + dev_err(&st->spi->dev, "iio trigger register failed\n"); + return ret; + } + + indio_dev->trig = iio_trigger_get(st->dready_trig); + + return 0; +} + static int adxrs290_probe(struct spi_device *spi) { struct iio_dev *indio_dev; @@ -384,6 +636,7 @@ static int adxrs290_probe(struct spi_device *spi) indio_dev->channels = adxrs290_channels; indio_dev->num_channels = ARRAY_SIZE(adxrs290_channels); indio_dev->info = &adxrs290_info; + indio_dev->available_scan_masks = adxrs290_avail_scan_masks; mutex_init(&st->lock); @@ -423,6 +676,17 @@ static int adxrs290_probe(struct spi_device *spi) st->lpf_3db_freq_idx = val; st->hpf_3db_freq_idx = val2; + ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, + &iio_pollfunc_store_time, + &adxrs290_trigger_handler, NULL); + if (ret < 0) + return dev_err_probe(&spi->dev, ret, + "iio triggered buffer setup failed\n"); + + ret = adxrs290_probe_trigger(indio_dev); + if (ret < 0) + return ret; + return devm_iio_device_register(&spi->dev, indio_dev); } diff --git a/drivers/iio/gyro/itg3200_buffer.c b/drivers/iio/gyro/itg3200_buffer.c index d3fbe9d86467..1c3c1bd53374 100644 --- a/drivers/iio/gyro/itg3200_buffer.c +++ b/drivers/iio/gyro/itg3200_buffer.c @@ -46,13 +46,20 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct itg3200 *st = iio_priv(indio_dev); - __be16 buf[ITG3200_SCAN_ELEMENTS + sizeof(s64)/sizeof(u16)]; - - int ret = itg3200_read_all_channels(st->i2c, buf); + /* + * Ensure correct alignment and padding including for the + * timestamp that may be inserted. + */ + struct { + __be16 buf[ITG3200_SCAN_ELEMENTS]; + s64 ts __aligned(8); + } scan; + + int ret = itg3200_read_all_channels(st->i2c, scan.buf); if (ret < 0) goto error_ret; - iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index 82f0040400a0..b35557a54ee2 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -19,7 +19,7 @@ #include <linux/irq.h> #include <linux/i2c.h> #include <linux/mutex.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/regmap.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -323,11 +323,10 @@ static int max30102_get_current_idx(unsigned int val, int *reg) static int max30102_led_init(struct max30102_data *data) { struct device *dev = &data->client->dev; - struct device_node *np = dev->of_node; unsigned int val; int reg, ret; - ret = of_property_read_u32(np, "maxim,red-led-current-microamp", &val); + ret = device_property_read_u32(dev, "maxim,red-led-current-microamp", &val); if (ret) { dev_info(dev, "no red-led-current-microamp set\n"); @@ -346,7 +345,7 @@ static int max30102_led_init(struct max30102_data *data) return ret; if (data->chip_id == max30105) { - ret = of_property_read_u32(np, + ret = device_property_read_u32(dev, "maxim,green-led-current-microamp", &val); if (ret) { dev_info(dev, "no green-led-current-microamp set\n"); @@ -368,7 +367,7 @@ static int max30102_led_init(struct max30102_data *data) return ret; } - ret = of_property_read_u32(np, "maxim,ir-led-current-microamp", &val); + ret = device_property_read_u32(dev, "maxim,ir-led-current-microamp", &val); if (ret) { dev_info(dev, "no ir-led-current-microamp set\n"); @@ -624,7 +623,7 @@ MODULE_DEVICE_TABLE(of, max30102_dt_ids); static struct i2c_driver max30102_driver = { .driver = { .name = MAX30102_DRV_NAME, - .of_match_table = of_match_ptr(max30102_dt_ids), + .of_match_table = max30102_dt_ids, }, .probe = max30102_probe, .remove = max30102_remove, diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c index 071cb2b12bb6..2a957f19048e 100644 --- a/drivers/iio/humidity/hdc100x.c +++ b/drivers/iio/humidity/hdc100x.c @@ -15,6 +15,7 @@ #include <linux/delay.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/init.h> #include <linux/i2c.h> @@ -417,7 +418,7 @@ MODULE_DEVICE_TABLE(of, hdc100x_dt_ids); static struct i2c_driver hdc100x_driver = { .driver = { .name = "hdc100x", - .of_match_table = of_match_ptr(hdc100x_dt_ids), + .of_match_table = hdc100x_dt_ids, }, .probe = hdc100x_probe, .id_table = hdc100x_id, diff --git a/drivers/iio/humidity/htu21.c b/drivers/iio/humidity/htu21.c index 4f5d9d1c05ab..36df2a102ca4 100644 --- a/drivers/iio/humidity/htu21.c +++ b/drivers/iio/humidity/htu21.c @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <linux/stat.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -247,7 +248,7 @@ static struct i2c_driver htu21_driver = { .id_table = htu21_id, .driver = { .name = "htu21", - .of_match_table = of_match_ptr(htu21_of_match), + .of_match_table = htu21_of_match, }, }; diff --git a/drivers/iio/humidity/si7020.c b/drivers/iio/humidity/si7020.c index a09b5773d377..ab6537f136ba 100644 --- a/drivers/iio/humidity/si7020.c +++ b/drivers/iio/humidity/si7020.c @@ -20,6 +20,7 @@ #include <linux/delay.h> #include <linux/i2c.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/slab.h> #include <linux/sysfs.h> @@ -153,7 +154,7 @@ MODULE_DEVICE_TABLE(of, si7020_dt_ids); static struct i2c_driver si7020_driver = { .driver = { .name = "si7020", - .of_match_table = of_match_ptr(si7020_dt_ids), + .of_match_table = si7020_dt_ids, }, .probe = si7020_probe, .id_table = si7020_id, diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c index 1ebe3e50d3e6..54af2ed664f6 100644 --- a/drivers/iio/imu/adis16400.c +++ b/drivers/iio/imu/adis16400.c @@ -173,6 +173,8 @@ struct adis16400_chip_info { * @variant: chip variant info * @filt_int: integer part of requested filter frequency * @adis: adis device + * @avail_scan_mask: NULL terminated array of bitmaps of channels + * that must be enabled together **/ struct adis16400_state { struct adis16400_chip_info *variant; @@ -317,11 +319,6 @@ enum adis16400_chip_variant { ADIS16448, }; -static struct adis_burst adis16400_burst = { - .en = true, - .reg_cmd = ADIS16400_GLOB_CMD, -}; - static int adis16334_get_freq(struct adis16400_state *st) { int ret; @@ -947,7 +944,7 @@ static const char * const adis16400_status_error_msgs[] = { [ADIS16400_DIAG_STAT_POWER_LOW] = "Power supply below 4.75V", }; -#define ADIS16400_DATA(_timeouts) \ +#define ADIS16400_DATA(_timeouts, _burst_len) \ { \ .msc_ctrl_reg = ADIS16400_MSC_CTRL, \ .glob_cmd_reg = ADIS16400_GLOB_CMD, \ @@ -973,6 +970,8 @@ static const char * const adis16400_status_error_msgs[] = { BIT(ADIS16400_DIAG_STAT_POWER_HIGH) | \ BIT(ADIS16400_DIAG_STAT_POWER_LOW), \ .timeouts = (_timeouts), \ + .burst_reg_cmd = ADIS16400_GLOB_CMD, \ + .burst_len = (_burst_len) \ } static const struct adis_timeout adis16300_timeouts = { @@ -1023,7 +1022,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 18), }, [ADIS16334] = { .channels = adis16334_channels, @@ -1036,7 +1035,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */ .set_freq = adis16334_set_freq, .get_freq = adis16334_get_freq, - .adis_data = ADIS16400_DATA(&adis16334_timeouts), + .adis_data = ADIS16400_DATA(&adis16334_timeouts, 0), }, [ADIS16350] = { .channels = adis16350_channels, @@ -1048,7 +1047,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE, .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 0), }, [ADIS16360] = { .channels = adis16350_channels, @@ -1061,7 +1060,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 28), }, [ADIS16362] = { .channels = adis16350_channels, @@ -1074,7 +1073,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16362_timeouts), + .adis_data = ADIS16400_DATA(&adis16362_timeouts, 28), }, [ADIS16364] = { .channels = adis16350_channels, @@ -1087,7 +1086,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16362_timeouts), + .adis_data = ADIS16400_DATA(&adis16362_timeouts, 28), }, [ADIS16367] = { .channels = adis16350_channels, @@ -1100,7 +1099,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 28), }, [ADIS16400] = { .channels = adis16400_channels, @@ -1112,7 +1111,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16400_timeouts), + .adis_data = ADIS16400_DATA(&adis16400_timeouts, 24), }, [ADIS16445] = { .channels = adis16445_channels, @@ -1126,7 +1125,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ .set_freq = adis16334_set_freq, .get_freq = adis16334_get_freq, - .adis_data = ADIS16400_DATA(&adis16445_timeouts), + .adis_data = ADIS16400_DATA(&adis16445_timeouts, 16), }, [ADIS16448] = { .channels = adis16448_channels, @@ -1140,7 +1139,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ .set_freq = adis16334_set_freq, .get_freq = adis16334_get_freq, - .adis_data = ADIS16400_DATA(&adis16448_timeouts), + .adis_data = ADIS16400_DATA(&adis16448_timeouts, 24), } }; @@ -1164,6 +1163,12 @@ static void adis16400_setup_chan_mask(struct adis16400_state *st) st->avail_scan_mask[0] |= BIT(ch->scan_index); } } + +static void adis16400_stop(void *data) +{ + adis16400_stop_device(data); +} + static int adis16400_probe(struct spi_device *spi) { struct adis16400_state *st; @@ -1190,9 +1195,6 @@ static int adis16400_probe(struct spi_device *spi) if (!(st->variant->flags & ADIS16400_NO_BURST)) { adis16400_setup_chan_mask(st); indio_dev->available_scan_masks = st->avail_scan_mask; - st->adis.burst = &adis16400_burst; - if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) - st->adis.burst_extra_len = sizeof(u16); } adis16400_data = &st->variant->adis_data; @@ -1201,37 +1203,24 @@ static int adis16400_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, - adis16400_trigger_handler); + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, adis16400_trigger_handler); if (ret) return ret; /* Get the device into a sane initial state */ ret = adis16400_initial_setup(indio_dev); if (ret) - goto error_cleanup_buffer; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer; - - adis16400_debugfs_init(indio_dev); - return 0; - -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - return ret; -} - -static int adis16400_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16400_state *st = iio_priv(indio_dev); + return ret; - iio_device_unregister(indio_dev); - adis16400_stop_device(indio_dev); + ret = devm_add_action_or_reset(&spi->dev, adis16400_stop, indio_dev); + if (ret) + return ret; - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); + if (ret) + return ret; + adis16400_debugfs_init(indio_dev); return 0; } @@ -1261,7 +1250,6 @@ static struct spi_driver adis16400_driver = { }, .id_table = adis16400_id, .probe = adis16400_probe, - .remove = adis16400_remove, }; module_spi_driver(adis16400_driver); diff --git a/drivers/iio/imu/adis16460.c b/drivers/iio/imu/adis16460.c index b26a5f1bc51a..74a161e39733 100644 --- a/drivers/iio/imu/adis16460.c +++ b/drivers/iio/imu/adis16460.c @@ -403,7 +403,7 @@ static int adis16460_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); if (ret) return ret; @@ -411,31 +411,15 @@ static int adis16460_probe(struct spi_device *spi) ret = __adis_initial_startup(&st->adis); if (ret) - goto error_cleanup_buffer; + return ret; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) - goto error_cleanup_buffer; + return ret; adis16460_debugfs_init(indio_dev); return 0; - -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - return ret; -} - -static int adis16460_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16460 *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - - return 0; } static const struct spi_device_id adis16460_ids[] = { @@ -457,7 +441,6 @@ static struct spi_driver adis16460_driver = { }, .id_table = adis16460_ids, .probe = adis16460_probe, - .remove = adis16460_remove, }; module_spi_driver(adis16460_driver); diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c index 35d10ccb66c2..197d48240991 100644 --- a/drivers/iio/imu/adis16475.c +++ b/drivers/iio/imu/adis16475.c @@ -565,6 +565,9 @@ static int adis16475_enable_irq(struct adis *adis, bool enable) BIT(ADIS16475_DIAG_STAT_CLK), \ .enable_irq = adis16475_enable_irq, \ .timeouts = (_timeouts), \ + .burst_reg_cmd = ADIS16475_REG_GLOB_CMD, \ + .burst_len = ADIS16475_BURST_MAX_DATA, \ + .burst_max_len = ADIS16475_BURST32_MAX_DATA \ } static const struct adis16475_sync adis16475_sync_mode[] = { @@ -910,20 +913,6 @@ static const struct iio_info adis16475_info = { .debugfs_reg_access = adis_debugfs_reg_access, }; -static struct adis_burst adis16475_burst = { - .en = true, - .reg_cmd = ADIS16475_REG_GLOB_CMD, - /* - * adis_update_scan_mode_burst() sets the burst length in respect with - * the number of channels and allocates 16 bits for each. However, - * adis1647x devices also need space for DIAG_STAT, DATA_CNTR or - * TIME_STAMP (depending on the clock mode but for us these bytes are - * don't care...) and CRC. - */ - .extra_len = 3 * sizeof(u16), - .burst_max_len = ADIS16475_BURST32_MAX_DATA, -}; - static bool adis16475_validate_crc(const u8 *buffer, u16 crc, const bool burst32) { @@ -1279,7 +1268,6 @@ static int adis16475_probe(struct spi_device *spi) st = iio_priv(indio_dev); spi_set_drvdata(spi, indio_dev); - st->adis.burst = &adis16475_burst; st->info = device_get_match_data(&spi->dev); if (!st->info) diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c index 1eb4f98076f1..dfe86c589325 100644 --- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c @@ -1212,6 +1212,16 @@ static int adis16480_get_ext_clocks(struct adis16480 *st) return 0; } +static void adis16480_stop(void *data) +{ + adis16480_stop_device(data); +} + +static void adis16480_clk_disable(void *data) +{ + clk_disable_unprepare(data); +} + static int adis16480_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); @@ -1245,18 +1255,26 @@ static int adis16480_probe(struct spi_device *spi) if (ret) return ret; + ret = devm_add_action_or_reset(&spi->dev, adis16480_stop, indio_dev); + if (ret) + return ret; + ret = adis16480_config_irq_pin(spi->dev.of_node, st); if (ret) - goto error_stop_device; + return ret; ret = adis16480_get_ext_clocks(st); if (ret) - goto error_stop_device; + return ret; if (!IS_ERR_OR_NULL(st->ext_clk)) { ret = adis16480_ext_clk_config(st, spi->dev.of_node, true); if (ret) - goto error_stop_device; + return ret; + + ret = devm_add_action_or_reset(&spi->dev, adis16480_clk_disable, st->ext_clk); + if (ret) + return ret; st->clk_freq = clk_get_rate(st->ext_clk); st->clk_freq *= 1000; /* micro */ @@ -1264,39 +1282,17 @@ static int adis16480_probe(struct spi_device *spi) st->clk_freq = st->chip_info->int_clk; } - ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); if (ret) - goto error_clk_disable_unprepare; + return ret; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) - goto error_cleanup_buffer; + return ret; adis16480_debugfs_init(indio_dev); return 0; - -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); -error_clk_disable_unprepare: - clk_disable_unprepare(st->ext_clk); -error_stop_device: - adis16480_stop_device(indio_dev); - return ret; -} - -static int adis16480_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16480 *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis16480_stop_device(indio_dev); - - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - clk_disable_unprepare(st->ext_clk); - - return 0; } static const struct spi_device_id adis16480_ids[] = { @@ -1338,7 +1334,6 @@ static struct spi_driver adis16480_driver = { }, .id_table = adis16480_ids, .probe = adis16480_probe, - .remove = adis16480_remove, }; module_spi_driver(adis16480_driver); diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c index 5b4225ee09b9..ac354321f63a 100644 --- a/drivers/iio/imu/adis_buffer.c +++ b/drivers/iio/imu/adis_buffer.c @@ -26,12 +26,10 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, unsigned int burst_length, burst_max_length; u8 *tx; - /* All but the timestamp channel */ - burst_length = (indio_dev->num_channels - 1) * sizeof(u16); - burst_length += adis->burst->extra_len + adis->burst_extra_len; + burst_length = adis->data->burst_len + adis->burst_extra_len; - if (adis->burst->burst_max_len) - burst_max_length = adis->burst->burst_max_len; + if (adis->data->burst_max_len) + burst_max_length = adis->data->burst_max_len; else burst_max_length = burst_length; @@ -47,7 +45,7 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, } tx = adis->buffer + burst_max_length; - tx[0] = ADIS_READ_REG(adis->burst->reg_cmd); + tx[0] = ADIS_READ_REG(adis->data->burst_reg_cmd); tx[1] = 0; adis->xfer[0].tx_buf = tx; @@ -76,7 +74,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, kfree(adis->xfer); kfree(adis->buffer); - if (adis->burst && adis->burst->en) + if (adis->data->burst_len) return adis_update_scan_mode_burst(indio_dev, scan_mask); scan_count = indio_dev->scan_bytes / 2; @@ -170,48 +168,6 @@ static void adis_buffer_cleanup(void *arg) } /** - * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device - * @adis: The adis device. - * @indio_dev: The IIO device. - * @trigger_handler: Optional trigger handler, may be NULL. - * - * Returns 0 on success, a negative error code otherwise. - * - * This function sets up the buffer and trigger for a adis devices. If - * 'trigger_handler' is NULL the default trigger handler will be used. The - * default trigger handler will simply read the registers assigned to the - * currently active channels. - * - * adis_cleanup_buffer_and_trigger() should be called to free the resources - * allocated by this function. - */ -int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, - irqreturn_t (*trigger_handler)(int, void *)) -{ - int ret; - - if (!trigger_handler) - trigger_handler = adis_trigger_handler; - - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - trigger_handler, NULL); - if (ret) - return ret; - - if (adis->spi->irq) { - ret = adis_probe_trigger(adis, indio_dev); - if (ret) - goto error_buffer_cleanup; - } - return 0; - -error_buffer_cleanup: - iio_triggered_buffer_cleanup(indio_dev); - return ret; -} -EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); - -/** * devm_adis_setup_buffer_and_trigger() - Sets up buffer and trigger for * the managed adis device * @adis: The adis device @@ -220,7 +176,10 @@ EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); * * Returns 0 on success, a negative error code otherwise. * - * This function perfoms exactly the same as adis_setup_buffer_and_trigger() + * This function sets up the buffer and trigger for a adis devices. If + * 'trigger_handler' is NULL the default trigger handler will be used. The + * default trigger handler will simply read the registers assigned to the + * currently active channels. */ int devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, @@ -248,20 +207,3 @@ devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, } EXPORT_SYMBOL_GPL(devm_adis_setup_buffer_and_trigger); -/** - * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources - * @adis: The adis device. - * @indio_dev: The IIO device. - * - * Frees resources allocated by adis_setup_buffer_and_trigger() - */ -void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ - if (adis->spi->irq) - adis_remove_trigger(adis); - kfree(adis->buffer); - kfree(adis->xfer); - iio_triggered_buffer_cleanup(indio_dev); -} -EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger); diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c index 8afe71947c00..64e0ba51cb18 100644 --- a/drivers/iio/imu/adis_trigger.c +++ b/drivers/iio/imu/adis_trigger.c @@ -55,53 +55,6 @@ static int adis_validate_irq_flag(struct adis *adis) return 0; } -/** - * adis_probe_trigger() - Sets up trigger for a adis device - * @adis: The adis device - * @indio_dev: The IIO device - * - * Returns 0 on success or a negative error code - * - * adis_remove_trigger() should be used to free the trigger. - */ -int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) -{ - int ret; - - adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, - indio_dev->id); - if (adis->trig == NULL) - return -ENOMEM; - - adis_trigger_setup(adis); - - ret = adis_validate_irq_flag(adis); - if (ret) - return ret; - - ret = request_irq(adis->spi->irq, - &iio_trigger_generic_data_rdy_poll, - adis->irq_flag, - indio_dev->name, - adis->trig); - if (ret) - goto error_free_trig; - - ret = iio_trigger_register(adis->trig); - - indio_dev->trig = iio_trigger_get(adis->trig); - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(adis->spi->irq, adis->trig); -error_free_trig: - iio_trigger_free(adis->trig); - return ret; -} -EXPORT_SYMBOL_GPL(adis_probe_trigger); /** * devm_adis_probe_trigger() - Sets up trigger for a managed adis device @@ -137,16 +90,3 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) } EXPORT_SYMBOL_GPL(devm_adis_probe_trigger); -/** - * adis_remove_trigger() - Remove trigger for a adis devices - * @adis: The adis device - * - * Removes the trigger previously registered with adis_probe_trigger(). - */ -void adis_remove_trigger(struct adis *adis) -{ - iio_trigger_unregister(adis->trig); - free_irq(adis->spi->irq, adis->trig); - iio_trigger_free(adis->trig); -} -EXPORT_SYMBOL_GPL(adis_remove_trigger); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index cd38b3fccc7b..eb522b38acf3 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -122,6 +122,13 @@ struct inv_mpu6050_chip_config { u8 user_ctrl; }; +/* + * Maximum of 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8. + * May be less if fewer channels are enabled, as long as the timestamp + * remains 8 byte aligned + */ +#define INV_MPU6050_OUTPUT_DATA_SIZE 32 + /** * struct inv_mpu6050_hw - Other important hardware information. * @whoami: Self identification byte from WHO_AM_I register @@ -165,6 +172,7 @@ struct inv_mpu6050_hw { * @magn_raw_to_gauss: coefficient to convert mag raw value to Gauss. * @magn_orient: magnetometer sensor chip orientation if available. * @suspended_sensors: sensors mask of sensors turned off for suspend + * @data: dma safe buffer used for bulk reads. */ struct inv_mpu6050_state { struct mutex lock; @@ -190,6 +198,7 @@ struct inv_mpu6050_state { s32 magn_raw_to_gauss[3]; struct iio_mount_matrix magn_orient; unsigned int suspended_sensors; + u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] ____cacheline_aligned; }; /*register and associated bit definition*/ @@ -334,9 +343,6 @@ struct inv_mpu6050_state { #define INV_ICM20608_TEMP_OFFSET 8170 #define INV_ICM20608_TEMP_SCALE 3059976 -/* 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8 */ -#define INV_MPU6050_OUTPUT_DATA_SIZE 32 - #define INV_MPU6050_REG_INT_PIN_CFG 0x37 #define INV_MPU6050_ACTIVE_HIGH 0x00 #define INV_MPU6050_ACTIVE_LOW 0x80 diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index b533fa2dad0a..45c37525c2f1 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -13,7 +13,6 @@ #include <linux/interrupt.h> #include <linux/poll.h> #include <linux/math64.h> -#include <asm/unaligned.h> #include "inv_mpu_iio.h" /** @@ -121,7 +120,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) struct inv_mpu6050_state *st = iio_priv(indio_dev); size_t bytes_per_datum; int result; - u8 data[INV_MPU6050_OUTPUT_DATA_SIZE]; u16 fifo_count; s64 timestamp; int int_status; @@ -160,11 +158,11 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) * read fifo_count register to know how many bytes are inside the FIFO * right now */ - result = regmap_bulk_read(st->map, st->reg->fifo_count_h, data, - INV_MPU6050_FIFO_COUNT_BYTE); + result = regmap_bulk_read(st->map, st->reg->fifo_count_h, + st->data, INV_MPU6050_FIFO_COUNT_BYTE); if (result) goto end_session; - fifo_count = get_unaligned_be16(&data[0]); + fifo_count = be16_to_cpup((__be16 *)&st->data[0]); /* * Handle fifo overflow by resetting fifo. @@ -181,8 +179,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) nb = fifo_count / bytes_per_datum; inv_mpu6050_update_period(st, pf->timestamp, nb); for (i = 0; i < nb; ++i) { - result = regmap_bulk_read(st->map, st->reg->fifo_r_w, - data, bytes_per_datum); + result = regmap_noinc_read(st->map, st->reg->fifo_r_w, + st->data, bytes_per_datum); if (result) goto flush_fifo; /* skip first samples if needed */ @@ -191,7 +189,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) continue; } timestamp = inv_mpu6050_get_timestamp(st); - iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, st->data, timestamp); } end_session: diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index d80ba2e688ed..9275346a9cc1 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -383,6 +383,7 @@ struct st_lsm6dsx_sensor { * @iio_devs: Pointers to acc/gyro iio_dev instances. * @settings: Pointer to the specific sensor settings in use. * @orientation: sensor chip orientation relative to main hardware. + * @scan: Temporary buffers used to align data before iio_push_to_buffers() */ struct st_lsm6dsx_hw { struct device *dev; @@ -411,6 +412,11 @@ struct st_lsm6dsx_hw { const struct st_lsm6dsx_settings *settings; struct iio_mount_matrix orientation; + /* Ensure natural alignment of buffer elements */ + struct { + __le16 channels[3]; + s64 ts __aligned(8); + } scan[3]; }; static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = { diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index 7de10bd636ea..12ed0a2e55e4 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -353,9 +353,6 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) int err, sip, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset; u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE; u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; - u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; - u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; - u8 ext_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; bool reset_ts = false; __le16 fifo_status; s64 ts = 0; @@ -416,19 +413,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) { if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { - memcpy(gyro_buff, &hw->buff[offset], - ST_LSM6DSX_SAMPLE_SIZE); - offset += ST_LSM6DSX_SAMPLE_SIZE; + memcpy(hw->scan[ST_LSM6DSX_ID_GYRO].channels, + &hw->buff[offset], + sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels)); + offset += sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels); } if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { - memcpy(acc_buff, &hw->buff[offset], - ST_LSM6DSX_SAMPLE_SIZE); - offset += ST_LSM6DSX_SAMPLE_SIZE; + memcpy(hw->scan[ST_LSM6DSX_ID_ACC].channels, + &hw->buff[offset], + sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels)); + offset += sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels); } if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { - memcpy(ext_buff, &hw->buff[offset], - ST_LSM6DSX_SAMPLE_SIZE); - offset += ST_LSM6DSX_SAMPLE_SIZE; + memcpy(hw->scan[ST_LSM6DSX_ID_EXT0].channels, + &hw->buff[offset], + sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels)); + offset += sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels); } if (ts_sip-- > 0) { @@ -458,19 +458,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { iio_push_to_buffers_with_timestamp( hw->iio_devs[ST_LSM6DSX_ID_GYRO], - gyro_buff, gyro_sensor->ts_ref + ts); + &hw->scan[ST_LSM6DSX_ID_GYRO], + gyro_sensor->ts_ref + ts); gyro_sip--; } if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { iio_push_to_buffers_with_timestamp( hw->iio_devs[ST_LSM6DSX_ID_ACC], - acc_buff, acc_sensor->ts_ref + ts); + &hw->scan[ST_LSM6DSX_ID_ACC], + acc_sensor->ts_ref + ts); acc_sip--; } if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { iio_push_to_buffers_with_timestamp( hw->iio_devs[ST_LSM6DSX_ID_EXT0], - ext_buff, ext_sensor->ts_ref + ts); + &hw->scan[ST_LSM6DSX_ID_EXT0], + ext_sensor->ts_ref + ts); ext_sip--; } sip++; @@ -555,7 +558,14 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) { u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE; u16 fifo_len, fifo_diff_mask; - u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE], tag; + /* + * Alignment needed as this can ultimately be passed to a + * call to iio_push_to_buffers_with_timestamp() which + * must be passed a buffer that is aligned to 8 bytes so + * as to allow insertion of a naturally aligned timestamp. + */ + u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8); + u8 tag; bool reset_ts = false; int i, err, read_len; __le16 fifo_status; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 346c24281d26..42f485634d04 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -157,10 +157,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x20, .mask = GENMASK(4, 3), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(732000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -169,9 +169,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .mask = GENMASK(4, 3), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 3, }, }, @@ -259,10 +259,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -270,10 +270,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -425,10 +425,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -436,10 +436,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -600,10 +600,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -611,10 +611,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -816,10 +816,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -827,10 +827,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -1021,10 +1021,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -1032,10 +1032,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -1200,10 +1200,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -1211,10 +1211,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -1598,7 +1598,7 @@ static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev, case IIO_CHAN_INFO_SCALE: *val = 0; *val2 = sensor->gain; - ret = IIO_VAL_INT_PLUS_MICRO; + ret = IIO_VAL_INT_PLUS_NANO; break; default: ret = -EINVAL; @@ -1836,13 +1836,31 @@ static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, fs_table = &hw->settings->fs_table[sensor->id]; for (i = 0; i < fs_table->fs_len; i++) - len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", + len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ", fs_table->fs_avl[i].gain); buf[len - 1] = '\n'; return len; } +static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_ANGL_VEL: + case IIO_ACCEL: + return IIO_VAL_INT_PLUS_NANO; + default: + return IIO_VAL_INT_PLUS_MICRO; + } + default: + return IIO_VAL_INT_PLUS_MICRO; + } +} + static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, st_lsm6dsx_sysfs_scale_avail, NULL, 0); @@ -1868,6 +1886,7 @@ static const struct iio_info st_lsm6dsx_acc_info = { .read_event_config = st_lsm6dsx_read_event_config, .write_event_config = st_lsm6dsx_write_event_config, .hwfifo_set_watermark = st_lsm6dsx_set_watermark, + .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, }; static struct attribute *st_lsm6dsx_gyro_attributes[] = { @@ -1885,6 +1904,7 @@ static const struct iio_info st_lsm6dsx_gyro_info = { .read_raw = st_lsm6dsx_read_raw, .write_raw = st_lsm6dsx_write_raw, .hwfifo_set_watermark = st_lsm6dsx_set_watermark, + .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, }; static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c index ed83471dc7dd..8c8d8870ca07 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c @@ -313,6 +313,8 @@ st_lsm6dsx_shub_read(struct st_lsm6dsx_sensor *sensor, u8 addr, err = st_lsm6dsx_shub_read_output(hw, data, len & ST_LS6DSX_READ_OP_MASK); + if (err < 0) + return err; st_lsm6dsx_shub_master_enable(sensor, false); diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index a7d7e5143ed2..a4f6bb96d4f4 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1264,26 +1264,14 @@ static struct attribute *iio_buffer_attrs[] = { &dev_attr_data_available.attr, }; -int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) +static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, + struct iio_dev *indio_dev) { struct iio_dev_attr *p; struct attribute **attr; - struct iio_buffer *buffer = indio_dev->buffer; int ret, i, attrn, attrcount; const struct iio_chan_spec *channels; - channels = indio_dev->channels; - if (channels) { - int ml = indio_dev->masklength; - - for (i = 0; i < indio_dev->num_channels; i++) - ml = max(ml, channels[i].scan_index + 1); - indio_dev->masklength = ml; - } - - if (!buffer) - return 0; - attrcount = 0; if (buffer->attrs) { while (buffer->attrs[attrcount] != NULL) @@ -1367,19 +1355,45 @@ error_cleanup_dynamic: return ret; } -void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) +int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev) { struct iio_buffer *buffer = indio_dev->buffer; + const struct iio_chan_spec *channels; + int i; + + channels = indio_dev->channels; + if (channels) { + int ml = indio_dev->masklength; + + for (i = 0; i < indio_dev->num_channels; i++) + ml = max(ml, channels[i].scan_index + 1); + indio_dev->masklength = ml; + } if (!buffer) - return; + return 0; + + return __iio_buffer_alloc_sysfs_and_mask(buffer, indio_dev); +} +static void __iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer) +{ bitmap_free(buffer->scan_mask); kfree(buffer->buffer_group.attrs); kfree(buffer->scan_el_group.attrs); iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list); } +void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer = indio_dev->buffer; + + if (!buffer) + return; + + __iio_buffer_free_sysfs_and_mask(buffer); +} + /** * iio_validate_scan_mask_onehot() - Validates that exactly one channel is selected * @indio_dev: the iio device diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index d882c7f31ba9..261d3b17edc9 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -166,10 +166,11 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_CALIBEMISSIVITY] = "calibemissivity", [IIO_CHAN_INFO_OVERSAMPLING_RATIO] = "oversampling_ratio", [IIO_CHAN_INFO_THERMOCOUPLE_TYPE] = "thermocouple_type", + [IIO_CHAN_INFO_CALIBAMBIENT] = "calibambient", }; #if defined(CONFIG_DEBUG_FS) -/** +/* * There's also a CONFIG_DEBUG_FS guard in include/linux/iio/iio.h for * iio_get_debugfs_dentry() to make it inline if CONFIG_DEBUG_FS is undefined */ @@ -1524,6 +1525,7 @@ struct device_type iio_device_type = { /** * iio_device_alloc() - allocate an iio_dev from a driver + * @parent: Parent device. * @sizeof_priv: Space to allocate for private structure. **/ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 6f16357fd732..583bb51f65a7 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -516,7 +516,8 @@ static void iio_trig_subirqunmask(struct irq_data *d) trig->subirqs[d->irq - trig->subirq_base].enabled = true; } -static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs) +static __printf(1, 0) +struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs) { struct iio_trigger *trig; int i; diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c index b1178dfc1f65..7b32dfaee9b3 100644 --- a/drivers/iio/light/as73211.c +++ b/drivers/iio/light/as73211.c @@ -259,10 +259,9 @@ static int as73211_req_data(struct as73211_data *data) data->osr &= ~AS73211_OSR_SS; /* - * Add some extra margin for the timeout. sensor timing is not as precise - * as our one ... + * Add 33% extra margin for the timeout. fclk,min = fclk,typ - 27%. */ - time_us += time_us / 8; + time_us += time_us / 3; if (data->client->irq) { ret = wait_for_completion_timeout(&data->completion, usecs_to_jiffies(time_us)); if (!ret) { diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c index 8f5f857c2e7d..b304801c7916 100644 --- a/drivers/iio/light/si1145.c +++ b/drivers/iio/light/si1145.c @@ -168,6 +168,7 @@ struct si1145_part_info { * @part_info: Part information * @trig: Pointer to iio trigger * @meas_rate: Value of MEAS_RATE register. Only set in HW in auto mode + * @buffer: Used to pack data read from sensor. */ struct si1145_data { struct i2c_client *client; @@ -179,6 +180,14 @@ struct si1145_data { bool autonomous; struct iio_trigger *trig; int meas_rate; + /* + * Ensure timestamp will be naturally aligned if present. + * Maximum buffer size (may be only partly used if not all + * channels are enabled): + * 6*2 bytes channels data + 4 bytes alignment + + * 8 bytes timestamp + */ + u8 buffer[24] __aligned(8); }; /* @@ -440,12 +449,6 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private) struct iio_poll_func *pf = private; struct iio_dev *indio_dev = pf->indio_dev; struct si1145_data *data = iio_priv(indio_dev); - /* - * Maximum buffer size: - * 6*2 bytes channels data + 4 bytes alignment + - * 8 bytes timestamp - */ - u8 buffer[24]; int i, j = 0; int ret; u8 irq_status = 0; @@ -478,7 +481,7 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private) ret = i2c_smbus_read_i2c_block_data_or_emulated( data->client, indio_dev->channels[i].address, - sizeof(u16) * run, &buffer[j]); + sizeof(u16) * run, &data->buffer[j]); if (ret < 0) goto done; j += run * sizeof(u16); @@ -493,7 +496,7 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private) goto done; } - iio_push_to_buffers_with_timestamp(indio_dev, buffer, + iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, iio_get_time_ns(indio_dev)); done: diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c index 548c686e29d6..24b2f7b1fe44 100644 --- a/drivers/iio/magnetometer/ak8974.c +++ b/drivers/iio/magnetometer/ak8974.c @@ -12,6 +12,7 @@ * Author: Linus Walleij <linus.walleij@linaro.org> */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/kernel.h> #include <linux/i2c.h> #include <linux/interrupt.h> @@ -1051,7 +1052,7 @@ static struct i2c_driver ak8974_driver = { .driver = { .name = "ak8974", .pm = &ak8974_dev_pm_ops, - .of_match_table = of_match_ptr(ak8974_of_match), + .of_match_table = ak8974_of_match, }, .probe = ak8974_probe, .remove = ak8974_remove, diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 623766ff800b..d988b6ac3659 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -8,6 +8,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/i2c.h> @@ -17,7 +18,6 @@ #include <linux/delay.h> #include <linux/bitops.h> #include <linux/gpio/consumer.h> -#include <linux/acpi.h> #include <linux/regulator/consumer.h> #include <linux/pm_runtime.h> @@ -779,7 +779,6 @@ static const struct iio_info ak8975_info = { .read_raw = &ak8975_read_raw, }; -#ifdef CONFIG_ACPI static const struct acpi_device_id ak_acpi_match[] = { {"AK8975", AK8975}, {"AK8963", AK8963}, @@ -791,7 +790,6 @@ static const struct acpi_device_id ak_acpi_match[] = { { } }; MODULE_DEVICE_TABLE(acpi, ak_acpi_match); -#endif static void ak8975_fill_buffer(struct iio_dev *indio_dev) { @@ -1081,8 +1079,8 @@ static struct i2c_driver ak8975_driver = { .driver = { .name = "ak8975", .pm = &ak8975_dev_pm_ops, - .of_match_table = of_match_ptr(ak8975_of_match), - .acpi_match_table = ACPI_PTR(ak_acpi_match), + .of_match_table = ak8975_of_match, + .acpi_match_table = ak_acpi_match, }, .probe = ak8975_probe, .remove = ak8975_remove, diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c index 1474ba63babe..780faea61d82 100644 --- a/drivers/iio/magnetometer/hmc5843_core.c +++ b/drivers/iio/magnetometer/hmc5843_core.c @@ -245,7 +245,7 @@ static const struct iio_enum hmc5843_meas_conf_enum = { }; static const struct iio_chan_spec_ext_info hmc5843_ext_info[] = { - IIO_ENUM("meas_conf", true, &hmc5843_meas_conf_enum), + IIO_ENUM("meas_conf", IIO_SHARED_BY_TYPE, &hmc5843_meas_conf_enum), IIO_ENUM_AVAILABLE("meas_conf", &hmc5843_meas_conf_enum), IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, hmc5843_get_mount_matrix), { } @@ -259,7 +259,7 @@ static const struct iio_enum hmc5983_meas_conf_enum = { }; static const struct iio_chan_spec_ext_info hmc5983_ext_info[] = { - IIO_ENUM("meas_conf", true, &hmc5983_meas_conf_enum), + IIO_ENUM("meas_conf", IIO_SHARED_BY_TYPE, &hmc5983_meas_conf_enum), IIO_ENUM_AVAILABLE("meas_conf", &hmc5983_meas_conf_enum), IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, hmc5843_get_mount_matrix), { } diff --git a/drivers/iio/potentiometer/ad5272.c b/drivers/iio/potentiometer/ad5272.c index 933afcf7e925..70c45d346df0 100644 --- a/drivers/iio/potentiometer/ad5272.c +++ b/drivers/iio/potentiometer/ad5272.c @@ -15,6 +15,7 @@ #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #define AD5272_RDAC_WR 1 #define AD5272_RDAC_RD 2 @@ -192,7 +193,6 @@ static int ad5272_probe(struct i2c_client *client, return devm_iio_device_register(dev, indio_dev); } -#if defined(CONFIG_OF) static const struct of_device_id ad5272_dt_ids[] = { { .compatible = "adi,ad5272-020", .data = (void *)AD5272_020 }, { .compatible = "adi,ad5272-050", .data = (void *)AD5272_050 }, @@ -202,7 +202,6 @@ static const struct of_device_id ad5272_dt_ids[] = { {} }; MODULE_DEVICE_TABLE(of, ad5272_dt_ids); -#endif /* CONFIG_OF */ static const struct i2c_device_id ad5272_id[] = { { "ad5272-020", AD5272_020 }, @@ -217,7 +216,7 @@ MODULE_DEVICE_TABLE(i2c, ad5272_id); static struct i2c_driver ad5272_driver = { .driver = { .name = "ad5272", - .of_match_table = of_match_ptr(ad5272_dt_ids), + .of_match_table = ad5272_dt_ids, }, .probe = ad5272_probe, .id_table = ad5272_id, diff --git a/drivers/iio/potentiometer/ds1803.c b/drivers/iio/potentiometer/ds1803.c index 5c061ab8f46c..20b45407eaac 100644 --- a/drivers/iio/potentiometer/ds1803.c +++ b/drivers/iio/potentiometer/ds1803.c @@ -14,7 +14,7 @@ #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/module.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #define DS1803_MAX_POS 255 #define DS1803_WRITE(chan) (0xa8 | ((chan) + 1)) @@ -134,7 +134,6 @@ static int ds1803_probe(struct i2c_client *client, return devm_iio_device_register(dev, indio_dev); } -#if defined(CONFIG_OF) static const struct of_device_id ds1803_dt_ids[] = { { .compatible = "maxim,ds1803-010", .data = &ds1803_cfg[DS1803_010] }, { .compatible = "maxim,ds1803-050", .data = &ds1803_cfg[DS1803_050] }, @@ -142,7 +141,6 @@ static const struct of_device_id ds1803_dt_ids[] = { {} }; MODULE_DEVICE_TABLE(of, ds1803_dt_ids); -#endif /* CONFIG_OF */ static const struct i2c_device_id ds1803_id[] = { { "ds1803-010", DS1803_010 }, @@ -155,7 +153,7 @@ MODULE_DEVICE_TABLE(i2c, ds1803_id); static struct i2c_driver ds1803_driver = { .driver = { .name = "ds1803", - .of_match_table = of_match_ptr(ds1803_dt_ids), + .of_match_table = ds1803_dt_ids, }, .probe = ds1803_probe, .id_table = ds1803_id, diff --git a/drivers/iio/potentiometer/max5432.c b/drivers/iio/potentiometer/max5432.c index 280de9c54471..aed3b6ab82a2 100644 --- a/drivers/iio/potentiometer/max5432.c +++ b/drivers/iio/potentiometer/max5432.c @@ -11,8 +11,8 @@ #include <linux/iio/iio.h> #include <linux/limits.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> /* All chip variants have 32 wiper positions. */ #define MAX5432_MAX_POS 31 @@ -100,7 +100,7 @@ static int max5432_probe(struct i2c_client *client, data = iio_priv(indio_dev); data->client = client; - data->ohm = (unsigned long)of_device_get_match_data(dev); + data->ohm = (unsigned long)device_get_match_data(dev); indio_dev->info = &max5432_info; indio_dev->channels = max5432_channels; @@ -122,7 +122,7 @@ MODULE_DEVICE_TABLE(of, max5432_dt_ids); static struct i2c_driver max5432_driver = { .driver = { .name = "max5432", - .of_match_table = of_match_ptr(max5432_dt_ids), + .of_match_table = max5432_dt_ids, }, .probe = max5432_probe, }; diff --git a/drivers/iio/potentiometer/max5481.c b/drivers/iio/potentiometer/max5481.c index 5f5988189796..a88ed0eb3adc 100644 --- a/drivers/iio/potentiometer/max5481.c +++ b/drivers/iio/potentiometer/max5481.c @@ -7,12 +7,11 @@ * https://datasheets.maximintegrated.com/en/ds/MAX5481-MAX5484.pdf */ -#include <linux/acpi.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> #include <linux/spi/spi.h> /* write wiper reg */ @@ -117,7 +116,6 @@ static const struct iio_info max5481_info = { .write_raw = max5481_write_raw, }; -#if defined(CONFIG_OF) static const struct of_device_id max5481_match[] = { { .compatible = "maxim,max5481", .data = &max5481_cfg[max5481] }, { .compatible = "maxim,max5482", .data = &max5481_cfg[max5482] }, @@ -126,7 +124,6 @@ static const struct of_device_id max5481_match[] = { { } }; MODULE_DEVICE_TABLE(of, max5481_match); -#endif static int max5481_probe(struct spi_device *spi) { @@ -144,7 +141,7 @@ static int max5481_probe(struct spi_device *spi) data->spi = spi; - data->cfg = of_device_get_match_data(&spi->dev); + data->cfg = device_get_match_data(&spi->dev); if (!data->cfg) data->cfg = &max5481_cfg[id->driver_data]; @@ -184,22 +181,10 @@ static const struct spi_device_id max5481_id_table[] = { }; MODULE_DEVICE_TABLE(spi, max5481_id_table); -#if defined(CONFIG_ACPI) -static const struct acpi_device_id max5481_acpi_match[] = { - { "max5481", max5481 }, - { "max5482", max5482 }, - { "max5483", max5483 }, - { "max5484", max5484 }, - { } -}; -MODULE_DEVICE_TABLE(acpi, max5481_acpi_match); -#endif - static struct spi_driver max5481_driver = { .driver = { .name = "max5481", - .of_match_table = of_match_ptr(max5481_match), - .acpi_match_table = ACPI_PTR(max5481_acpi_match), + .of_match_table = max5481_match, }, .probe = max5481_probe, .remove = max5481_remove, diff --git a/drivers/iio/potentiometer/mcp4018.c b/drivers/iio/potentiometer/mcp4018.c index fd0579ad3c83..c0e171fec062 100644 --- a/drivers/iio/potentiometer/mcp4018.c +++ b/drivers/iio/potentiometer/mcp4018.c @@ -16,8 +16,8 @@ #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> #define MCP4018_WIPER_MAX 127 @@ -116,8 +116,6 @@ static const struct i2c_device_id mcp4018_id[] = { }; MODULE_DEVICE_TABLE(i2c, mcp4018_id); -#ifdef CONFIG_OF - #define MCP4018_COMPATIBLE(of_compatible, cfg) { \ .compatible = of_compatible, \ .data = &mcp4018_cfg[cfg], \ @@ -140,8 +138,6 @@ static const struct of_device_id mcp4018_of_match[] = { }; MODULE_DEVICE_TABLE(of, mcp4018_of_match); -#endif - static int mcp4018_probe(struct i2c_client *client) { struct device *dev = &client->dev; @@ -161,7 +157,7 @@ static int mcp4018_probe(struct i2c_client *client) i2c_set_clientdata(client, indio_dev); data->client = client; - data->cfg = of_device_get_match_data(dev); + data->cfg = device_get_match_data(dev); if (!data->cfg) data->cfg = &mcp4018_cfg[i2c_match_id(mcp4018_id, client)->driver_data]; @@ -176,7 +172,7 @@ static int mcp4018_probe(struct i2c_client *client) static struct i2c_driver mcp4018_driver = { .driver = { .name = "mcp4018", - .of_match_table = of_match_ptr(mcp4018_of_match), + .of_match_table = mcp4018_of_match, }, .probe_new = mcp4018_probe, .id_table = mcp4018_id, diff --git a/drivers/iio/potentiometer/mcp4131.c b/drivers/iio/potentiometer/mcp4131.c index 2923ce250fc3..7c8c18ab8764 100644 --- a/drivers/iio/potentiometer/mcp4131.c +++ b/drivers/iio/potentiometer/mcp4131.c @@ -37,9 +37,9 @@ #include <linux/iio/iio.h> #include <linux/iio/types.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/property.h> #include <linux/spi/spi.h> #define MCP4131_WRITE (0x00 << 2) @@ -252,7 +252,7 @@ static int mcp4131_probe(struct spi_device *spi) data = iio_priv(indio_dev); spi_set_drvdata(spi, indio_dev); data->spi = spi; - data->cfg = of_device_get_match_data(&spi->dev); + data->cfg = device_get_match_data(&spi->dev); if (!data->cfg) { devid = spi_get_device_id(spi)->driver_data; data->cfg = &mcp4131_cfg[devid]; @@ -479,7 +479,7 @@ MODULE_DEVICE_TABLE(spi, mcp4131_id); static struct spi_driver mcp4131_driver = { .driver = { .name = "mcp4131", - .of_match_table = of_match_ptr(mcp4131_dt_ids), + .of_match_table = mcp4131_dt_ids, }, .probe = mcp4131_probe, .id_table = mcp4131_id, diff --git a/drivers/iio/potentiometer/mcp4531.c b/drivers/iio/potentiometer/mcp4531.c index 95efc4b40514..c25f84b4a270 100644 --- a/drivers/iio/potentiometer/mcp4531.c +++ b/drivers/iio/potentiometer/mcp4531.c @@ -28,8 +28,8 @@ #include <linux/module.h> #include <linux/i2c.h> #include <linux/err.h> -#include <linux/of.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> +#include <linux/property.h> #include <linux/iio/iio.h> @@ -275,8 +275,6 @@ static const struct i2c_device_id mcp4531_id[] = { }; MODULE_DEVICE_TABLE(i2c, mcp4531_id); -#ifdef CONFIG_OF - #define MCP4531_COMPATIBLE(of_compatible, cfg) { \ .compatible = of_compatible, \ .data = &mcp4531_cfg[cfg], \ @@ -350,7 +348,6 @@ static const struct of_device_id mcp4531_of_match[] = { { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mcp4531_of_match); -#endif static int mcp4531_probe(struct i2c_client *client) { @@ -371,7 +368,7 @@ static int mcp4531_probe(struct i2c_client *client) i2c_set_clientdata(client, indio_dev); data->client = client; - data->cfg = of_device_get_match_data(dev); + data->cfg = device_get_match_data(dev); if (!data->cfg) data->cfg = &mcp4531_cfg[i2c_match_id(mcp4531_id, client)->driver_data]; @@ -386,7 +383,7 @@ static int mcp4531_probe(struct i2c_client *client) static struct i2c_driver mcp4531_driver = { .driver = { .name = "mcp4531", - .of_match_table = of_match_ptr(mcp4531_of_match), + .of_match_table = mcp4531_of_match, }, .probe_new = mcp4531_probe, .id_table = mcp4531_id, diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c index 67ae635a05f3..f34ca769dc20 100644 --- a/drivers/iio/potentiostat/lmp91000.c +++ b/drivers/iio/potentiostat/lmp91000.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/i2c.h> #include <linux/delay.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/regmap.h> #include <linux/iio/iio.h> #include <linux/iio/buffer.h> @@ -205,13 +205,12 @@ static const struct iio_info lmp91000_info = { static int lmp91000_read_config(struct lmp91000_data *data) { struct device *dev = data->dev; - struct device_node *np = dev->of_node; unsigned int reg, val; int i, ret; - ret = of_property_read_u32(np, "ti,tia-gain-ohm", &val); + ret = device_property_read_u32(dev, "ti,tia-gain-ohm", &val); if (ret) { - if (!of_property_read_bool(np, "ti,external-tia-resistor")) { + if (!device_property_read_bool(dev, "ti,external-tia-resistor")) { dev_err(dev, "no ti,tia-gain-ohm defined and external resistor not specified\n"); return ret; } @@ -232,7 +231,7 @@ static int lmp91000_read_config(struct lmp91000_data *data) return ret; } - ret = of_property_read_u32(np, "ti,rload-ohm", &val); + ret = device_property_read_u32(dev, "ti,rload-ohm", &val); if (ret) { val = 100; dev_info(dev, "no ti,rload-ohm defined, default to %d\n", val); @@ -422,7 +421,7 @@ MODULE_DEVICE_TABLE(i2c, lmp91000_id); static struct i2c_driver lmp91000_driver = { .driver = { .name = LMP91000_DRV_NAME, - .of_match_table = of_match_ptr(lmp91000_of_match), + .of_match_table = lmp91000_of_match, }, .probe = lmp91000_probe, .remove = lmp91000_remove, diff --git a/drivers/iio/pressure/icp10100.c b/drivers/iio/pressure/icp10100.c index 90c0df068bbb..48759fc4bf18 100644 --- a/drivers/iio/pressure/icp10100.c +++ b/drivers/iio/pressure/icp10100.c @@ -10,6 +10,7 @@ #include <linux/device.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/i2c.h> #include <linux/pm_runtime.h> #include <linux/crc8.h> @@ -645,7 +646,7 @@ static struct i2c_driver icp10100_driver = { .driver = { .name = "icp10100", .pm = &icp10100_pm, - .of_match_table = of_match_ptr(icp10100_of_match), + .of_match_table = icp10100_of_match, }, .probe = icp10100_probe, .id_table = icp10100_id, diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c index 072c106dd66d..7c04f730430c 100644 --- a/drivers/iio/pressure/ms5611_i2c.c +++ b/drivers/iio/pressure/ms5611_i2c.c @@ -14,7 +14,7 @@ #include <linux/delay.h> #include <linux/i2c.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <asm/unaligned.h> @@ -113,14 +113,12 @@ static int ms5611_i2c_remove(struct i2c_client *client) return ms5611_remove(i2c_get_clientdata(client)); } -#if defined(CONFIG_OF) static const struct of_device_id ms5611_i2c_matches[] = { { .compatible = "meas,ms5611" }, { .compatible = "meas,ms5607" }, { } }; MODULE_DEVICE_TABLE(of, ms5611_i2c_matches); -#endif static const struct i2c_device_id ms5611_id[] = { { "ms5611", MS5611 }, @@ -132,7 +130,7 @@ MODULE_DEVICE_TABLE(i2c, ms5611_id); static struct i2c_driver ms5611_driver = { .driver = { .name = "ms5611", - .of_match_table = of_match_ptr(ms5611_i2c_matches) + .of_match_table = ms5611_i2c_matches, }, .id_table = ms5611_id, .probe = ms5611_i2c_probe, diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c index 4799aa57135e..45d3a7d5be8e 100644 --- a/drivers/iio/pressure/ms5611_spi.c +++ b/drivers/iio/pressure/ms5611_spi.c @@ -9,7 +9,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/spi/spi.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include <asm/unaligned.h> @@ -115,14 +115,12 @@ static int ms5611_spi_remove(struct spi_device *spi) return ms5611_remove(spi_get_drvdata(spi)); } -#if defined(CONFIG_OF) static const struct of_device_id ms5611_spi_matches[] = { { .compatible = "meas,ms5611" }, { .compatible = "meas,ms5607" }, { } }; MODULE_DEVICE_TABLE(of, ms5611_spi_matches); -#endif static const struct spi_device_id ms5611_id[] = { { "ms5611", MS5611 }, @@ -134,7 +132,7 @@ MODULE_DEVICE_TABLE(spi, ms5611_id); static struct spi_driver ms5611_driver = { .driver = { .name = "ms5611", - .of_match_table = of_match_ptr(ms5611_spi_matches) + .of_match_table = ms5611_spi_matches }, .id_table = ms5611_id, .probe = ms5611_spi_probe, diff --git a/drivers/iio/pressure/ms5637.c b/drivers/iio/pressure/ms5637.c index 05e0ef7260d5..5b59a4137d32 100644 --- a/drivers/iio/pressure/ms5637.c +++ b/drivers/iio/pressure/ms5637.c @@ -22,6 +22,7 @@ #include <linux/kernel.h> #include <linux/stat.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/i2c.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -192,7 +193,7 @@ static struct i2c_driver ms5637_driver = { .id_table = ms5637_id, .driver = { .name = "ms5637", - .of_match_table = of_match_ptr(ms5637_of_match), + .of_match_table = ms5637_of_match, }, }; diff --git a/drivers/iio/pressure/zpa2326_i2c.c b/drivers/iio/pressure/zpa2326_i2c.c index 1a65791ba279..95d9739444c4 100644 --- a/drivers/iio/pressure/zpa2326_i2c.c +++ b/drivers/iio/pressure/zpa2326_i2c.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/regmap.h> #include <linux/i2c.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include "zpa2326.h" /* @@ -66,18 +66,16 @@ static const struct i2c_device_id zpa2326_i2c_ids[] = { }; MODULE_DEVICE_TABLE(i2c, zpa2326_i2c_ids); -#if defined(CONFIG_OF) static const struct of_device_id zpa2326_i2c_matches[] = { { .compatible = "murata,zpa2326" }, { } }; MODULE_DEVICE_TABLE(of, zpa2326_i2c_matches); -#endif static struct i2c_driver zpa2326_i2c_driver = { .driver = { .name = "zpa2326-i2c", - .of_match_table = of_match_ptr(zpa2326_i2c_matches), + .of_match_table = zpa2326_i2c_matches, .pm = ZPA2326_PM_OPS, }, .probe = zpa2326_probe_i2c, diff --git a/drivers/iio/pressure/zpa2326_spi.c b/drivers/iio/pressure/zpa2326_spi.c index f37a4c738c75..85201a4bae44 100644 --- a/drivers/iio/pressure/zpa2326_spi.c +++ b/drivers/iio/pressure/zpa2326_spi.c @@ -10,7 +10,7 @@ #include <linux/module.h> #include <linux/regmap.h> #include <linux/spi/spi.h> -#include <linux/of_device.h> +#include <linux/mod_devicetable.h> #include "zpa2326.h" /* @@ -70,18 +70,16 @@ static const struct spi_device_id zpa2326_spi_ids[] = { }; MODULE_DEVICE_TABLE(spi, zpa2326_spi_ids); -#if defined(CONFIG_OF) static const struct of_device_id zpa2326_spi_matches[] = { { .compatible = "murata,zpa2326" }, { } }; MODULE_DEVICE_TABLE(of, zpa2326_spi_matches); -#endif static struct spi_driver zpa2326_spi_driver = { .driver = { .name = "zpa2326-spi", - .of_match_table = of_match_ptr(zpa2326_spi_matches), + .of_match_table = zpa2326_spi_matches, .pm = ZPA2326_PM_OPS, }, .probe = zpa2326_probe_spi, diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index c339e7339ec8..b79ada839e01 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -7,6 +7,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/delay.h> @@ -352,19 +353,19 @@ static void as3935_stop_work(void *data) static int as3935_probe(struct spi_device *spi) { + struct device *dev = &spi->dev; struct iio_dev *indio_dev; struct iio_trigger *trig; struct as3935_state *st; - struct device_node *np = spi->dev.of_node; int ret; /* Be sure lightning event interrupt is specified */ if (!spi->irq) { - dev_err(&spi->dev, "unable to get event interrupt\n"); + dev_err(dev, "unable to get event interrupt\n"); return -EINVAL; } - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; @@ -374,27 +375,24 @@ static int as3935_probe(struct spi_device *spi) spi_set_drvdata(spi, indio_dev); mutex_init(&st->lock); - ret = of_property_read_u32(np, + ret = device_property_read_u32(dev, "ams,tuning-capacitor-pf", &st->tune_cap); if (ret) { st->tune_cap = 0; - dev_warn(&spi->dev, - "no tuning-capacitor-pf set, defaulting to %d", + dev_warn(dev, "no tuning-capacitor-pf set, defaulting to %d", st->tune_cap); } if (st->tune_cap > MAX_PF_CAP) { - dev_err(&spi->dev, - "wrong tuning-capacitor-pf setting of %d\n", + dev_err(dev, "wrong tuning-capacitor-pf setting of %d\n", st->tune_cap); return -EINVAL; } - ret = of_property_read_u32(np, + ret = device_property_read_u32(dev, "ams,nflwdth", &st->nflwdth_reg); if (!ret && st->nflwdth_reg > AS3935_NFLWDTH_MASK) { - dev_err(&spi->dev, - "invalid nflwdth setting of %d\n", + dev_err(dev, "invalid nflwdth setting of %d\n", st->nflwdth_reg); return -EINVAL; } @@ -405,7 +403,7 @@ static int as3935_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &as3935_info; - trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d", + trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name, indio_dev->id); if (!trig) @@ -417,42 +415,42 @@ static int as3935_probe(struct spi_device *spi) iio_trigger_set_drvdata(trig, indio_dev); trig->ops = &iio_interrupt_trigger_ops; - ret = devm_iio_trigger_register(&spi->dev, trig); + ret = devm_iio_trigger_register(dev, trig); if (ret) { - dev_err(&spi->dev, "failed to register trigger\n"); + dev_err(dev, "failed to register trigger\n"); return ret; } - ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, iio_pollfunc_store_time, as3935_trigger_handler, NULL); if (ret) { - dev_err(&spi->dev, "cannot setup iio trigger\n"); + dev_err(dev, "cannot setup iio trigger\n"); return ret; } calibrate_as3935(st); INIT_DELAYED_WORK(&st->work, as3935_event_work); - ret = devm_add_action(&spi->dev, as3935_stop_work, indio_dev); + ret = devm_add_action(dev, as3935_stop_work, indio_dev); if (ret) return ret; - ret = devm_request_irq(&spi->dev, spi->irq, + ret = devm_request_irq(dev, spi->irq, &as3935_interrupt_handler, IRQF_TRIGGER_RISING, - dev_name(&spi->dev), + dev_name(dev), indio_dev); if (ret) { - dev_err(&spi->dev, "unable to request irq\n"); + dev_err(dev, "unable to request irq\n"); return ret; } - ret = devm_iio_device_register(&spi->dev, indio_dev); + ret = devm_iio_device_register(dev, indio_dev); if (ret < 0) { - dev_err(&spi->dev, "unable to register device\n"); + dev_err(dev, "unable to register device\n"); return ret; } return 0; @@ -473,7 +471,7 @@ MODULE_DEVICE_TABLE(spi, as3935_id); static struct spi_driver as3935_driver = { .driver = { .name = "as3935", - .of_match_table = of_match_ptr(as3935_of_match), + .of_match_table = as3935_of_match, .pm = AS3935_PM_OPS, }, .probe = as3935_probe, diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index a8e716dbd24e..c685f10b5ae4 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -13,6 +13,7 @@ #include <linux/i2c.h> #include <linux/delay.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/pm_runtime.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> @@ -360,7 +361,7 @@ static const struct dev_pm_ops lidar_pm_ops = { static struct i2c_driver lidar_driver = { .driver = { .name = LIDAR_DRV_NAME, - .of_match_table = of_match_ptr(lidar_dt_ids), + .of_match_table = lidar_dt_ids, .pm = &lidar_pm_ops, }, .probe = lidar_probe, diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c index 9d72d08ab9e7..6d3f4ab8c6b2 100644 --- a/drivers/iio/proximity/sx9310.c +++ b/drivers/iio/proximity/sx9310.c @@ -1056,6 +1056,13 @@ static struct i2c_driver sx9310_driver = { .acpi_match_table = sx9310_acpi_match, .of_match_table = sx9310_of_match, .pm = &sx9310_pm_ops, + + /* + * Lots of i2c transfers in probe + over 200 ms waiting in + * sx9310_init_compensation() mean a slow probe; prefer async + * so we don't delay boot if we're builtin to the kernel. + */ + .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, .probe_new = sx9310_probe, .id_table = sx9310_id, diff --git a/drivers/iio/proximity/vl53l0x-i2c.c b/drivers/iio/proximity/vl53l0x-i2c.c index 5fbda9475ba9..235e125aeb3a 100644 --- a/drivers/iio/proximity/vl53l0x-i2c.c +++ b/drivers/iio/proximity/vl53l0x-i2c.c @@ -4,18 +4,19 @@ * * Copyright (C) 2016 STMicroelectronics Imaging Division. * Copyright (C) 2018 Song Qiang <songqiang1304521@gmail.com> + * Copyright (C) 2020 Ivan Drobyshevskyi <drobyshevskyi@gmail.com> * * Datasheet available at * <https://www.st.com/resource/en/datasheet/vl53l0x.pdf> * * Default 7-bit i2c slave address 0x29. * - * TODO: FIFO buffer, continuous mode, interrupts, range selection, - * sensor ID check. + * TODO: FIFO buffer, continuous mode, range selection, sensor ID check. */ #include <linux/delay.h> #include <linux/i2c.h> +#include <linux/interrupt.h> #include <linux/module.h> #include <linux/iio/iio.h> @@ -29,14 +30,72 @@ #define VL_REG_SYSRANGE_MODE_TIMED BIT(2) #define VL_REG_SYSRANGE_MODE_HISTOGRAM BIT(3) +#define VL_REG_SYSTEM_INTERRUPT_CONFIG_GPIO 0x0A +#define VL_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY BIT(2) + +#define VL_REG_SYSTEM_INTERRUPT_CLEAR 0x0B + #define VL_REG_RESULT_INT_STATUS 0x13 #define VL_REG_RESULT_RANGE_STATUS 0x14 #define VL_REG_RESULT_RANGE_STATUS_COMPLETE BIT(0) struct vl53l0x_data { struct i2c_client *client; + struct completion completion; }; +static irqreturn_t vl53l0x_handle_irq(int irq, void *priv) +{ + struct iio_dev *indio_dev = priv; + struct vl53l0x_data *data = iio_priv(indio_dev); + + complete(&data->completion); + + return IRQ_HANDLED; +} + +static int vl53l0x_configure_irq(struct i2c_client *client, + struct iio_dev *indio_dev) +{ + struct vl53l0x_data *data = iio_priv(indio_dev); + int ret; + + ret = devm_request_irq(&client->dev, client->irq, vl53l0x_handle_irq, + IRQF_TRIGGER_FALLING, indio_dev->name, indio_dev); + if (ret) { + dev_err(&client->dev, "devm_request_irq error: %d\n", ret); + return ret; + } + + ret = i2c_smbus_write_byte_data(data->client, + VL_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, + VL_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY); + if (ret < 0) + dev_err(&client->dev, "failed to configure IRQ: %d\n", ret); + + return ret; +} + +static void vl53l0x_clear_irq(struct vl53l0x_data *data) +{ + struct device *dev = &data->client->dev; + int ret; + + ret = i2c_smbus_write_byte_data(data->client, + VL_REG_SYSTEM_INTERRUPT_CLEAR, 1); + if (ret < 0) + dev_err(dev, "failed to clear error irq: %d\n", ret); + + ret = i2c_smbus_write_byte_data(data->client, + VL_REG_SYSTEM_INTERRUPT_CLEAR, 0); + if (ret < 0) + dev_err(dev, "failed to clear range irq: %d\n", ret); + + ret = i2c_smbus_read_byte_data(data->client, VL_REG_RESULT_INT_STATUS); + if (ret < 0 || ret & 0x07) + dev_err(dev, "failed to clear irq: %d\n", ret); +} + static int vl53l0x_read_proximity(struct vl53l0x_data *data, const struct iio_chan_spec *chan, int *val) @@ -50,19 +109,31 @@ static int vl53l0x_read_proximity(struct vl53l0x_data *data, if (ret < 0) return ret; - do { - ret = i2c_smbus_read_byte_data(client, - VL_REG_RESULT_RANGE_STATUS); + if (data->client->irq) { + reinit_completion(&data->completion); + + ret = wait_for_completion_timeout(&data->completion, HZ/10); if (ret < 0) return ret; + else if (ret == 0) + return -ETIMEDOUT; - if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE) - break; + vl53l0x_clear_irq(data); + } else { + do { + ret = i2c_smbus_read_byte_data(client, + VL_REG_RESULT_RANGE_STATUS); + if (ret < 0) + return ret; - usleep_range(1000, 5000); - } while (--tries); - if (!tries) - return -ETIMEDOUT; + if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE) + break; + + usleep_range(1000, 5000); + } while (--tries); + if (!tries) + return -ETIMEDOUT; + } ret = i2c_smbus_read_i2c_block_data(client, VL_REG_RESULT_RANGE_STATUS, 12, buffer); @@ -140,6 +211,17 @@ static int vl53l0x_probe(struct i2c_client *client) indio_dev->num_channels = ARRAY_SIZE(vl53l0x_channels); indio_dev->modes = INDIO_DIRECT_MODE; + /* usage of interrupt is optional */ + if (client->irq) { + int ret; + + init_completion(&data->completion); + + ret = vl53l0x_configure_irq(client, indio_dev); + if (ret) + return ret; + } + return devm_iio_device_register(&client->dev, indio_dev); } diff --git a/drivers/iio/resolver/ad2s1200.c b/drivers/iio/resolver/ad2s1200.c index 6007abad116b..9746bd935628 100644 --- a/drivers/iio/resolver/ad2s1200.c +++ b/drivers/iio/resolver/ad2s1200.c @@ -12,6 +12,7 @@ #include <linux/device.h> #include <linux/gpio/consumer.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> #include <linux/spi/spi.h> #include <linux/sysfs.h> @@ -192,7 +193,7 @@ MODULE_DEVICE_TABLE(spi, ad2s1200_id); static struct spi_driver ad2s1200_driver = { .driver = { .name = DRV_NAME, - .of_match_table = of_match_ptr(ad2s1200_of_match), + .of_match_table = ad2s1200_of_match, }, .probe = ad2s1200_probe, .id_table = ad2s1200_id, diff --git a/drivers/iio/temperature/mlx90632.c b/drivers/iio/temperature/mlx90632.c index 472a7fb20615..503fe54a0bb9 100644 --- a/drivers/iio/temperature/mlx90632.c +++ b/drivers/iio/temperature/mlx90632.c @@ -761,7 +761,9 @@ static int mlx90632_read_raw(struct iio_dev *indio_dev, *val2 = data->emissivity * 1000; } return IIO_VAL_INT_PLUS_MICRO; - + case IIO_CHAN_INFO_CALIBAMBIENT: + *val = data->object_ambient_temperature; + return IIO_VAL_INT; default: return -EINVAL; } @@ -781,6 +783,9 @@ static int mlx90632_write_raw(struct iio_dev *indio_dev, return -EINVAL; data->emissivity = val * 1000 + val2 / 1000; return 0; + case IIO_CHAN_INFO_CALIBAMBIENT: + data->object_ambient_temperature = val; + return 0; default: return -EINVAL; } @@ -798,7 +803,7 @@ static const struct iio_chan_spec mlx90632_channels[] = { .modified = 1, .channel2 = IIO_MOD_TEMP_OBJECT, .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | - BIT(IIO_CHAN_INFO_CALIBEMISSIVITY), + BIT(IIO_CHAN_INFO_CALIBEMISSIVITY) | BIT(IIO_CHAN_INFO_CALIBAMBIENT), }, }; diff --git a/drivers/iio/temperature/tmp007.c b/drivers/iio/temperature/tmp007.c index f90fe9e5617b..ad2b35c65548 100644 --- a/drivers/iio/temperature/tmp007.c +++ b/drivers/iio/temperature/tmp007.c @@ -20,7 +20,7 @@ #include <linux/module.h> #include <linux/pm.h> #include <linux/bitops.h> -#include <linux/of.h> +#include <linux/mod_devicetable.h> #include <linux/irq.h> #include <linux/interrupt.h> @@ -578,7 +578,7 @@ MODULE_DEVICE_TABLE(i2c, tmp007_id); static struct i2c_driver tmp007_driver = { .driver = { .name = "tmp007", - .of_match_table = of_match_ptr(tmp007_of_match), + .of_match_table = tmp007_of_match, .pm = &tmp007_pm_ops, }, .probe = tmp007_probe, diff --git a/drivers/iio/temperature/tsys01.c b/drivers/iio/temperature/tsys01.c index 2c631a1ca33b..bbfbad9a8767 100644 --- a/drivers/iio/temperature/tsys01.c +++ b/drivers/iio/temperature/tsys01.c @@ -13,6 +13,7 @@ #include <linux/device.h> #include <linux/mutex.h> #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/stat.h> @@ -222,7 +223,7 @@ static struct i2c_driver tsys01_driver = { .id_table = tsys01_id, .driver = { .name = "tsys01", - .of_match_table = of_match_ptr(tsys01_of_match), + .of_match_table = tsys01_of_match, }, }; diff --git a/drivers/staging/iio/Documentation/dac/max517 b/drivers/staging/iio/Documentation/dac/max517 deleted file mode 100644 index e60ec2f91a7a..000000000000 --- a/drivers/staging/iio/Documentation/dac/max517 +++ /dev/null @@ -1,41 +0,0 @@ -Kernel driver max517 -==================== - -Supported chips: - * Maxim MAX517, MAX518, MAX519 - Prefix: 'max517' - Datasheet: Publicly available at the Maxim website - http://www.maxim-ic.com/ - -Author: - Roland Stigge <stigge@antcom.de> - -Description ------------ - -The Maxim MAX517/518/519 is an 8-bit DAC on the I2C bus. The following table -shows the different feature sets of the variants MAX517, MAX518 and MAX519: - -Feature MAX517 MAX518 MAX519 --------------------------------------------------------------------------- -One output channel X -Two output channels X X -Simultaneous output updates X X -Supply voltage as reference X -Separate reference input X -Reference input for each DAC X - -Via the iio sysfs interface, there are three attributes available: out1_raw, -out2_raw and out12_raw. With out1_raw and out2_raw, the current output values -(0..255) of the DACs can be written to the device. out12_raw can be used to set -both output channel values simultaneously. - -With MAX517, only out1_raw is available. - -Via out1_scale (and where appropriate, out2_scale), the current scaling factor -in mV can be read. - -When the operating system goes to a power down state, the Power Down function -of the chip is activated, reducing the supply current to 4uA. - -On power-up, the device is in 0V-output state. diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt deleted file mode 100644 index 0d1275b1eb3f..000000000000 --- a/drivers/staging/iio/Documentation/device.txt +++ /dev/null @@ -1,74 +0,0 @@ -IIO Device drivers - -This is not intended to provide a comprehensive guide to writing an -IIO device driver. For further information see the drivers within the -subsystem. - -The crucial structure for device drivers in iio is iio_dev. - -First allocate one using: - -struct iio_dev *indio_dev = iio_device_alloc(parent, sizeof(struct chip_state)); -where chip_state is a structure of local state data for this instance of -the chip. - -That data can be accessed using iio_priv(struct iio_dev *). - -Then fill in the following: - -- indio_dev->name - Name of the device being driven - made available as the name - attribute in sysfs. - -- indio_dev->info - pointer to a structure with elements that tend to be fixed for - large sets of different parts supported by a given driver. - This contains: - * info->event_attrs: - Attributes used to enable / disable hardware events. - * info->attrs: - General device attributes. Typically used for the weird - and the wonderful bits not covered by the channel specification. - * info->read_raw: - Raw data reading function. Used for both raw channel access - and for associate parameters such as offsets and scales. - * info->write_raw: - Raw value writing function. Used for writable device values such - as DAC values and calibbias. - * info->read_event_config: - Typically only set if there are some interrupt lines. This - is used to read if an on sensor event detector is enabled. - * info->write_event_config: - Enable / disable an on sensor event detector. - * info->read_event_value: - Read value associated with on sensor event detectors. Note that - the meaning of the returned value is dependent on the event - type. - * info->write_event_value: - Write the value associated with on sensor event detectors. E.g. - a threshold above which an interrupt occurs. Note that the - meaning of the value to be set is event type dependent. - -- indio_dev->modes: - Specify whether direct access and / or ring buffer access is supported. -- indio_dev->buffer: - An optional associated buffer. -- indio_dev->pollfunc: - Poll function related elements. This controls what occurs when a trigger - to which this device is attached sends an event. -- indio_dev->channels: - Specification of device channels. Most attributes etc. are built - from this spec. -- indio_dev->num_channels: - How many channels are there? - -Once these are set up, a call to iio_device_register(indio_dev) -will register the device with the iio core. - -Worth noting here is that, if a ring buffer is to be used, it can be -allocated prior to registering the device with the iio-core, but must -be registered afterwards (otherwise the whole parentage of devices -gets confused) - -On remove, iio_device_unregister(indio_dev) will remove the device from -the core, and iio_device_free(indio_dev) will clean up. diff --git a/drivers/staging/iio/Documentation/overview.txt b/drivers/staging/iio/Documentation/overview.txt deleted file mode 100644 index 00409d5dab4e..000000000000 --- a/drivers/staging/iio/Documentation/overview.txt +++ /dev/null @@ -1,57 +0,0 @@ -Overview of IIO - -The Industrial I/O subsystem is intended to provide support for devices -that in some sense are analog to digital converters (ADCs). As many -actual devices combine some ADCs with digital to analog converters -(DACs) that functionality is also supported. - -The aim is to fill the gap between the somewhat similar hwmon and -input subsystems. Hwmon is very much directed at low sample rate -sensors used in applications such as fan speed control and temperature -measurement. Input is, as its name suggests focused on input -devices. In some cases, there is considerable overlap between these and -IIO. - -A typical device falling into this category would be connected via SPI -or I2C. - -Functionality of IIO - -* Basic device registration and handling. This is very similar to -hwmon with simple polled access to device channels via sysfs. - -* Event chrdevs. These are similar to input in that they provide a -route to user space for hardware triggered events. Such events include -threshold detectors, free-fall detectors and more complex action -detection. The events themselves are currently very simple with -merely an event code and a timestamp. Any data associated with the -event must be accessed via polling. - -Note: A given device may have one or more event channel. These events are -turned on or off (if possible) via sysfs interfaces. - -* Hardware buffer support. Some recent sensors have included -fifo / ring buffers on the sensor chip. These greatly reduce the load -on the host CPU by buffering relatively large numbers of data samples -based on an internal sampling clock. Examples include VTI SCA3000 -series and Analog Devices ADXL345 accelerometers. Each buffer supports -polling to establish when data is available. - -* Trigger and software buffer support. In many data analysis -applications it is useful to be able to capture data based on some -external signal (trigger). These triggers might be a data ready -signal, a gpio line connected to some external system or an on -processor periodic interrupt. A single trigger may initialize data -capture or reading from a number of sensors. These triggers are -used in IIO to fill software buffers acting in a very similar -fashion to the hardware buffers described above. - -Other documentation: - -device.txt - elements of a typical device driver. - -trigger.txt - elements of a typical trigger driver. - -ring.txt - additional elements required for buffer support. - -sysfs-bus-iio - abi documentation file. diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt deleted file mode 100644 index 18718fcaf259..000000000000 --- a/drivers/staging/iio/Documentation/ring.txt +++ /dev/null @@ -1,47 +0,0 @@ -Buffer support within IIO - -This document is intended as a general overview of the functionality -a buffer may supply and how it is specified within IIO. For more -specific information on a given buffer implementation, see the -comments in the source code. Note that some drivers allow buffer -implementation to be selected at compile time via Kconfig options. - -A given buffer implementation typically embeds a struct -iio_ring_buffer and it is a pointer to this that is provided to the -IIO core. Access to the embedding structure is typically done via -container_of functions. - -struct iio_ring_buffer contains a struct iio_ring_setup_ops *setup_ops -which in turn contains the 4 function pointers -(preenable, postenable, predisable and postdisable). -These are used to perform device specific steps on either side -of the core changing its current mode to indicate that the buffer -is enabled or disabled (along with enabling triggering etc. as appropriate). - -Also in struct iio_ring_buffer is a struct iio_ring_access_funcs. -The function pointers within here are used to allow the core to handle -as much buffer functionality as possible. Note almost all of these -are optional. - -store_to - If possible, push data to the buffer. - -read_last - If possible, get the most recent scan from the buffer (without removal). - This provides polling like functionality whilst the ring buffering is in - use without a separate read from the device. - -rip_first_n - The primary buffer reading function. Note that it may well not return - as much data as requested. - -request_update - If parameters have changed that require reinitialization or configuration of - the buffer this will trigger it. - -set_bytes_per_datum - Set the number of bytes for a complete scan. (All samples + timestamp) - -set_length - Set the number of complete scans that may be held by the buffer. - diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-light b/drivers/staging/iio/Documentation/sysfs-bus-iio-light deleted file mode 100644 index 7c7cd8456060..000000000000 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio-light +++ /dev/null @@ -1,79 +0,0 @@ -What: /sys/bus/iio/devices/device[n]/in_illuminance0[_input|_raw] -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - This should return the calculated lux from the light sensor. If - it comes back in SI units, it should also include _input else it - should include _raw to signify it is not in SI units. - -What: /sys/.../device[n]/proximity_on_chip_ambient_infrared_suppression -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Hardware dependent mode for an ALS device to calculate the value - in proximity mode. When this is enabled, then the device should - use a infrared sensor reading to remove infrared noise from the - proximity reading. If this is not enabled, the driver can still - do this calculation manually by reading the infrared sensor - value and doing the negation in sw. - -What: /sys/bus/iio/devices/device[n]/in_proximity[_input|_raw] -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - This property is supported by proximity sensors and should be - used to return the value of a reading by the sensor. If this - value is returned in SI units, it should also include _input - but if it is not, then it should include _raw. - -What: /sys/bus/iio/devices/device[n]/intensity_infrared[_input|_raw] -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - This property is supported by sensors that have an infrared - sensing mode. This value should be the output from a reading - and if expressed in SI units, should include _input. If this - value is not in SI units, then it should include _raw. - -What: /sys/bus/iio/devices/device[n]/in_illuminance0_target -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - This property gets/sets the last known external - lux measurement used in/for calibration. - -What: /sys/bus/iio/devices/device[n]/in_illuminance0_integration_time -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - This property gets/sets the sensors ADC analog integration time. - -What: /sys/bus/iio/devices/device[n]/in_illuminance0_lux_table -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - This property gets/sets the table of coefficients - used in calculating illuminance in lux. - -What: /sys/bus/iio/devices/device[n]/in_intensity_clear[_input|_raw] -What: /sys/bus/iio/devices/device[n]/in_intensity_red[_input|_raw] -What: /sys/bus/iio/devices/device[n]/in_intensity_green[_input|_raw] -What: /sys/bus/iio/devices/device[n]/in_intensity_blue[_input|_raw] -KernelVersion: 3.6.0 -Contact: linux-iio@vger.kernel.org -Description: - This property is supported by sensors that have a RGBC - sensing mode. This value should be the output from a reading - and if expressed in SI units, should include _input. If this - value is not in SI units (irradiance, uW/mm^2), then it should - include _raw. - -What: /sys/bus/iio/devices/device[n]/in_cct0[_input|_raw] -KernelVersion: 3.6.0 -Contact: linux-iio@vger.kernel.org -Description: - This should return the correlated color temperature from the - light sensor. If it comes back in SI units, it should also - include _input else it should include _raw to signify it is not - in SI units. - diff --git a/drivers/staging/iio/Documentation/trigger.txt b/drivers/staging/iio/Documentation/trigger.txt deleted file mode 100644 index 299a1add98bf..000000000000 --- a/drivers/staging/iio/Documentation/trigger.txt +++ /dev/null @@ -1,31 +0,0 @@ -IIO trigger drivers. - -Many triggers are provided by hardware that will also be registered as -an IIO device. Whilst this can create device specific complexities -such triggers are registered with the core in the same way as -stand-alone triggers. - -struct iio_trig *trig = iio_trigger_alloc("<trigger format string>", ...); - -allocates a trigger structure. The key elements to then fill in within -a driver are: - -trig->set_trigger_state: - Function that enables / disables the underlying source of the trigger. - -There is also a -trig->alloc_list which is useful for drivers that allocate multiple -triggers to keep track of what they have created. - -When these have been set call: - -iio_trigger_register(trig); - -to register the trigger with the core, making it available to trigger -consumers. - -Trigger Consumers - -Currently triggers are only used for the filling of software -buffers and as such any device supporting INDIO_BUFFER_TRIGGERED has the -consumer interface automatically created. diff --git a/drivers/staging/iio/accel/adis16203.c b/drivers/staging/iio/accel/adis16203.c index c7798908ef0e..b68304da288b 100644 --- a/drivers/staging/iio/accel/adis16203.c +++ b/drivers/staging/iio/accel/adis16203.c @@ -286,35 +286,16 @@ static int adis16203_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) return ret; /* Get the device into a sane initial state */ ret = adis_initial_startup(st); if (ret) - goto error_cleanup_buffer_trigger; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer_trigger; - - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16203_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct of_device_id adis16203_of_match[] = { @@ -330,7 +311,6 @@ static struct spi_driver adis16203_driver = { .of_match_table = adis16203_of_match, }, .probe = adis16203_probe, - .remove = adis16203_remove, }; module_spi_driver(adis16203_driver); diff --git a/drivers/staging/iio/accel/adis16240.c b/drivers/staging/iio/accel/adis16240.c index 38ec40b458c9..5064adce5f58 100644 --- a/drivers/staging/iio/accel/adis16240.c +++ b/drivers/staging/iio/accel/adis16240.c @@ -415,35 +415,17 @@ static int adis16240_probe(struct spi_device *spi) ret = adis_init(st, indio_dev, spi, &adis16240_data); if (ret) return ret; - ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) return ret; /* Get the device into a sane initial state */ ret = adis_initial_startup(st); if (ret) - goto error_cleanup_buffer_trigger; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer_trigger; - return 0; - -error_cleanup_buffer_trigger: - adis_cleanup_buffer_and_trigger(st, indio_dev); - return ret; -} - -static int adis16240_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis_cleanup_buffer_and_trigger(st, indio_dev); + return ret; - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } - static const struct of_device_id adis16240_of_match[] = { { .compatible = "adi,adis16240" }, { }, @@ -456,7 +438,6 @@ static struct spi_driver adis16240_driver = { .of_match_table = adis16240_of_match, }, .probe = adis16240_probe, - .remove = adis16240_remove, }; module_spi_driver(adis16240_driver); diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index e2df67a3b9ab..2e45b3ceafa7 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -691,8 +691,9 @@ static inline void *iio_priv(const struct iio_dev *indio_dev) void iio_device_free(struct iio_dev *indio_dev); struct iio_dev *devm_iio_device_alloc(struct device *parent, int sizeof_priv); +__printf(2, 3) struct iio_trigger *devm_iio_trigger_alloc(struct device *dev, - const char *fmt, ...); + const char *fmt, ...); /** * iio_buffer_enabled() - helper function to test if the buffer is enabled * @indio_dev: IIO device structure for device diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index 2df67448f0d1..04e96d688ba9 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -20,7 +20,6 @@ #define ADIS_REG_PAGE_ID 0x00 struct adis; -struct adis_burst; /** * struct adis_timeouts - ADIS chip variant timeouts @@ -51,6 +50,11 @@ struct adis_timeout { * @timeouts: Chip specific delays * @enable_irq: Hook for ADIS devices that have a special IRQ enable/disable * @has_paging: True if ADIS device has paged registers + * @burst_reg_cmd: Register command that triggers burst + * @burst_len: Burst size in the SPI RX buffer. If @burst_max_len is defined, + * this should be the minimum size supported by the device. + * @burst_max_len: Holds the maximum burst size when the device supports + * more than one burst mode with different sizes */ struct adis_data { unsigned int read_delay; @@ -75,6 +79,10 @@ struct adis_data { int (*enable_irq)(struct adis *adis, bool enable); bool has_paging; + + unsigned int burst_reg_cmd; + unsigned int burst_len; + unsigned int burst_max_len; }; /** @@ -99,7 +107,6 @@ struct adis { struct iio_trigger *trig; const struct adis_data *data; - struct adis_burst *burst; unsigned int burst_extra_len; /** * The state_lock is meant to be used during operations that require @@ -499,32 +506,11 @@ int adis_single_conversion(struct iio_dev *indio_dev, #ifdef CONFIG_IIO_ADIS_LIB_BUFFER -/** - * struct adis_burst - ADIS data for burst transfers - * @en burst mode enabled - * @reg_cmd register command that triggers burst - * @extra_len extra length to account in the SPI RX buffer - * @burst_max_len holds the maximum burst size when the device supports - * more than one burst mode with different sizes - */ -struct adis_burst { - bool en; - unsigned int reg_cmd; - const u32 extra_len; - const u32 burst_max_len; -}; - int devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, irq_handler_t trigger_handler); -int adis_setup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)); -void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev); int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); -int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); -void adis_remove_trigger(struct adis *adis); int adis_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask); @@ -538,33 +524,12 @@ devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, return 0; } -static inline int adis_setup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)) -{ - return 0; -} - -static inline void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ -} - static inline int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) { return 0; } -static inline int adis_probe_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis_remove_trigger(struct adis *adis) -{ -} - #define adis_update_scan_mode NULL #endif /* CONFIG_IIO_BUFFER */ diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h index 3aa2f132dd67..2c05dfad88d7 100644 --- a/include/linux/iio/trigger_consumer.h +++ b/include/linux/iio/trigger_consumer.h @@ -38,7 +38,7 @@ struct iio_poll_func { }; -struct iio_poll_func +__printf(5, 6) struct iio_poll_func *iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), irqreturn_t (*thread)(int irq, void *p), int type, diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index e6fd3645963c..1e3ed6f55bca 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -59,6 +59,7 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_CALIBEMISSIVITY, IIO_CHAN_INFO_OVERSAMPLING_RATIO, IIO_CHAN_INFO_THERMOCOUPLE_TYPE, + IIO_CHAN_INFO_CALIBAMBIENT, }; #endif /* _IIO_TYPES_H_ */ |