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.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAl9o+P4RHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0FohJyRAAjEa6RhQkoJMn4QRp5gNj+BhWoYeM4yeL
 kjOTI9WIfi5acuJiQK/bscqPjVoa9xkp33Za6gRYLFHtxiY0M1c7IKxK7jdDIxyT
 ak5JkmhbklhpAqAaXtGhngBQ/pmctunefjfJbV6ltlZP4W+7aHhGgVEW74Qiagn0
 +FuT3g23pcaCelm7uf1hynxkPUSvH0HlYPUdCptuYhE1YeFSsaCxSVl8DxIK0a52
 MC/rVl4Psjn01mTtVTcwD/JlcO2LnoGC3kJThYguvY52mDqNZBYCseUKwB9ribAT
 AUj7X9rxbAsdQAoN/RF0umD6hxoTnEePf0B29NfdXM/6sn/nhMzWMpVPEPRPRN3B
 /g+WDBPCdOKs5mdyHgfSKhJko0p4jQ5dhGFbzBVA75Uq0yxxRrdXLI2D4rdBjUmF
 6MXgAqaaAGRMq7qg3t3Kt9scR5J0CoPTY7oQvcetu/ZItFmaLEP4zM6wpYp1YXQg
 4GnUKFmwSAb1/Ah4x4XWKkgtvAgJ0RjfebTifa0u/kqi4ZBjacdP7dd4ttEY/3pH
 Zg7OQuMZCF70tDkksSkdAWXEdTJuCZtzaCTdck3NS7yZv0d/MYq2aqDqmON1GbEU
 18yTcGQYGvCJgUq2IlMOpFmlzCzA32+FS5/d2VIiL9xPtS0/weEmIJqY7ONvkQ+A
 VQq0c2u9Xck=
 =yrII
 -----END PGP SIGNATURE-----

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
  ...
This commit is contained in:
Greg Kroah-Hartman 2020-09-22 09:45:11 +02:00
commit b290f902b8
144 changed files with 2386 additions and 1822 deletions

View File

@ -1942,6 +1942,10 @@ S: Post Office Box 611311
S: San Jose, California 95161-1311
S: USA
N: Hartmut Knaack
E: knaack.h@gmx.de
D: IIO subsystem and drivers
N: Thorsten Knabe
E: Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de>
E: Thorsten Knabe <tek01@hrzpub.tu-darmstadt.de>

View File

@ -1758,6 +1758,14 @@ Contact: linux-iio@vger.kernel.org
Description:
One of the following thermocouple types: B, E, J, K, N, R, S, T.
What: /sys/bus/iio/devices/iio:deviceX/in_temp_object_calibambient
What: /sys/bus/iio/devices/iio:deviceX/in_tempX_object_calibambient
KernelVersion: 5.10
Contact: linux-iio@vger.kernel.org
Description:
Calibrated ambient temperature for object temperature
calculation in milli degrees Celsius.
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_x_raw
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_y_raw
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_raw

View File

@ -1,16 +0,0 @@
* Analog Devices AD7949/AD7682/AD7689
Required properties:
- compatible: Should be one of
* "adi,ad7949"
* "adi,ad7682"
* "adi,ad7689"
- reg: spi chip select number for the device
- vref-supply: The regulator supply for ADC reference voltage
Example:
adc@0 {
compatible = "adi,ad7949";
reg = <0>;
vref-supply = <&vdd_supply>;
};

View File

@ -1,41 +0,0 @@
Analog Devices AD7768-1 ADC device driver
Required properties for the AD7768-1:
- compatible: Must be "adi,ad7768-1"
- reg: SPI chip select number for the device
- spi-max-frequency: Max SPI frequency to use
see: Documentation/devicetree/bindings/spi/spi-bus.txt
- clocks: phandle to the master clock (mclk)
see: Documentation/devicetree/bindings/clock/clock-bindings.txt
- clock-names: Must be "mclk".
- interrupts: IRQ line for the ADC
see: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
- vref-supply: vref supply can be used as reference for conversion
- adi,sync-in-gpios: must be the device tree identifier of the SYNC-IN pin. Enables
synchronization of multiple devices that require simultaneous sampling.
A pulse is always required if the configuration is changed in any way, for example
if the filter decimation rate changes. As the line is active low, it should
be marked GPIO_ACTIVE_LOW.
Optional properties:
- reset-gpios : GPIO spec for the RESET pin. If specified, it will be asserted during
driver probe. As the line is active low, it should be marked GPIO_ACTIVE_LOW.
Example:
adc@0 {
compatible = "adi,ad7768-1";
reg = <0>;
spi-max-frequency = <2000000>;
spi-cpol;
spi-cpha;
vref-supply = <&adc_vref>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gpio>;
adi,sync-in-gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
clocks = <&ad7768_mclk>;
clock-names = "mclk";
};

View File

@ -0,0 +1,89 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adi,ad7768-1.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD7768-1 ADC device driver
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
description: |
Datasheet at:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad7768-1.pdf
properties:
compatible:
const: adi,ad7768-1
reg:
maxItems: 1
clocks:
maxItems: 1
clock-names:
const: mclk
interrupts:
maxItems: 1
vref-supply:
description:
ADC reference voltage supply
adi,sync-in-gpios:
description:
Enables synchronization of multiple devices that require simultaneous
sampling. A pulse is always required if the configuration is changed
in any way, for example if the filter decimation rate changes.
As the line is active low, it should be marked GPIO_ACTIVE_LOW.
reset-gpios:
maxItems: 1
spi-max-frequency: true
spi-cpol: true
spi-cpha : true
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- clocks
- clock-names
- vref-supply
- spi-cpol
- spi-cpha
- adi,sync-in-gpios
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7768-1";
reg = <0>;
spi-max-frequency = <2000000>;
spi-cpol;
spi-cpha;
vref-supply = <&adc_vref>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gpio>;
adi,sync-in-gpios = <&gpio 22 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
clocks = <&ad7768_mclk>;
clock-names = "mclk";
};
};
...

View File

@ -0,0 +1,57 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adi,ad7949.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD7949/AD7682/AD7689 analog to digital converters
maintainers:
- Charles-Antoine Couret <charles-antoine.couret@essensium.com>
description: |
Specifications on the converters can be found at:
AD7949:
https://www.analog.com/media/en/technical-documentation/data-sheets/AD7949.pdf
AD7682/AD7698:
https://www.analog.com/media/en/technical-documentation/data-sheets/AD7682_7689.pdf
properties:
compatible:
enum:
- adi,ad7682
- adi,ad7689
- adi,ad7949
reg:
maxItems: 1
vref-supply:
description:
ADC reference voltage supply
spi-max-frequency: true
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- vref-supply
additionalProperties: false
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7949";
reg = <0>;
vref-supply = <&vdd_supply>;
};
};
...

View File

@ -1,73 +0,0 @@
ADS1015 (I2C)
This device is a 12-bit A-D converter with 4 inputs.
The inputs can be used single ended or in certain differential combinations.
For configuration all possible combinations are mapped to 8 channels:
0: Voltage over AIN0 and AIN1.
1: Voltage over AIN0 and AIN3.
2: Voltage over AIN1 and AIN3.
3: Voltage over AIN2 and AIN3.
4: Voltage over AIN0 and GND.
5: Voltage over AIN1 and GND.
6: Voltage over AIN2 and GND.
7: Voltage over AIN3 and GND.
Each channel can be configured individually:
- pga is the programmable gain amplifier (values are full scale)
0: +/- 6.144 V
1: +/- 4.096 V
2: +/- 2.048 V (default)
3: +/- 1.024 V
4: +/- 0.512 V
5: +/- 0.256 V
- data_rate in samples per second
0: 128
1: 250
2: 490
3: 920
4: 1600 (default)
5: 2400
6: 3300
1) The /ads1015 node
Required properties:
- compatible : must be "ti,ads1015"
- reg : I2C bus address of the device
- #address-cells : must be <1>
- #size-cells : must be <0>
The node contains child nodes for each channel that the platform uses.
Example ADS1015 node:
ads1015@49 {
compatible = "ti,ads1015";
reg = <0x49>;
#address-cells = <1>;
#size-cells = <0>;
[ child node definitions... ]
}
2) channel nodes
Required properties:
- reg : the channel number
Optional properties:
- ti,gain : the programmable gain amplifier setting
- ti,datarate : the converter data rate
Example ADS1015 channel node:
channel@4 {
reg = <4>;
ti,gain = <3>;
ti,datarate = <5>;
};

View File

@ -0,0 +1,55 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/aspeed,ast2400-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ADC that forms part of an ASPEED server management processor.
maintainers:
- Joel Stanley <joel@jms.id.au>
description:
This device is a 10-bit converter for 16 voltage channels. All inputs are
single ended.
properties:
compatible:
enum:
- aspeed,ast2400-adc
- aspeed,ast2500-adc
reg:
maxItems: 1
clocks:
description:
Input clock used to derive the sample clock. Expected to be the
SoC's APB clock.
resets:
maxItems: 1
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- clocks
- resets
- "#io-channel-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/aspeed-clock.h>
adc@1e6e9000 {
compatible = "aspeed,ast2400-adc";
reg = <0x1e6e9000 0xb0>;
clocks = <&syscon ASPEED_CLK_APB>;
resets = <&syscon ASPEED_RESET_ADC>;
#io-channel-cells = <1>;
};
...

View File

@ -1,22 +0,0 @@
Aspeed ADC
This device is a 10-bit converter for 16 voltage channels. All inputs are
single ended.
Required properties:
- compatible: Should be "aspeed,ast2400-adc" or "aspeed,ast2500-adc"
- reg: memory window mapping address and length
- clocks: Input clock used to derive the sample clock. Expected to be the
SoC's APB clock.
- resets: Reset controller phandle
- #io-channel-cells: Must be set to <1> to indicate channels are selected
by index.
Example:
adc@1e6e9000 {
compatible = "aspeed,ast2400-adc";
reg = <0x1e6e9000 0xb0>;
clocks = <&syscon ASPEED_CLK_APB>;
resets = <&syscon ASPEED_RESET_ADC>;
#io-channel-cells = <1>;
};

View File

@ -1,19 +0,0 @@
* Berlin Analog to Digital Converter (ADC)
The Berlin ADC has 8 channels, with one connected to a temperature sensor.
It is part of the system controller register set. The ADC node should be a
sub-node of the system controller node.
Required properties:
- compatible: must be "marvell,berlin2-adc"
- interrupts: the interrupts for the ADC and the temperature sensor
- interrupt-names: should be "adc" and "tsen"
Example:
adc: adc {
compatible = "marvell,berlin2-adc";
interrupt-parent = <&sic>;
interrupts = <12>, <14>;
interrupt-names = "adc", "tsen";
};

View File

@ -1,22 +0,0 @@
* Cosmic Circuits - Analog to Digital Converter (CC-10001-ADC)
Required properties:
- compatible: Should be "cosmic,10001-adc"
- reg: Should contain adc registers location and length.
- clock-names: Should contain "adc".
- clocks: Should contain a clock specifier for each entry in clock-names
- vref-supply: The regulator supply ADC reference voltage.
Optional properties:
- adc-reserved-channels: Bitmask of reserved channels,
i.e. channels that cannot be used by the OS.
Example:
adc: adc@18101600 {
compatible = "cosmic,10001-adc";
reg = <0x18101600 0x24>;
adc-reserved-channels = <0x2>;
clocks = <&adc_clk>;
clock-names = "adc";
vref-supply = <&reg_1v8>;
};

View File

@ -0,0 +1,59 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/cosmic,10001-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cosmic Circuits CC-10001 ADC
maintainers:
- Jonathan Cameron <jic23@kernel.org>
description:
Cosmic Circuits 10001 10-bit ADC device.
properties:
compatible:
const: cosmic,10001-adc
reg:
maxItems: 1
adc-reserved-channels:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Bitmask of reserved channels, i.e. channels that cannot be
used by the OS.
clocks:
maxItems: 1
clock-names:
const: adc
vref-supply: true
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- clocks
- clock-names
- vref-supply
additionalProperties: false
examples:
- |
adc@18101600 {
compatible = "cosmic,10001-adc";
reg = <0x18101600 0x24>;
adc-reserved-channels = <0x2>;
clocks = <&adc_clk>;
clock-names = "adc";
vref-supply = <&reg_1v8>;
};
...

View File

@ -1,17 +0,0 @@
Motorola CPCAP PMIC ADC binding
Required properties:
- compatible: Should be "motorola,cpcap-adc" or "motorola,mapphone-cpcap-adc"
- interrupts: The interrupt number for the ADC device
- interrupt-names: Should be "adcdone"
- #io-channel-cells: Number of cells in an IIO specifier
Example:
cpcap_adc: adc {
compatible = "motorola,mapphone-cpcap-adc";
interrupt-parent = <&cpcap>;
interrupts = <8 IRQ_TYPE_NONE>;
interrupt-names = "adcdone";
#io-channel-cells = <1>;
};

View File

@ -1,16 +0,0 @@
Dialog Semiconductor DA9150 IIO GPADC bindings
Required properties:
- compatible: "dlg,da9150-gpadc" for DA9150 IIO GPADC
- #io-channel-cells: Should be set to <1>
(See Documentation/devicetree/bindings/iio/iio-bindings.txt for further info)
For further information on GPADC channels, see device datasheet.
Example:
gpadc: da9150-gpadc {
compatible = "dlg,da9150-gpadc";
#io-channel-cells = <1>;
};

View File

@ -0,0 +1,35 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/dlg,da9150-gpadc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Dialog Semiconductor DA9150 IIO GPADC
maintainers:
- Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
description:
This patch adds support for general purpose ADC within the
DA9150 Charger & Fuel-Gauge IC.
properties:
compatible:
const: dlg,da9150-gpadc
"#io-channel-cells":
const: 1
required:
- compatible
- "#io-channel-cells"
additionalProperties: false
examples:
- |
adc {
compatible = "dlg,da9150-gpadc";
#io-channel-cells = <1>;
};
...

View File

@ -1,57 +0,0 @@
Freescale i.MX25 ADC GCQ device
This is a generic conversion queue device that can convert any of the
analog inputs using the ADC unit of the i.MX25.
Required properties:
- compatible: Should be "fsl,imx25-gcq".
- reg: Should be the register range of the module.
- interrupts: Should be the interrupt number of the module.
Typically this is <1>.
- #address-cells: Should be <1> (setting for the subnodes)
- #size-cells: Should be <0> (setting for the subnodes)
Optional properties:
- vref-ext-supply: The regulator supplying the ADC reference voltage.
Required when at least one subnode uses the this reference.
- vref-xp-supply: The regulator supplying the ADC reference voltage on pin XP.
Required when at least one subnode uses this reference.
- vref-yp-supply: The regulator supplying the ADC reference voltage on pin YP.
Required when at least one subnode uses this reference.
Sub-nodes:
Optionally you can define subnodes which define the reference voltage
for the analog inputs.
Required properties for subnodes:
- reg: Should be the number of the analog input.
0: xp
1: yp
2: xn
3: yn
4: wiper
5: inaux0
6: inaux1
7: inaux2
Optional properties for subnodes:
- fsl,adc-refp: specifies the positive reference input as defined in
<dt-bindings/iio/adc/fsl-imx25-gcq.h>
- fsl,adc-refn: specifies the negative reference input as defined in
<dt-bindings/iio/adc/fsl-imx25-gcq.h>
Example:
adc: adc@50030800 {
compatible = "fsl,imx25-gcq";
reg = <0x50030800 0x60>;
interrupt-parent = <&tscadc>;
interrupts = <1>;
#address-cells = <1>;
#size-cells = <0>;
inaux@5 {
reg = <5>;
fsl,adc-refp = <MX25_ADC_REFP_INT>;
fsl,adc-refn = <MX25_ADC_REFN_NGND>;
};
};

View File

@ -0,0 +1,131 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/fsl,imx25-gcq.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale ADC GCQ device
description:
This is a generic conversion queue device that can convert any of the
analog inputs using the ADC unit of the i.MX25.
maintainers:
- Jonathan Cameron <jic23@kernel.org>
properties:
compatible:
const: fsl,imx25-gcq
reg:
maxItems: 1
interrupts:
maxItems: 1
vref-ext-supply:
description:
The regulator supplying the ADC reference voltage.
Required when at least one subnode uses the this reference.
vref-xp-supply:
description:
The regulator supplying the ADC reference voltage on pin XP.
Required when at least one subnode uses this reference.
vref-yp-supply:
description:
The regulator supplying the ADC reference voltage on pin YP.
Required when at least one subnode uses this reference.
"#io-channel-cells":
const: 1
"#address-cells":
const: 1
"#size-cells":
const: 0
required:
- compatible
- reg
- interrupts
- "#address-cells"
- "#size-cells"
patternProperties:
"[a-z][a-z0-9]+@[0-9a-f]+$":
type: object
description:
Child nodes used to define the reference voltages used for each channel
properties:
reg:
description: |
Number of the analog input.
0: xp
1: yp
2: xn
3: yn
4: wiper
5: inaux0
6: inaux1
7: inaux2
items:
- minimum: 0
maximum: 7
fsl,adc-refp:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Specifies the positive reference input as defined in
<dt-bindings/iio/adc/fsl-imx25-gcq.h>
0: YP voltage reference
1: XP voltage reference
2: External voltage reference
3: Internal voltage reference (default)
minimum: 0
maximum: 3
fsl,adc-refn:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Specifies the negative reference input as defined in
<dt-bindings/iio/adc/fsl-imx25-gcq.h>
0: XN ground reference
1: YN ground reference
2: Internal ground reference
3: External ground reference (default)
minimum: 0
maximum: 3
required:
- reg
additionalProperties: false
additionalProperties: false
examples:
- |
#include <dt-bindings/iio/adc/fsl-imx25-gcq.h>
soc {
#address-cells = <1>;
#size-cells = <1>;
adc@50030800 {
compatible = "fsl,imx25-gcq";
reg = <0x50030800 0x60>;
interrupt-parent = <&tscadc>;
interrupts = <1>;
#address-cells = <1>;
#size-cells = <0>;
inaux@5 {
reg = <5>;
fsl,adc-refp = <MX25_ADC_REFP_INT>;
fsl,adc-refn = <MX25_ADC_REFN_NGND>;
};
};
};
...

View File

@ -0,0 +1,62 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/fsl,imx7d-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale ADC found on the imx7d SoC
maintainers:
- Haibo Chen <haibo.chen@nxp.com>
properties:
compatible:
const: fsl,imx7d-adc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
clock-names:
const: adc
vref-supply: true
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- vref-supply
- "#io-channel-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/clock/imx7d-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
soc {
#address-cells = <1>;
#size-cells = <1>;
adc@30610000 {
compatible = "fsl,imx7d-adc";
reg = <0x30610000 0x10000>;
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_ADC_ROOT_CLK>;
clock-names = "adc";
vref-supply = <&reg_vcc_3v3_mcu>;
#io-channel-cells = <1>;
};
};
...

View File

@ -0,0 +1,81 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/fsl,vf610-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ADC found on Freescale vf610 and similar SoCs
maintainers:
- Fugang Duan <fugang.duan@nxp.com>
description:
ADCs found on vf610/i.MX6slx and upward SoCs from Freescale.
properties:
compatible:
const: fsl,vf610-adc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
description: ADC source clock (ipg clock)
maxItems: 1
clock-names:
const: adc
vref-supply:
description: ADC reference voltage supply.
fsl,adck-max-frequency:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 3
maxItems: 3
description: |
Maximum frequencies from datasheet operating requirements.
Three values necessary to cover the 3 conversion modes.
* Frequency in normal mode (ADLPC=0, ADHSC=0)
* Frequency in high-speed mode (ADLPC=0, ADHSC=1)
* Frequency in low-power mode (ADLPC=1, ADHSC=0)
min-sample-time:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Minimum sampling time in nanoseconds. This value has
to be chosen according to the conversion mode and the connected analog
source resistance (R_as) and capacitance (C_as). Refer the datasheet's
operating requirements. A safe default across a wide range of R_as and
C_as as well as conversion modes is 1000ns.
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- vref-supply
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/vf610-clock.h>
adc@4003b000 {
compatible = "fsl,vf610-adc";
reg = <0x4003b000 0x1000>;
interrupts = <0 53 0x04>;
clocks = <&clks VF610_CLK_ADC0>;
clock-names = "adc";
fsl,adck-max-frequency = <30000000>, <40000000>, <20000000>;
vref-supply = <&reg_vcc_3v3_mcu>;
min-sample-time = <10000>;
};
...

View File

@ -1,21 +0,0 @@
Holt Integrated Circuits HI-8435 threshold detector bindings
Required properties:
- compatible: should be "holt,hi8435"
- reg: spi chip select number for the device
Recommended properties:
- spi-max-frequency: definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
Optional properties:
- gpios: GPIO used for controlling the reset pin
Example:
sensor@0 {
compatible = "holt,hi8435";
reg = <0>;
gpios = <&gpio6 1 0>;
spi-max-frequency = <1000000>;
};

View File

@ -0,0 +1,50 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/holt,hi8435.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Holt Integrated Circuits HI-8435 SPI threshold detector
maintainers:
- Vladimir Barinov <vladimir.barinov@cogentembedded.com>
description: |
Datasheet: http://www.holtic.com/documents/427-hi-8435_v-rev-lpdf.do
properties:
compatible:
const: holt,hi8435
reg:
maxItems: 1
gpios:
description:
GPIO used for controlling the reset pin
maxItems: 1
spi-max-frequency: true
"#io-channel-cells":
const: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
threshold-detector@0 {
compatible = "holt,hi8435";
reg = <0>;
gpios = <&gpio6 1 0>;
spi-max-frequency = <1000000>;
};
};
...

View File

@ -1,24 +0,0 @@
Freescale imx7d ADC bindings
The devicetree bindings are for the ADC driver written for
imx7d SoC.
Required properties:
- compatible: Should be "fsl,imx7d-adc"
- reg: Offset and length of the register set for the ADC device
- interrupts: The interrupt number for the ADC device
- clocks: The root clock of the ADC controller
- clock-names: Must contain "adc", matching entry in the clocks property
- vref-supply: The regulator supply ADC reference voltage
- #io-channel-cells: Must be 1 as per ../iio-bindings.txt
Example:
adc1: adc@30610000 {
compatible = "fsl,imx7d-adc";
reg = <0x30610000 0x10000>;
interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX7D_ADC_ROOT_CLK>;
clock-names = "adc";
vref-supply = <&reg_vcc_3v3_mcu>;
#io-channel-cells = <1>;
};

View File

@ -1,20 +0,0 @@
NXP LPC1850 ADC bindings
Required properties:
- compatible: Should be "nxp,lpc1850-adc"
- reg: Offset and length of the register set for the ADC device
- interrupts: The interrupt number for the ADC device
- clocks: The root clock of the ADC controller
- vref-supply: The regulator supply ADC reference voltage
- resets: phandle to reset controller and line specifier
Example:
adc0: adc@400e3000 {
compatible = "nxp,lpc1850-adc";
reg = <0x400e3000 0x1000>;
interrupts = <17>;
clocks = <&ccu1 CLK_APB3_ADC0>;
vref-supply = <&reg_vdda>;
resets = <&rgu 40>;
};

View File

@ -1,21 +0,0 @@
* NXP LPC32xx SoC ADC controller
Required properties:
- compatible: must be "nxp,lpc3220-adc"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: The ADC interrupt
Optional:
- vref-supply: The regulator supply ADC reference voltage, optional
for legacy reason, but highly encouraging to us in new device tree
Example:
adc@40048000 {
compatible = "nxp,lpc3220-adc";
reg = <0x40048000 0x1000>;
interrupt-parent = <&mic>;
interrupts = <39 0>;
vref-supply = <&vcc>;
};

View File

@ -0,0 +1,50 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/marvell,berlin2-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Berlin 2 Analog to Digital Converter (ADC)
maintainers:
- Antoine Tenart <antoine.tenart@free-electrons.com>
description:
The Berlin ADC has 8 channels, with one connected to a temperature sensor.
It is part of the system controller register set. The ADC node should be a
sub-node of the system controller node.
properties:
compatible:
const: marvell,berlin2-adc
interrupts:
minItems: 2
maxItems: 2
interrupt-names:
items:
- const: adc
- const: tsen
"#io-channel-cells":
const: 1
required:
- compatible
- interrupts
- interrupt-names
additionalProperties: false
examples:
- |
sysctrl {
adc {
compatible = "marvell,berlin2-adc";
interrupt-parent = <&sic>;
interrupts = <12>, <14>;
interrupt-names = "adc", "tsen";
};
};
...

View File

@ -0,0 +1,53 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/motorola,cpcap-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Motorola CPCAP PMIC ADC binding
maintainers:
- Tony Lindgren <tony@atomide.com>
description:
On Motorola phones like droid 4 there is a custom CPCAP PMIC. This PMIC
has ADCs that are used for battery charging and USB PHY VBUS and ID pin
detection.
properties:
compatible:
enum:
- motorola,cpcap-adc
- motorola,mapphone-cpcap-adc
interrupts:
maxItems: 1
interrupt-names:
const: adcdone
"#io-channel-cells":
const: 1
required:
- compatible
- interrupts
- "#io-channel-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
pmic {
#address-cells = <1>;
#size-cells = <0>;
adc {
compatible = "motorola,mapphone-cpcap-adc";
interrupt-parent = <&cpcap>;
interrupts = <8 IRQ_TYPE_NONE>;
interrupt-names = "adcdone";
#io-channel-cells = <1>;
};
};
...

View File

@ -0,0 +1,50 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/nuvoton,nau7802.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Nuvoton NAU7802 I2c Analog to Digital Converter (ADC)
maintainers:
- Alexandre Belloni <alexandre.belloni@bootlin.com>
- Maxime Ripard <mripard@kernel.org>
properties:
compatible:
const: nuvoton,nau7802
reg:
maxItems: 1
interrupts:
maxItems: 1
nuvoton,vldo:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Internal reference voltage in millivolts to be configured.
minimum: 2400
maximum: 4500
"#io-channel-cells":
const: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
nau7802@2a {
compatible = "nuvoton,nau7802";
reg = <0x2a>;
nuvoton,vldo = <3000>;
};
};
...

View File

@ -1,26 +0,0 @@
Nuvoton NPCM Analog to Digital Converter (ADC)
The NPCM ADC is a 10-bit converter for eight channel inputs.
Required properties:
- compatible: "nuvoton,npcm750-adc" for the NPCM7XX BMC.
- reg: specifies physical base address and size of the registers.
- interrupts: Contain the ADC interrupt with flags for falling edge.
- resets : phandle to the reset control for this device.
Optional properties:
- clocks: phandle of ADC reference clock, in case the clock is not
added the ADC will use the default ADC sample rate.
- vref-supply: The regulator supply ADC reference voltage, in case the
vref-supply is not added the ADC will use internal voltage
reference.
Example:
adc: adc@f000c000 {
compatible = "nuvoton,npcm750-adc";
reg = <0xf000c000 0x8>;
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk NPCM7XX_CLK_ADC>;
resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>;
};

View File

@ -0,0 +1,64 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/nuvoton,npcm750-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Nuvoton NPCM BMC Analog to Digital Converter (ADC)
maintainers:
- Tomer Maimon <tmaimon77@gmail.com>
description:
The NPCM ADC is a 10-bit converter for eight channel inputs.
properties:
compatible:
const: nuvoton,npcm750-adc
reg:
maxItems: 1
interrupts:
maxItems: 1
description: ADC interrupt, should be set for falling edge.
resets:
maxItems: 1
clocks:
maxItems: 1
description: If not provided the defulat ADC sample rate will be used.
vref-supply:
description: If not supplied, the internal voltage reference will be used.
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- interrupts
- resets
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/nuvoton,npcm7xx-clock.h>
#include <dt-bindings/reset/nuvoton,npcm7xx-reset.h>
soc {
#address-cells = <1>;
#size-cells = <1>;
adc@f000c000 {
compatible = "nuvoton,npcm750-adc";
reg = <0xf000c000 0x8>;
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk NPCM7XX_CLK_ADC>;
resets = <&rstc NPCM7XX_RESET_IPSRST1 NPCM7XX_RESET_ADC>;
};
};
...

View File

@ -1,18 +0,0 @@
* Nuvoton NAU7802 Analog to Digital Converter (ADC)
Required properties:
- compatible: Should be "nuvoton,nau7802"
- reg: Should contain the ADC I2C address
Optional properties:
- nuvoton,vldo: Internal reference voltage in millivolts to be
configured valid values are between 2400 mV and 4500 mV.
- interrupts: IRQ line for the ADC. If not used the driver will use
polling.
Example:
adc2: nau7802@2a {
compatible = "nuvoton,nau7802";
reg = <0x2a>;
nuvoton,vldo = <3000>;
};

View File

@ -0,0 +1,61 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/nxp,lpc1850-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP LPC1850 ADC bindings
maintainers:
- Joachim Eastwood <manabian@gmail.com>
description:
Supports the ADC found on the LPC1850 SoC.
properties:
compatible:
const: nxp,lpc1850-adc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
maxItems: 1
vref-supply: true
resets:
maxItems: 1
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- interrupts
- clocks
- vref-supply
- resets
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/lpc18xx-ccu.h>
soc {
#address-cells = <1>;
#size-cells = <1>;
adc@400e3000 {
compatible = "nxp,lpc1850-adc";
reg = <0x400e3000 0x1000>;
interrupts = <17>;
clocks = <&ccu1 CLK_APB3_ADC0>;
vref-supply = <&reg_vdda>;
resets = <&rgu 40>;
};
};
...

View File

@ -0,0 +1,50 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/nxp,lpc3220-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP LPC3220 SoC ADC controller
maintainers:
- Gregory Clement <gregory.clement@bootlin.com>
description:
This hardware block has been used on several LPC32XX SoCs.
properties:
compatible:
const: nxp,lpc3220-adc
reg:
maxItems: 1
interrupts:
maxItems: 1
vref-supply: true
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- interrupts
additionalProperties: false
examples:
- |
soc {
#address-cells = <1>;
#size-cells = <1>;
adc@40048000 {
compatible = "nxp,lpc3220-adc";
reg = <0x40048000 0x1000>;
interrupt-parent = <&mic>;
interrupts = <39 0>;
vref-supply = <&vcc>;
};
};
...

View File

@ -41,7 +41,10 @@ properties:
maxItems: 2
interrupts:
maxItems: 1
description:
ADC interrupt followed by optional touchscreen interrupt.
minItems: 1
maxItems: 2
"#io-channel-cells":
const: 1
@ -78,7 +81,6 @@ allOf:
- samsung,exynos-adc-v2
- samsung,exynos3250-adc
- samsung,exynos4212-adc
- samsung,s5pv210-adc
then:
required:
- samsung,syscon-phandle
@ -107,6 +109,15 @@ allOf:
items:
- const: adc
- if:
required:
- has-touchscreen
then:
properties:
interrupts:
minItems: 2
maxItems: 2
examples:
- |
adc: adc@12d10000 {

View File

@ -0,0 +1,72 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/sprd,sc2720-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Spreadtrum SC27XX series PMICs ADC binding
maintainers:
- Baolin Wang <baolin.wang7@gmail.com>
description:
Supports the ADC found on these PMICs.
properties:
compatible:
enum:
- sprd,sc2720-adc
- sprd,sc2721-adc
- sprd,sc2723-adc
- sprd,sc2730-adc
- sprd,sc2731-adc
reg:
maxItems: 1
interrupts:
maxItems: 1
"#io-channel-cells":
const: 1
hwlocks:
maxItems: 1
nvmem-cells:
maxItems: 2
nvmem-cell-names:
items:
- const: big_scale_calib
- const: small_scale_calib
required:
- compatible
- reg
- interrupts
- "#io-channel-cells"
- hwlocks
- nvmem-cells
- nvmem-cell-names
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
pmic {
#address-cells = <1>;
#size-cells = <0>;
adc@480 {
compatible = "sprd,sc2731-adc";
reg = <0x480>;
interrupt-parent = <&sc2731_pmic>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
#io-channel-cells = <1>;
hwlocks = <&hwlock 4>;
nvmem-cells = <&adc_big_scale>, <&adc_small_scale>;
nvmem-cell-names = "big_scale_calib", "small_scale_calib";
};
};
...

View File

@ -1,40 +0,0 @@
Spreadtrum SC27XX series PMICs ADC binding
Required properties:
- compatible: Should be one of the following.
"sprd,sc2720-adc"
"sprd,sc2721-adc"
"sprd,sc2723-adc"
"sprd,sc2730-adc"
"sprd,sc2731-adc"
- reg: The address offset of ADC controller.
- interrupt-parent: The interrupt controller.
- interrupts: The interrupt number for the ADC device.
- #io-channel-cells: Number of cells in an IIO specifier.
- hwlocks: Reference to a phandle of a hwlock provider node.
- nvmem-cells: A phandle to the calibration cells provided by eFuse device.
- nvmem-cell-names: Should be "big_scale_calib", "small_scale_calib".
Example:
sc2731_pmic: pmic@0 {
compatible = "sprd,sc2731";
reg = <0>;
spi-max-frequency = <26000000>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
interrupt-controller;
#interrupt-cells = <2>;
#address-cells = <1>;
#size-cells = <0>;
pmic_adc: adc@480 {
compatible = "sprd,sc2731-adc";
reg = <0x480>;
interrupt-parent = <&sc2731_pmic>;
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
#io-channel-cells = <1>;
hwlocks = <&hwlock 4>;
nvmem-cells = <&adc_big_scale>, <&adc_small_scale>;
nvmem-cell-names = "big_scale_calib", "small_scale_calib";
};
};

View File

@ -0,0 +1,45 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/st,stmpe-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ADC on an STMPE multifunction device.
maintainers:
- Stefan Agner <stefan@agner.ch>
description:
This ADC forms part of an ST microelectronics STMPE multifunction device .
The ADC is shared with the STMPE touchscreen. As a result some ADC related
settings are specified in the parent node.
The node name myst be stmpe_adc and should be a child node of the stmpe node
to which it belongs.
properties:
compatible:
const: st,stmpe-adc
st,norequest-mask:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Bitmask specifying which ADC channels should _not_ be
requestable due to different usage (e.g. touch).
"#io-channel-cells":
const: 1
required:
- compatible
additionalProperties: false
examples:
- |
stmpe {
stmpe_adc {
compatible = "st,stmpe-adc";
st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */
};
};
...

View File

@ -1,21 +0,0 @@
STMPE ADC driver
----------------
Required properties:
- compatible: "st,stmpe-adc"
Optional properties:
Note that the ADC is shared with the STMPE touchscreen. ADC related settings
have to be done in the mfd.
- st,norequest-mask: bitmask specifying which ADC channels should _not_ be
requestable due to different usage (e.g. touch)
Node name must be stmpe_adc and should be child node of stmpe node to
which it belongs.
Example:
stmpe_adc {
compatible = "st,stmpe-adc";
st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */
};

View File

@ -0,0 +1,86 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,adc12138.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments ADC12138 and similar self-calibrating ADCs
maintainers:
- Akinobu Mita <akinobu.mita@gmail.com>
description: |
13 bit ADCs with 1, 2 or 8 inputs and self calibrating circuitry to
correct for linearity, zero and full scale errors.
properties:
compatible:
enum:
- ti,adc12130
- ti,adc12132
- ti,adc12138
reg:
maxItems: 1
interrupts:
maxItems: 1
description: End of Conversion (EOC) interrupt
clocks:
maxItems: 1
description: Conversion clock input.
spi-max-frequency: true
vref-p-supply:
description: The regulator supply for positive analog voltage reference
vref-n-supply:
description: |
The regulator supply for negative analog voltage reference
(Note that this must not go below GND or exceed vref-p)
If not specified, this is assumed to be analog ground.
ti,acquisition-time:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 6, 10, 18, 34 ]
description: |
The number of conversion clock periods for the S/H's acquisition time.
For high source impedances, this value can be increased to 18 or 34.
For less ADC accuracy and/or slower CCLK frequencies this value may be
decreased to 6. See section 6.0 INPUT SOURCE RESISTANCE in the
datasheet for details.
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- interrupts
- clocks
- vref-p-supply
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "ti,adc12138";
reg = <0>;
interrupts = <28 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gpio1>;
clocks = <&cclk>;
vref-p-supply = <&ldo4_reg>;
spi-max-frequency = <5000000>;
ti,acquisition-time = <6>;
#io-channel-cells = <1>;
};
};
...

View File

@ -0,0 +1,112 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,ads1015.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI ADS1015 4 channel I2C analog to digital converter
maintainers:
- Daniel Baluta <daniel.baluta@nxp.com>
description: |
Datasheet at: https://www.ti.com/lit/gpn/ads1015
Supports both single ended and differential channels.
properties:
compatible:
const: ti,ads1015
reg:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 0
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- "#address-cells"
- "#size-cells"
additionalProperties: false
patternProperties:
"^channel@[0-7]+$":
type: object
description:
Child nodes needed for each channel that the platform uses.
properties:
reg:
description: |
0: Voltage over AIN0 and AIN1.
1: Voltage over AIN0 and AIN3.
2: Voltage over AIN1 and AIN3.
3: Voltage over AIN2 and AIN3.
4: Voltage over AIN0 and GND.
5: Voltage over AIN1 and GND.
6: Voltage over AIN2 and GND.
7: Voltage over AIN3 and GND.
items:
- minimum: 0
maximum: 7
ti,gain:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 5
description: |
pga is the programmable gain amplifier (values are full scale)
0: +/- 6.144 V
1: +/- 4.096 V
2: +/- 2.048 V (default)
3: +/- 1.024 V
4: +/- 0.512 V
5: +/- 0.256 V
ti,datarate:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 6
description: |
Data acquisition rate in samples per second
0: 128
1: 250
2: 490
3: 920
4: 1600 (default)
5: 2400
6: 3300
required:
- reg
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
adc@49 {
compatible = "ti,ads1015";
reg = <0x49>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
};
channel@4 {
reg = <4>;
ti,gain = <3>;
ti,datarate = <5>;
};
};
};
...

View File

@ -0,0 +1,65 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,ads7950.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments ADS7950 and similar ADCs
maintainers:
- David Lechner <david@lechnology.com>
description: |
Family of 4-16 channel, 8-12 bit ADCs with SPI interface.
properties:
compatible:
enum:
- ti,ads7950
- ti,ads7951
- ti,ads7952
- ti,ads7953
- ti,ads7954
- ti,ads7955
- ti,ads7956
- ti,ads7957
- ti,ads7958
- ti,ads7959
- ti,ads7960
- ti,ads7961
reg:
maxItems: 1
spi-max-frequency:
maximum: 20000000
vref-supply:
description: Supplies the 2.5V or 5V reference voltage
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- vref-supply
- "#io-channel-cells"
additionalProperties: false
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "ti,ads7957";
reg = <0>;
vref-supply = <&refin_supply>;
spi-max-frequency = <10000000>;
#io-channel-cells = <1>;
};
};
...

View File

@ -0,0 +1,48 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,twl4030-madc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MADC subsystem in the TWL4030 power module
maintainers:
- Sebastian Reichel <sre@kernel.org>
description:
The MADC subsystem in the TWL4030 consists of a 10-bit ADC
combined with a 16-input analog multiplexer.
properties:
compatible:
const: ti,twl4030-madc
interrupts:
maxItems: 1
ti,system-uses-second-madc-irq:
type: boolean
description:
Set if the second madc irq register should be used, which is intended
to be used by Co-Processors (e.g. a modem).
"#io-channel-cells":
const: 1
required:
- compatible
- interrupts
- "#io-channel-cells"
additionalProperties: false
examples:
- |
twl {
madc {
compatible = "ti,twl4030-madc";
interrupts = <3>;
#io-channel-cells = <1>;
};
};
...

View File

@ -1,37 +0,0 @@
* Texas Instruments' ADC12130/ADC12132/ADC12138
Required properties:
- compatible: Should be one of
* "ti,adc12130"
* "ti,adc12132"
* "ti,adc12138"
- reg: SPI chip select number for the device
- interrupts: Should contain interrupt for EOC (end of conversion)
- clocks: phandle to conversion clock input
- spi-max-frequency: Definision as per
Documentation/devicetree/bindings/spi/spi-bus.txt
- vref-p-supply: The regulator supply for positive analog voltage reference
Optional properties:
- vref-n-supply: The regulator supply for negative analog voltage reference
(Note that this must not go below GND or exceed vref-p)
If not specified, this is assumed to be analog ground.
- ti,acquisition-time: The number of conversion clock periods for the S/H's
acquisition time. Should be one of 6, 10, 18, 34. If not specified,
default value of 10 is used.
For high source impedances, this value can be increased to 18 or 34.
For less ADC accuracy and/or slower CCLK frequencies this value may be
decreased to 6. See section 6.0 INPUT SOURCE RESISTANCE in the
datasheet for details.
Example:
adc@0 {
compatible = "ti,adc12138";
reg = <0>;
interrupts = <28 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gpio1>;
clocks = <&cclk>;
vref-p-supply = <&ldo4_reg>;
spi-max-frequency = <5000000>;
ti,acquisition-time = <6>;
};

View File

@ -1,23 +0,0 @@
* Texas Instruments ADS7950 family of A/DC chips
Required properties:
- compatible: Must be one of "ti,ads7950", "ti,ads7951", "ti,ads7952",
"ti,ads7953", "ti,ads7954", "ti,ads7955", "ti,ads7956", "ti,ads7957",
"ti,ads7958", "ti,ads7959", "ti,ads7960", or "ti,ads7961"
- reg: SPI chip select number for the device
- #io-channel-cells: Must be 1 as per ../iio-bindings.txt
- vref-supply: phandle to a regulator node that supplies the 2.5V or 5V
reference voltage
Recommended properties:
- spi-max-frequency: Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
Example:
adc@0 {
compatible = "ti,ads7957";
reg = <0>;
#io-channel-cells = <1>;
vref-supply = <&refin_supply>;
spi-max-frequency = <10000000>;
};

View File

@ -1,24 +0,0 @@
* TWL4030 Monitoring Analog to Digital Converter (MADC)
The MADC subsystem in the TWL4030 consists of a 10-bit ADC
combined with a 16-input analog multiplexer.
Required properties:
- compatible: Should contain "ti,twl4030-madc".
- interrupts: IRQ line for the MADC submodule.
- #io-channel-cells: Should be set to <1>.
Optional properties:
- ti,system-uses-second-madc-irq: boolean, set if the second madc irq register
should be used, which is intended to be used
by Co-Processors (e.g. a modem).
Example:
&twl {
madc {
compatible = "ti,twl4030-madc";
interrupts = <3>;
#io-channel-cells = <1>;
};
};

View File

@ -1,36 +0,0 @@
Freescale vf610 Analog to Digital Converter bindings
The devicetree bindings are for the new ADC driver written for
vf610/i.MX6slx and upward SoCs from Freescale.
Required properties:
- compatible: Should contain "fsl,vf610-adc"
- reg: Offset and length of the register set for the device
- interrupts: Should contain the interrupt for the device
- clocks: The clock is needed by the ADC controller, ADC clock source is ipg clock.
- clock-names: Must contain "adc", matching entry in the clocks property.
- vref-supply: The regulator supply ADC reference voltage.
Recommended properties:
- fsl,adck-max-frequency: Maximum frequencies according to datasheets operating
requirements. Three values are required, depending on conversion mode:
- Frequency in normal mode (ADLPC=0, ADHSC=0)
- Frequency in high-speed mode (ADLPC=0, ADHSC=1)
- Frequency in low-power mode (ADLPC=1, ADHSC=0)
- min-sample-time: Minimum sampling time in nanoseconds. This value has
to be chosen according to the conversion mode and the connected analog
source resistance (R_as) and capacitance (C_as). Refer the datasheet's
operating requirements. A safe default across a wide range of R_as and
C_as as well as conversion modes is 1000ns.
Example:
adc0: adc@4003b000 {
compatible = "fsl,vf610-adc";
reg = <0x4003b000 0x1000>;
interrupts = <0 53 0x04>;
clocks = <&clks VF610_CLK_ADC0>;
clock-names = "adc";
fsl,adck-max-frequency = <30000000>, <40000000>,
<20000000>;
vref-supply = <&reg_vcc_3v3_mcu>;
};

View File

@ -28,6 +28,9 @@ properties:
spi-cpha: true
interrupts:
maxItems: 1
required:
- compatible
- reg
@ -39,6 +42,7 @@ additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
@ -48,6 +52,8 @@ examples:
spi-max-frequency = <5000000>;
spi-cpol;
spi-cpha;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
};
};
...

View File

@ -24,6 +24,10 @@ properties:
- vishay,vcnl4020
- vishay,vcnl4040
- vishay,vcnl4200
interrupts:
maxItems: 1
reg:
maxItems: 1

View File

@ -4,9 +4,15 @@ Required properties:
- compatible: must be "st,vl53l0x"
- reg: i2c address where to find the device
Optional properties:
- interrupts: Interrupt for notifying that new measurement is ready.
If no interrupt is specified, polling is used.
Example:
vl53l0x@29 {
compatible = "st,vl53l0x";
reg = <0x29>;
interrupt-parent = <&gpio>;
interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
};

View File

@ -950,38 +950,6 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/light/ams,as73211.yaml
F: drivers/iio/light/as73211.c
ANALOG DEVICES INC AD5686 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com>
L: linux-pm@vger.kernel.org
S: Supported
W: http://ez.analog.com/community/linux-device-drivers
F: drivers/iio/dac/ad5686*
F: drivers/iio/dac/ad5696*
ANALOG DEVICES INC AD5758 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: http://ez.analog.com/community/linux-device-drivers
F: Documentation/devicetree/bindings/iio/dac/ad5758.txt
F: drivers/iio/dac/ad5758.c
ANALOG DEVICES INC AD7091R5 DRIVER
M: Beniamin Bia <beniamin.bia@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: http://ez.analog.com/community/linux-device-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad7091r5.yaml
F: drivers/iio/adc/ad7091r5.c
ANALOG DEVICES INC AD7124 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: http://ez.analog.com/community/linux-device-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml
F: drivers/iio/adc/ad7124.c
ANALOG DEVICES INC AD7192 DRIVER
M: Alexandru Tachici <alexandru.tachici@analog.com>
L: linux-iio@vger.kernel.org
@ -998,15 +966,6 @@ W: http://ez.analog.com/community/linux-device-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml
F: drivers/iio/adc/ad7292.c
ANALOG DEVICES INC AD7606 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com>
M: Beniamin Bia <beniamin.bia@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: http://ez.analog.com/community/linux-device-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml
F: drivers/iio/adc/ad7606.c
ANALOG DEVICES INC AD7768-1 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com>
L: linux-iio@vger.kernel.org
@ -1068,7 +1027,6 @@ F: drivers/iio/imu/adis16475.c
F: Documentation/devicetree/bindings/iio/imu/adi,adis16475.yaml
ANALOG DEVICES INC ADM1177 DRIVER
M: Beniamin Bia <beniamin.bia@analog.com>
M: Michael Hennerich <Michael.Hennerich@analog.com>
L: linux-hwmon@vger.kernel.org
S: Supported
@ -1142,15 +1100,6 @@ S: Supported
W: http://ez.analog.com/community/linux-device-drivers
F: drivers/dma/dma-axi-dmac.c
ANALOG DEVICES INC HMC425A DRIVER
M: Beniamin Bia <beniamin.bia@analog.com>
M: Michael Hennerich <michael.hennerich@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: http://ez.analog.com/community/linux-device-drivers
F: Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml
F: drivers/iio/amplifiers/hmc425a.c
ANALOG DEVICES INC IIO DRIVERS
M: Lars-Peter Clausen <lars@metafoo.de>
M: Michael Hennerich <Michael.Hennerich@analog.com>
@ -1159,8 +1108,11 @@ W: http://wiki.analog.com/
W: http://ez.analog.com/community/linux-device-drivers
F: Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9523
F: Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4350
F: Documentation/devicetree/bindings/iio/*/adi,*
F: Documentation/devicetree/bindings/iio/dac/ad5758.txt
F: drivers/iio/*/ad*
F: drivers/iio/adc/ltc249*
F: drivers/iio/amplifiers/hmc425a.c
F: drivers/staging/iio/*/ad*
X: drivers/iio/*/adjd*
@ -8524,7 +8476,6 @@ F: drivers/iio/multiplexer/iio-mux.c
IIO SUBSYSTEM AND DRIVERS
M: Jonathan Cameron <jic23@kernel.org>
R: Hartmut Knaack <knaack.h@gmx.de>
R: Lars-Peter Clausen <lars@metafoo.de>
R: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
L: linux-iio@vger.kernel.org
@ -16515,7 +16466,6 @@ F: drivers/staging/rtl8712/
STAGING - SEPS525 LCD CONTROLLER DRIVERS
M: Michael Hennerich <michael.hennerich@analog.com>
M: Beniamin Bia <beniamin.bia@analog.com>
L: linux-fbdev@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml

View File

@ -281,34 +281,15 @@ static int adis16201_probe(struct spi_device *spi)
if (ret)
return ret;
ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret)
return ret;
ret = adis_initial_startup(st);
if (ret)
goto error_cleanup_buffer_trigger;
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 = {
@ -316,7 +297,6 @@ static struct spi_driver adis16201_driver = {
.name = "adis16201",
},
.probe = adis16201_probe,
.remove = adis16201_remove,
};
module_spi_driver(adis16201_driver);

View File

@ -291,33 +291,15 @@ static int adis16209_probe(struct spi_device *spi)
if (ret)
return ret;
ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL);
ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL);
if (ret)
return ret;
ret = adis_initial_startup(st);
if (ret)
goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev);
if (ret)
goto error_cleanup_buffer_trigger;
return ret;
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 = {
@ -325,7 +307,6 @@ static struct spi_driver adis16209_driver = {
.name = "adis16209",
},
.probe = adis16209_probe,
.remove = adis16209_remove,
};
module_spi_driver(adis16209_driver);

View File

@ -673,7 +673,7 @@ static const struct iio_chan_spec_ext_info bma023_ext_info[] = {
};
static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
IIO_ENUM("power_mode", true, &bma180_power_mode_enum),
IIO_ENUM("power_mode", IIO_SHARED_BY_TYPE, &bma180_power_mode_enum),
IIO_ENUM_AVAILABLE("power_mode", &bma180_power_mode_enum),
IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma180_accel_get_mount_matrix),
{ }

View File

@ -863,7 +863,7 @@ config RN5T618_ADC
config ROCKCHIP_SARADC
tristate "Rockchip SARADC driver"
depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST)
depends on ARCH_ROCKCHIP || COMPILE_TEST
depends on RESET_CONTROLLER
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER

View File

@ -39,7 +39,7 @@ static const struct ad7949_adc_spec ad7949_adc_spec[] = {
* struct ad7949_adc_chip - AD ADC chip
* @lock: protects write sequences
* @vref: regulator generating Vref
* @iio_dev: reference to iio structure
* @indio_dev: reference to iio structure
* @spi: reference to spi structure
* @resolution: resolution of the chip
* @cfg: copy of the configuration register

View File

@ -324,7 +324,7 @@ static int ad9467_setup(struct ad9467_state *st, unsigned int chip_id)
AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
return 0;
default:
return -EINVAL;
return -ENODEV;
}
}
@ -390,7 +390,8 @@ static int ad9467_probe(struct spi_device *spi)
id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID);
if (id != conv->chip_info->id) {
dev_err(&spi->dev, "Unrecognized CHIP_ID 0x%X\n", id);
dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n",
id, conv->chip_info->id);
return -ENODEV;
}

View File

@ -138,6 +138,16 @@ struct exynos_adc {
bool read_ts;
u32 ts_x;
u32 ts_y;
/*
* Lock to protect from potential concurrent access to the
* completion callback during a manual conversion. For this driver
* a wait-callback is used to wait for the conversion result,
* so in the meantime no other read request (or conversion start)
* must be performed, otherwise it would interfere with the
* current conversion result.
*/
struct mutex lock;
};
struct exynos_adc_data {
@ -542,7 +552,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
mutex_lock(&indio_dev->mlock);
mutex_lock(&info->lock);
reinit_completion(&info->completion);
/* Select the channel to be used and Trigger conversion */
@ -562,7 +572,7 @@ static int exynos_read_raw(struct iio_dev *indio_dev,
ret = IIO_VAL_INT;
}
mutex_unlock(&indio_dev->mlock);
mutex_unlock(&info->lock);
return ret;
}
@ -573,7 +583,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y)
unsigned long timeout;
int ret;
mutex_lock(&indio_dev->mlock);
mutex_lock(&info->lock);
info->read_ts = true;
reinit_completion(&info->completion);
@ -598,7 +608,7 @@ static int exynos_read_s3c64xx_ts(struct iio_dev *indio_dev, int *x, int *y)
}
info->read_ts = false;
mutex_unlock(&indio_dev->mlock);
mutex_unlock(&info->lock);
return ret;
}
@ -868,6 +878,8 @@ static int exynos_adc_probe(struct platform_device *pdev)
indio_dev->channels = exynos_adc_iio_channels;
indio_dev->num_channels = info->data->num_channels;
mutex_init(&info->lock);
ret = request_irq(info->irq, exynos_adc_isr,
0, dev_name(&pdev->dev), info);
if (ret < 0) {

View File

@ -40,6 +40,15 @@ struct mx25_gcq_priv {
int irq;
struct regulator *vref[4];
u32 channel_vref_mv[MX25_NUM_CFGS];
/*
* Lock to protect the device state during a potential concurrent
* read access from userspace. Reading a raw value requires a sequence
* of register writes, then a wait for a completion callback,
* and finally a register read, during which userspace could issue
* another read request. This lock protects a read access from
* ocurring before another one has finished.
*/
struct mutex lock;
};
#define MX25_CQG_CHAN(chan, id) {\
@ -137,9 +146,9 @@ static int mx25_gcq_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&indio_dev->mlock);
mutex_lock(&priv->lock);
ret = mx25_gcq_get_raw_value(&indio_dev->dev, chan, priv, val);
mutex_unlock(&indio_dev->mlock);
mutex_unlock(&priv->lock);
return ret;
case IIO_CHAN_INFO_SCALE:
@ -314,6 +323,8 @@ static int mx25_gcq_probe(struct platform_device *pdev)
return PTR_ERR(priv->regs);
}
mutex_init(&priv->lock);
init_completion(&priv->completed);
ret = mx25_gcq_setup_cfgs(pdev, priv);

View File

@ -1150,16 +1150,13 @@ static const struct of_device_id meson_sar_adc_of_match[] = {
{
.compatible = "amlogic,meson8-saradc",
.data = &meson_sar_adc_meson8_data,
},
{
}, {
.compatible = "amlogic,meson8b-saradc",
.data = &meson_sar_adc_meson8b_data,
},
{
}, {
.compatible = "amlogic,meson8m2-saradc",
.data = &meson_sar_adc_meson8m2_data,
},
{
}, {
.compatible = "amlogic,meson-gxbb-saradc",
.data = &meson_sar_adc_gxbb_data,
}, {
@ -1175,7 +1172,7 @@ static const struct of_device_id meson_sar_adc_of_match[] = {
.compatible = "amlogic,meson-g12a-saradc",
.data = &meson_sar_adc_g12a_data,
},
{},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match);

View File

@ -834,18 +834,7 @@ static struct platform_driver palmas_gpadc_driver = {
.of_match_table = of_palmas_gpadc_match_tbl,
},
};
static int __init palmas_gpadc_init(void)
{
return platform_driver_register(&palmas_gpadc_driver);
}
module_init(palmas_gpadc_init);
static void __exit palmas_gpadc_exit(void)
{
platform_driver_unregister(&palmas_gpadc_driver);
}
module_exit(palmas_gpadc_exit);
module_platform_driver(palmas_gpadc_driver);
MODULE_DESCRIPTION("palmas GPADC driver");
MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>");

View File

@ -595,7 +595,7 @@ static int stm32_adc_core_switches_probe(struct device *dev,
if (IS_ERR(priv->booster)) {
ret = PTR_ERR(priv->booster);
if (ret != -ENODEV)
dev_err_probe(dev, ret, "can't get booster\n");
return dev_err_probe(dev, ret, "can't get booster\n");
priv->booster = NULL;
}

View File

@ -29,6 +29,12 @@ struct adc0832 {
struct regulator *reg;
struct mutex lock;
u8 mux_bits;
/*
* Max size needed: 16x 1 byte ADC data + 8 bytes timestamp
* May be shorter if not all channels are enabled subject
* to the timestamp remaining 8 byte aligned.
*/
u8 data[24] __aligned(8);
u8 tx_buf[2] ____cacheline_aligned;
u8 rx_buf[2];
@ -200,7 +206,6 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adc0832 *adc = iio_priv(indio_dev);
u8 data[24] = { }; /* 16x 1 byte ADC data + 8 bytes timestamp */
int scan_index;
int i = 0;
@ -218,10 +223,10 @@ static irqreturn_t adc0832_trigger_handler(int irq, void *p)
goto out;
}
data[i] = ret;
adc->data[i] = ret;
i++;
}
iio_push_to_buffers_with_timestamp(indio_dev, data,
iio_push_to_buffers_with_timestamp(indio_dev, adc->data,
iio_get_time_ns(indio_dev));
out:
mutex_unlock(&adc->lock);

View File

@ -47,6 +47,12 @@ struct adc12138 {
struct completion complete;
/* The number of cclk periods for the S/H's acquisition time */
unsigned int acquisition_time;
/*
* Maximum size needed: 16x 2 bytes ADC data + 8 bytes timestamp.
* Less may be need if not all channels are enabled, as long as
* the 8 byte alignment of the timestamp is maintained.
*/
__be16 data[20] __aligned(8);
u8 tx_buf[2] ____cacheline_aligned;
u8 rx_buf[2];
@ -329,7 +335,6 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adc12138 *adc = iio_priv(indio_dev);
__be16 data[20] = { }; /* 16x 2 bytes ADC data + 8 bytes timestamp */
__be16 trash;
int ret;
int scan_index;
@ -345,7 +350,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
reinit_completion(&adc->complete);
ret = adc12138_start_and_read_conv(adc, scan_chan,
i ? &data[i - 1] : &trash);
i ? &adc->data[i - 1] : &trash);
if (ret) {
dev_warn(&adc->spi->dev,
"failed to start conversion\n");
@ -362,7 +367,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
}
if (i) {
ret = adc12138_read_conv_data(adc, &data[i - 1]);
ret = adc12138_read_conv_data(adc, &adc->data[i - 1]);
if (ret) {
dev_warn(&adc->spi->dev,
"failed to get conversion data\n");
@ -370,7 +375,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
}
}
iio_push_to_buffers_with_timestamp(indio_dev, data,
iio_push_to_buffers_with_timestamp(indio_dev, adc->data,
iio_get_time_ns(indio_dev));
out:
mutex_unlock(&adc->lock);

View File

@ -7,6 +7,7 @@
*/
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/i2c.h>
@ -177,7 +178,7 @@ MODULE_DEVICE_TABLE(of, ams_iaqcore_dt_ids);
static struct i2c_driver ams_iaqcore_driver = {
.driver = {
.name = "ams-iaq-core",
.of_match_table = of_match_ptr(ams_iaqcore_dt_ids),
.of_match_table = ams_iaqcore_dt_ids,
},
.probe = ams_iaqcore_probe,
.id_table = ams_iaqcore_id,

View File

@ -15,7 +15,7 @@
#include <linux/irq.h>
#include <linux/irq_work.h>
#include <linux/i2c.h>
#include <linux/of_device.h>
#include <linux/mod_devicetable.h>
#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
@ -620,7 +620,6 @@ static int atlas_probe(struct i2c_client *client,
{
struct atlas_data *data;
struct atlas_device *chip;
const struct of_device_id *of_id;
struct iio_trigger *trig;
struct iio_dev *indio_dev;
int ret;
@ -629,11 +628,10 @@ static int atlas_probe(struct i2c_client *client,
if (!indio_dev)
return -ENOMEM;
of_id = of_match_device(atlas_dt_ids, &client->dev);
if (!of_id)
if (!dev_fwnode(&client->dev))
chip = &atlas_devices[id->driver_data];
else
chip = &atlas_devices[(unsigned long)of_id->data];
chip = &atlas_devices[(unsigned long)device_get_match_data(&client->dev)];
indio_dev->info = &atlas_info;
indio_dev->name = ATLAS_DRV_NAME;
@ -775,7 +773,7 @@ static const struct dev_pm_ops atlas_pm_ops = {
static struct i2c_driver atlas_driver = {
.driver = {
.name = ATLAS_DRV_NAME,
.of_match_table = of_match_ptr(atlas_dt_ids),
.of_match_table = atlas_dt_ids,
.pm = &atlas_pm_ops,
},
.probe = atlas_probe,

View File

@ -20,9 +20,9 @@
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/i2c.h>
#include <linux/of_device.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@ -227,6 +227,7 @@ static int sgp_verify_buffer(const struct sgp_data *data,
* @cmd: SGP Command to issue
* @buf: Raw data buffer to use
* @word_count: Num words to read, excluding CRC bytes
* @duration_us: Time taken to sensor to take a reading and data to be ready.
*
* Return: 0 on success, negative error otherwise.
*/
@ -409,6 +410,7 @@ static int sgp_read_raw(struct iio_dev *indio_dev,
static int sgp_check_compat(struct sgp_data *data,
unsigned int product_id)
{
struct device *dev = &data->client->dev;
const struct sgp_version *supported_versions;
u16 ix, num_fs;
u16 product, generation, major, minor;
@ -416,21 +418,20 @@ static int sgp_check_compat(struct sgp_data *data,
/* driver does not match product */
generation = SGP_VERS_GEN(data);
if (generation != 0) {
dev_err(&data->client->dev,
dev_err(dev,
"incompatible product generation %d != 0", generation);
return -ENODEV;
}
product = SGP_VERS_PRODUCT(data);
if (product != product_id) {
dev_err(&data->client->dev,
"sensor reports a different product: 0x%04hx\n",
dev_err(dev, "sensor reports a different product: 0x%04hx\n",
product);
return -ENODEV;
}
if (SGP_VERS_RESERVED(data))
dev_warn(&data->client->dev, "reserved bit is set\n");
dev_warn(dev, "reserved bit is set\n");
/* engineering samples are not supported: no interface guarantees */
if (SGP_VERS_ENG_BIT(data))
@ -456,8 +457,7 @@ static int sgp_check_compat(struct sgp_data *data,
minor >= supported_versions[ix].minor)
return 0;
}
dev_err(&data->client->dev, "unsupported sgp version: %d.%d\n",
major, minor);
dev_err(dev, "unsupported sgp version: %d.%d\n", major, minor);
return -ENODEV;
}
@ -499,19 +499,18 @@ static const struct of_device_id sgp_dt_ids[] = {
static int sgp_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct iio_dev *indio_dev;
struct sgp_data *data;
const struct of_device_id *of_id;
unsigned long product_id;
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
of_id = of_match_device(sgp_dt_ids, &client->dev);
if (of_id)
product_id = (unsigned long)of_id->data;
if (dev_fwnode(dev))
product_id = (unsigned long)device_get_match_data(dev);
else
product_id = id->driver_data;
@ -541,9 +540,9 @@ static int sgp_probe(struct i2c_client *client,
sgp_init(data);
ret = devm_iio_device_register(&client->dev, indio_dev);
ret = devm_iio_device_register(dev, indio_dev);
if (ret) {
dev_err(&client->dev, "failed to register iio device\n");
dev_err(dev, "failed to register iio device\n");
return ret;
}
@ -576,7 +575,7 @@ MODULE_DEVICE_TABLE(of, sgp_dt_ids);
static struct i2c_driver sgp_driver = {
.driver = {
.name = "sgp30",
.of_match_table = of_match_ptr(sgp_dt_ids),
.of_match_table = sgp_dt_ids,
},
.probe = sgp_probe,
.remove = sgp_remove,

View File

@ -10,8 +10,7 @@
#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/mod_devicetable.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@ -352,12 +351,12 @@ MODULE_DEVICE_TABLE(of, vz89x_dt_ids);
static int vz89x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct iio_dev *indio_dev;
struct vz89x_data *data;
const struct of_device_id *of_id;
int chip_id;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
@ -370,11 +369,10 @@ static int vz89x_probe(struct i2c_client *client,
else
return -EOPNOTSUPP;
of_id = of_match_device(vz89x_dt_ids, &client->dev);
if (!of_id)
if (!dev_fwnode(dev))
chip_id = id->driver_data;
else
chip_id = (unsigned long)of_id->data;
chip_id = (unsigned long)device_get_match_data(dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
@ -383,13 +381,13 @@ static int vz89x_probe(struct i2c_client *client,
mutex_init(&data->lock);
indio_dev->info = &vz89x_info;
indio_dev->name = dev_name(&client->dev);
indio_dev->name = dev_name(dev);
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = data->chip->channels;
indio_dev->num_channels = data->chip->num_channels;
return devm_iio_device_register(&client->dev, indio_dev);
return devm_iio_device_register(dev, indio_dev);
}
static const struct i2c_device_id vz89x_id[] = {
@ -402,7 +400,7 @@ MODULE_DEVICE_TABLE(i2c, vz89x_id);
static struct i2c_driver vz89x_driver = {
.driver = {
.name = "vz89x",
.of_match_table = of_match_ptr(vz89x_dt_ids),
.of_match_table = vz89x_dt_ids,
},
.probe = vz89x_probe,
.id_table = vz89x_id,

View File

@ -68,8 +68,8 @@ enum ad5064_regmap_type {
* struct ad5064_chip_info - chip specific information
* @shared_vref: whether the vref supply is shared between channels
* @internal_vref: internal reference voltage. 0 if the chip has no
internal vref.
* @channel: channel specification
* internal vref.
* @channels: channel specification
* @num_channels: number of channels
* @regmap_type: register map layout variant
*/
@ -98,6 +98,7 @@ typedef int (*ad5064_write_func)(struct ad5064_state *st, unsigned int cmd,
* @use_internal_vref: set to true if the internal reference voltage should be
* used.
* @write: register write callback
* @lock: maintain consistency between cached and dev state
* @data: i2c/spi transfer buffers
*/
@ -111,7 +112,6 @@ struct ad5064_state {
bool use_internal_vref;
ad5064_write_func write;
/* Lock used to maintain consistency between cached and dev state */
struct mutex lock;
/*

View File

@ -17,6 +17,7 @@
#include <linux/regulator/consumer.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@ -478,13 +479,11 @@ static const struct spi_device_id ad5446_spi_ids[] = {
};
MODULE_DEVICE_TABLE(spi, ad5446_spi_ids);
#ifdef CONFIG_OF
static const struct of_device_id ad5446_of_ids[] = {
{ .compatible = "ti,dac7512" },
{ }
};
MODULE_DEVICE_TABLE(of, ad5446_of_ids);
#endif
static int ad5446_spi_probe(struct spi_device *spi)
{
@ -502,7 +501,7 @@ static int ad5446_spi_remove(struct spi_device *spi)
static struct spi_driver ad5446_spi_driver = {
.driver = {
.name = "ad5446",
.of_match_table = of_match_ptr(ad5446_of_ids),
.of_match_table = ad5446_of_ids,
},
.probe = ad5446_spi_probe,
.remove = ad5446_spi_remove,

View File

@ -374,36 +374,36 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
{
struct ad5592r_state *st = iio_priv(iio_dev);
u16 read_val;
int ret;
int ret, mult;
switch (m) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&st->lock);
if (!chan->output) {
mutex_lock(&st->lock);
ret = st->ops->read_adc(st, chan->channel, &read_val);
mutex_unlock(&st->lock);
if (ret)
goto unlock;
return ret;
if ((read_val >> 12 & 0x7) != (chan->channel & 0x7)) {
dev_err(st->dev, "Error while reading channel %u\n",
chan->channel);
ret = -EIO;
goto unlock;
return -EIO;
}
read_val &= GENMASK(11, 0);
} else {
mutex_lock(&st->lock);
read_val = st->cached_dac[chan->channel];
mutex_unlock(&st->lock);
}
dev_dbg(st->dev, "Channel %u read: 0x%04hX\n",
chan->channel, read_val);
*val = (int) read_val;
ret = IIO_VAL_INT;
break;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = ad5592r_get_vref(st);
@ -412,24 +412,24 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
*val = div_s64_rem(tmp, 1000000000LL, val2);
return IIO_VAL_INT_PLUS_MICRO;
} else {
int mult;
mutex_lock(&st->lock);
if (chan->output)
mult = !!(st->cached_gp_ctrl &
AD5592R_REG_CTRL_DAC_RANGE);
else
mult = !!(st->cached_gp_ctrl &
AD5592R_REG_CTRL_ADC_RANGE);
*val *= ++mult;
*val2 = chan->scan_type.realbits;
ret = IIO_VAL_FRACTIONAL_LOG2;
}
break;
mutex_lock(&st->lock);
if (chan->output)
mult = !!(st->cached_gp_ctrl &
AD5592R_REG_CTRL_DAC_RANGE);
else
mult = !!(st->cached_gp_ctrl &
AD5592R_REG_CTRL_ADC_RANGE);
mutex_unlock(&st->lock);
*val *= ++mult;
*val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_OFFSET:
ret = ad5592r_get_vref(st);
@ -439,15 +439,13 @@ static int ad5592r_read_raw(struct iio_dev *iio_dev,
*val = (-34365 * 25) / ret;
else
*val = (-75365 * 25) / ret;
ret = IIO_VAL_INT;
break;
mutex_unlock(&st->lock);
return IIO_VAL_INT;
default:
return -EINVAL;
}
unlock:
mutex_unlock(&st->lock);
return ret;
}
static int ad5592r_write_raw_get_fmt(struct iio_dev *indio_dev,
@ -486,7 +484,7 @@ static const struct iio_chan_spec_ext_info ad5592r_ext_info[] = {
{
.name = "scale_available",
.read = ad5592r_show_scale_available,
.shared = true,
.shared = IIO_SHARED_BY_TYPE,
},
{},
};

View File

@ -10,9 +10,8 @@
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
#include <linux/acpi.h>
#define AD5592R_GPIO_READBACK_EN BIT(10)
#define AD5592R_LDAC_READBACK_EN BIT(6)
@ -157,8 +156,8 @@ MODULE_DEVICE_TABLE(acpi, ad5592r_acpi_match);
static struct spi_driver ad5592r_spi_driver = {
.driver = {
.name = "ad5592r",
.of_match_table = of_match_ptr(ad5592r_of_match),
.acpi_match_table = ACPI_PTR(ad5592r_acpi_match),
.of_match_table = ad5592r_of_match,
.acpi_match_table = ad5592r_acpi_match,
},
.probe = ad5592r_spi_probe,
.remove = ad5592r_spi_remove,

View File

@ -11,8 +11,7 @@
#include <linux/bitops.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/acpi.h>
#include <linux/mod_devicetable.h>
#define AD5593R_MODE_CONF (0 << 4)
#define AD5593R_MODE_DAC_WRITE (1 << 4)
@ -124,8 +123,8 @@ MODULE_DEVICE_TABLE(acpi, ad5593r_acpi_match);
static struct i2c_driver ad5593r_driver = {
.driver = {
.name = "ad5593r",
.of_match_table = of_match_ptr(ad5593r_of_match),
.acpi_match_table = ACPI_PTR(ad5593r_acpi_match),
.of_match_table = ad5593r_of_match,
.acpi_match_table = ad5593r_acpi_match,
},
.probe = ad5593r_i2c_probe,
.remove = ad5593r_i2c_remove,

View File

@ -7,6 +7,7 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
@ -29,6 +30,9 @@
* @spi: the device for this driver instance
* @config: cached config register value
* @dac_cache: current DAC raw value (chip does not support readback)
* @vdd_reg: reference to VDD regulator
* @vref_reg: reference to VREF regulator
* @lock: protect writes and cache updates
* @data: spi transfer buffer
*/
@ -287,7 +291,7 @@ MODULE_DEVICE_TABLE(spi, ad7303_spi_ids);
static struct spi_driver ad7303_driver = {
.driver = {
.name = "ad7303",
.of_match_table = of_match_ptr(ad7303_spi_of_match),
.of_match_table = ad7303_spi_of_match,
},
.probe = ad7303_probe,
.remove = ad7303_remove,

View File

@ -16,8 +16,8 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/mod_devicetable.h>
#include <linux/property.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@ -357,29 +357,16 @@ static const struct iio_info mcp4725_info = {
.attrs = &mcp4725_attribute_group,
};
#ifdef CONFIG_OF
static int mcp4725_probe_dt(struct device *dev,
struct mcp4725_platform_data *pdata)
{
struct device_node *np = dev->of_node;
if (!np)
return -ENODEV;
/* check if is the vref-supply defined */
pdata->use_vref = of_property_read_bool(np, "vref-supply");
pdata->use_vref = device_property_read_bool(dev, "vref-supply");
pdata->vref_buffered =
of_property_read_bool(np, "microchip,vref-buffered");
device_property_read_bool(dev, "microchip,vref-buffered");
return 0;
}
#else
static int mcp4725_probe_dt(struct device *dev,
struct mcp4725_platform_data *platform_data)
{
return -ENODEV;
}
#endif
static int mcp4725_probe(struct i2c_client *client,
const struct i2c_device_id *id)
@ -398,8 +385,8 @@ static int mcp4725_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
if (client->dev.of_node)
data->id = (enum chip_id)of_device_get_match_data(&client->dev);
if (dev_fwnode(&client->dev))
data->id = (enum chip_id)device_get_match_data(&client->dev);
else
data->id = id->driver_data;
pdata = dev_get_platdata(&client->dev);
@ -519,7 +506,6 @@ static const struct i2c_device_id mcp4725_id[] = {
};
MODULE_DEVICE_TABLE(i2c, mcp4725_id);
#ifdef CONFIG_OF
static const struct of_device_id mcp4725_of_match[] = {
{
.compatible = "microchip,mcp4725",
@ -532,12 +518,11 @@ static const struct of_device_id mcp4725_of_match[] = {
{ }
};
MODULE_DEVICE_TABLE(of, mcp4725_of_match);
#endif
static struct i2c_driver mcp4725_driver = {
.driver = {
.name = MCP4725_DRV_NAME,
.of_match_table = of_match_ptr(mcp4725_of_match),
.of_match_table = mcp4725_of_match,
.pm = &mcp4725_pm_ops,
},
.probe = mcp4725_probe,

View File

@ -26,9 +26,12 @@
/**
* struct stm32_dac - private data of DAC driver
* @common: reference to DAC common data
* @lock: lock to protect against potential races when reading
* and update CR, to keep it in sync with pm_runtime
*/
struct stm32_dac {
struct stm32_dac_common *common;
struct mutex lock;
};
static int stm32_dac_is_enabled(struct iio_dev *indio_dev, int channel)
@ -58,10 +61,10 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch,
int ret;
/* already enabled / disabled ? */
mutex_lock(&indio_dev->mlock);
mutex_lock(&dac->lock);
ret = stm32_dac_is_enabled(indio_dev, ch);
if (ret < 0 || enable == !!ret) {
mutex_unlock(&indio_dev->mlock);
mutex_unlock(&dac->lock);
return ret < 0 ? ret : 0;
}
@ -69,13 +72,13 @@ static int stm32_dac_set_enable_state(struct iio_dev *indio_dev, int ch,
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_put_noidle(dev);
mutex_unlock(&indio_dev->mlock);
mutex_unlock(&dac->lock);
return ret;
}
}
ret = regmap_update_bits(dac->common->regmap, STM32_DAC_CR, msk, en);
mutex_unlock(&indio_dev->mlock);
mutex_unlock(&dac->lock);
if (ret < 0) {
dev_err(&indio_dev->dev, "%s failed\n", en ?
"Enable" : "Disable");
@ -327,6 +330,8 @@ static int stm32_dac_probe(struct platform_device *pdev)
indio_dev->info = &stm32_dac_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
mutex_init(&dac->lock);
ret = stm32_dac_chan_of_init(indio_dev);
if (ret < 0)
return ret;

View File

@ -14,6 +14,7 @@
#include <linux/iio/iio.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
@ -324,7 +325,6 @@ static int ti_dac_remove(struct spi_device *spi)
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id ti_dac_of_id[] = {
{ .compatible = "ti,dac082s085" },
{ .compatible = "ti,dac102s085" },
@ -335,7 +335,6 @@ static const struct of_device_id ti_dac_of_id[] = {
{ }
};
MODULE_DEVICE_TABLE(of, ti_dac_of_id);
#endif
static const struct spi_device_id ti_dac_spi_id[] = {
{ "dac082s085", dual_8bit },
@ -351,7 +350,7 @@ MODULE_DEVICE_TABLE(spi, ti_dac_spi_id);
static struct spi_driver ti_dac_driver = {
.driver = {
.name = "ti-dac082s085",
.of_match_table = of_match_ptr(ti_dac_of_id),
.of_match_table = ti_dac_of_id,
},
.probe = ti_dac_probe,
.remove = ti_dac_remove,

View File

@ -18,8 +18,7 @@
#include <linux/iio/iio.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/mod_devicetable.h>
#include <linux/regulator/consumer.h>
enum chip_id {
@ -384,7 +383,6 @@ static int dac5571_remove(struct i2c_client *i2c)
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id dac5571_of_id[] = {
{.compatible = "ti,dac5571"},
{.compatible = "ti,dac6571"},
@ -398,7 +396,6 @@ static const struct of_device_id dac5571_of_id[] = {
{}
};
MODULE_DEVICE_TABLE(of, dac5571_of_id);
#endif
static const struct i2c_device_id dac5571_id[] = {
{"dac5571", single_8bit},
@ -417,7 +414,7 @@ MODULE_DEVICE_TABLE(i2c, dac5571_id);
static struct i2c_driver dac5571_driver = {
.driver = {
.name = "ti-dac5571",
.of_match_table = of_match_ptr(dac5571_of_id),
.of_match_table = dac5571_of_id,
},
.probe = dac5571_probe,
.remove = dac5571_remove,

View File

@ -22,6 +22,14 @@ struct dac7612 {
struct gpio_desc *loaddacs;
uint16_t cache[2];
/*
* Lock to protect the state of the device from potential concurrent
* write accesses from userspace. The write operation requires an
* SPI write, then toggling of a GPIO, so the lock aims to protect
* the sanity of the entire sequence of operation.
*/
struct mutex lock;
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
@ -101,9 +109,9 @@ static int dac7612_write_raw(struct iio_dev *iio_dev,
if (val == priv->cache[chan->channel])
return 0;
mutex_lock(&iio_dev->mlock);
mutex_lock(&priv->lock);
ret = dac7612_cmd_single(priv, chan->channel, val);
mutex_unlock(&iio_dev->mlock);
mutex_unlock(&priv->lock);
return ret;
}
@ -145,6 +153,8 @@ static int dac7612_probe(struct spi_device *spi)
iio_dev->num_channels = ARRAY_SIZE(priv->cache);
iio_dev->name = spi_get_device_id(spi)->name;
mutex_init(&priv->lock);
for (i = 0; i < ARRAY_SIZE(priv->cache); i++) {
ret = dac7612_cmd_single(priv, i, 0);
if (ret)

View File

@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
/**
/*
* Copyright (c) 2011 Jonathan Cameron
*
* Companion module to the iio simple dummy example driver.
@ -27,11 +27,13 @@
#define IIO_EVENTGEN_NO 10
/**
* struct iio_dummy_eventgen - event generator specific state
* @regs: irq regs we are faking
* @lock: protect the evgen state
* @inuse: mask of which irqs are connected
* @irq_sim: interrupt simulator
* @base: base of irq range
* @irq_sim_domain: irq simulator domain
*/
struct iio_dummy_eventgen {
struct iio_dummy_regs regs[IIO_EVENTGEN_NO];

View File

@ -47,6 +47,13 @@ struct adf4350_state {
unsigned long regs[6];
unsigned long regs_hw[6];
unsigned long long freq_req;
/*
* Lock to protect the state of the device from potential concurrent
* writes. The device is configured via a sequence of SPI writes,
* and this lock is meant to prevent the start of another sequence
* before another one has finished.
*/
struct mutex lock;
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
@ -99,7 +106,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev,
if (reg > ADF4350_REG5)
return -EINVAL;
mutex_lock(&indio_dev->mlock);
mutex_lock(&st->lock);
if (readval == NULL) {
st->regs[reg] = writeval & ~(BIT(0) | BIT(1) | BIT(2));
ret = adf4350_sync_config(st);
@ -107,7 +114,7 @@ static int adf4350_reg_access(struct iio_dev *indio_dev,
*readval = st->regs_hw[reg];
ret = 0;
}
mutex_unlock(&indio_dev->mlock);
mutex_unlock(&st->lock);
return ret;
}
@ -254,7 +261,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev,
if (ret)
return ret;
mutex_lock(&indio_dev->mlock);
mutex_lock(&st->lock);
switch ((u32)private) {
case ADF4350_FREQ:
ret = adf4350_set_freq(st, readin);
@ -295,7 +302,7 @@ static ssize_t adf4350_write(struct iio_dev *indio_dev,
default:
ret = -EINVAL;
}
mutex_unlock(&indio_dev->mlock);
mutex_unlock(&st->lock);
return ret ? ret : len;
}
@ -309,7 +316,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
unsigned long long val;
int ret = 0;
mutex_lock(&indio_dev->mlock);
mutex_lock(&st->lock);
switch ((u32)private) {
case ADF4350_FREQ:
val = (u64)((st->r0_int * st->r1_mod) + st->r0_fract) *
@ -338,7 +345,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
ret = -EINVAL;
val = 0;
}
mutex_unlock(&indio_dev->mlock);
mutex_unlock(&st->lock);
return ret < 0 ? ret : sprintf(buf, "%llu\n", val);
}
@ -539,6 +546,8 @@ static int adf4350_probe(struct spi_device *spi)
indio_dev->channels = &adf4350_chan;
indio_dev->num_channels = 1;
mutex_init(&st->lock);
st->chspc = pdata->channel_spacing;
if (clk) {
st->clk = clk;

View File

@ -44,6 +44,8 @@ config ADIS16260
config ADXRS290
tristate "Analog Devices ADXRS290 Dual-Axis MEMS Gyroscope SPI driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Analog Devices ADXRS290 programmable
digital output gyroscope.

View File

@ -38,7 +38,7 @@ struct adis16080_chip_info {
* @us: actual spi_device to write data
* @info: chip specific parameters
* @buf: transmit or receive buffer
* @lock lock to protect buffer during reads
* @lock: lock to protect buffer during reads
**/
struct adis16080_state {
struct spi_device *us;

View File

@ -523,6 +523,11 @@ static const struct adis16136_chip_info adis16136_chip_info[] = {
},
};
static void adis16136_stop(void *data)
{
adis16136_stop_device(data);
}
static int adis16136_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
@ -552,39 +557,24 @@ static int adis16136_probe(struct spi_device *spi)
if (ret)
return ret;
ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL);
ret = devm_adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL);
if (ret)
return ret;
ret = adis16136_initial_setup(indio_dev);
if (ret)
goto error_cleanup_buffer;
return ret;
ret = iio_device_register(indio_dev);
ret = devm_add_action_or_reset(&spi->dev, adis16136_stop, indio_dev);
if (ret)
goto error_stop_device;
return ret;
ret = devm_iio_device_register(&spi->dev, indio_dev);
if (ret)
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);
adis16136_stop_device(indio_dev);
adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
return 0;
}
@ -603,7 +593,6 @@ static struct spi_driver adis16136_driver = {
},
.id_table = adis16136_ids,
.probe = adis16136_probe,
.remove = adis16136_remove,
};
module_spi_driver(adis16136_driver);

View File

@ -359,6 +359,11 @@ static const struct adis_data adis16260_data = {
BIT(ADIS16260_DIAG_STAT_POWER_LOW_BIT),
};
static void adis16260_stop(void *data)
{
adis16260_stop_device(data);
}
static int adis16260_probe(struct spi_device *spi)
{
const struct spi_device_id *id;
@ -390,35 +395,20 @@ static int adis16260_probe(struct spi_device *spi)
if (ret)
return ret;
ret = adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL);
ret = devm_adis_setup_buffer_and_trigger(&adis16260->adis, indio_dev, NULL);
if (ret)
return ret;
/* Get the device into a sane initial state */
ret = adis_initial_startup(&adis16260->adis);
if (ret)
goto error_cleanup_buffer_trigger;
ret = iio_device_register(indio_dev);
return ret;
ret = devm_add_action_or_reset(&spi->dev, adis16260_stop, indio_dev);
if (ret)
goto error_cleanup_buffer_trigger;
return ret;
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);
adis16260_stop_device(indio_dev);
adis_cleanup_buffer_and_trigger(&adis16260->adis, indio_dev);
return 0;
return devm_iio_device_register(&spi->dev, indio_dev);
}
/*
@ -441,7 +431,6 @@ static struct spi_driver adis16260_driver = {
.name = "adis16260",
},
.probe = adis16260_probe,
.remove = adis16260_remove,
.id_table = adis16260_id,
};
module_spi_driver(adis16260_driver);

View File

@ -13,8 +13,12 @@
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#define ADXRS290_ADI_ID 0xAD
#define ADXRS290_MEMS_ID 0x1D
@ -35,7 +39,9 @@
#define ADXRS290_READ BIT(7)
#define ADXRS290_TSM BIT(0)
#define ADXRS290_MEASUREMENT BIT(1)
#define ADXRS290_SYNC GENMASK(1, 0)
#define ADXRS290_DATA_RDY_OUT BIT(0)
#define ADXRS290_SYNC_MASK GENMASK(1, 0)
#define ADXRS290_SYNC(x) FIELD_PREP(ADXRS290_SYNC_MASK, x)
#define ADXRS290_LPF_MASK GENMASK(2, 0)
#define ADXRS290_LPF(x) FIELD_PREP(ADXRS290_LPF_MASK, x)
#define ADXRS290_HPF_MASK GENMASK(7, 4)
@ -50,6 +56,13 @@ enum adxrs290_mode {
ADXRS290_MODE_MEASUREMENT,
};
enum adxrs290_scan_index {
ADXRS290_IDX_X,
ADXRS290_IDX_Y,
ADXRS290_IDX_TEMP,
ADXRS290_IDX_TS,
};
struct adxrs290_state {
struct spi_device *spi;
/* Serialize reads and their subsequent processing */
@ -57,6 +70,12 @@ struct adxrs290_state {
enum adxrs290_mode mode;
unsigned int lpf_3db_freq_idx;
unsigned int hpf_3db_freq_idx;
struct iio_trigger *dready_trig;
/* Ensure correct alignment of timestamp when present */
struct {
s16 channels[3];
s64 ts __aligned(8);
} buffer;
};
/*
@ -192,15 +211,70 @@ static int adxrs290_set_filter_freq(struct iio_dev *indio_dev,
return adxrs290_spi_write_reg(st->spi, ADXRS290_REG_FILTER, val);
}
static int adxrs290_set_mode(struct iio_dev *indio_dev, enum adxrs290_mode mode)
{
struct adxrs290_state *st = iio_priv(indio_dev);
int val, ret;
if (st->mode == mode)
return 0;
mutex_lock(&st->lock);
ret = spi_w8r8(st->spi, ADXRS290_READ_REG(ADXRS290_REG_POWER_CTL));
if (ret < 0)
goto out_unlock;
val = ret;
switch (mode) {
case ADXRS290_MODE_STANDBY:
val &= ~ADXRS290_MEASUREMENT;
break;
case ADXRS290_MODE_MEASUREMENT:
val |= ADXRS290_MEASUREMENT;
break;
default:
ret = -EINVAL;
goto out_unlock;
}
ret = adxrs290_spi_write_reg(st->spi, ADXRS290_REG_POWER_CTL, val);
if (ret < 0) {
dev_err(&st->spi->dev, "unable to set mode: %d\n", ret);
goto out_unlock;
}
/* update cached mode */
st->mode = mode;
out_unlock:
mutex_unlock(&st->lock);
return ret;
}
static void adxrs290_chip_off_action(void *data)
{
struct iio_dev *indio_dev = data;
adxrs290_set_mode(indio_dev, ADXRS290_MODE_STANDBY);
}
static int adxrs290_initial_setup(struct iio_dev *indio_dev)
{
struct adxrs290_state *st = iio_priv(indio_dev);
struct spi_device *spi = st->spi;
int ret;
ret = adxrs290_spi_write_reg(spi, ADXRS290_REG_POWER_CTL,
ADXRS290_MEASUREMENT | ADXRS290_TSM);
if (ret < 0)
return ret;
st->mode = ADXRS290_MODE_MEASUREMENT;
return adxrs290_spi_write_reg(st->spi,
ADXRS290_REG_POWER_CTL,
ADXRS290_MEASUREMENT | ADXRS290_TSM);
return devm_add_action_or_reset(&spi->dev, adxrs290_chip_off_action,
indio_dev);
}
static int adxrs290_read_raw(struct iio_dev *indio_dev,
@ -215,24 +289,34 @@ static int adxrs290_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
return ret;
switch (chan->type) {
case IIO_ANGL_VEL:
ret = adxrs290_get_rate_data(indio_dev,
ADXRS290_READ_REG(chan->address),
val);
if (ret < 0)
return ret;
break;
return IIO_VAL_INT;
ret = IIO_VAL_INT;
break;
case IIO_TEMP:
ret = adxrs290_get_temp_data(indio_dev, val);
if (ret < 0)
return ret;
break;
return IIO_VAL_INT;
ret = IIO_VAL_INT;
break;
default:
return -EINVAL;
ret = -EINVAL;
break;
}
iio_device_release_direct_mode(indio_dev);
return ret;
case IIO_CHAN_INFO_SCALE:
switch (chan->type) {
case IIO_ANGL_VEL:
@ -279,34 +363,52 @@ static int adxrs290_write_raw(struct iio_dev *indio_dev,
long mask)
{
struct adxrs290_state *st = iio_priv(indio_dev);
int lpf_idx, hpf_idx;
int ret, lpf_idx, hpf_idx;
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
return ret;
switch (mask) {
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
lpf_idx = adxrs290_find_match(adxrs290_lpf_3db_freq_hz_table,
ARRAY_SIZE(adxrs290_lpf_3db_freq_hz_table),
val, val2);
if (lpf_idx < 0)
return -EINVAL;
if (lpf_idx < 0) {
ret = -EINVAL;
break;
}
/* caching the updated state of the low-pass filter */
st->lpf_3db_freq_idx = lpf_idx;
/* retrieving the current state of the high-pass filter */
hpf_idx = st->hpf_3db_freq_idx;
return adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx);
ret = adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx);
break;
case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
hpf_idx = adxrs290_find_match(adxrs290_hpf_3db_freq_hz_table,
ARRAY_SIZE(adxrs290_hpf_3db_freq_hz_table),
val, val2);
if (hpf_idx < 0)
return -EINVAL;
if (hpf_idx < 0) {
ret = -EINVAL;
break;
}
/* caching the updated state of the high-pass filter */
st->hpf_3db_freq_idx = hpf_idx;
/* retrieving the current state of the low-pass filter */
lpf_idx = st->lpf_3db_freq_idx;
return adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx);
ret = adxrs290_set_filter_freq(indio_dev, lpf_idx, hpf_idx);
break;
default:
ret = -EINVAL;
break;
}
return -EINVAL;
iio_device_release_direct_mode(indio_dev);
return ret;
}
static int adxrs290_read_avail(struct iio_dev *indio_dev,
@ -334,6 +436,97 @@ static int adxrs290_read_avail(struct iio_dev *indio_dev,
}
}
static int adxrs290_reg_access_rw(struct spi_device *spi, unsigned int reg,
unsigned int *readval)
{
int ret;
ret = spi_w8r8(spi, ADXRS290_READ_REG(reg));
if (ret < 0)
return ret;
*readval = ret;
return 0;
}
static int adxrs290_reg_access(struct iio_dev *indio_dev, unsigned int reg,
unsigned int writeval, unsigned int *readval)
{
struct adxrs290_state *st = iio_priv(indio_dev);
if (readval)
return adxrs290_reg_access_rw(st->spi, reg, readval);
else
return adxrs290_spi_write_reg(st->spi, reg, writeval);
}
static int adxrs290_data_rdy_trigger_set_state(struct iio_trigger *trig,
bool state)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct adxrs290_state *st = iio_priv(indio_dev);
int ret;
u8 val;
val = state ? ADXRS290_SYNC(ADXRS290_DATA_RDY_OUT) : 0;
ret = adxrs290_spi_write_reg(st->spi, ADXRS290_REG_DATA_RDY, val);
if (ret < 0)
dev_err(&st->spi->dev, "failed to start data rdy interrupt\n");
return ret;
}
static int adxrs290_reset_trig(struct iio_trigger *trig)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
int val;
/*
* Data ready interrupt is reset after a read of the data registers.
* Here, we only read the 16b DATAY registers as that marks the end of
* a read of the data registers and initiates a reset for the interrupt
* line.
*/
adxrs290_get_rate_data(indio_dev,
ADXRS290_READ_REG(ADXRS290_REG_DATAY0), &val);
return 0;
}
static const struct iio_trigger_ops adxrs290_trigger_ops = {
.set_trigger_state = &adxrs290_data_rdy_trigger_set_state,
.validate_device = &iio_trigger_validate_own_device,
.try_reenable = &adxrs290_reset_trig,
};
static irqreturn_t adxrs290_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adxrs290_state *st = iio_priv(indio_dev);
u8 tx = ADXRS290_READ_REG(ADXRS290_REG_DATAX0);
int ret;
mutex_lock(&st->lock);
/* exercise a bulk data capture starting from reg DATAX0... */
ret = spi_write_then_read(st->spi, &tx, sizeof(tx), st->buffer.channels,
sizeof(st->buffer.channels));
if (ret < 0)
goto out_unlock_notify;
iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer,
pf->timestamp);
out_unlock_notify:
mutex_unlock(&st->lock);
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
#define ADXRS290_ANGL_VEL_CHANNEL(reg, axis) { \
.type = IIO_ANGL_VEL, \
.address = reg, \
@ -346,6 +539,13 @@ static int adxrs290_read_avail(struct iio_dev *indio_dev,
.info_mask_shared_by_type_available = \
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \
BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \
.scan_index = ADXRS290_IDX_##axis, \
.scan_type = { \
.sign = 's', \
.realbits = 16, \
.storagebits = 16, \
.endianness = IIO_LE, \
}, \
}
static const struct iio_chan_spec adxrs290_channels[] = {
@ -356,15 +556,67 @@ static const struct iio_chan_spec adxrs290_channels[] = {
.address = ADXRS290_REG_TEMP0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.scan_index = ADXRS290_IDX_TEMP,
.scan_type = {
.sign = 's',
.realbits = 12,
.storagebits = 16,
.endianness = IIO_LE,
},
},
IIO_CHAN_SOFT_TIMESTAMP(ADXRS290_IDX_TS),
};
static const unsigned long adxrs290_avail_scan_masks[] = {
BIT(ADXRS290_IDX_X) | BIT(ADXRS290_IDX_Y) | BIT(ADXRS290_IDX_TEMP),
0
};
static const struct iio_info adxrs290_info = {
.read_raw = &adxrs290_read_raw,
.write_raw = &adxrs290_write_raw,
.read_avail = &adxrs290_read_avail,
.debugfs_reg_access = &adxrs290_reg_access,
};
static int adxrs290_probe_trigger(struct iio_dev *indio_dev)
{
struct adxrs290_state *st = iio_priv(indio_dev);
int ret;
if (!st->spi->irq) {
dev_info(&st->spi->dev, "no irq, using polling\n");
return 0;
}
st->dready_trig = devm_iio_trigger_alloc(&st->spi->dev, "%s-dev%d",
indio_dev->name,
indio_dev->id);
if (!st->dready_trig)
return -ENOMEM;
st->dready_trig->dev.parent = &st->spi->dev;
st->dready_trig->ops = &adxrs290_trigger_ops;
iio_trigger_set_drvdata(st->dready_trig, indio_dev);
ret = devm_request_irq(&st->spi->dev, st->spi->irq,
&iio_trigger_generic_data_rdy_poll,
IRQF_ONESHOT, "adxrs290_irq", st->dready_trig);
if (ret < 0)
return dev_err_probe(&st->spi->dev, ret,
"request irq %d failed\n", st->spi->irq);
ret = devm_iio_trigger_register(&st->spi->dev, st->dready_trig);
if (ret) {
dev_err(&st->spi->dev, "iio trigger register failed\n");
return ret;
}
indio_dev->trig = iio_trigger_get(st->dready_trig);
return 0;
}
static int adxrs290_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
@ -384,6 +636,7 @@ static int adxrs290_probe(struct spi_device *spi)
indio_dev->channels = adxrs290_channels;
indio_dev->num_channels = ARRAY_SIZE(adxrs290_channels);
indio_dev->info = &adxrs290_info;
indio_dev->available_scan_masks = adxrs290_avail_scan_masks;
mutex_init(&st->lock);
@ -423,6 +676,17 @@ static int adxrs290_probe(struct spi_device *spi)
st->lpf_3db_freq_idx = val;
st->hpf_3db_freq_idx = val2;
ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
&iio_pollfunc_store_time,
&adxrs290_trigger_handler, NULL);
if (ret < 0)
return dev_err_probe(&spi->dev, ret,
"iio triggered buffer setup failed\n");
ret = adxrs290_probe_trigger(indio_dev);
if (ret < 0)
return ret;
return devm_iio_device_register(&spi->dev, indio_dev);
}

View File

@ -46,13 +46,20 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct itg3200 *st = iio_priv(indio_dev);
__be16 buf[ITG3200_SCAN_ELEMENTS + sizeof(s64)/sizeof(u16)];
/*
* Ensure correct alignment and padding including for the
* timestamp that may be inserted.
*/
struct {
__be16 buf[ITG3200_SCAN_ELEMENTS];
s64 ts __aligned(8);
} scan;
int ret = itg3200_read_all_channels(st->i2c, buf);
int ret = itg3200_read_all_channels(st->i2c, scan.buf);
if (ret < 0)
goto error_ret;
iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp);
iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);

View File

@ -19,7 +19,7 @@
#include <linux/irq.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/mod_devicetable.h>
#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
@ -323,11 +323,10 @@ static int max30102_get_current_idx(unsigned int val, int *reg)
static int max30102_led_init(struct max30102_data *data)
{
struct device *dev = &data->client->dev;
struct device_node *np = dev->of_node;
unsigned int val;
int reg, ret;
ret = of_property_read_u32(np, "maxim,red-led-current-microamp", &val);
ret = device_property_read_u32(dev, "maxim,red-led-current-microamp", &val);
if (ret) {
dev_info(dev, "no red-led-current-microamp set\n");
@ -346,7 +345,7 @@ static int max30102_led_init(struct max30102_data *data)
return ret;
if (data->chip_id == max30105) {
ret = of_property_read_u32(np,
ret = device_property_read_u32(dev,
"maxim,green-led-current-microamp", &val);
if (ret) {
dev_info(dev, "no green-led-current-microamp set\n");
@ -368,7 +367,7 @@ static int max30102_led_init(struct max30102_data *data)
return ret;
}
ret = of_property_read_u32(np, "maxim,ir-led-current-microamp", &val);
ret = device_property_read_u32(dev, "maxim,ir-led-current-microamp", &val);
if (ret) {
dev_info(dev, "no ir-led-current-microamp set\n");
@ -624,7 +623,7 @@ MODULE_DEVICE_TABLE(of, max30102_dt_ids);
static struct i2c_driver max30102_driver = {
.driver = {
.name = MAX30102_DRV_NAME,
.of_match_table = of_match_ptr(max30102_dt_ids),
.of_match_table = max30102_dt_ids,
},
.probe = max30102_probe,
.remove = max30102_remove,

View File

@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/init.h>
#include <linux/i2c.h>
@ -417,7 +418,7 @@ MODULE_DEVICE_TABLE(of, hdc100x_dt_ids);
static struct i2c_driver hdc100x_driver = {
.driver = {
.name = "hdc100x",
.of_match_table = of_match_ptr(hdc100x_dt_ids),
.of_match_table = hdc100x_dt_ids,
},
.probe = hdc100x_probe,
.id_table = hdc100x_id,

View File

@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/stat.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@ -247,7 +248,7 @@ static struct i2c_driver htu21_driver = {
.id_table = htu21_id,
.driver = {
.name = "htu21",
.of_match_table = of_match_ptr(htu21_of_match),
.of_match_table = htu21_of_match,
},
};

View File

@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
@ -153,7 +154,7 @@ MODULE_DEVICE_TABLE(of, si7020_dt_ids);
static struct i2c_driver si7020_driver = {
.driver = {
.name = "si7020",
.of_match_table = of_match_ptr(si7020_dt_ids),
.of_match_table = si7020_dt_ids,
},
.probe = si7020_probe,
.id_table = si7020_id,

View File

@ -173,6 +173,8 @@ struct adis16400_chip_info {
* @variant: chip variant info
* @filt_int: integer part of requested filter frequency
* @adis: adis device
* @avail_scan_mask: NULL terminated array of bitmaps of channels
* that must be enabled together
**/
struct adis16400_state {
struct adis16400_chip_info *variant;
@ -317,11 +319,6 @@ enum adis16400_chip_variant {
ADIS16448,
};
static struct adis_burst adis16400_burst = {
.en = true,
.reg_cmd = ADIS16400_GLOB_CMD,
};
static int adis16334_get_freq(struct adis16400_state *st)
{
int ret;
@ -947,7 +944,7 @@ static const char * const adis16400_status_error_msgs[] = {
[ADIS16400_DIAG_STAT_POWER_LOW] = "Power supply below 4.75V",
};
#define ADIS16400_DATA(_timeouts) \
#define ADIS16400_DATA(_timeouts, _burst_len) \
{ \
.msc_ctrl_reg = ADIS16400_MSC_CTRL, \
.glob_cmd_reg = ADIS16400_GLOB_CMD, \
@ -973,6 +970,8 @@ static const char * const adis16400_status_error_msgs[] = {
BIT(ADIS16400_DIAG_STAT_POWER_HIGH) | \
BIT(ADIS16400_DIAG_STAT_POWER_LOW), \
.timeouts = (_timeouts), \
.burst_reg_cmd = ADIS16400_GLOB_CMD, \
.burst_len = (_burst_len) \
}
static const struct adis_timeout adis16300_timeouts = {
@ -1023,7 +1022,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16300_timeouts),
.adis_data = ADIS16400_DATA(&adis16300_timeouts, 18),
},
[ADIS16334] = {
.channels = adis16334_channels,
@ -1036,7 +1035,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 67850, /* 25 C = 0x00 */
.set_freq = adis16334_set_freq,
.get_freq = adis16334_get_freq,
.adis_data = ADIS16400_DATA(&adis16334_timeouts),
.adis_data = ADIS16400_DATA(&adis16334_timeouts, 0),
},
[ADIS16350] = {
.channels = adis16350_channels,
@ -1048,7 +1047,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE,
.set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16300_timeouts),
.adis_data = ADIS16400_DATA(&adis16300_timeouts, 0),
},
[ADIS16360] = {
.channels = adis16350_channels,
@ -1061,7 +1060,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16300_timeouts),
.adis_data = ADIS16400_DATA(&adis16300_timeouts, 28),
},
[ADIS16362] = {
.channels = adis16350_channels,
@ -1074,7 +1073,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16362_timeouts),
.adis_data = ADIS16400_DATA(&adis16362_timeouts, 28),
},
[ADIS16364] = {
.channels = adis16350_channels,
@ -1087,7 +1086,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16362_timeouts),
.adis_data = ADIS16400_DATA(&adis16362_timeouts, 28),
},
[ADIS16367] = {
.channels = adis16350_channels,
@ -1100,7 +1099,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16300_timeouts),
.adis_data = ADIS16400_DATA(&adis16300_timeouts, 28),
},
[ADIS16400] = {
.channels = adis16400_channels,
@ -1112,7 +1111,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
.set_freq = adis16400_set_freq,
.get_freq = adis16400_get_freq,
.adis_data = ADIS16400_DATA(&adis16400_timeouts),
.adis_data = ADIS16400_DATA(&adis16400_timeouts, 24),
},
[ADIS16445] = {
.channels = adis16445_channels,
@ -1126,7 +1125,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
.set_freq = adis16334_set_freq,
.get_freq = adis16334_get_freq,
.adis_data = ADIS16400_DATA(&adis16445_timeouts),
.adis_data = ADIS16400_DATA(&adis16445_timeouts, 16),
},
[ADIS16448] = {
.channels = adis16448_channels,
@ -1140,7 +1139,7 @@ static struct adis16400_chip_info adis16400_chips[] = {
.temp_offset = 31000000 / 73860, /* 31 C = 0x00 */
.set_freq = adis16334_set_freq,
.get_freq = adis16334_get_freq,
.adis_data = ADIS16400_DATA(&adis16448_timeouts),
.adis_data = ADIS16400_DATA(&adis16448_timeouts, 24),
}
};
@ -1164,6 +1163,12 @@ static void adis16400_setup_chan_mask(struct adis16400_state *st)
st->avail_scan_mask[0] |= BIT(ch->scan_index);
}
}
static void adis16400_stop(void *data)
{
adis16400_stop_device(data);
}
static int adis16400_probe(struct spi_device *spi)
{
struct adis16400_state *st;
@ -1190,9 +1195,6 @@ static int adis16400_probe(struct spi_device *spi)
if (!(st->variant->flags & ADIS16400_NO_BURST)) {
adis16400_setup_chan_mask(st);
indio_dev->available_scan_masks = st->avail_scan_mask;
st->adis.burst = &adis16400_burst;
if (st->variant->flags & ADIS16400_BURST_DIAG_STAT)
st->adis.burst_extra_len = sizeof(u16);
}
adis16400_data = &st->variant->adis_data;
@ -1201,38 +1203,25 @@ static int adis16400_probe(struct spi_device *spi)
if (ret)
return ret;
ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev,
adis16400_trigger_handler);
ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, adis16400_trigger_handler);
if (ret)
return ret;
/* Get the device into a sane initial state */
ret = adis16400_initial_setup(indio_dev);
if (ret)
goto error_cleanup_buffer;
ret = iio_device_register(indio_dev);
return ret;
ret = devm_add_action_or_reset(&spi->dev, adis16400_stop, indio_dev);
if (ret)
goto error_cleanup_buffer;
return ret;
ret = devm_iio_device_register(&spi->dev, indio_dev);
if (ret)
return ret;
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);
adis16400_stop_device(indio_dev);
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
return 0;
}
static const struct spi_device_id adis16400_id[] = {
@ -1261,7 +1250,6 @@ static struct spi_driver adis16400_driver = {
},
.id_table = adis16400_id,
.probe = adis16400_probe,
.remove = adis16400_remove,
};
module_spi_driver(adis16400_driver);

View File

@ -403,7 +403,7 @@ static int adis16460_probe(struct spi_device *spi)
if (ret)
return ret;
ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
if (ret)
return ret;
@ -411,30 +411,14 @@ static int adis16460_probe(struct spi_device *spi)
ret = __adis_initial_startup(&st->adis);
if (ret)
goto error_cleanup_buffer;
return ret;
ret = iio_device_register(indio_dev);
ret = devm_iio_device_register(&spi->dev, indio_dev);
if (ret)
goto error_cleanup_buffer;
return ret;
adis16460_debugfs_init(indio_dev);
return 0;
error_cleanup_buffer:
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
return ret;
}
static int adis16460_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct adis16460 *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
return 0;
}
@ -457,7 +441,6 @@ static struct spi_driver adis16460_driver = {
},
.id_table = adis16460_ids,
.probe = adis16460_probe,
.remove = adis16460_remove,
};
module_spi_driver(adis16460_driver);

View File

@ -565,6 +565,9 @@ static int adis16475_enable_irq(struct adis *adis, bool enable)
BIT(ADIS16475_DIAG_STAT_CLK), \
.enable_irq = adis16475_enable_irq, \
.timeouts = (_timeouts), \
.burst_reg_cmd = ADIS16475_REG_GLOB_CMD, \
.burst_len = ADIS16475_BURST_MAX_DATA, \
.burst_max_len = ADIS16475_BURST32_MAX_DATA \
}
static const struct adis16475_sync adis16475_sync_mode[] = {
@ -910,20 +913,6 @@ static const struct iio_info adis16475_info = {
.debugfs_reg_access = adis_debugfs_reg_access,
};
static struct adis_burst adis16475_burst = {
.en = true,
.reg_cmd = ADIS16475_REG_GLOB_CMD,
/*
* adis_update_scan_mode_burst() sets the burst length in respect with
* the number of channels and allocates 16 bits for each. However,
* adis1647x devices also need space for DIAG_STAT, DATA_CNTR or
* TIME_STAMP (depending on the clock mode but for us these bytes are
* don't care...) and CRC.
*/
.extra_len = 3 * sizeof(u16),
.burst_max_len = ADIS16475_BURST32_MAX_DATA,
};
static bool adis16475_validate_crc(const u8 *buffer, u16 crc,
const bool burst32)
{
@ -1279,7 +1268,6 @@ static int adis16475_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
spi_set_drvdata(spi, indio_dev);
st->adis.burst = &adis16475_burst;
st->info = device_get_match_data(&spi->dev);
if (!st->info)

View File

@ -1212,6 +1212,16 @@ static int adis16480_get_ext_clocks(struct adis16480 *st)
return 0;
}
static void adis16480_stop(void *data)
{
adis16480_stop_device(data);
}
static void adis16480_clk_disable(void *data)
{
clk_disable_unprepare(data);
}
static int adis16480_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
@ -1245,18 +1255,26 @@ static int adis16480_probe(struct spi_device *spi)
if (ret)
return ret;
ret = devm_add_action_or_reset(&spi->dev, adis16480_stop, indio_dev);
if (ret)
return ret;
ret = adis16480_config_irq_pin(spi->dev.of_node, st);
if (ret)
goto error_stop_device;
return ret;
ret = adis16480_get_ext_clocks(st);
if (ret)
goto error_stop_device;
return ret;
if (!IS_ERR_OR_NULL(st->ext_clk)) {
ret = adis16480_ext_clk_config(st, spi->dev.of_node, true);
if (ret)
goto error_stop_device;
return ret;
ret = devm_add_action_or_reset(&spi->dev, adis16480_clk_disable, st->ext_clk);
if (ret)
return ret;
st->clk_freq = clk_get_rate(st->ext_clk);
st->clk_freq *= 1000; /* micro */
@ -1264,38 +1282,16 @@ static int adis16480_probe(struct spi_device *spi)
st->clk_freq = st->chip_info->int_clk;
}
ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
if (ret)
goto error_clk_disable_unprepare;
return ret;
ret = iio_device_register(indio_dev);
ret = devm_iio_device_register(&spi->dev, indio_dev);
if (ret)
goto error_cleanup_buffer;
return ret;
adis16480_debugfs_init(indio_dev);
return 0;
error_cleanup_buffer:
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
error_clk_disable_unprepare:
clk_disable_unprepare(st->ext_clk);
error_stop_device:
adis16480_stop_device(indio_dev);
return ret;
}
static int adis16480_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct adis16480 *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
adis16480_stop_device(indio_dev);
adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
clk_disable_unprepare(st->ext_clk);
return 0;
}
@ -1338,7 +1334,6 @@ static struct spi_driver adis16480_driver = {
},
.id_table = adis16480_ids,
.probe = adis16480_probe,
.remove = adis16480_remove,
};
module_spi_driver(adis16480_driver);

View File

@ -26,12 +26,10 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev,
unsigned int burst_length, burst_max_length;
u8 *tx;
/* All but the timestamp channel */
burst_length = (indio_dev->num_channels - 1) * sizeof(u16);
burst_length += adis->burst->extra_len + adis->burst_extra_len;
burst_length = adis->data->burst_len + adis->burst_extra_len;
if (adis->burst->burst_max_len)
burst_max_length = adis->burst->burst_max_len;
if (adis->data->burst_max_len)
burst_max_length = adis->data->burst_max_len;
else
burst_max_length = burst_length;
@ -47,7 +45,7 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev,
}
tx = adis->buffer + burst_max_length;
tx[0] = ADIS_READ_REG(adis->burst->reg_cmd);
tx[0] = ADIS_READ_REG(adis->data->burst_reg_cmd);
tx[1] = 0;
adis->xfer[0].tx_buf = tx;
@ -76,7 +74,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev,
kfree(adis->xfer);
kfree(adis->buffer);
if (adis->burst && adis->burst->en)
if (adis->data->burst_len)
return adis_update_scan_mode_burst(indio_dev, scan_mask);
scan_count = indio_dev->scan_bytes / 2;
@ -169,48 +167,6 @@ static void adis_buffer_cleanup(void *arg)
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
* the managed adis device
@ -220,7 +176,10 @@ EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger);
*
* Returns 0 on success, a negative error code otherwise.
*
* This function perfoms exactly the same as adis_setup_buffer_and_trigger()
* This function sets up the buffer and trigger for a adis devices. If
* 'trigger_handler' is NULL the default trigger handler will be used. The
* default trigger handler will simply read the registers assigned to the
* currently active channels.
*/
int
devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
@ -248,20 +207,3 @@ devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
}
EXPORT_SYMBOL_GPL(devm_adis_setup_buffer_and_trigger);
/**
* adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources
* @adis: The adis device.
* @indio_dev: The IIO device.
*
* Frees resources allocated by adis_setup_buffer_and_trigger()
*/
void adis_cleanup_buffer_and_trigger(struct adis *adis,
struct iio_dev *indio_dev)
{
if (adis->spi->irq)
adis_remove_trigger(adis);
kfree(adis->buffer);
kfree(adis->xfer);
iio_triggered_buffer_cleanup(indio_dev);
}
EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger);

View File

@ -55,53 +55,6 @@ static int adis_validate_irq_flag(struct adis *adis)
return 0;
}
/**
* adis_probe_trigger() - Sets up trigger for a adis device
* @adis: The adis device
* @indio_dev: The IIO device
*
* Returns 0 on success or a negative error code
*
* adis_remove_trigger() should be used to free the trigger.
*/
int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
{
int ret;
adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
indio_dev->id);
if (adis->trig == NULL)
return -ENOMEM;
adis_trigger_setup(adis);
ret = adis_validate_irq_flag(adis);
if (ret)
return ret;
ret = request_irq(adis->spi->irq,
&iio_trigger_generic_data_rdy_poll,
adis->irq_flag,
indio_dev->name,
adis->trig);
if (ret)
goto error_free_trig;
ret = iio_trigger_register(adis->trig);
indio_dev->trig = iio_trigger_get(adis->trig);
if (ret)
goto error_free_irq;
return 0;
error_free_irq:
free_irq(adis->spi->irq, adis->trig);
error_free_trig:
iio_trigger_free(adis->trig);
return ret;
}
EXPORT_SYMBOL_GPL(adis_probe_trigger);
/**
* devm_adis_probe_trigger() - Sets up trigger for a managed adis device
@ -137,16 +90,3 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
}
EXPORT_SYMBOL_GPL(devm_adis_probe_trigger);
/**
* adis_remove_trigger() - Remove trigger for a adis devices
* @adis: The adis device
*
* Removes the trigger previously registered with adis_probe_trigger().
*/
void adis_remove_trigger(struct adis *adis)
{
iio_trigger_unregister(adis->trig);
free_irq(adis->spi->irq, adis->trig);
iio_trigger_free(adis->trig);
}
EXPORT_SYMBOL_GPL(adis_remove_trigger);

View File

@ -122,6 +122,13 @@ struct inv_mpu6050_chip_config {
u8 user_ctrl;
};
/*
* Maximum of 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8.
* May be less if fewer channels are enabled, as long as the timestamp
* remains 8 byte aligned
*/
#define INV_MPU6050_OUTPUT_DATA_SIZE 32
/**
* struct inv_mpu6050_hw - Other important hardware information.
* @whoami: Self identification byte from WHO_AM_I register
@ -165,6 +172,7 @@ struct inv_mpu6050_hw {
* @magn_raw_to_gauss: coefficient to convert mag raw value to Gauss.
* @magn_orient: magnetometer sensor chip orientation if available.
* @suspended_sensors: sensors mask of sensors turned off for suspend
* @data: dma safe buffer used for bulk reads.
*/
struct inv_mpu6050_state {
struct mutex lock;
@ -190,6 +198,7 @@ struct inv_mpu6050_state {
s32 magn_raw_to_gauss[3];
struct iio_mount_matrix magn_orient;
unsigned int suspended_sensors;
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] ____cacheline_aligned;
};
/*register and associated bit definition*/
@ -334,9 +343,6 @@ struct inv_mpu6050_state {
#define INV_ICM20608_TEMP_OFFSET 8170
#define INV_ICM20608_TEMP_SCALE 3059976
/* 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8 */
#define INV_MPU6050_OUTPUT_DATA_SIZE 32
#define INV_MPU6050_REG_INT_PIN_CFG 0x37
#define INV_MPU6050_ACTIVE_HIGH 0x00
#define INV_MPU6050_ACTIVE_LOW 0x80

View File

@ -13,7 +13,6 @@
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/math64.h>
#include <asm/unaligned.h>
#include "inv_mpu_iio.h"
/**
@ -121,7 +120,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
struct inv_mpu6050_state *st = iio_priv(indio_dev);
size_t bytes_per_datum;
int result;
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
u16 fifo_count;
s64 timestamp;
int int_status;
@ -160,11 +158,11 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
* read fifo_count register to know how many bytes are inside the FIFO
* right now
*/
result = regmap_bulk_read(st->map, st->reg->fifo_count_h, data,
INV_MPU6050_FIFO_COUNT_BYTE);
result = regmap_bulk_read(st->map, st->reg->fifo_count_h,
st->data, INV_MPU6050_FIFO_COUNT_BYTE);
if (result)
goto end_session;
fifo_count = get_unaligned_be16(&data[0]);
fifo_count = be16_to_cpup((__be16 *)&st->data[0]);
/*
* Handle fifo overflow by resetting fifo.
@ -181,8 +179,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
nb = fifo_count / bytes_per_datum;
inv_mpu6050_update_period(st, pf->timestamp, nb);
for (i = 0; i < nb; ++i) {
result = regmap_bulk_read(st->map, st->reg->fifo_r_w,
data, bytes_per_datum);
result = regmap_noinc_read(st->map, st->reg->fifo_r_w,
st->data, bytes_per_datum);
if (result)
goto flush_fifo;
/* skip first samples if needed */
@ -191,7 +189,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
continue;
}
timestamp = inv_mpu6050_get_timestamp(st);
iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp);
iio_push_to_buffers_with_timestamp(indio_dev, st->data, timestamp);
}
end_session:

View File

@ -383,6 +383,7 @@ struct st_lsm6dsx_sensor {
* @iio_devs: Pointers to acc/gyro iio_dev instances.
* @settings: Pointer to the specific sensor settings in use.
* @orientation: sensor chip orientation relative to main hardware.
* @scan: Temporary buffers used to align data before iio_push_to_buffers()
*/
struct st_lsm6dsx_hw {
struct device *dev;
@ -411,6 +412,11 @@ struct st_lsm6dsx_hw {
const struct st_lsm6dsx_settings *settings;
struct iio_mount_matrix orientation;
/* Ensure natural alignment of buffer elements */
struct {
__le16 channels[3];
s64 ts __aligned(8);
} scan[3];
};
static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = {

View File

@ -353,9 +353,6 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
int err, sip, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset;
u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
u8 ext_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
bool reset_ts = false;
__le16 fifo_status;
s64 ts = 0;
@ -416,19 +413,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) {
if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
memcpy(gyro_buff, &hw->buff[offset],
ST_LSM6DSX_SAMPLE_SIZE);
offset += ST_LSM6DSX_SAMPLE_SIZE;
memcpy(hw->scan[ST_LSM6DSX_ID_GYRO].channels,
&hw->buff[offset],
sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels));
offset += sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels);
}
if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
memcpy(acc_buff, &hw->buff[offset],
ST_LSM6DSX_SAMPLE_SIZE);
offset += ST_LSM6DSX_SAMPLE_SIZE;
memcpy(hw->scan[ST_LSM6DSX_ID_ACC].channels,
&hw->buff[offset],
sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels));
offset += sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels);
}
if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
memcpy(ext_buff, &hw->buff[offset],
ST_LSM6DSX_SAMPLE_SIZE);
offset += ST_LSM6DSX_SAMPLE_SIZE;
memcpy(hw->scan[ST_LSM6DSX_ID_EXT0].channels,
&hw->buff[offset],
sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels));
offset += sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels);
}
if (ts_sip-- > 0) {
@ -458,19 +458,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
iio_push_to_buffers_with_timestamp(
hw->iio_devs[ST_LSM6DSX_ID_GYRO],
gyro_buff, gyro_sensor->ts_ref + ts);
&hw->scan[ST_LSM6DSX_ID_GYRO],
gyro_sensor->ts_ref + ts);
gyro_sip--;
}
if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
iio_push_to_buffers_with_timestamp(
hw->iio_devs[ST_LSM6DSX_ID_ACC],
acc_buff, acc_sensor->ts_ref + ts);
&hw->scan[ST_LSM6DSX_ID_ACC],
acc_sensor->ts_ref + ts);
acc_sip--;
}
if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
iio_push_to_buffers_with_timestamp(
hw->iio_devs[ST_LSM6DSX_ID_EXT0],
ext_buff, ext_sensor->ts_ref + ts);
&hw->scan[ST_LSM6DSX_ID_EXT0],
ext_sensor->ts_ref + ts);
ext_sip--;
}
sip++;
@ -555,7 +558,14 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
{
u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
u16 fifo_len, fifo_diff_mask;
u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE], tag;
/*
* Alignment needed as this can ultimately be passed to a
* call to iio_push_to_buffers_with_timestamp() which
* must be passed a buffer that is aligned to 8 bytes so
* as to allow insertion of a naturally aligned timestamp.
*/
u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8);
u8 tag;
bool reset_ts = false;
int i, err, read_len;
__le16 fifo_status;

Some files were not shown because too many files have changed in this diff Show More