Commit b290f902 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-5.10b-take2' of...

Merge tag 'iio-for-5.10b-take2' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

Jonathan writes:

Second set of features and cleanups for IIO in 5.10

We have a couple of changes that apply to large sets of drivers, so
I have grouped those to keep this short.

There are a few late breaking fixes in here that can wait for the
merge window.

dt yaml conversions
-------------------

* adi,ad7768-1
* adi,ad7949
* aspeed,ast2400
* cosmic,10001-adc
* dlg,da9150-gpadc
* fsl,imx25-gcq
* fsl,imx7d-adc
* fsl,vf610
* holt,hi8435
* marvell,berlin2-adc
* motorola,cpcap-adc
* nuvoton,nau7802
* nuvoton,npcm750-adc
* nxp,lpc1850-adc
* nxp,lpc3220
* sprd,sc2720-adc
* st,stmpe-adc
* ti,adc12138
* ti,ads1015
* ti,ads7950
* ti,twl4030-madc

Features
--------

* adxrs290
  - Add triggered buffer support and expose data ready signal as a possible
    trigger. Includes updating bindings.
  - Add debugfs hooks for register access.
* mlx90632
  - Add a clear user interface to override the measured ambient temperature.
* vl53l0x
  - Add IRQ support including dt bindings.

Cleanups and minor fixes
------------------------
(groups)
Replace mlock with local lock:
  * adf4350
  * exynos-adc
  * fls-imx25-gcq
  * stm32-dac

devm use to simplify probe error handling and remove functions.
  * adis16201
  * adis16203
  * adis16209
  * adis16240
  * adis16136
  * adis16260
  * adis16400
  * adis16460
  * adis16480
  * adis library - drop unused adis_setup_buffer_and_trigger()

of_match_ptr removal and incorrect ACPI binding removal
  of_match_ptr() rarely makes sense in an IIO driver as space saving
  is trivial and it breaks ACPI PRP0001 based instantiation.
  Mostly this series is about removing examples that get copied into new
  drivers.
  * ad2s1200
  * ad5272
  * ad5446
  * ad5592r
  * ad5593r
  * ad5703
  * ak8974
  * ak8975
  * ams-iaq-core
  * as3935
  * atlas-sensor
  * ds1803
  * hdc100x
  * htu21
  * icp10100
  * lmp91000
  * pulsedlight
  * max30102
  * max5432
  * max5481
  * mcp4018
  * mcp4131
  * mcp4531
  * mcp4725
  * ms5611
  * ms5637
  * si7020
  * sgp30
  * ti-dac082s085
  * ti-dac5571
  * tmp007
  * tsys01
  * vz89x
  * zpa2326

kernel-doc fixes
  * iio-core
  * ad7303
  * ad7947
  * adis16080
  * adis16400
  * iio_dummy_evgen
  * sgp30

Fixes for buffer alignment when passed to iio_push_to_buffers_with_timestamp()
This is a long running effort.  There are a few more drivers to come.
  * inv_mpu6050
  * itg3200
  * si1145
  * st_lsm6dsx
  * ti-adc0832
  * ti-adc12138

(not driver focused)
* MAINTAINERS
  - Consolidate Analog Device IIO entries whilst removing Beniamin Bia.
  - Remove Hartmut Knaack as a listed IIO maintainer as he hasn't been
    active for a long time and people are getting intermitted bounces.
* Add __printf() markings to a few functions that were missing them.
* drop some rotted documentation from staging.
* rework buffer sysfs file creation (precursor to multiple buffer support)

(individual drivers)
* ad5592r
  - Fix use of true for IIO_SHARED_BY_TYPE
  - Tidy up locking and indentation.
* ad9467
  - Improve error message on chip-id missmatch.
  - Use more appropriate error value if chip-id not recognised.
* adis-library
  - Simplify burst mode handling.
* adxrs290
  - Make sure to switch device to standby mode during remove.
* as73211
  - Increase measurement timeout as seems some devices are slower.
* bma180
  - Fix use of true fo IIO_SHARED_BY_TYPE
* exynos_adc
  - Update binding to require second interrut with touch screen.
  - Update binding to not require syscon on S5Pv210
* hmc5843
  - Fix use of true for IIO_SHARED_BY_TYPE
* inv_mpu6050
  - Use regmap_noinc_read() for fifo reading.
* palmas_gpadc
  - Use module_platform_driver() to remove boilerplate.
* meson-saradc
  - style consistency fixes
* rockchip_saradc
  - Allow compile testing with !ARM.
* st_lsm6dsx
  - Changing scaling factor to use IIO_VAL_INT_PLUS_NANO to improve precision.
  - Fix an issue with unchecked return value.
* stm32-adc
  - Fix a missing return introduced in dev_err_probe() patch earlier in
    cycle.
* sx9310
  - Prefer async mode for probe as paticularly slow startup.
* vcnl4000
  - Add missing interrupt property to dt binding.

* tag 'iio-for-5.10b-take2' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (126 commits)
  dt-bindings: iio: vishay,vcnl4000: add interrupts property
  iio:imu:inv_mpu6050: Use regmap_noinc_read for fifo reads.
  iio:imu:inv_mpu6050 Fix dma and ts alignment and data leak issues.
  iio:adc:ti-adc12138 Fix alignment issue with timestamp
  iio:adc:ti-adc0832 Fix alignment issue with timestamp
  iio:imu:st_lsm6dsx Fix alignment and data leak issues
  iio:light:si1145: Fix timestamp alignment and prevent data leak.
  iio:gyro:itg3200: Fix timestamp alignment and prevent data leak.
  iio:imu:st_lsm6dsx: check st_lsm6dsx_shub_read_output return
  iio: adc: exynos_adc: Replace indio_dev->mlock with own device lock
  dt-bindings:iio:adc:holt,hi8435 yaml conversion
  dt-bindings:iio:adc:adi,ad7768-1 yaml conversion
  dt-bindings:iio:adc:adi,ad7949 yaml conversion
  dt-bindings:iio:adc:dlg,da9150-gpadc yaml conversion
  dt-bindings:iio:adc:motorola,cpcap-adc yaml conversion
  dt-bindings:iio:adc:nxp,lpc3220-adc yaml conversion
  dt-bindings:iio:adc:nxp,lpc1850-adc yaml conversion
  dt-bindings:iio:adc:fsl,imx25-gcq yaml conversion
  dt-bindings:iio:adc:fsl,imx7d-adc yaml conversion
  dt-bindings:iio:adc:ti,ads1015 yaml conversion
  ...
parents 93b61540 596fd016
...@@ -1942,6 +1942,10 @@ S: Post Office Box 611311 ...@@ -1942,6 +1942,10 @@ S: Post Office Box 611311
S: San Jose, California 95161-1311 S: San Jose, California 95161-1311
S: USA S: USA
N: Hartmut Knaack
E: knaack.h@gmx.de
D: IIO subsystem and drivers
N: Thorsten Knabe N: Thorsten Knabe
E: Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de> E: Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de>
E: Thorsten Knabe <tek01@hrzpub.tu-darmstadt.de> E: Thorsten Knabe <tek01@hrzpub.tu-darmstadt.de>
......
...@@ -1758,6 +1758,14 @@ Contact: linux-iio@vger.kernel.org ...@@ -1758,6 +1758,14 @@ Contact: linux-iio@vger.kernel.org
Description: Description:
One of the following thermocouple types: B, E, J, K, N, R, S, T. 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_x_raw
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_raw What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_raw
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_raw What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_raw
......
* 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>;
};
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";
};
# 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";
};
};
...
# 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>;
};
};
...
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>;
};
# 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>;
};
...
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>;
};
* 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";
};
* 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 = <&reg_1v8>;
};
# 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 = <&reg_1v8>;
};
...
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>;
};
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>;
};
# 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>;
};
...
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>;
};
};
# 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>;
};
};
};
...
# 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 = <&reg_vcc_3v3_mcu>;
#io-channel-cells = <1>;
};
};
...
# 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 = <&reg_vcc_3v3_mcu>;
min-sample-time = <10000>;
};
...
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>;
};
# 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>;
};
};
...
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 = <&reg_vcc_3v3_mcu>;
#io-channel-cells = <1>;
};
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 = <&reg_vdda>;
resets = <&rgu 40>;
};
* 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>;
};
# 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";
};
};
...
# 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>;
};
};
...
# 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>;
};
};
...
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>;
};
# 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>;
};
};
...
* 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>;
};
# 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 = <&reg_vdda>;
resets = <&rgu 40>;
};
};
...
# 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>;
};
};
...
...@@ -41,7 +41,10 @@ properties: ...@@ -41,7 +41,10 @@ properties:
maxItems: 2 maxItems: 2
interrupts: interrupts:
maxItems: 1 description:
ADC interrupt followed by optional touchscreen interrupt.
minItems: 1
maxItems: 2
"#io-channel-cells": "#io-channel-cells":
const: 1 const: 1
...@@ -78,7 +81,6 @@ allOf: ...@@ -78,7 +81,6 @@ allOf:
- samsung,exynos-adc-v2 - samsung,exynos-adc-v2
- samsung,exynos3250-adc - samsung,exynos3250-adc
- samsung,exynos4212-adc - samsung,exynos4212-adc
- samsung,s5pv210-adc
then: then:
required: required:
- samsung,syscon-phandle - samsung,syscon-phandle
...@@ -107,6 +109,15 @@ allOf: ...@@ -107,6 +109,15 @@ allOf:
items: items:
- const: adc - const: adc
- if:
required:
- has-touchscreen
then:
properties:
interrupts:
minItems: 2
maxItems: 2
examples: examples:
- | - |
adc: adc@12d10000 { adc: adc@12d10000 {
......
# 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";
};
};
...
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";
};
};
# 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 */
};
};
...
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 */
};
# 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>;
};
};
...
# 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>;
};
};
};
...
# 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>;
};
};
...
# 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>;
};
};
...
* 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>;
};
* 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>;
};
* 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>;
};
};
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 = <&reg_vcc_3v3_mcu>;
};
...@@ -28,6 +28,9 @@ properties: ...@@ -28,6 +28,9 @@ properties:
spi-cpha: true spi-cpha: true
interrupts:
maxItems: 1
required: required:
- compatible - compatible
- reg - reg
...@@ -39,6 +42,7 @@ additionalProperties: false ...@@ -39,6 +42,7 @@ additionalProperties: false
examples: examples:
- | - |
#include <dt-bindings/interrupt-controller/irq.h>
spi { spi {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
...@@ -48,6 +52,8 @@ examples: ...@@ -48,6 +52,8 @@ examples:
spi-max-frequency = <5000000>; spi-max-frequency = <5000000>;
spi-cpol; spi-cpol;
spi-cpha; spi-cpha;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
}; };
}; };
... ...
...@@ -24,6 +24,10 @@ properties: ...@@ -24,6 +24,10 @@ properties:
- vishay,vcnl4020 - vishay,vcnl4020
- vishay,vcnl4040 - vishay,vcnl4040
- vishay,vcnl4200 - vishay,vcnl4200
interrupts:
maxItems: 1
reg: reg:
maxItems: 1 maxItems: 1
......
...@@ -4,9 +4,15 @@ Required properties: ...@@ -4,9 +4,15 @@ Required properties:
- compatible: must be "st,vl53l0x" - compatible: must be "st,vl53l0x"
- reg: i2c address where to find the device - 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: Example:
vl53l0x@29 { vl53l0x@29 {
compatible = "st,vl53l0x"; compatible = "st,vl53l0x";
reg = <0x29>; reg = <0x29>;
interrupt-parent = <&gpio>;
interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
}; };
...@@ -950,38 +950,6 @@ S: Maintained ...@@ -950,38 +950,6 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/light/ams,as73211.yaml F: Documentation/devicetree/bindings/iio/light/ams,as73211.yaml
F: drivers/iio/light/as73211.c 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 ANALOG DEVICES INC AD7192 DRIVER
M: Alexandru Tachici <alexandru.tachici@analog.com> M: Alexandru Tachici <alexandru.tachici@analog.com>
L: linux-iio@vger.kernel.org L: linux-iio@vger.kernel.org
...@@ -998,15 +966,6 @@ W: http://ez.analog.com/community/linux-device-drivers ...@@ -998,15 +966,6 @@ W: http://ez.analog.com/community/linux-device-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml F: Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml
F: drivers/iio/adc/ad7292.c 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 ANALOG DEVICES INC AD7768-1 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com> M: Michael Hennerich <Michael.Hennerich@analog.com>
L: linux-iio@vger.kernel.org L: linux-iio@vger.kernel.org
...@@ -1068,7 +1027,6 @@ F: drivers/iio/imu/adis16475.c ...@@ -1068,7 +1027,6 @@ F: drivers/iio/imu/adis16475.c
F: Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml F: Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml
ANALOG DEVICES INC ADM1177 DRIVER ANALOG DEVICES INC ADM1177 DRIVER
M: Beniamin Bia <beniamin.bia@analog.com>
M: Michael Hennerich <Michael.Hennerich@analog.com> M: Michael Hennerich <Michael.Hennerich@analog.com>
L: linux-hwmon@vger.kernel.org L: linux-hwmon@vger.kernel.org
S: Supported S: Supported
...@@ -1142,15 +1100,6 @@ S: Supported ...@@ -1142,15 +1100,6 @@ S: Supported
W: http://ez.analog.com/community/linux-device-drivers W: http://ez.analog.com/community/linux-device-drivers
F: drivers/dma/dma-axi-dmac.c 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 ANALOG DEVICES INC IIO DRIVERS
M: Lars-Peter Clausen <lars@metafoo.de> M: Lars-Peter Clausen <lars@metafoo.de>
M: Michael Hennerich <Michael.Hennerich@analog.com> M: Michael Hennerich <Michael.Hennerich@analog.com>
...@@ -1159,8 +1108,11 @@ W: http://wiki.analog.com/ ...@@ -1159,8 +1108,11 @@ W: http://wiki.analog.com/
W: http://ez.analog.com/community/linux-device-drivers 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-ad9523
F: Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350 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/*/ad*
F: drivers/iio/adc/ltc249* F: drivers/iio/adc/ltc249*
F: drivers/iio/amplifiers/hmc425a.c
F: drivers/staging/iio/*/ad* F: drivers/staging/iio/*/ad*
X: drivers/iio/*/adjd* X: drivers/iio/*/adjd*
...@@ -8524,7 +8476,6 @@ F: drivers/iio/multiplexer/iio-mux.c ...@@ -8524,7 +8476,6 @@ F: drivers/iio/multiplexer/iio-mux.c
IIO SUBSYSTEM AND DRIVERS IIO SUBSYSTEM AND DRIVERS
M: Jonathan Cameron <jic23@kernel.org> M: Jonathan Cameron <jic23@kernel.org>
R: Hartmut Knaack <knaack.h@gmx.de>
R: Lars-Peter Clausen <lars@metafoo.de> R: Lars-Peter Clausen <lars@metafoo.de>
R: Peter Meerwald-Stadler <pmeerw@pmeerw.net> R: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
L: linux-iio@vger.kernel.org L: linux-iio@vger.kernel.org
...@@ -16515,7 +16466,6 @@ F: drivers/staging/rtl8712/ ...@@ -16515,7 +16466,6 @@ F: drivers/staging/rtl8712/
STAGING - SEPS525 LCD CONTROLLER DRIVERS STAGING - SEPS525 LCD CONTROLLER DRIVERS
M: Michael Hennerich <michael.hennerich@analog.com> M: Michael Hennerich <michael.hennerich@analog.com>
M: Beniamin Bia <beniamin.bia@analog.com>
L: linux-fbdev@vger.kernel.org L: linux-fbdev@vger.kernel.org
S: Supported S: Supported
F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml
......
...@@ -281,34 +281,15 @@ static int adis16201_probe(struct spi_device *spi) ...@@ -281,34 +281,15 @@ static int adis16201_probe(struct spi_device *spi)
if (ret) if (ret)
return 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) if (ret)
return ret; return ret;
ret = adis_initial_startup(st); ret = adis_initial_startup(st);
if (ret) if (ret)
goto error_cleanup_buffer_trigger; return ret;
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 0; return devm_iio_device_register(&spi->dev, indio_dev);
} }
static struct spi_driver adis16201_driver = { static struct spi_driver adis16201_driver = {
...@@ -316,7 +297,6 @@ static struct spi_driver adis16201_driver = { ...@@ -316,7 +297,6 @@ static struct spi_driver adis16201_driver = {
.name = "adis16201", .name = "adis16201",
}, },
.probe = adis16201_probe, .probe = adis16201_probe,
.remove = adis16201_remove,
}; };
module_spi_driver(adis16201_driver); module_spi_driver(adis16201_driver);
......
...@@ -291,33 +291,15 @@ static int adis16209_probe(struct spi_device *spi) ...@@ -291,33 +291,15 @@ static int adis16209_probe(struct spi_device *spi)
if (ret) if (ret)
return 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) if (ret)
return ret; return ret;
ret = adis_initial_startup(st); ret = adis_initial_startup(st);
if (ret) if (ret)
goto error_cleanup_buffer_trigger; return ret;
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 0; return devm_iio_device_register(&spi->dev, indio_dev);
} }
static struct spi_driver adis16209_driver = { static struct spi_driver adis16209_driver = {
...@@ -325,7 +307,6 @@ static struct spi_driver adis16209_driver = { ...@@ -325,7 +307,6 @@ static struct spi_driver adis16209_driver = {
.name = "adis16209", .name = "adis16209",
}, },
.probe = adis16209_probe, .probe = adis16209_probe,
.remove = adis16209_remove,
}; };
module_spi_driver(adis16209_driver); module_spi_driver(adis16209_driver);
......
...@@ -673,7 +673,7 @@ static const struct iio_chan_spec_ext_info bma023_ext_info[] = { ...@@ -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[] = { 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_ENUM_AVAILABLE("power_mode", &bma180_power_mode_enum),
IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma180_accel_get_mount_matrix), IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma180_accel_get_mount_matrix),
{ } { }
......
...@@ -863,7 +863,7 @@ config RN5T618_ADC ...@@ -863,7 +863,7 @@ config RN5T618_ADC
config ROCKCHIP_SARADC config ROCKCHIP_SARADC
tristate "Rockchip SARADC driver" tristate "Rockchip SARADC driver"
depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) depends on ARCH_ROCKCHIP || COMPILE_TEST
depends on RESET_CONTROLLER depends on RESET_CONTROLLER
select IIO_BUFFER select IIO_BUFFER
select IIO_TRIGGERED_BUFFER select IIO_TRIGGERED_BUFFER
......
...@@ -39,7 +39,7 @@ static const struct ad7949_adc_spec ad7949_adc_spec[] = { ...@@ -39,7 +39,7 @@ static const struct ad7949_adc_spec ad7949_adc_spec[] = {
* struct ad7949_adc_chip - AD ADC chip * struct ad7949_adc_chip - AD ADC chip
* @lock: protects write sequences * @lock: protects write sequences
* @vref: regulator generating Vref * @vref: regulator generating Vref
* @iio_dev: reference to iio structure * @indio_dev: reference to iio structure
* @spi: reference to spi structure * @spi: reference to spi structure
* @resolution: resolution of the chip * @resolution: resolution of the chip
* @cfg: copy of the configuration register * @cfg: copy of the configuration register
......
...@@ -324,7 +324,7 @@ static int ad9467_setup(struct ad9467_state *st, unsigned int chip_id) ...@@ -324,7 +324,7 @@ static int ad9467_setup(struct ad9467_state *st, unsigned int chip_id)
AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
return 0; return 0;
default: default:
return -EINVAL; return -ENODEV;
} }
} }
...@@ -390,7 +390,8 @@ static int ad9467_probe(struct spi_device *spi) ...@@ -390,7 +390,8 @@ static int ad9467_probe(struct spi_device *spi)
id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID); id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID);
if (id != conv->chip_info->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; return -ENODEV;
} }
......
...@@ -138,6 +138,16 @@ struct exynos_adc { ...@@ -138,6 +138,16 @@ struct exynos_adc {
bool read_ts; bool read_ts;
u32 ts_x; u32 ts_x;
u32 ts_y; 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 { struct exynos_adc_data {
...@@ -542,7 +552,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev, ...@@ -542,7 +552,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
return -EINVAL; return -EINVAL;
} }
mutex_lock(&indio_dev->mlock); mutex_lock(&info->lock);
reinit_completion(&info->completion); reinit_completion(&info->completion);
/* Select the channel to be used and Trigger conversion */ /* Select the channel to be used and Trigger conversion */
...@@ -562,7 +572,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev, ...@@ -562,7 +572,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
ret = IIO_VAL_INT; ret = IIO_VAL_INT;
} }
mutex_unlock(&indio_dev->mlock); mutex_unlock(&info->lock);
return ret; return ret;
} }
...@@ -573,7 +583,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y) ...@@ -573,7 +583,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y)
unsigned long timeout; unsigned long timeout;
int ret; int ret;
mutex_lock(&indio_dev->mlock); mutex_lock(&info->lock);
info->read_ts = true; info->read_ts = true;
reinit_completion(&info->completion); reinit_completion(&info->completion);
...@@ -598,7 +608,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y) ...@@ -598,7 +608,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y)
} }
info->read_ts = false; info->read_ts = false;
mutex_unlock(&indio_dev->mlock); mutex_unlock(&info->lock);
return ret; return ret;
} }
...@@ -868,6 +878,8 @@ static int exynos_adc_probe(struct platform_device *pdev) ...@@ -868,6 +878,8 @@ static int exynos_adc_probe(struct platform_device *pdev)
indio_dev->channels = exynos_adc_iio_channels; indio_dev->channels = exynos_adc_iio_channels;
indio_dev->num_channels = info->data->num_channels; indio_dev->num_channels = info->data->num_channels;
mutex_init(&info->lock);
ret = request_irq(info->irq, exynos_adc_isr, ret = request_irq(info->irq, exynos_adc_isr,
0, dev_name(&pdev->dev), info); 0, dev_name(&pdev->dev), info);
if (ret < 0) { if (ret < 0) {
......
...@@ -40,6 +40,15 @@ struct mx25_gcq_priv { ...@@ -40,6 +40,15 @@ struct mx25_gcq_priv {
int irq; int irq;
struct regulator *vref[4]; struct regulator *vref[4];
u32 channel_vref_mv[MX25_NUM_CFGS]; 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) {\ #define MX25_CQG_CHAN(chan, id) {\
...@@ -137,9 +146,9 @@ static int mx25_gcq_read_raw(struct iio_dev *indio_dev, ...@@ -137,9 +146,9 @@ static int mx25_gcq_read_raw(struct iio_dev *indio_dev,
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_RAW: 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); ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val);
mutex_unlock(&indio_dev->mlock); mutex_unlock(&priv->lock);
return ret; return ret;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
...@@ -314,6 +323,8 @@ static int mx25_gcq_probe(struct platform_device *pdev) ...@@ -314,6 +323,8 @@ static int mx25_gcq_probe(struct platform_device *pdev)
return PTR_ERR(priv->regs); return PTR_ERR(priv->regs);
} }
mutex_init(&priv->lock);
init_completion(&priv->completed); init_completion(&priv->completed);
ret = mx25_gcq_setup_cfgs(pdev, priv); ret = mx25_gcq_setup_cfgs(pdev, priv);
......
...@@ -1150,16 +1150,13 @@ static const struct of_device_id meson_sar_adc_of_match[] = { ...@@ -1150,16 +1150,13 @@ static const struct of_device_id meson_sar_adc_of_match[] = {
{ {
.compatible = "amlogic,meson8-saradc", .compatible = "amlogic,meson8-saradc",
.data = &meson_sar_adc_meson8_data, .data = &meson_sar_adc_meson8_data,
}, }, {
{
.compatible = "amlogic,meson8b-saradc", .compatible = "amlogic,meson8b-saradc",
.data = &meson_sar_adc_meson8b_data, .data = &meson_sar_adc_meson8b_data,
}, }, {
{
.compatible = "amlogic,meson8m2-saradc", .compatible = "amlogic,meson8m2-saradc",
.data = &meson_sar_adc_meson8m2_data, .data = &meson_sar_adc_meson8m2_data,
}, }, {
{
.compatible = "amlogic,meson-gxbb-saradc", .compatible = "amlogic,meson-gxbb-saradc",
.data = &meson_sar_adc_gxbb_data, .data = &meson_sar_adc_gxbb_data,
}, { }, {
...@@ -1175,7 +1172,7 @@ static const struct of_device_id meson_sar_adc_of_match[] = { ...@@ -1175,7 +1172,7 @@ static const struct of_device_id meson_sar_adc_of_match[] = {
.compatible = "amlogic,meson-g12a-saradc", .compatible = "amlogic,meson-g12a-saradc",
.data = &meson_sar_adc_g12a_data, .data = &meson_sar_adc_g12a_data,
}, },
{}, { /* sentinel */ }
}; };
MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match); MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match);
......
...@@ -834,18 +834,7 @@ static struct platform_driver palmas_gpadc_driver = { ...@@ -834,18 +834,7 @@ static struct platform_driver palmas_gpadc_driver = {
.of_match_table = of_palmas_gpadc_match_tbl, .of_match_table = of_palmas_gpadc_match_tbl,
}, },
}; };
module_platform_driver(palmas_gpadc_driver);
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_DESCRIPTION("palmas GPADC driver"); MODULE_DESCRIPTION("palmas GPADC driver");
MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>"); MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>");
......
...@@ -595,7 +595,7 @@ static int stm32_adc_core_switches_probe(struct device *dev, ...@@ -595,7 +595,7 @@ static int stm32_adc_core_switches_probe(struct device *dev,
if (IS_ERR(priv->booster)) { if (IS_ERR(priv->booster)) {
ret = PTR_ERR(priv->booster); ret = PTR_ERR(priv->booster);
if (ret != -ENODEV) 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; priv->booster = NULL;
} }
......
...@@ -29,6 +29,12 @@ struct adc0832 { ...@@ -29,6 +29,12 @@ struct adc0832 {
struct regulator *reg; struct regulator *reg;
struct mutex lock; struct mutex lock;
u8 mux_bits; 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 tx_buf[2] ____cacheline_aligned;
u8 rx_buf[2]; u8 rx_buf[2];
...@@ -200,7 +206,6 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p) ...@@ -200,7 +206,6 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p; struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev; struct iio_dev *indio_dev = pf->indio_dev;
struct adc0832 *adc = iio_priv(indio_dev); struct adc0832 *adc = iio_priv(indio_dev);
u8 data[24] = { }; /* 16x 1 byte ADC data + 8 bytes timestamp */
int scan_index; int scan_index;
int i = 0; int i = 0;
...@@ -218,10 +223,10 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p) ...@@ -218,10 +223,10 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p)
goto out; goto out;
} }
data[i] = ret; adc->data[i] = ret;
i++; 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)); iio_get_time_ns(indio_dev));
out: out:
mutex_unlock(&adc->lock); mutex_unlock(&adc->lock);
......
...@@ -47,6 +47,12 @@ struct adc12138 { ...@@ -47,6 +47,12 @@ struct adc12138 {
struct completion complete; struct completion complete;
/* The number of cclk periods for the S/H's acquisition time */ /* The number of cclk periods for the S/H's acquisition time */
unsigned int 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 tx_buf[2] ____cacheline_aligned;
u8 rx_buf[2]; u8 rx_buf[2];
...@@ -329,7 +335,6 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) ...@@ -329,7 +335,6 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p; struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev; struct iio_dev *indio_dev = pf->indio_dev;
struct adc12138 *adc = iio_priv(indio_dev); struct adc12138 *adc = iio_priv(indio_dev);
__be16 data[20] = { }; /* 16x 2 bytes ADC data + 8 bytes timestamp */
__be16 trash; __be16 trash;
int ret; int ret;
int scan_index; int scan_index;
...@@ -345,7 +350,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) ...@@ -345,7 +350,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
reinit_completion(&adc->complete); reinit_completion(&adc->complete);
ret = adc12138_start_and_read_conv(adc, scan_chan, ret = adc12138_start_and_read_conv(adc, scan_chan,
i ? &data[i - 1] : &trash); i ? &adc->data[i - 1] : &trash);
if (ret) { if (ret) {
dev_warn(&adc->spi->dev, dev_warn(&adc->spi->dev,
"failed to start conversion\n"); "failed to start conversion\n");
...@@ -362,7 +367,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) ...@@ -362,7 +367,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
} }
if (i) { if (i) {
ret = adc12138_read_conv_data(adc, &data[i - 1]); ret = adc12138_read_conv_data(adc, &adc->data[i - 1]);
if (ret) { if (ret) {
dev_warn(&adc->spi->dev, dev_warn(&adc->spi->dev,
"failed to get conversion data\n"); "failed to get conversion data\n");
...@@ -370,7 +375,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p) ...@@ -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)); iio_get_time_ns(indio_dev));
out: out:
mutex_unlock(&adc->lock); mutex_unlock(&adc->lock);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/i2c.h> #include <linux/i2c.h>
...@@ -177,7 +178,7 @@ MODULE_DEVICE_TABLE(of, ams_iaqcore_dt_ids); ...@@ -177,7 +178,7 @@ MODULE_DEVICE_TABLE(of, ams_iaqcore_dt_ids);
static struct i2c_driver ams_iaqcore_driver = { static struct i2c_driver ams_iaqcore_driver = {
.driver = { .driver = {
.name = "ams-iaq-core", .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, .probe = ams_iaqcore_probe,
.id_table = ams_iaqcore_id, .id_table = ams_iaqcore_id,
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/irq_work.h> #include <linux/irq_work.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/of_device.h> #include <linux/mod_devicetable.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/buffer.h> #include <linux/iio/buffer.h>
...@@ -620,7 +620,6 @@ static int atlas_probe(struct i2c_client *client, ...@@ -620,7 +620,6 @@ static int atlas_probe(struct i2c_client *client,
{ {
struct atlas_data *data; struct atlas_data *data;
struct atlas_device *chip; struct atlas_device *chip;
const struct of_device_id *of_id;
struct iio_trigger *trig; struct iio_trigger *trig;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
int ret; int ret;
...@@ -629,11 +628,10 @@ static int atlas_probe(struct i2c_client *client, ...@@ -629,11 +628,10 @@ static int atlas_probe(struct i2c_client *client,
if (!indio_dev) if (!indio_dev)
return -ENOMEM; return -ENOMEM;
of_id = of_match_device(atlas_dt_ids, &client->dev); if (!dev_fwnode(&client->dev))
if (!of_id)
chip = &atlas_devices[id->driver_data]; chip = &atlas_devices[id->driver_data];
else 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->info = &atlas_info;
indio_dev->name = ATLAS_DRV_NAME; indio_dev->name = ATLAS_DRV_NAME;
...@@ -775,7 +773,7 @@ static const struct dev_pm_ops atlas_pm_ops = { ...@@ -775,7 +773,7 @@ static const struct dev_pm_ops atlas_pm_ops = {
static struct i2c_driver atlas_driver = { static struct i2c_driver atlas_driver = {
.driver = { .driver = {
.name = ATLAS_DRV_NAME, .name = ATLAS_DRV_NAME,
.of_match_table = of_match_ptr(atlas_dt_ids), .of_match_table = atlas_dt_ids,
.pm = &atlas_pm_ops, .pm = &atlas_pm_ops,
}, },
.probe = atlas_probe, .probe = atlas_probe,
......
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/of_device.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
...@@ -227,6 +227,7 @@ static int sgp_verify_buffer(const struct sgp_data *data, ...@@ -227,6 +227,7 @@ static int sgp_verify_buffer(const struct sgp_data *data,
* @cmd: SGP Command to issue * @cmd: SGP Command to issue
* @buf: Raw data buffer to use * @buf: Raw data buffer to use
* @word_count: Num words to read, excluding CRC bytes * @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. * Return: 0 on success, negative error otherwise.
*/ */
...@@ -409,6 +410,7 @@ static int sgp_read_raw(struct iio_dev *indio_dev, ...@@ -409,6 +410,7 @@ static int sgp_read_raw(struct iio_dev *indio_dev,
static int sgp_check_compat(struct sgp_data *data, static int sgp_check_compat(struct sgp_data *data,
unsigned int product_id) unsigned int product_id)
{ {
struct device *dev = &data->client->dev;
const struct sgp_version *supported_versions; const struct sgp_version *supported_versions;
u16 ix, num_fs; u16 ix, num_fs;
u16 product, generation, major, minor; u16 product, generation, major, minor;
...@@ -416,21 +418,20 @@ static int sgp_check_compat(struct sgp_data *data, ...@@ -416,21 +418,20 @@ static int sgp_check_compat(struct sgp_data *data,
/* driver does not match product */ /* driver does not match product */
generation = SGP_VERS_GEN(data); generation = SGP_VERS_GEN(data);
if (generation != 0) { if (generation != 0) {
dev_err(&data->client->dev, dev_err(dev,
"incompatible product generation %d != 0", generation); "incompatible product generation %d != 0", generation);
return -ENODEV; return -ENODEV;
} }
product = SGP_VERS_PRODUCT(data); product = SGP_VERS_PRODUCT(data);
if (product != product_id) { if (product != product_id) {
dev_err(&data->client->dev, dev_err(dev, "sensor reports a different product: 0x%04hx\n",
"sensor reports a different product: 0x%04hx\n",
product); product);
return -ENODEV; return -ENODEV;
} }
if (SGP_VERS_RESERVED(data)) 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 */ /* engineering samples are not supported: no interface guarantees */
if (SGP_VERS_ENG_BIT(data)) if (SGP_VERS_ENG_BIT(data))
...@@ -456,8 +457,7 @@ static int sgp_check_compat(struct sgp_data *data, ...@@ -456,8 +457,7 @@ static int sgp_check_compat(struct sgp_data *data,
minor >= supported_versions[ix].minor) minor >= supported_versions[ix].minor)
return 0; return 0;
} }
dev_err(&data->client->dev, "unsupported sgp version: %d.%d\n", dev_err(dev, "unsupported sgp version: %d.%d\n", major, minor);
major, minor);
return -ENODEV; return -ENODEV;
} }
...@@ -499,19 +499,18 @@ static const struct of_device_id sgp_dt_ids[] = { ...@@ -499,19 +499,18 @@ static const struct of_device_id sgp_dt_ids[] = {
static int sgp_probe(struct i2c_client *client, static int sgp_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct device *dev = &client->dev;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
struct sgp_data *data; struct sgp_data *data;
const struct of_device_id *of_id;
unsigned long product_id; unsigned long product_id;
int ret; int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev) if (!indio_dev)
return -ENOMEM; return -ENOMEM;
of_id = of_match_device(sgp_dt_ids, &client->dev); if (dev_fwnode(dev))
if (of_id) product_id = (unsigned long)device_get_match_data(dev);
product_id = (unsigned long)of_id->data;
else else
product_id = id->driver_data; product_id = id->driver_data;
...@@ -541,9 +540,9 @@ static int sgp_probe(struct i2c_client *client, ...@@ -541,9 +540,9 @@ static int sgp_probe(struct i2c_client *client,
sgp_init(data); sgp_init(data);
ret = devm_iio_device_register(&client->dev, indio_dev); ret = devm_iio_device_register(dev, indio_dev);
if (ret) { if (ret) {
dev_err(&client->dev, "failed to register iio device\n"); dev_err(dev, "failed to register iio device\n");
return ret; return ret;
} }
...@@ -576,7 +575,7 @@ MODULE_DEVICE_TABLE(of, sgp_dt_ids); ...@@ -576,7 +575,7 @@ MODULE_DEVICE_TABLE(of, sgp_dt_ids);
static struct i2c_driver sgp_driver = { static struct i2c_driver sgp_driver = {
.driver = { .driver = {
.name = "sgp30", .name = "sgp30",
.of_match_table = of_match_ptr(sgp_dt_ids), .of_match_table = sgp_dt_ids,
}, },
.probe = sgp_probe, .probe = sgp_probe,
.remove = sgp_remove, .remove = sgp_remove,
......
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/of.h> #include <linux/mod_devicetable.h>
#include <linux/of_device.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
...@@ -352,12 +351,12 @@ MODULE_DEVICE_TABLE(of, vz89x_dt_ids); ...@@ -352,12 +351,12 @@ MODULE_DEVICE_TABLE(of, vz89x_dt_ids);
static int vz89x_probe(struct i2c_client *client, static int vz89x_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct device *dev = &client->dev;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
struct vz89x_data *data; struct vz89x_data *data;
const struct of_device_id *of_id;
int chip_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) if (!indio_dev)
return -ENOMEM; return -ENOMEM;
data = iio_priv(indio_dev); data = iio_priv(indio_dev);
...@@ -370,11 +369,10 @@ static int vz89x_probe(struct i2c_client *client, ...@@ -370,11 +369,10 @@ static int vz89x_probe(struct i2c_client *client,
else else
return -EOPNOTSUPP; return -EOPNOTSUPP;
of_id = of_match_device(vz89x_dt_ids, &client->dev); if (!dev_fwnode(dev))
if (!of_id)
chip_id = id->driver_data; chip_id = id->driver_data;
else else
chip_id = (unsigned long)of_id->data; chip_id = (unsigned long)device_get_match_data(dev);
i2c_set_clientdata(client, indio_dev); i2c_set_clientdata(client, indio_dev);
data->client = client; data->client = client;
...@@ -383,13 +381,13 @@ static int vz89x_probe(struct i2c_client *client, ...@@ -383,13 +381,13 @@ static int vz89x_probe(struct i2c_client *client,
mutex_init(&data->lock); mutex_init(&data->lock);
indio_dev->info = &vz89x_info; 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->modes = INDIO_DIRECT_MODE;
indio_dev->channels = data->chip->channels; indio_dev->channels = data->chip->channels;
indio_dev->num_channels = data->chip->num_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[] = { static const struct i2c_device_id vz89x_id[] = {
...@@ -402,7 +400,7 @@ MODULE_DEVICE_TABLE(i2c, vz89x_id); ...@@ -402,7 +400,7 @@ MODULE_DEVICE_TABLE(i2c, vz89x_id);
static struct i2c_driver vz89x_driver = { static struct i2c_driver vz89x_driver = {
.driver = { .driver = {
.name = "vz89x", .name = "vz89x",
.of_match_table = of_match_ptr(vz89x_dt_ids), .of_match_table = vz89x_dt_ids,
}, },
.probe = vz89x_probe, .probe = vz89x_probe,
.id_table = vz89x_id, .id_table = vz89x_id,
......
...@@ -68,8 +68,8 @@ enum ad5064_regmap_type { ...@@ -68,8 +68,8 @@ enum ad5064_regmap_type {
* struct ad5064_chip_info - chip specific information * struct ad5064_chip_info - chip specific information
* @shared_vref: whether the vref supply is shared between channels * @shared_vref: whether the vref supply is shared between channels
* @internal_vref: internal reference voltage. 0 if the chip has no * @internal_vref: internal reference voltage. 0 if the chip has no
internal vref. * internal vref.
* @channel: channel specification * @channels: channel specification
* @num_channels: number of channels * @num_channels: number of channels
* @regmap_type: register map layout variant * @regmap_type: register map layout variant
*/ */
...@@ -98,6 +98,7 @@ typedef int (*ad5064_write_func)(struct ad5064_state *st, unsigned int cmd, ...@@ -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 * @use_internal_vref: set to true if the internal reference voltage should be
* used. * used.
* @write: register write callback * @write: register write callback
* @lock: maintain consistency between cached and dev state
* @data: i2c/spi transfer buffers * @data: i2c/spi transfer buffers
*/ */
...@@ -111,7 +112,6 @@ struct ad5064_state { ...@@ -111,7 +112,6 @@ struct ad5064_state {
bool use_internal_vref; bool use_internal_vref;
ad5064_write_func write; ad5064_write_func write;
/* Lock used to maintain consistency between cached and dev state */
struct mutex lock; struct mutex lock;
/* /*
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
...@@ -478,13 +479,11 @@ static const struct spi_device_id ad5446_spi_ids[] = { ...@@ -478,13 +479,11 @@ static const struct spi_device_id ad5446_spi_ids[] = {
}; };
MODULE_DEVICE_TABLE(spi, ad5446_spi_ids); MODULE_DEVICE_TABLE(spi, ad5446_spi_ids);
#ifdef CONFIG_OF
static const struct of_device_id ad5446_of_ids[] = { static const struct of_device_id ad5446_of_ids[] = {
{ .compatible = "ti,dac7512" }, { .compatible = "ti,dac7512" },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, ad5446_of_ids); MODULE_DEVICE_TABLE(of, ad5446_of_ids);
#endif
static int ad5446_spi_probe(struct spi_device *spi) static int ad5446_spi_probe(struct spi_device *spi)
{ {
...@@ -502,7 +501,7 @@ static int ad5446_spi_remove(struct spi_device *spi) ...@@ -502,7 +501,7 @@ static int ad5446_spi_remove(struct spi_device *spi)
static struct spi_driver ad5446_spi_driver = { static struct spi_driver ad5446_spi_driver = {
.driver = { .driver = {
.name = "ad5446", .name = "ad5446",
.of_match_table = of_match_ptr(ad5446_of_ids), .of_match_table = ad5446_of_ids,
}, },
.probe = ad5446_spi_probe, .probe = ad5446_spi_probe,
.remove = ad5446_spi_remove, .remove = ad5446_spi_remove,
......
...@@ -374,36 +374,36 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, ...@@ -374,36 +374,36 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
{ {
struct ad5592r_state *st = iio_priv(iio_dev); struct ad5592r_state *st = iio_priv(iio_dev);
u16 read_val; u16 read_val;
int ret; int ret, mult;
switch (m) { switch (m) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
mutex_lock(&st->lock);
if (!chan->output) { if (!chan->output) {
mutex_lock(&st->lock);
ret = st->ops->read_adc(st, chan->channel, &read_val); ret = st->ops->read_adc(st, chan->channel, &read_val);
mutex_unlock(&st->lock);
if (ret) if (ret)
goto unlock; return ret;
if ((read_val >> 12 & 0x7) != (chan->channel & 0x7)) { if ((read_val >> 12 & 0x7) != (chan->channel & 0x7)) {
dev_err(st->dev, "Error while reading channel %u\n", dev_err(st->dev, "Error while reading channel %u\n",
chan->channel); chan->channel);
ret = -EIO; return -EIO;
goto unlock;
} }
read_val &= GENMASK(11, 0); read_val &= GENMASK(11, 0);
} else { } else {
mutex_lock(&st->lock);
read_val = st->cached_dac[chan->channel]; read_val = st->cached_dac[chan->channel];
mutex_unlock(&st->lock);
} }
dev_dbg(st->dev, "Channel %u read: 0x%04hX\n", dev_dbg(st->dev, "Channel %u read: 0x%04hX\n",
chan->channel, read_val); chan->channel, read_val);
*val = (int) read_val; *val = (int) read_val;
ret = IIO_VAL_INT; return IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
*val = ad5592r_get_vref(st); *val = ad5592r_get_vref(st);
...@@ -412,24 +412,24 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, ...@@ -412,24 +412,24 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
*val = div_s64_rem(tmp, 1000000000LL, val2); *val = div_s64_rem(tmp, 1000000000LL, val2);
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
} else { }
int mult;
mutex_lock(&st->lock); mutex_lock(&st->lock);
if (chan->output) if (chan->output)
mult = !!(st->cached_gp_ctrl & mult = !!(st->cached_gp_ctrl &
AD5592R_REG_CTRL_DAC_RANGE); AD5592R_REG_CTRL_DAC_RANGE);
else else
mult = !!(st->cached_gp_ctrl & mult = !!(st->cached_gp_ctrl &
AD5592R_REG_CTRL_ADC_RANGE); AD5592R_REG_CTRL_ADC_RANGE);
*val *= ++mult; mutex_unlock(&st->lock);
*val2 = chan->scan_type.realbits; *val *= ++mult;
ret = IIO_VAL_FRACTIONAL_LOG2;
} *val2 = chan->scan_type.realbits;
break;
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_OFFSET: case IIO_CHAN_INFO_OFFSET:
ret = ad5592r_get_vref(st); ret = ad5592r_get_vref(st);
...@@ -439,15 +439,13 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev, ...@@ -439,15 +439,13 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
*val = (-34365 * 25) / ret; *val = (-34365 * 25) / ret;
else else
*val = (-75365 * 25) / ret; *val = (-75365 * 25) / ret;
ret = IIO_VAL_INT;
break; mutex_unlock(&st->lock);
return IIO_VAL_INT;
default: default:
return -EINVAL; return -EINVAL;
} }
unlock:
mutex_unlock(&st->lock);
return ret;
} }
static int ad5592r_write_raw_get_fmt(struct iio_dev *indio_dev, 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[] = { ...@@ -486,7 +484,7 @@ static const struct iio_chan_spec_ext_info ad5592r_ext_info[] = {
{ {
.name = "scale_available", .name = "scale_available",
.read = ad5592r_show_scale_available, .read = ad5592r_show_scale_available,
.shared = true, .shared = IIO_SHARED_BY_TYPE,
}, },
{}, {},
}; };
......
...@@ -10,9 +10,8 @@ ...@@ -10,9 +10,8 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/mod_devicetable.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/acpi.h>
#define AD5592R_GPIO_READBACK_EN BIT(10) #define AD5592R_GPIO_READBACK_EN BIT(10)
#define AD5592R_LDAC_READBACK_EN BIT(6) #define AD5592R_LDAC_READBACK_EN BIT(6)
...@@ -157,8 +156,8 @@ MODULE_DEVICE_TABLE(acpi, ad5592r_acpi_match); ...@@ -157,8 +156,8 @@ MODULE_DEVICE_TABLE(acpi, ad5592r_acpi_match);
static struct spi_driver ad5592r_spi_driver = { static struct spi_driver ad5592r_spi_driver = {
.driver = { .driver = {
.name = "ad5592r", .name = "ad5592r",
.of_match_table = of_match_ptr(ad5592r_of_match), .of_match_table = ad5592r_of_match,
.acpi_match_table = ACPI_PTR(ad5592r_acpi_match), .acpi_match_table = ad5592r_acpi_match,
}, },
.probe = ad5592r_spi_probe, .probe = ad5592r_spi_probe,
.remove = ad5592r_spi_remove, .remove = ad5592r_spi_remove,
......
...@@ -11,8 +11,7 @@ ...@@ -11,8 +11,7 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/mod_devicetable.h>
#include <linux/acpi.h>
#define AD5593R_MODE_CONF (0 << 4) #define AD5593R_MODE_CONF (0 << 4)
#define AD5593R_MODE_DAC_WRITE (1 << 4) #define AD5593R_MODE_DAC_WRITE (1 << 4)
...@@ -124,8 +123,8 @@ MODULE_DEVICE_TABLE(acpi, ad5593r_acpi_match); ...@@ -124,8 +123,8 @@ MODULE_DEVICE_TABLE(acpi, ad5593r_acpi_match);
static struct i2c_driver ad5593r_driver = { static struct i2c_driver ad5593r_driver = {
.driver = { .driver = {
.name = "ad5593r", .name = "ad5593r",
.of_match_table = of_match_ptr(ad5593r_of_match), .of_match_table = ad5593r_of_match,
.acpi_match_table = ACPI_PTR(ad5593r_acpi_match), .acpi_match_table = ad5593r_acpi_match,
}, },
.probe = ad5593r_i2c_probe, .probe = ad5593r_i2c_probe,
.remove = ad5593r_i2c_remove, .remove = ad5593r_i2c_remove,
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -29,6 +30,9 @@ ...@@ -29,6 +30,9 @@
* @spi: the device for this driver instance * @spi: the device for this driver instance
* @config: cached config register value * @config: cached config register value
* @dac_cache: current DAC raw value (chip does not support readback) * @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 * @data: spi transfer buffer
*/ */
...@@ -287,7 +291,7 @@ MODULE_DEVICE_TABLE(spi, ad7303_spi_ids); ...@@ -287,7 +291,7 @@ MODULE_DEVICE_TABLE(spi, ad7303_spi_ids);
static struct spi_driver ad7303_driver = { static struct spi_driver ad7303_driver = {
.driver = { .driver = {
.name = "ad7303", .name = "ad7303",
.of_match_table = of_match_ptr(ad7303_spi_of_match), .of_match_table = ad7303_spi_of_match,
}, },
.probe = ad7303_probe, .probe = ad7303_probe,
.remove = ad7303_remove, .remove = ad7303_remove,
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/of_device.h> #include <linux/mod_devicetable.h>
#include <linux/of.h> #include <linux/property.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
...@@ -357,29 +357,16 @@ static const struct iio_info mcp4725_info = { ...@@ -357,29 +357,16 @@ static const struct iio_info mcp4725_info = {
.attrs = &mcp4725_attribute_group, .attrs = &mcp4725_attribute_group,
}; };
#ifdef CONFIG_OF
static int mcp4725_probe_dt(struct device *dev, static int mcp4725_probe_dt(struct device *dev,
struct mcp4725_platform_data *pdata) struct mcp4725_platform_data *pdata)
{ {
struct device_node *np = dev->of_node;
if (!np)
return -ENODEV;
/* check if is the vref-supply defined */ /* 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 = pdata->vref_buffered =
of_property_read_bool(np, "microchip,vref-buffered"); device_property_read_bool(dev, "microchip,vref-buffered");
return 0; 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, static int mcp4725_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
...@@ -398,8 +385,8 @@ static int mcp4725_probe(struct i2c_client *client, ...@@ -398,8 +385,8 @@ static int mcp4725_probe(struct i2c_client *client,
data = iio_priv(indio_dev); data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev); i2c_set_clientdata(client, indio_dev);
data->client = client; data->client = client;
if (client->dev.of_node) if (dev_fwnode(&client->dev))
data->id = (enum chip_id)of_device_get_match_data(&client->dev); data->id = (enum chip_id)device_get_match_data(&client->dev);
else else
data->id = id->driver_data; data->id = id->driver_data;
pdata = dev_get_platdata(&client->dev); pdata = dev_get_platdata(&client->dev);
...@@ -519,7 +506,6 @@ static const struct i2c_device_id mcp4725_id[] = { ...@@ -519,7 +506,6 @@ static const struct i2c_device_id mcp4725_id[] = {
}; };
MODULE_DEVICE_TABLE(i2c, mcp4725_id); MODULE_DEVICE_TABLE(i2c, mcp4725_id);
#ifdef CONFIG_OF
static const struct of_device_id mcp4725_of_match[] = { static const struct of_device_id mcp4725_of_match[] = {
{ {
.compatible = "microchip,mcp4725", .compatible = "microchip,mcp4725",
...@@ -532,12 +518,11 @@ static const struct of_device_id mcp4725_of_match[] = { ...@@ -532,12 +518,11 @@ static const struct of_device_id mcp4725_of_match[] = {
{ } { }
}; };
MODULE_DEVICE_TABLE(of, mcp4725_of_match); MODULE_DEVICE_TABLE(of, mcp4725_of_match);
#endif
static struct i2c_driver mcp4725_driver = { static struct i2c_driver mcp4725_driver = {
.driver = { .driver = {
.name = MCP4725_DRV_NAME, .name = MCP4725_DRV_NAME,
.of_match_table = of_match_ptr(mcp4725_of_match), .of_match_table = mcp4725_of_match,
.pm = &mcp4725_pm_ops, .pm = &mcp4725_pm_ops,
}, },
.probe = mcp4725_probe, .probe = mcp4725_probe,
......
...@@ -26,9 +26,12 @@ ...@@ -26,9 +26,12 @@
/** /**
* struct stm32_dac - private data of DAC driver * struct stm32_dac - private data of DAC driver
* @common: reference to DAC common data * @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 {
struct stm32_dac_common *common; struct stm32_dac_common *common;
struct mutex lock;
}; };
static int stm32_dac_is_enabled(struct iio_dev *indio_dev, int channel) 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, ...@@ -58,10 +61,10 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch,
int ret; int ret;
/* already enabled / disabled ? */ /* already enabled / disabled ? */
mutex_lock(&indio_dev->mlock); mutex_lock(&dac->lock);
ret = stm32_dac_is_enabled(indio_dev, ch); ret = stm32_dac_is_enabled(indio_dev, ch);
if (ret < 0 || enable == !!ret) { if (ret < 0 || enable == !!ret) {
mutex_unlock(&indio_dev->mlock); mutex_unlock(&dac->lock);
return ret < 0 ? ret : 0; return ret < 0 ? ret : 0;
} }
...@@ -69,13 +72,13 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch, ...@@ -69,13 +72,13 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch,
ret = pm_runtime_get_sync(dev); ret = pm_runtime_get_sync(dev);
if (ret < 0) { if (ret < 0) {
pm_runtime_put_noidle(dev); pm_runtime_put_noidle(dev);
mutex_unlock(&indio_dev->mlock); mutex_unlock(&dac->lock);
return ret; return ret;
} }
} }
ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, msk, en); ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, msk, en);
mutex_unlock(&indio_dev->mlock); mutex_unlock(&dac->lock);
if (ret < 0) { if (ret < 0) {
dev_err(&indio_dev->dev, "%s failed\n", en ? dev_err(&indio_dev->dev, "%s failed\n", en ?
"Enable" : "Disable"); "Enable" : "Disable");
...@@ -327,6 +330,8 @@ static int stm32_dac_probe(struct platform_device *pdev) ...@@ -327,6 +330,8 @@ static int stm32_dac_probe(struct platform_device *pdev)
indio_dev->info = &stm32_dac_iio_info; indio_dev->info = &stm32_dac_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
mutex_init(&dac->lock);
ret = stm32_dac_chan_of_init(indio_dev); ret = stm32_dac_chan_of_init(indio_dev);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
...@@ -324,7 +325,6 @@ static int ti_dac_remove(struct spi_device *spi) ...@@ -324,7 +325,6 @@ static int ti_dac_remove(struct spi_device *spi)
return 0; return 0;
} }
#ifdef CONFIG_OF
static const struct of_device_id ti_dac_of_id[] = { static const struct of_device_id ti_dac_of_id[] = {
{ .compatible = "ti,dac082s085" }, { .compatible = "ti,dac082s085" },
{ .compatible = "ti,dac102s085" }, { .compatible = "ti,dac102s085" },
...@@ -335,7 +335,6 @@ static const struct of_device_id ti_dac_of_id[] = { ...@@ -335,7 +335,6 @@ static const struct of_device_id ti_dac_of_id[] = {
{ } { }
}; };
MODULE_DEVICE_TABLE(of, ti_dac_of_id); MODULE_DEVICE_TABLE(of, ti_dac_of_id);
#endif
static const struct spi_device_id ti_dac_spi_id[] = { static const struct spi_device_id ti_dac_spi_id[] = {
{ "dac082s085", dual_8bit }, { "dac082s085", dual_8bit },
...@@ -351,7 +350,7 @@ MODULE_DEVICE_TABLE(spi, ti_dac_spi_id); ...@@ -351,7 +350,7 @@ MODULE_DEVICE_TABLE(spi, ti_dac_spi_id);
static struct spi_driver ti_dac_driver = { static struct spi_driver ti_dac_driver = {
.driver = { .driver = {
.name = "ti-dac082s085", .name = "ti-dac082s085",
.of_match_table = of_match_ptr(ti_dac_of_id), .of_match_table = ti_dac_of_id,
}, },
.probe = ti_dac_probe, .probe = ti_dac_probe,
.remove = ti_dac_remove, .remove = ti_dac_remove,
......
...@@ -18,8 +18,7 @@ ...@@ -18,8 +18,7 @@
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h> #include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
enum chip_id { enum chip_id {
...@@ -384,7 +383,6 @@ static int dac5571_remove(struct i2c_client *i2c) ...@@ -384,7 +383,6 @@ static int dac5571_remove(struct i2c_client *i2c)
return 0; return 0;
} }
#ifdef CONFIG_OF
static const struct of_device_id dac5571_of_id[] = { static const struct of_device_id dac5571_of_id[] = {
{.compatible = "ti,dac5571"}, {.compatible = "ti,dac5571"},
{.compatible = "ti,dac6571"}, {.compatible = "ti,dac6571"},
...@@ -398,7 +396,6 @@ static const struct of_device_id dac5571_of_id[] = { ...@@ -398,7 +396,6 @@ static const struct of_device_id dac5571_of_id[] = {
{} {}
}; };
MODULE_DEVICE_TABLE(of, dac5571_of_id); MODULE_DEVICE_TABLE(of, dac5571_of_id);
#endif
static const struct i2c_device_id dac5571_id[] = { static const struct i2c_device_id dac5571_id[] = {
{"dac5571", single_8bit}, {"dac5571", single_8bit},
...@@ -417,7 +414,7 @@ MODULE_DEVICE_TABLE(i2c, dac5571_id); ...@@ -417,7 +414,7 @@ MODULE_DEVICE_TABLE(i2c, dac5571_id);
static struct i2c_driver dac5571_driver = { static struct i2c_driver dac5571_driver = {
.driver = { .driver = {
.name = "ti-dac5571", .name = "ti-dac5571",
.of_match_table = of_match_ptr(dac5571_of_id), .of_match_table = dac5571_of_id,
}, },
.probe = dac5571_probe, .probe = dac5571_probe,
.remove = dac5571_remove, .remove = dac5571_remove,
......
...@@ -22,6 +22,14 @@ struct dac7612 { ...@@ -22,6 +22,14 @@ struct dac7612 {
struct gpio_desc *loaddacs; struct gpio_desc *loaddacs;
uint16_t cache[2]; 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 * DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines. * transfer buffers to live in their own cache lines.
...@@ -101,9 +109,9 @@ static int dac7612_write_raw(struct iio_dev *iio_dev, ...@@ -101,9 +109,9 @@ static int dac7612_write_raw(struct iio_dev *iio_dev,
if (val == priv->cache[chan->channel]) if (val == priv->cache[chan->channel])
return 0; return 0;
mutex_lock(&iio_dev->mlock); mutex_lock(&priv->lock);
ret = dac7612_cmd_single(priv, chan->channel, val); ret = dac7612_cmd_single(priv, chan->channel, val);
mutex_unlock(&iio_dev->mlock); mutex_unlock(&priv->lock);
return ret; return ret;
} }
...@@ -145,6 +153,8 @@ static int dac7612_probe(struct spi_device *spi) ...@@ -145,6 +153,8 @@ static int dac7612_probe(struct spi_device *spi)
iio_dev->num_channels = ARRAY_SIZE(priv->cache); iio_dev->num_channels = ARRAY_SIZE(priv->cache);
iio_dev->name = spi_get_device_id(spi)->name; iio_dev->name = spi_get_device_id(spi)->name;
mutex_init(&priv->lock);
for (i = 0; i < ARRAY_SIZE(priv->cache); i++) { for (i = 0; i < ARRAY_SIZE(priv->cache); i++) {
ret = dac7612_cmd_single(priv, i, 0); ret = dac7612_cmd_single(priv, i, 0);
if (ret) if (ret)
......
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Copyright (c) 2011 Jonathan Cameron * Copyright (c) 2011 Jonathan Cameron
* *
* Companion module to the iio simple dummy example driver. * Companion module to the iio simple dummy example driver.
...@@ -27,11 +27,13 @@ ...@@ -27,11 +27,13 @@
#define IIO_EVENTGEN_NO 10 #define IIO_EVENTGEN_NO 10
/** /**
* struct iio_dummy_eventgen - event generator specific state
* @regs: irq regs we are faking * @regs: irq regs we are faking
* @lock: protect the evgen state * @lock: protect the evgen state
* @inuse: mask of which irqs are connected * @inuse: mask of which irqs are connected
* @irq_sim: interrupt simulator * @irq_sim: interrupt simulator
* @base: base of irq range * @base: base of irq range
* @irq_sim_domain: irq simulator domain
*/ */
struct iio_dummy_eventgen { struct iio_dummy_eventgen {
struct iio_dummy_regs regs[IIO_EVENTGEN_NO]; struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
......
...@@ -47,6 +47,13 @@ struct adf4350_state { ...@@ -47,6 +47,13 @@ struct adf4350_state {
unsigned long regs[6]; unsigned long regs[6];
unsigned long regs_hw[6]; unsigned long regs_hw[6];
unsigned long long freq_req; 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 * DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines. * transfer buffers to live in their own cache lines.
...@@ -99,7 +106,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev, ...@@ -99,7 +106,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev,
if (reg > ADF4350_REG5) if (reg > ADF4350_REG5)
return -EINVAL; return -EINVAL;
mutex_lock(&indio_dev->mlock); mutex_lock(&st->lock);
if (readval == NULL) { if (readval == NULL) {
st->regs[reg] = writeval & ~(BIT(0) | BIT(1) | BIT(2)); st->regs[reg] = writeval & ~(BIT(0) | BIT(1) | BIT(2));
ret = adf4350_sync_config(st); ret = adf4350_sync_config(st);
...@@ -107,7 +114,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev, ...@@ -107,7 +114,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev,
*readval = st->regs_hw[reg]; *readval = st->regs_hw[reg];
ret = 0; ret = 0;
} }
mutex_unlock(&indio_dev->mlock); mutex_unlock(&st->lock);
return ret; return ret;
} }
...@@ -254,7 +261,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev, ...@@ -254,7 +261,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev,
if (ret) if (ret)
return ret; return ret;
mutex_lock(&indio_dev->mlock); mutex_lock(&st->lock);
switch ((u32)private) { switch ((u32)private) {
case ADF4350_FREQ: case ADF4350_FREQ:
ret = adf4350_set_freq(st, readin); ret = adf4350_set_freq(st, readin);
...@@ -295,7 +302,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev, ...@@ -295,7 +302,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev,
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
mutex_unlock(&indio_dev->mlock); mutex_unlock(&st->lock);
return ret ? ret : len; return ret ? ret : len;
} }
...@@ -309,7 +316,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev, ...@@ -309,7 +316,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
unsigned long long val; unsigned long long val;
int ret = 0; int ret = 0;
mutex_lock(&indio_dev->mlock); mutex_lock(&st->lock);
switch ((u32)private) { switch ((u32)private) {
case ADF4350_FREQ: case ADF4350_FREQ:
val = (u64)((st->r0_int * st->r1_mod) + st->r0_fract) * 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, ...@@ -338,7 +345,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
ret = -EINVAL; ret = -EINVAL;
val = 0; val = 0;
} }
mutex_unlock(&indio_dev->mlock); mutex_unlock(&st->lock);
return ret < 0 ? ret : sprintf(buf, "%llu\n", val); return ret < 0 ? ret : sprintf(buf, "%llu\n", val);
} }
...@@ -539,6 +546,8 @@ static int adf4350_probe(struct spi_device *spi) ...@@ -539,6 +546,8 @@ static int adf4350_probe(struct spi_device *spi)
indio_dev->channels = &adf4350_chan; indio_dev->channels = &adf4350_chan;
indio_dev->num_channels = 1; indio_dev->num_channels = 1;
mutex_init(&st->lock);
st->chspc = pdata->channel_spacing; st->chspc = pdata->channel_spacing;
if (clk) { if (clk) {
st->clk = clk; st->clk = clk;
......
...@@ -44,6 +44,8 @@ config ADIS16260 ...@@ -44,6 +44,8 @@ config ADIS16260
config ADXRS290 config ADXRS290
tristate "Analog Devices ADXRS290 Dual-Axis MEMS Gyroscope SPI driver" tristate "Analog Devices ADXRS290 Dual-Axis MEMS Gyroscope SPI driver"
depends on SPI depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help help
Say yes here to build support for Analog Devices ADXRS290 programmable Say yes here to build support for Analog Devices ADXRS290 programmable
digital output gyroscope. digital output gyroscope.
......
...@@ -38,7 +38,7 @@ struct adis16080_chip_info { ...@@ -38,7 +38,7 @@ struct adis16080_chip_info {
* @us: actual spi_device to write data * @us: actual spi_device to write data
* @info: chip specific parameters * @info: chip specific parameters
* @buf: transmit or receive buffer * @buf: transmit or receive buffer
* @lock lock to protect buffer during reads * @lock: lock to protect buffer during reads
**/ **/
struct adis16080_state { struct adis16080_state {
struct spi_device *us; struct spi_device *us;
......
...@@ -523,6 +523,11 @@ static const struct adis16136_chip_info adis16136_chip_info[] = { ...@@ -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) static int adis16136_probe(struct spi_device *spi)
{ {
const struct spi_device_id *id = spi_get_device_id(spi); const struct spi_device_id *id = spi_get_device_id(spi);
...@@ -552,38 +557,23 @@ static int adis16136_probe(struct spi_device *spi) ...@@ -552,38 +557,23 @@ static int adis16136_probe(struct spi_device *spi)
if (ret) if (ret)
return 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) if (ret)
return ret; return ret;
ret = adis16136_initial_setup(indio_dev); ret = adis16136_initial_setup(indio_dev);
if (ret) 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) if (ret)
goto error_stop_device; return ret;
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);
iio_device_unregister(indio_dev); ret = devm_iio_device_register(&spi->dev, indio_dev);
adis16136_stop_device(indio_dev); if (ret)
return ret;
adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); adis16136_debugfs_init(indio_dev);
return 0; return 0;
} }
...@@ -603,7 +593,6 @@ static struct spi_driver adis16136_driver = { ...@@ -603,7 +593,6 @@ static struct spi_driver adis16136_driver = {
}, },
.id_table = adis16136_ids, .id_table = adis16136_ids,
.probe = adis16136_probe, .probe = adis16136_probe,
.remove = adis16136_remove,
}; };
module_spi_driver(adis16136_driver); module_spi_driver(adis16136_driver);
......
...@@ -359,6 +359,11 @@ static const struct adis_data adis16260_data = { ...@@ -359,6 +359,11 @@ static const struct adis_data adis16260_data = {
BIT(ADIS16260_DIAG_STAT_POWER_LOW_BIT), 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) static int adis16260_probe(struct spi_device *spi)
{ {
const struct spi_device_id *id; const struct spi_device_id *id;
...@@ -390,35 +395,20 @@ static int adis16260_probe(struct spi_device *spi) ...@@ -390,35 +395,20 @@ static int adis16260_probe(struct spi_device *spi)
if (ret) if (ret)
return 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) if (ret)
return ret; return ret;
/* Get the device into a sane initial state */ /* Get the device into a sane initial state */
ret = adis_initial_startup(&adis16260->adis); ret = adis_initial_startup(&adis16260->adis);
if (ret) if (ret)
goto error_cleanup_buffer_trigger; return ret;
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);
iio_device_unregister(indio_dev); ret = devm_add_action_or_reset(&spi->dev, adis16260_stop, indio_dev);
adis16260_stop_device(indio_dev); if (ret)
adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev); return ret;
return 0; return devm_iio_device_register(&spi->dev, indio_dev);
} }
/* /*
...@@ -441,7 +431,6 @@ static struct spi_driver adis16260_driver = { ...@@ -441,7 +431,6 @@ static struct spi_driver adis16260_driver = {
.name = "adis16260", .name = "adis16260",
}, },
.probe = adis16260_probe, .probe = adis16260_probe,
.remove = adis16260_remove,
.id_table = adis16260_id, .id_table = adis16260_id,
}; };
module_spi_driver(adis16260_driver); module_spi_driver(adis16260_driver);
......
This diff is collapsed.
...@@ -46,13 +46,20 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p) ...@@ -46,13 +46,20 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p; struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev; struct iio_dev *indio_dev = pf->indio_dev;
struct itg3200 *st = iio_priv(indio_dev); struct itg3200 *st = iio_priv(indio_dev);
__be16 buf[ITG3200_SCAN_ELEMENTS + sizeof(s64)/sizeof(u16)]; /*
* Ensure correct alignment and padding including for the
int ret = itg3200_read_all_channels(st->i2c, buf); * 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) if (ret < 0)
goto error_ret; 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); iio_trigger_notify_done(indio_dev->trig);
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/of.h> #include <linux/mod_devicetable.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/buffer.h> #include <linux/iio/buffer.h>
...@@ -323,11 +323,10 @@ static int max30102_get_current_idx(unsigned int val, int *reg) ...@@ -323,11 +323,10 @@ static int max30102_get_current_idx(unsigned int val, int *reg)
static int max30102_led_init(struct max30102_data *data) static int max30102_led_init(struct max30102_data *data)
{ {
struct device *dev = &data->client->dev; struct device *dev = &data->client->dev;
struct device_node *np = dev->of_node;
unsigned int val; unsigned int val;
int reg, ret; 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) { if (ret) {
dev_info(dev, "no red-led-current-microamp set\n"); dev_info(dev, "no red-led-current-microamp set\n");
...@@ -346,7 +345,7 @@ static int max30102_led_init(struct max30102_data *data) ...@@ -346,7 +345,7 @@ static int max30102_led_init(struct max30102_data *data)
return ret; return ret;
if (data->chip_id == max30105) { if (data->chip_id == max30105) {
ret = of_property_read_u32(np, ret = device_property_read_u32(dev,
"maxim,green-led-current-microamp", &val); "maxim,green-led-current-microamp", &val);
if (ret) { if (ret) {
dev_info(dev, "no green-led-current-microamp set\n"); dev_info(dev, "no green-led-current-microamp set\n");
...@@ -368,7 +367,7 @@ static int max30102_led_init(struct max30102_data *data) ...@@ -368,7 +367,7 @@ static int max30102_led_init(struct max30102_data *data)
return ret; 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) { if (ret) {
dev_info(dev, "no ir-led-current-microamp set\n"); dev_info(dev, "no ir-led-current-microamp set\n");
...@@ -624,7 +623,7 @@ MODULE_DEVICE_TABLE(of, max30102_dt_ids); ...@@ -624,7 +623,7 @@ MODULE_DEVICE_TABLE(of, max30102_dt_ids);
static struct i2c_driver max30102_driver = { static struct i2c_driver max30102_driver = {
.driver = { .driver = {
.name = MAX30102_DRV_NAME, .name = MAX30102_DRV_NAME,
.of_match_table = of_match_ptr(max30102_dt_ids), .of_match_table = max30102_dt_ids,
}, },
.probe = max30102_probe, .probe = max30102_probe,
.remove = max30102_remove, .remove = max30102_remove,
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/i2c.h> #include <linux/i2c.h>
...@@ -417,7 +418,7 @@ MODULE_DEVICE_TABLE(of, hdc100x_dt_ids); ...@@ -417,7 +418,7 @@ MODULE_DEVICE_TABLE(of, hdc100x_dt_ids);
static struct i2c_driver hdc100x_driver = { static struct i2c_driver hdc100x_driver = {
.driver = { .driver = {
.name = "hdc100x", .name = "hdc100x",
.of_match_table = of_match_ptr(hdc100x_dt_ids), .of_match_table = hdc100x_dt_ids,
}, },
.probe = hdc100x_probe, .probe = hdc100x_probe,
.id_table = hdc100x_id, .id_table = hdc100x_id,
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
...@@ -247,7 +248,7 @@ static struct i2c_driver htu21_driver = { ...@@ -247,7 +248,7 @@ static struct i2c_driver htu21_driver = {
.id_table = htu21_id, .id_table = htu21_id,
.driver = { .driver = {
.name = "htu21", .name = "htu21",
.of_match_table = of_match_ptr(htu21_of_match), .of_match_table = htu21_of_match,
}, },
}; };
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
...@@ -153,7 +154,7 @@ MODULE_DEVICE_TABLE(of, si7020_dt_ids); ...@@ -153,7 +154,7 @@ MODULE_DEVICE_TABLE(of, si7020_dt_ids);
static struct i2c_driver si7020_driver = { static struct i2c_driver si7020_driver = {
.driver = { .driver = {
.name = "si7020", .name = "si7020",
.of_match_table = of_match_ptr(si7020_dt_ids), .of_match_table = si7020_dt_ids,
}, },
.probe = si7020_probe, .probe = si7020_probe,
.id_table = si7020_id, .id_table = si7020_id,
......
...@@ -173,6 +173,8 @@ struct adis16400_chip_info { ...@@ -173,6 +173,8 @@ struct adis16400_chip_info {
* @variant: chip variant info * @variant: chip variant info
* @filt_int: integer part of requested filter frequency * @filt_int: integer part of requested filter frequency
* @adis: adis device * @adis: adis device
* @avail_scan_mask: NULL terminated array of bitmaps of channels
* that must be enabled together
**/ **/
struct adis16400_state { struct adis16400_state {
struct adis16400_chip_info *variant; struct adis16400_chip_info *variant;
...@@ -317,11 +319,6 @@ enum adis16400_chip_variant { ...@@ -317,11 +319,6 @@ enum adis16400_chip_variant {
ADIS16448, ADIS16448,
}; };
static struct adis_burst adis16400_burst = {
.en = true,
.reg_cmd = ADIS16400_GLOB_CMD,
};
static int adis16334_get_freq(struct adis16400_state *st) static int adis16334_get_freq(struct adis16400_state *st)
{ {
int ret; int ret;
...@@ -947,7 +944,7 @@ static const char * const adis16400_status_error_msgs[] = { ...@@ -947,7 +944,7 @@ static const char * const adis16400_status_error_msgs[] = {
[ADIS16400_DIAG_STAT_POWER_LOW] = "Power supply below 4.75V", [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, \ .msc_ctrl_reg = ADIS16400_MSC_CTRL, \
.glob_cmd_reg = ADIS16400_GLOB_CMD, \ .glob_cmd_reg = ADIS16400_GLOB_CMD, \
...@@ -973,6 +970,8 @@ static const char * const adis16400_status_error_msgs[] = { ...@@ -973,6 +970,8 @@ static const char * const adis16400_status_error_msgs[] = {
BIT(ADIS16400_DIAG_STAT_POWER_HIGH) | \ BIT(ADIS16400_DIAG_STAT_POWER_HIGH) | \
BIT(ADIS16400_DIAG_STAT_POWER_LOW), \ BIT(ADIS16400_DIAG_STAT_POWER_LOW), \
.timeouts = (_timeouts), \ .timeouts = (_timeouts), \
.burst_reg_cmd = ADIS16400_GLOB_CMD, \
.burst_len = (_burst_len) \
} }
static const struct adis_timeout adis16300_timeouts = { static const struct adis_timeout adis16300_timeouts = {
...@@ -1023,7 +1022,7 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -1023,7 +1022,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq, .set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq, .get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16300_timeouts), .adis_data = ADIS16400_DATA(&adis16300_timeouts, 18),
}, },
[ADIS16334] = { [ADIS16334] = {
.channels = adis16334_channels, .channels = adis16334_channels,
...@@ -1036,7 +1035,7 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -1036,7 +1035,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 67850, /* 25 C = 0x00 */ .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */
.set_freq = adis16334_set_freq, .set_freq = adis16334_set_freq,
.get_freq = adis16334_get_freq, .get_freq = adis16334_get_freq,
.adis_data = ADIS16400_DATA(&adis16334_timeouts), .adis_data = ADIS16400_DATA(&adis16334_timeouts, 0),
}, },
[ADIS16350] = { [ADIS16350] = {
.channels = adis16350_channels, .channels = adis16350_channels,
...@@ -1048,7 +1047,7 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -1048,7 +1047,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE, .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE,
.set_freq = adis16400_set_freq, .set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq, .get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16300_timeouts), .adis_data = ADIS16400_DATA(&adis16300_timeouts, 0),
}, },
[ADIS16360] = { [ADIS16360] = {
.channels = adis16350_channels, .channels = adis16350_channels,
...@@ -1061,7 +1060,7 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -1061,7 +1060,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq, .set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq, .get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16300_timeouts), .adis_data = ADIS16400_DATA(&adis16300_timeouts, 28),
}, },
[ADIS16362] = { [ADIS16362] = {
.channels = adis16350_channels, .channels = adis16350_channels,
...@@ -1074,7 +1073,7 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -1074,7 +1073,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq, .set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq, .get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16362_timeouts), .adis_data = ADIS16400_DATA(&adis16362_timeouts, 28),
}, },
[ADIS16364] = { [ADIS16364] = {
.channels = adis16350_channels, .channels = adis16350_channels,
...@@ -1087,7 +1086,7 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -1087,7 +1086,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq, .set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq, .get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16362_timeouts), .adis_data = ADIS16400_DATA(&adis16362_timeouts, 28),
}, },
[ADIS16367] = { [ADIS16367] = {
.channels = adis16350_channels, .channels = adis16350_channels,
...@@ -1100,7 +1099,7 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -1100,7 +1099,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq, .set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq, .get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16300_timeouts), .adis_data = ADIS16400_DATA(&adis16300_timeouts, 28),
}, },
[ADIS16400] = { [ADIS16400] = {
.channels = adis16400_channels, .channels = adis16400_channels,
...@@ -1112,7 +1111,7 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -1112,7 +1111,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq, .set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq, .get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16400_timeouts), .adis_data = ADIS16400_DATA(&adis16400_timeouts, 24),
}, },
[ADIS16445] = { [ADIS16445] = {
.channels = adis16445_channels, .channels = adis16445_channels,
...@@ -1126,7 +1125,7 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -1126,7 +1125,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
.set_freq = adis16334_set_freq, .set_freq = adis16334_set_freq,
.get_freq = adis16334_get_freq, .get_freq = adis16334_get_freq,
.adis_data = ADIS16400_DATA(&adis16445_timeouts), .adis_data = ADIS16400_DATA(&adis16445_timeouts, 16),
}, },
[ADIS16448] = { [ADIS16448] = {
.channels = adis16448_channels, .channels = adis16448_channels,
...@@ -1140,7 +1139,7 @@ static struct adis16400_chip_info adis16400_chips[] = { ...@@ -1140,7 +1139,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
.set_freq = adis16334_set_freq, .set_freq = adis16334_set_freq,
.get_freq = adis16334_get_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) ...@@ -1164,6 +1163,12 @@ static void adis16400_setup_chan_mask(struct adis16400_state *st)
st->avail_scan_mask[0] |= BIT(ch->scan_index); 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) static int adis16400_probe(struct spi_device *spi)
{ {
struct adis16400_state *st; struct adis16400_state *st;
...@@ -1190,9 +1195,6 @@ static int adis16400_probe(struct spi_device *spi) ...@@ -1190,9 +1195,6 @@ static int adis16400_probe(struct spi_device *spi)
if (!(st->variant->flags & ADIS16400_NO_BURST)) { if (!(st->variant->flags & ADIS16400_NO_BURST)) {
adis16400_setup_chan_mask(st); adis16400_setup_chan_mask(st);
indio_dev->available_scan_masks = st->avail_scan_mask; 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; adis16400_data = &st->variant->adis_data;
...@@ -1201,37 +1203,24 @@ static int adis16400_probe(struct spi_device *spi) ...@@ -1201,37 +1203,24 @@ static int adis16400_probe(struct spi_device *spi)
if (ret) if (ret)
return ret; return ret;
ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, adis16400_trigger_handler);
adis16400_trigger_handler);
if (ret) if (ret)
return ret; return ret;
/* Get the device into a sane initial state */ /* Get the device into a sane initial state */
ret = adis16400_initial_setup(indio_dev); ret = adis16400_initial_setup(indio_dev);
if (ret) if (ret)
goto error_cleanup_buffer; return ret;
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);
iio_device_unregister(indio_dev); ret = devm_add_action_or_reset(&spi->dev, adis16400_stop, indio_dev);
adis16400_stop_device(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; return 0;
} }
...@@ -1261,7 +1250,6 @@ static struct spi_driver adis16400_driver = { ...@@ -1261,7 +1250,6 @@ static struct spi_driver adis16400_driver = {
}, },
.id_table = adis16400_id, .id_table = adis16400_id,
.probe = adis16400_probe, .probe = adis16400_probe,
.remove = adis16400_remove,
}; };
module_spi_driver(adis16400_driver); module_spi_driver(adis16400_driver);
......
...@@ -403,7 +403,7 @@ static int adis16460_probe(struct spi_device *spi) ...@@ -403,7 +403,7 @@ static int adis16460_probe(struct spi_device *spi)
if (ret) if (ret)
return 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) if (ret)
return ret; return ret;
...@@ -411,30 +411,14 @@ static int adis16460_probe(struct spi_device *spi) ...@@ -411,30 +411,14 @@ static int adis16460_probe(struct spi_device *spi)
ret = __adis_initial_startup(&st->adis); ret = __adis_initial_startup(&st->adis);
if (ret) 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) if (ret)
goto error_cleanup_buffer; return ret;
adis16460_debugfs_init(indio_dev); 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; return 0;
} }
...@@ -457,7 +441,6 @@ static struct spi_driver adis16460_driver = { ...@@ -457,7 +441,6 @@ static struct spi_driver adis16460_driver = {
}, },
.id_table = adis16460_ids, .id_table = adis16460_ids,
.probe = adis16460_probe, .probe = adis16460_probe,
.remove = adis16460_remove,
}; };
module_spi_driver(adis16460_driver); module_spi_driver(adis16460_driver);
......
...@@ -565,6 +565,9 @@ static int adis16475_enable_irq(struct adis *adis, bool enable) ...@@ -565,6 +565,9 @@ static int adis16475_enable_irq(struct adis *adis, bool enable)
BIT(ADIS16475_DIAG_STAT_CLK), \ BIT(ADIS16475_DIAG_STAT_CLK), \
.enable_irq = adis16475_enable_irq, \ .enable_irq = adis16475_enable_irq, \
.timeouts = (_timeouts), \ .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[] = { static const struct adis16475_sync adis16475_sync_mode[] = {
...@@ -910,20 +913,6 @@ static const struct iio_info adis16475_info = { ...@@ -910,20 +913,6 @@ static const struct iio_info adis16475_info = {
.debugfs_reg_access = adis_debugfs_reg_access, .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, static bool adis16475_validate_crc(const u8 *buffer, u16 crc,
const bool burst32) const bool burst32)
{ {
...@@ -1279,7 +1268,6 @@ static int adis16475_probe(struct spi_device *spi) ...@@ -1279,7 +1268,6 @@ static int adis16475_probe(struct spi_device *spi)
st = iio_priv(indio_dev); st = iio_priv(indio_dev);
spi_set_drvdata(spi, indio_dev); spi_set_drvdata(spi, indio_dev);
st->adis.burst = &adis16475_burst;
st->info = device_get_match_data(&spi->dev); st->info = device_get_match_data(&spi->dev);
if (!st->info) if (!st->info)
......
...@@ -1212,6 +1212,16 @@ static int adis16480_get_ext_clocks(struct adis16480 *st) ...@@ -1212,6 +1212,16 @@ static int adis16480_get_ext_clocks(struct adis16480 *st)
return 0; 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) static int adis16480_probe(struct spi_device *spi)
{ {
const struct spi_device_id *id = spi_get_device_id(spi); const struct spi_device_id *id = spi_get_device_id(spi);
...@@ -1245,18 +1255,26 @@ static int adis16480_probe(struct spi_device *spi) ...@@ -1245,18 +1255,26 @@ static int adis16480_probe(struct spi_device *spi)
if (ret) if (ret)
return 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); ret = adis16480_config_irq_pin(spi->dev.of_node, st);
if (ret) if (ret)
goto error_stop_device; return ret;
ret = adis16480_get_ext_clocks(st); ret = adis16480_get_ext_clocks(st);
if (ret) if (ret)
goto error_stop_device; return ret;
if (!IS_ERR_OR_NULL(st->ext_clk)) { if (!IS_ERR_OR_NULL(st->ext_clk)) {
ret = adis16480_ext_clk_config(st, spi->dev.of_node, true); ret = adis16480_ext_clk_config(st, spi->dev.of_node, true);
if (ret) 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 = clk_get_rate(st->ext_clk);
st->clk_freq *= 1000; /* micro */ st->clk_freq *= 1000; /* micro */
...@@ -1264,38 +1282,16 @@ static int adis16480_probe(struct spi_device *spi) ...@@ -1264,38 +1282,16 @@ static int adis16480_probe(struct spi_device *spi)
st->clk_freq = st->chip_info->int_clk; 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) 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) if (ret)
goto error_cleanup_buffer; return ret;
adis16480_debugfs_init(indio_dev); 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; return 0;
} }
...@@ -1338,7 +1334,6 @@ static struct spi_driver adis16480_driver = { ...@@ -1338,7 +1334,6 @@ static struct spi_driver adis16480_driver = {
}, },
.id_table = adis16480_ids, .id_table = adis16480_ids,
.probe = adis16480_probe, .probe = adis16480_probe,
.remove = adis16480_remove,
}; };
module_spi_driver(adis16480_driver); module_spi_driver(adis16480_driver);
......
...@@ -26,12 +26,10 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, ...@@ -26,12 +26,10 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev,
unsigned int burst_length, burst_max_length; unsigned int burst_length, burst_max_length;
u8 *tx; u8 *tx;
/* All but the timestamp channel */ burst_length = adis->data->burst_len + adis->burst_extra_len;
burst_length = (indio_dev->num_channels - 1) * sizeof(u16);
burst_length += adis->burst->extra_len + adis->burst_extra_len;
if (adis->burst->burst_max_len) if (adis->data->burst_max_len)
burst_max_length = adis->burst->burst_max_len; burst_max_length = adis->data->burst_max_len;
else else
burst_max_length = burst_length; burst_max_length = burst_length;
...@@ -47,7 +45,7 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, ...@@ -47,7 +45,7 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev,
} }
tx = adis->buffer + burst_max_length; 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; tx[1] = 0;
adis->xfer[0].tx_buf = tx; adis->xfer[0].tx_buf = tx;
...@@ -76,7 +74,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, ...@@ -76,7 +74,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev,
kfree(adis->xfer); kfree(adis->xfer);
kfree(adis->buffer); kfree(adis->buffer);
if (adis->burst && adis->burst->en) if (adis->data->burst_len)
return adis_update_scan_mode_burst(indio_dev, scan_mask); return adis_update_scan_mode_burst(indio_dev, scan_mask);
scan_count = indio_dev->scan_bytes / 2; scan_count = indio_dev->scan_bytes / 2;
...@@ -169,48 +167,6 @@ static void adis_buffer_cleanup(void *arg) ...@@ -169,48 +167,6 @@ static void adis_buffer_cleanup(void *arg)
kfree(adis->xfer); kfree(adis->xfer);
} }
/**
* 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 * devm_adis_setup_buffer_and_trigger() - Sets up buffer and trigger for
* the managed adis device * the managed adis device
...@@ -220,7 +176,10 @@ EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); ...@@ -220,7 +176,10 @@ EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger);
* *
* Returns 0 on success, a negative error code otherwise. * 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 int
devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, 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, ...@@ -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); 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);
...@@ -55,53 +55,6 @@ static int adis_validate_irq_flag(struct adis *adis) ...@@ -55,53 +55,6 @@ static int adis_validate_irq_flag(struct adis *adis)
return 0; 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 * 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) ...@@ -137,16 +90,3 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
} }
EXPORT_SYMBOL_GPL(devm_adis_probe_trigger); 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);
...@@ -122,6 +122,13 @@ struct inv_mpu6050_chip_config { ...@@ -122,6 +122,13 @@ struct inv_mpu6050_chip_config {
u8 user_ctrl; 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. * struct inv_mpu6050_hw - Other important hardware information.
* @whoami: Self identification byte from WHO_AM_I register * @whoami: Self identification byte from WHO_AM_I register
...@@ -165,6 +172,7 @@ struct inv_mpu6050_hw { ...@@ -165,6 +172,7 @@ struct inv_mpu6050_hw {
* @magn_raw_to_gauss: coefficient to convert mag raw value to Gauss. * @magn_raw_to_gauss: coefficient to convert mag raw value to Gauss.
* @magn_orient: magnetometer sensor chip orientation if available. * @magn_orient: magnetometer sensor chip orientation if available.
* @suspended_sensors: sensors mask of sensors turned off for suspend * @suspended_sensors: sensors mask of sensors turned off for suspend
* @data: dma safe buffer used for bulk reads.
*/ */
struct inv_mpu6050_state { struct inv_mpu6050_state {
struct mutex lock; struct mutex lock;
...@@ -190,6 +198,7 @@ struct inv_mpu6050_state { ...@@ -190,6 +198,7 @@ struct inv_mpu6050_state {
s32 magn_raw_to_gauss[3]; s32 magn_raw_to_gauss[3];
struct iio_mount_matrix magn_orient; struct iio_mount_matrix magn_orient;
unsigned int suspended_sensors; unsigned int suspended_sensors;
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] ____cacheline_aligned;
}; };
/*register and associated bit definition*/ /*register and associated bit definition*/
...@@ -334,9 +343,6 @@ struct inv_mpu6050_state { ...@@ -334,9 +343,6 @@ struct inv_mpu6050_state {
#define INV_ICM20608_TEMP_OFFSET 8170 #define INV_ICM20608_TEMP_OFFSET 8170
#define INV_ICM20608_TEMP_SCALE 3059976 #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_REG_INT_PIN_CFG 0x37
#define INV_MPU6050_ACTIVE_HIGH 0x00 #define INV_MPU6050_ACTIVE_HIGH 0x00
#define INV_MPU6050_ACTIVE_LOW 0x80 #define INV_MPU6050_ACTIVE_LOW 0x80
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/math64.h> #include <linux/math64.h>
#include <asm/unaligned.h>
#include "inv_mpu_iio.h" #include "inv_mpu_iio.h"
/** /**
...@@ -121,7 +120,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) ...@@ -121,7 +120,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
struct inv_mpu6050_state *st = iio_priv(indio_dev); struct inv_mpu6050_state *st = iio_priv(indio_dev);
size_t bytes_per_datum; size_t bytes_per_datum;
int result; int result;
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
u16 fifo_count; u16 fifo_count;
s64 timestamp; s64 timestamp;
int int_status; int int_status;
...@@ -160,11 +158,11 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) ...@@ -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 * read fifo_count register to know how many bytes are inside the FIFO
* right now * right now
*/ */
result = regmap_bulk_read(st->map, st->reg->fifo_count_h, data, result = regmap_bulk_read(st->map, st->reg->fifo_count_h,
INV_MPU6050_FIFO_COUNT_BYTE); st->data, INV_MPU6050_FIFO_COUNT_BYTE);
if (result) if (result)
goto end_session; 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. * Handle fifo overflow by resetting fifo.
...@@ -181,8 +179,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) ...@@ -181,8 +179,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
nb = fifo_count / bytes_per_datum; nb = fifo_count / bytes_per_datum;
inv_mpu6050_update_period(st, pf->timestamp, nb); inv_mpu6050_update_period(st, pf->timestamp, nb);
for (i = 0; i < nb; ++i) { for (i = 0; i < nb; ++i) {
result = regmap_bulk_read(st->map, st->reg->fifo_r_w, result = regmap_noinc_read(st->map, st->reg->fifo_r_w,
data, bytes_per_datum); st->data, bytes_per_datum);
if (result) if (result)
goto flush_fifo; goto flush_fifo;
/* skip first samples if needed */ /* skip first samples if needed */
...@@ -191,7 +189,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) ...@@ -191,7 +189,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
continue; continue;
} }
timestamp = inv_mpu6050_get_timestamp(st); 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: end_session:
......
...@@ -383,6 +383,7 @@ struct st_lsm6dsx_sensor { ...@@ -383,6 +383,7 @@ struct st_lsm6dsx_sensor {
* @iio_devs: Pointers to acc/gyro iio_dev instances. * @iio_devs: Pointers to acc/gyro iio_dev instances.
* @settings: Pointer to the specific sensor settings in use. * @settings: Pointer to the specific sensor settings in use.
* @orientation: sensor chip orientation relative to main hardware. * @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 st_lsm6dsx_hw {
struct device *dev; struct device *dev;
...@@ -411,6 +412,11 @@ struct st_lsm6dsx_hw { ...@@ -411,6 +412,11 @@ struct st_lsm6dsx_hw {
const struct st_lsm6dsx_settings *settings; const struct st_lsm6dsx_settings *settings;
struct iio_mount_matrix orientation; 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 = { static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = {
......
...@@ -353,9 +353,6 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) ...@@ -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; 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_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; 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; bool reset_ts = false;
__le16 fifo_status; __le16 fifo_status;
s64 ts = 0; s64 ts = 0;
...@@ -416,19 +413,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) ...@@ -416,19 +413,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) { while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) {
if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
memcpy(gyro_buff, &hw->buff[offset], memcpy(hw->scan[ST_LSM6DSX_ID_GYRO].channels,
ST_LSM6DSX_SAMPLE_SIZE); &hw->buff[offset],
offset += ST_LSM6DSX_SAMPLE_SIZE; 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)) { if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
memcpy(acc_buff, &hw->buff[offset], memcpy(hw->scan[ST_LSM6DSX_ID_ACC].channels,
ST_LSM6DSX_SAMPLE_SIZE); &hw->buff[offset],
offset += ST_LSM6DSX_SAMPLE_SIZE; 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)) { if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
memcpy(ext_buff, &hw->buff[offset], memcpy(hw->scan[ST_LSM6DSX_ID_EXT0].channels,
ST_LSM6DSX_SAMPLE_SIZE); &hw->buff[offset],
offset += ST_LSM6DSX_SAMPLE_SIZE; sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels));
offset += sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels);
} }
if (ts_sip-- > 0) { if (ts_sip-- > 0) {
...@@ -458,19 +458,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) ...@@ -458,19 +458,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
iio_push_to_buffers_with_timestamp( iio_push_to_buffers_with_timestamp(
hw->iio_devs[ST_LSM6DSX_ID_GYRO], 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--; gyro_sip--;
} }
if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
iio_push_to_buffers_with_timestamp( iio_push_to_buffers_with_timestamp(
hw->iio_devs[ST_LSM6DSX_ID_ACC], 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--; acc_sip--;
} }
if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
iio_push_to_buffers_with_timestamp( iio_push_to_buffers_with_timestamp(
hw->iio_devs[ST_LSM6DSX_ID_EXT0], 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--; ext_sip--;
} }
sip++; sip++;
...@@ -555,7 +558,14 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) ...@@ -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 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
u16 fifo_len, fifo_diff_mask; 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; bool reset_ts = false;
int i, err, read_len; int i, err, read_len;
__le16 fifo_status; __le16 fifo_status;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment