1st set of IIO new device support, features and cleanups for the 6.3 cycle

The usual mixed bag. So far this has been a quiet cycle for IIO.
 
 New device support
 * adi,ad8686
   - Add support for the AD5337 DAC - ID and 8 bit channel support.
 * maxim,max5522
   - New driver for this 2 channel DAC.
 * nxp,imx93-adc
   - New driver for this SoC ADC which is a fresh IP that will probably
     turn up in additional SoCs going forwards.
 * st,magn
   - Add support for magnetometer part of LSM303C which is very similar
     to standalone LIS3MDL already supported.
 * ti,ads7924
   - New driver for this 4 channel, 12-bit I2C ADC.
 * ti,lmp92064
   - New driver for this 12 bit SPI ADC.
 * ti,tmag5273
   - New driver for this 3D Hall-Effect Sensor.
 
 Features
 * core
   - Add a standard structure for the value pairs in IIO_VAL_INT_PLUS_MICRO
     available attributes and similar.
 * cirrus,ep93xx
   - Add DT binding docs and convert driver to DT based probing.
   - Enable testing building with CONFIG_COMPILE_TEST.
 * st,stm32-dfsdm
   - Enable ID register support for discovery of hardware capabilities on
     some devices.
 
 Cleanups and minor fixes
 * core
   - Drop the custom iio_sysfs_match_string_with_gaps().
     The special ability of this function to skip gaps in an array
     was never used by any upstream driver.
   - Sort headers whilst touching this file.
 * tools
   - Fix memory leak in iio_utils.c
 * various
   - leftover i2c probe_new() conversions.
   - scnprintf() -> sysfs_emit() cleanups.
   - hand rolled devm enables -> devm_regulator[_bulk]_get_enable()
   - typo fixes
   - dt-binding cleanup (whitespace, excess quotes and similar)
 * adi,ad7746
   - Set variable without pointless conditional.
 * fsl,mma9551
   - Squash false positives about use of uninitialized variable where
     garbage undergoes an endian conversion before being ignored.
 * measspec,ms5611
   - Switch to fully devm_ managed probe() and so drop explicit remove()
 * qcom,spmi-adc
   - Use dev_err_probe() to suppress deferred print.
 * qcom,spmi-adc5
   - Define a missing channel used for battery identification.
 * qcom,spmi-iadc
   - Document a compatible seen in wild.
 * semtech,sx9360
   - Fix units on semtech,resolution dt-binding.
 * sensiron,scd30
   - dev_err_probe() usage to simplify error paths a little.
 * st,lsm6dsx
   - Add missing mount matrix for the gyro IIO device.
 * taos,tsl2563
   - Respect firmware configured interrupt polarity if present.
   - Use i2c_smbus_write_word_data() in a few cases not previously covered.
   - Factor out duplicated interrupt configuration.
   - Switch to GENMASK() / BIT() from hand coded equivalents.
   - Tidy up unused definitions.
   - Use dev_err_probe() as appropriate.
   - Drop platform_data as no in kernel users and there are better ways to
     do equivalent if any are added.
   - Add local struct device variable to tidy up code.
   - Avoid dance via i2c_client to get the drvdata.
   - Tidy up headers ordering and Makefile ordering.
 * ti,adc128s052
   - Use new spi_get_device_match_data().
   - Drop ACPI_PTR() protection.
   - Sort headers whilst here.
   - Use asm instead of incorrect include of asm-generic/unaligned.h
 * vishay,vcn4000
   - Interrupt support for vcnl4040 (lots of refactoring needed)
 * xilinx,ams
   - Use fwnode_device_is_compatible() instead of open coding it.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmPb+A4RHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0FoiXQw/+N0ubxewmq7dUfhgzTv2GLjhNBlVJXgC0
 GyXNEF3r2PMmKHQCpUHcJo2NxsOx4tpYhb0J61kuaCjBlRR3ON+KRKNWK+PLVGZh
 I/ljRDxHo0vw9RQs1d+MRZAobZDVkEvJOoovtQC4Xna8vs+HDNVgpiQA/xVCHTF4
 2qxqlRMloTpI4RprLTu6oeDgCthX3RcMM9yw+9N2dcQBw1MxqEZzkJej2dOJncz7
 AJ7Wtw62EDhG+rOaWQHNUMTxOxVBZkJd3KEvc2aKDT8D08iZRtpWCGauaOrRn6Ss
 IddopUW7ihAyyxDYXxLzSRJLs4XJ7t5HlKUJX4tSyuoMU/roPP8ACYte5SbiC9eD
 wJ65wWQqkCIhgOD6KP2Q44GYDtWCARioun181Et4mcJTPduUiKZxRhyD6aiXcLGr
 vJWaDcOmu1OtUbM57cNDaft3bEi8qh1+uY05ex7TRyonlw+d9QQvVBkaCWBvJwIm
 DHJf6p9V6srxHhpsQziG3xYHzacc4GNP7+nr/rQw7lvatJYEYujUJEKfJ1QsDn9G
 gNMkZeSga1b2Tsvg4InNPfrzO+K3XlT1HSF2nBZE9+o+w++5oX3DQng+2nnapzL0
 jTTfpw6B4p40hbJB0bykfoy+XeDpgPhacUZvWwKmwLIy2/LnsorJgIc9aNkOfsvx
 a+/m7/8/zaM=
 =Dfec
 -----END PGP SIGNATURE-----

Merge tag 'iio-for-6.3a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-next

Jonathan writes:

1st set of IIO new device support, features and cleanups for the 6.3 cycle

The usual mixed bag. So far this has been a quiet cycle for IIO.

New device support
* adi,ad8686
  - Add support for the AD5337 DAC - ID and 8 bit channel support.
* maxim,max5522
  - New driver for this 2 channel DAC.
* nxp,imx93-adc
  - New driver for this SoC ADC which is a fresh IP that will probably
    turn up in additional SoCs going forwards.
* st,magn
  - Add support for magnetometer part of LSM303C which is very similar
    to standalone LIS3MDL already supported.
* ti,ads7924
  - New driver for this 4 channel, 12-bit I2C ADC.
* ti,lmp92064
  - New driver for this 12 bit SPI ADC.
* ti,tmag5273
  - New driver for this 3D Hall-Effect Sensor.

Features
* core
  - Add a standard structure for the value pairs in IIO_VAL_INT_PLUS_MICRO
    available attributes and similar.
* cirrus,ep93xx
  - Add DT binding docs and convert driver to DT based probing.
  - Enable testing building with CONFIG_COMPILE_TEST.
* st,stm32-dfsdm
  - Enable ID register support for discovery of hardware capabilities on
    some devices.

Cleanups and minor fixes
* core
  - Drop the custom iio_sysfs_match_string_with_gaps().
    The special ability of this function to skip gaps in an array
    was never used by any upstream driver.
  - Sort headers whilst touching this file.
* tools
  - Fix memory leak in iio_utils.c
* various
  - leftover i2c probe_new() conversions.
  - scnprintf() -> sysfs_emit() cleanups.
  - hand rolled devm enables -> devm_regulator[_bulk]_get_enable()
  - typo fixes
  - dt-binding cleanup (whitespace, excess quotes and similar)
* adi,ad7746
  - Set variable without pointless conditional.
* fsl,mma9551
  - Squash false positives about use of uninitialized variable where
    garbage undergoes an endian conversion before being ignored.
* measspec,ms5611
  - Switch to fully devm_ managed probe() and so drop explicit remove()
* qcom,spmi-adc
  - Use dev_err_probe() to suppress deferred print.
* qcom,spmi-adc5
  - Define a missing channel used for battery identification.
* qcom,spmi-iadc
  - Document a compatible seen in wild.
* semtech,sx9360
  - Fix units on semtech,resolution dt-binding.
* sensiron,scd30
  - dev_err_probe() usage to simplify error paths a little.
* st,lsm6dsx
  - Add missing mount matrix for the gyro IIO device.
* taos,tsl2563
  - Respect firmware configured interrupt polarity if present.
  - Use i2c_smbus_write_word_data() in a few cases not previously covered.
  - Factor out duplicated interrupt configuration.
  - Switch to GENMASK() / BIT() from hand coded equivalents.
  - Tidy up unused definitions.
  - Use dev_err_probe() as appropriate.
  - Drop platform_data as no in kernel users and there are better ways to
    do equivalent if any are added.
  - Add local struct device variable to tidy up code.
  - Avoid dance via i2c_client to get the drvdata.
  - Tidy up headers ordering and Makefile ordering.
* ti,adc128s052
  - Use new spi_get_device_match_data().
  - Drop ACPI_PTR() protection.
  - Sort headers whilst here.
  - Use asm instead of incorrect include of asm-generic/unaligned.h
* vishay,vcn4000
  - Interrupt support for vcnl4040 (lots of refactoring needed)
* xilinx,ams
  - Use fwnode_device_is_compatible() instead of open coding it.

* tag 'iio-for-6.3a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (71 commits)
  iio: adc: ad7291: Fix indentation error by adding extra spaces
  iio: accel: mma9551_core: Prevent uninitialized variable in mma9551_read_config_word()
  iio: accel: mma9551_core: Prevent uninitialized variable in mma9551_read_status_word()
  dt-bindings: iio/proximity: semtech,sx9360: Fix 'semtech,resolution' type
  iio: imu: fix spdx format
  iio: adc: imx93: Fix spelling mistake "geting" -> "getting"
  dt-bindings: iio: cleanup examples - indentation
  dt-bindings: iio: use lowercase hex in examples
  dt-bindings: iio: correct node names in examples
  dt-bindings: iio: minor whitespace cleanups
  dt-bindings: iio: drop unneeded quotes
  dt-bindings: iio: adc: Add NXP IMX93 ADC
  iio: adc: add imx93 adc support
  dt-bindings: iio: adc: add Texas Instruments ADS7924
  iio: adc: ti-ads7924: add Texas Instruments ADS7924 driver
  iio: imu: st_lsm6dsx: add 'mount_matrix' sysfs entry to gyro channel.
  iio: imu: st_lsm6dsx: fix naming of 'struct iio_info' in st_lsm6dsx_shub.c.
  iio: light: vcnl4000: Add interrupt support for vcnl4040
  iio: light: vcnl4000: Make irq handling more generic
  iio: light: vcnl4000: Prepare for more generic setup
  ...
This commit is contained in:
Greg Kroah-Hartman 2023-02-03 07:01:54 +01:00
commit 196db6bb44
133 changed files with 4002 additions and 1031 deletions

View file

@ -41,7 +41,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;

View file

@ -39,7 +39,7 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;

View file

@ -59,7 +59,7 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
i2c {
#address-cells = <1>;
#size-cells = <0>;

View file

@ -49,7 +49,7 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
i2c {
#address-cells = <1>;
#size-cells = <0>;
@ -64,7 +64,7 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;

View file

@ -58,34 +58,34 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
/* Example for a I2C device node */
accelerometer@1d {
compatible = "adi,adxl355";
reg = <0x1d>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "DRDY";
};
/* Example for a I2C device node */
accelerometer@1d {
compatible = "adi,adxl355";
reg = <0x1d>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "DRDY";
};
};
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
accelerometer@0 {
compatible = "adi,adxl355";
reg = <0>;
spi-max-frequency = <1000000>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "DRDY";
};
accelerometer@0 {
compatible = "adi,adxl355";
reg = <0>;
spi-max-frequency = <1000000>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "DRDY";
};
};

View file

@ -37,32 +37,32 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
#address-cells = <1>;
#size-cells = <0>;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
/* Example for a I2C device node */
accelerometer@53 {
compatible = "adi,adxl372";
reg = <0x53>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
};
/* Example for a I2C device node */
accelerometer@53 {
compatible = "adi,adxl372";
reg = <0x53>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
};
};
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
#address-cells = <1>;
#size-cells = <0>;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
accelerometer@0 {
compatible = "adi,adxl372";
reg = <0>;
spi-max-frequency = <1000000>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
};
accelerometer@0 {
compatible = "adi,adxl372";
reg = <0>;
spi-max-frequency = <1000000>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
};
};

View file

@ -36,7 +36,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;

View file

@ -44,7 +44,7 @@ examples:
accel@f {
compatible = "kionix,kxtf9";
reg = <0x0F>;
reg = <0xf>;
mount-matrix = "0", "1", "0",
"1", "0", "0",
"0", "0", "1";

View file

@ -1,9 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: "http://devicetree.org/schemas/iio/accel/memsensing,msa311.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/iio/accel/memsensing,msa311.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MEMSensing digital 3-Axis accelerometer

View file

@ -50,7 +50,7 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
i2c {
#address-cells = <1>;
#size-cells = <0>;
@ -65,7 +65,7 @@ examples:
};
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;

View file

@ -44,11 +44,11 @@ examples:
#size-cells = <0>;
adc@2f {
compatible = "adi,ad7091r5";
reg = <0x2f>;
compatible = "adi,ad7091r5";
reg = <0x2f>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpio>;
};
};
...

View file

@ -61,7 +61,7 @@ required:
patternProperties:
"^channel@([0-9]|1[0-5])$":
$ref: "adc.yaml"
$ref: adc.yaml
type: object
description: |
Represents the external channels which are connected to the ADC.

View file

@ -99,26 +99,26 @@ unevaluatedProperties: false
examples:
- |
spi0 {
#address-cells = <1>;
#size-cells = <0>;
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7192";
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpol;
spi-cpha;
clocks = <&ad7192_mclk>;
clock-names = "mclk";
interrupts = <25 0x2>;
interrupt-parent = <&gpio>;
dvdd-supply = <&dvdd>;
avdd-supply = <&avdd>;
adc@0 {
compatible = "adi,ad7192";
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpol;
spi-cpha;
clocks = <&ad7192_mclk>;
clock-names = "mclk";
interrupts = <25 0x2>;
interrupt-parent = <&gpio>;
dvdd-supply = <&dvdd>;
avdd-supply = <&avdd>;
adi,refin2-pins-enable;
adi,rejection-60-Hz-enable;
adi,buffer-enable;
adi,burnout-currents-enable;
adi,refin2-pins-enable;
adi,rejection-60-Hz-enable;
adi,buffer-enable;
adi,burnout-currents-enable;
};
};

View file

@ -43,7 +43,7 @@ required:
patternProperties:
"^channel@[0-7]$":
$ref: "adc.yaml"
$ref: adc.yaml
type: object
description: |
Represents the external channels which are connected to the ADC.

View file

@ -112,30 +112,30 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7606-8";
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpol;
spi-cpha;
compatible = "adi,ad7606-8";
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpol;
spi-cpha;
avcc-supply = <&adc_vref>;
avcc-supply = <&adc_vref>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpio>;
adi,conversion-start-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
adi,first-data-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
adi,oversampling-ratio-gpios = <&gpio 18 GPIO_ACTIVE_HIGH>,
<&gpio 23 GPIO_ACTIVE_HIGH>,
<&gpio 26 GPIO_ACTIVE_HIGH>;
standby-gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
adi,sw-mode;
adi,conversion-start-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
adi,first-data-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
adi,oversampling-ratio-gpios = <&gpio 18 GPIO_ACTIVE_HIGH>,
<&gpio 23 GPIO_ACTIVE_HIGH>,
<&gpio 26 GPIO_ACTIVE_HIGH>;
standby-gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
adi,sw-mode;
};
};
...

View file

@ -72,7 +72,7 @@ additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;

View file

@ -57,17 +57,17 @@ additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
adc1: adc@28 {
reg = <0x28>;
compatible = "adi,ad7991";
interrupts = <13 2>;
interrupt-parent = <&gpio6>;
adc1: adc@28 {
reg = <0x28>;
compatible = "adi,ad7991";
interrupts = <13 2>;
interrupt-parent = <&gpio6>;
vcc-supply = <&vcc_3v3>;
vref-supply = <&adc_vref>;
vcc-supply = <&vcc_3v3>;
vref-supply = <&adc_vref>;
};
};
...

View file

@ -64,10 +64,10 @@ examples:
#size-cells = <0>;
adc@0 {
compatible = "adi,ad9467";
reg = <0>;
clocks = <&adc_clk>;
clock-names = "adc-clk";
compatible = "adi,ad9467";
reg = <0>;
clocks = <&adc_clk>;
clock-names = "adc-clk";
};
};
...

View file

@ -51,11 +51,11 @@ additionalProperties: false
examples:
- |
axi-adc@44a00000 {
compatible = "adi,axi-adc-10.0.a";
reg = <0x44a00000 0x10000>;
dmas = <&rx_dma 0>;
dma-names = "rx";
compatible = "adi,axi-adc-10.0.a";
reg = <0x44a00000 0x10000>;
dmas = <&rx_dma 0>;
dma-names = "rx";
adi,adc-dev = <&spi_adc>;
adi,adc-dev = <&spi_adc>;
};
...

View file

@ -41,7 +41,7 @@ properties:
description: Startup time expressed in ms, it depends on SoC.
atmel,trigger-edge-type:
$ref: '/schemas/types.yaml#/definitions/uint32'
$ref: /schemas/types.yaml#/definitions/uint32
description:
One of possible edge types for the ADTRG hardware trigger pin.
When the specific edge type is detected, the conversion will

View file

@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: "http://devicetree.org/schemas/iio/adc/avia-hx711.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/iio/adc/avia-hx711.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: AVIA HX711 ADC chip for weight cells

View file

@ -0,0 +1,47 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/cirrus,ep9301-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Cirrus Logic EP930x internal ADC
description: |
Cirrus Logic EP9301/EP9302 SoCs' internal ADC block.
User's manual:
https://cdn.embeddedts.com/resource-attachments/ts-7000_ep9301-ug.pdf
maintainers:
- Alexander Sverdlin <alexander.sverdlin@gmail.com>
properties:
compatible:
const: cirrus,ep9301-adc
reg:
maxItems: 1
clocks:
maxItems: 1
interrupts:
maxItems: 1
required:
- compatible
- reg
- clocks
additionalProperties: false
examples:
- |
adc: adc@80900000 {
compatible = "cirrus,ep9301-adc";
reg = <0x80900000 0x28>;
clocks = <&syscon 24>;
interrupt-parent = <&vic1>;
interrupts = <30>;
};
...

View file

@ -2,8 +2,8 @@
# Copyright 2019-2020 Artur Rojek
%YAML 1.2
---
$id: "http://devicetree.org/schemas/iio/adc/ingenic,adc.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/iio/adc/ingenic,adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Ingenic JZ47xx ADC controller IIO
@ -78,14 +78,14 @@ examples:
#include <dt-bindings/iio/adc/ingenic,adc.h>
adc@10070000 {
compatible = "ingenic,jz4740-adc";
#io-channel-cells = <1>;
compatible = "ingenic,jz4740-adc";
#io-channel-cells = <1>;
reg = <0x10070000 0x30>;
reg = <0x10070000 0x30>;
clocks = <&cgu JZ4740_CLK_ADC>;
clock-names = "adc";
clocks = <&cgu JZ4740_CLK_ADC>;
clock-names = "adc";
interrupt-parent = <&intc>;
interrupts = <18>;
interrupt-parent = <&intc>;
interrupts = <18>;
};

View file

@ -54,8 +54,8 @@ examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
maxadc: adc@0 {
compatible = "maxim,max1027";
reg = <0>;

View file

@ -10,7 +10,7 @@ maintainers:
- Jonathan Cameron <jic23@kernel.org>
description: |
Family of simple ADCs with i2c inteface and internal references.
Family of simple ADCs with i2c interface and internal references.
properties:
compatible:

View file

@ -54,8 +54,8 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "maxim,max1241";

View file

@ -10,7 +10,7 @@ maintainers:
- Jonathan Cameron <jic23@kernel.org>
description: |
Family of ADCs with i2c inteface, internal references and threshold
Family of ADCs with i2c interface, internal references and threshold
monitoring.
properties:

View file

@ -2,8 +2,8 @@
# Copyright 2019 Marcus Folkesson <marcus.folkesson@gmail.com>
%YAML 1.2
---
$id: "http://devicetree.org/schemas/iio/adc/microchip,mcp3911.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/iio/adc/microchip,mcp3911.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip MCP3911 Dual channel analog front end (ADC)

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/nxp,imx93-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP iMX93 ADC
maintainers:
- Haibo Chen <haibo.chen@nxp.com>
description:
The ADC on iMX93 is a 8-channel 12-bit 1MS/s ADC with 4 channels
connected to pins. it support normal and inject mode, include
One-Shot and Scan (continuous) conversions. Programmable DMA
enables for each channel Also this ADC contain alternate analog
watchdog thresholds, select threshold through input ports. And
also has Self-test logic and Software-initiated calibration.
properties:
compatible:
const: nxp,imx93-adc
reg:
maxItems: 1
interrupts:
items:
- description: WDGnL, watchdog threshold interrupt requests.
- description: WDGnH, watchdog threshold interrupt requests.
- description: normal conversion, include EOC (End of Conversion),
ECH (End of Chain), JEOC (End of Injected Conversion) and
JECH (End of injected Chain).
- description: Self-testing Interrupts.
clocks:
maxItems: 1
clock-names:
const: ipg
vref-supply:
description:
The reference voltage which used to establish channel scaling.
"#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/imx93-clock.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
soc {
#address-cells = <1>;
#size-cells = <1>;
adc@44530000 {
compatible = "nxp,imx93-adc";
reg = <0x44530000 0x10000>;
interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk IMX93_CLK_ADC1_GATE>;
clock-names = "ipg";
vref-supply = <&reg_vref_1v8>;
#io-channel-cells = <1>;
};
};
...

View file

@ -160,7 +160,7 @@ examples:
};
ref_muxoff: adc-channel@f {
reg = <0x00 0x0f>;
};
};
};
};
...

View file

@ -20,6 +20,7 @@ properties:
compatible:
items:
- enum:
- qcom,pm8226-iadc
- qcom,pm8941-iadc
- const: qcom,spmi-iadc
@ -49,7 +50,7 @@ additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spmi_bus {
spmi {
#address-cells = <1>;
#size-cells = <0>;
pmic_iadc: adc@3600 {

View file

@ -40,12 +40,12 @@ additionalProperties: false
examples:
- |
pmic {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
pmic_rradc: adc@4500 {
compatible = "qcom,pmi8998-rradc";
reg = <0x4500>;
#io-channel-cells = <1>;
};
pmic_rradc: adc@4500 {
compatible = "qcom,pmi8998-rradc";
reg = <0x4500>;
#io-channel-cells = <1>;
};
};

View file

@ -69,7 +69,7 @@ required:
patternProperties:
"^channel@[0-7]$":
$ref: "adc.yaml"
$ref: adc.yaml
type: object
description: |
Represents the external channels which are connected to the ADC.

View file

@ -52,7 +52,7 @@ properties:
vdd-supply: true
samsung,syscon-phandle:
$ref: '/schemas/types.yaml#/definitions/phandle'
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to the PMU system controller node (to access the ADC_PHY
register on Exynos3250/4x12/5250/5420/5800).
@ -142,7 +142,7 @@ examples:
pullup-ohm = <47000>;
pulldown-ohm = <0>;
io-channels = <&adc 4>;
};
};
};
- |
@ -150,7 +150,7 @@ examples:
adc@126c0000 {
compatible = "samsung,exynos3250-adc";
reg = <0x126C0000 0x100>;
reg = <0x126c0000 0x100>;
interrupts = <0 137 0>;
#io-channel-cells = <1>;

View file

@ -1,8 +1,8 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/iio/adc/st,stm32-adc.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/iio/adc/st,stm32-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics STM32 ADC
@ -80,7 +80,7 @@ properties:
description:
Phandle to system configuration controller. It can be used to control the
analog circuitry on stm32mp1.
$ref: "/schemas/types.yaml#/definitions/phandle-array"
$ref: /schemas/types.yaml#/definitions/phandle-array
interrupt-controller: true
@ -341,7 +341,7 @@ patternProperties:
patternProperties:
"^channel@([0-9]|1[0-9])$":
type: object
$ref: "adc.yaml"
$ref: adc.yaml
description: Represents the external channels which are connected to the ADC.
properties:

View file

@ -35,10 +35,8 @@ additionalProperties: false
examples:
- |
stmpe {
stmpe_adc {
compatible = "st,stmpe-adc";
st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */
};
adc {
compatible = "st,stmpe-adc";
st,norequest-mask = <0x0f>; /* dont use ADC CH3-0 */
};
...

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/ti,adc081c.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI Single-channel I2C ADCs
maintainers:
- Jonathan Cameron <jic23@kernel.org>
- Lars-Peter Clausen <lars@metafoo.de>
description: |
Single-channel ADC supporting 8, 10, or 12-bit samples and high/low alerts.
properties:
compatible:
enum:
- ti,adc081c
- ti,adc101c
- ti,adc121c
reg:
maxItems: 1
interrupts:
maxItems: 1
vref-supply:
description:
Regulator for the combined power supply and voltage reference
"#io-channel-cells":
const: 1
required:
- compatible
- reg
- vref-supply
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
adc@52 {
compatible = "ti,adc081c";
reg = <0x52>;
vref-supply = <&reg_2p5v>;
};
};
...

View file

@ -104,12 +104,12 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
reg = <0>;
};
channel@4 {
reg = <4>;
ti,gain = <3>;
ti,datarate = <5>;
reg = <4>;
ti,gain = <3>;
ti,datarate = <5>;
};
};
};

View file

@ -77,7 +77,7 @@ required:
patternProperties:
"^channel@([0-7])$":
$ref: "adc.yaml"
$ref: adc.yaml
type: object
description: |
Represents the external channels which are connected to the ADC.

View file

@ -0,0 +1,110 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,ads7924.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI ADS7924 4 channels 12 bits I2C analog to digital converter
maintainers:
- Hugo Villeneuve <hvilleneuve@dimonoff.com>
description: |
Texas Instruments ADS7924 4 channels 12 bits I2C analog to digital converter
Specifications:
https://www.ti.com/lit/gpn/ads7924
properties:
compatible:
const: ti,ads7924
reg:
maxItems: 1
vref-supply:
description:
The regulator supply for the ADC reference voltage (AVDD)
reset-gpios:
maxItems: 1
interrupts:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 0
"#io-channel-cells":
const: 1
patternProperties:
"^channel@[0-3]+$":
$ref: adc.yaml
description: |
Represents the external channels which are connected to the ADC.
properties:
reg:
description: |
The channel number. It can have up to 4 channels numbered from 0 to 3.
items:
- minimum: 0
maximum: 3
label: true
required:
- reg
additionalProperties: false
additionalProperties: false
required:
- compatible
- reg
- vref-supply
- "#address-cells"
- "#size-cells"
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
adc@48 {
compatible = "ti,ads7924";
reg = <0x48>;
vref-supply = <&ads7924_reg>;
reset-gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
interrupt-parent = <&gpio>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
label = "CH0";
};
channel@1 {
reg = <1>;
label = "CH1";
};
channel@2 {
reg = <2>;
label = "CH2";
};
channel@3 {
reg = <3>;
label = "CH3";
};
};
};
...

View file

@ -0,0 +1,70 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,lmp92064.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments LMP92064 Precision Current and Voltage Sensor.
maintainers:
- Leonard Göhrs <l.goehrs@pengutronix.de>
description: |
The LMP92064 is a two channel ADC intended for combined voltage and current
measurements.
The device contains two ADCs to allow simultaneous sampling of voltage and
current and thus of instantaneous power consumption.
properties:
compatible:
enum:
- ti,lmp92064
reg:
maxItems: 1
vdd-supply:
description: Regulator that provides power to the main part of the chip
vdig-supply:
description: |
Regulator that provides power to the digital I/O part of the chip
shunt-resistor-micro-ohms:
description: |
Value of the shunt resistor (in µΩ) connected between INCP and INCN,
across which current is measured. Used to provide correct scaling of the
raw ADC measurement.
reset-gpios:
maxItems: 1
required:
- compatible
- reg
- shunt-resistor-micro-ohms
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "ti,lmp92064";
reg = <0>;
vdd-supply = <&vdd>;
vdig-supply = <&vdd>;
spi-max-frequency = <20000000>;
shunt-resistor-micro-ohms = <15000>;
reset-gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
};
};
...

View file

@ -41,7 +41,7 @@ required:
patternProperties:
"^channel@[0-7]$":
$ref: "adc.yaml"
$ref: adc.yaml
type: object
properties:
@ -83,36 +83,36 @@ examples:
#size-cells = <0>;
channel@0 {
reg = <0>;
reg = <0>;
};
channel@1 {
reg = <1>;
settling-time-us = <700>;
oversampling-ratio = <5>;
reg = <1>;
settling-time-us = <700>;
oversampling-ratio = <5>;
};
channel@2 {
reg = <2>;
reg = <2>;
};
channel@3 {
reg = <3>;
settling-time-us = <700>;
oversampling-ratio = <5>;
reg = <3>;
settling-time-us = <700>;
oversampling-ratio = <5>;
};
channel@4 {
reg = <4>;
settling-time-us = <700>;
oversampling-ratio = <5>;
reg = <4>;
settling-time-us = <700>;
oversampling-ratio = <5>;
};
channel@5 {
reg = <5>;
settling-time-us = <700>;
oversampling-ratio = <5>;
reg = <5>;
settling-time-us = <700>;
oversampling-ratio = <5>;
};
channel@6 {
reg = <6>;
reg = <6>;
};
channel@7 {
reg = <7>;
reg = <7>;
};
};
};

View file

@ -192,26 +192,26 @@ additionalProperties: false
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
ad3552r@0 {
compatible = "adi,ad3552r";
reg = <0>;
spi-max-frequency = <20000000>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
adi,output-range-microvolt = <0 10000000>;
};
channel@1 {
reg = <1>;
custom-output-range-config {
adi,gain-offset = <5>;
adi,gain-scaling-p-inv-log2 = <1>;
adi,gain-scaling-n-inv-log2 = <2>;
adi,rfb-ohms = <1>;
};
#address-cells = <1>;
#size-cells = <0>;
ad3552r@0 {
compatible = "adi,ad3552r";
reg = <0>;
spi-max-frequency = <20000000>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
adi,output-range-microvolt = <0 10000000>;
};
channel@1 {
reg = <1>;
custom-output-range-config {
adi,gain-offset = <5>;
adi,gain-scaling-p-inv-log2 = <1>;
adi,gain-scaling-n-inv-log2 = <2>;
adi,rfb-ohms = <1>;
};
};
};
};

View file

@ -12,6 +12,7 @@ maintainers:
description: |
DAC devices supporting both SPI and I2C interfaces.
properties:
compatible:
enum:

View file

@ -33,6 +33,7 @@ properties:
- description: I2C devices
enum:
- adi,ad5311r
- adi,ad5337r
- adi,ad5338r
- adi,ad5671r
- adi,ad5675r

View file

@ -51,15 +51,15 @@ additionalProperties: false
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
ad5766@0 {
compatible = "adi,ad5766";
output-range-microvolts = <(-5000000) 5000000>;
reg = <0>;
spi-cpol;
spi-max-frequency = <1000000>;
reset-gpios = <&gpio 22 0>;
};
};
ad5766@0 {
compatible = "adi,ad5766";
output-range-microvolts = <(-5000000) 5000000>;
reg = <0>;
spi-cpol;
spi-max-frequency = <1000000>;
reset-gpios = <&gpio 22 0>;
};
};

View file

@ -147,49 +147,49 @@ unevaluatedProperties: false
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
spi {
#address-cells = <1>;
#size-cells = <0>;
ad5770r@0 {
compatible = "adi,ad5770r";
reg = <0>;
spi-max-frequency = <1000000>;
vref-supply = <&vref>;
adi,external-resistor;
reset-gpios = <&gpio 22 0>;
#address-cells = <1>;
#size-cells = <0>;
ad5770r@0 {
compatible = "adi,ad5770r";
reg = <0>;
spi-max-frequency = <1000000>;
vref-supply = <&vref>;
adi,external-resistor;
reset-gpios = <&gpio 22 0>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
adi,range-microamp = <0 300000>;
};
channel@0 {
reg = <0>;
adi,range-microamp = <0 300000>;
};
channel@1 {
reg = <1>;
adi,range-microamp = <0 140000>;
};
channel@1 {
reg = <1>;
adi,range-microamp = <0 140000>;
};
channel@2 {
reg = <2>;
adi,range-microamp = <0 55000>;
};
channel@2 {
reg = <2>;
adi,range-microamp = <0 55000>;
};
channel@3 {
reg = <3>;
adi,range-microamp = <0 45000>;
};
channel@3 {
reg = <3>;
adi,range-microamp = <0 45000>;
};
channel@4 {
reg = <4>;
adi,range-microamp = <0 45000>;
};
channel@4 {
reg = <4>;
adi,range-microamp = <0 45000>;
};
channel@5 {
reg = <5>;
adi,range-microamp = <0 45000>;
};
};
channel@5 {
reg = <5>;
adi,range-microamp = <0 45000>;
};
};
};
...

View file

@ -116,32 +116,32 @@ examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
ltc2688: ltc2688@0 {
compatible = "adi,ltc2688";
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
ltc2688: ltc2688@0 {
compatible = "adi,ltc2688";
reg = <0>;
vcc-supply = <&vcc>;
iovcc-supply = <&vcc>;
vref-supply = <&vref>;
vcc-supply = <&vcc>;
iovcc-supply = <&vcc>;
vref-supply = <&vref>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
adi,toggle-mode;
adi,overrange;
};
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
adi,toggle-mode;
adi,overrange;
};
channel@1 {
reg = <1>;
adi,output-range-microvolt = <0 10000000>;
channel@1 {
reg = <1>;
adi,output-range-microvolt = <0 10000000>;
clocks = <&clock_tgp3>;
adi,toggle-dither-input = <2>;
};
};
clocks = <&clock_tgp3>;
adi,toggle-dither-input = <2>;
};
};
};
...

View file

@ -2,8 +2,8 @@
# Copyright 2019 Marcus Folkesson <marcus.folkesson@gmail.com>
%YAML 1.2
---
$id: "http://devicetree.org/schemas/iio/dac/lltc,ltc1660.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/iio/dac/lltc,ltc1660.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Linear Technology Micropower octal 8-Bit and 10-Bit DACs

View file

@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
%YAML 1.2
---
$id: "http://devicetree.org/schemas/iio/dac/lltc,ltc2632.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/iio/dac/lltc,ltc2632.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Linear Technology LTC263x 12-/10-/8-Bit Rail-to-Rail DAC
@ -64,14 +64,14 @@ examples:
};
spi {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "lltc,ltc2632-l12";
reg = <0>; /* CS0 */
spi-max-frequency = <1000000>;
vref-supply = <&vref>;
};
dac@0 {
compatible = "lltc,ltc2632-l12";
reg = <0>; /* CS0 */
spi-max-frequency = <1000000>;
vref-supply = <&vref>;
};
};
...

View file

@ -0,0 +1,49 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/maxim,max5522.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Maxim Integrated MAX5522 Dual 10-bit Voltage-Output SPI DACs
maintainers:
- Angelo Dureghello <angelo.dureghello@timesys.com>
- Jonathan Cameron <jic23@kernel.org>
description: |
Datasheet available at:
https://www.analog.com/en/products/max5522.html
properties:
compatible:
const: maxim,max5522
reg:
maxItems: 1
vdd-supply: true
vrefin-supply: true
required:
- compatible
- reg
- vrefin-supply
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "maxim,max5522";
reg = <0>;
vrefin-supply = <&vref>;
};
};
...

View file

@ -1,8 +1,8 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/iio/dac/st,stm32-dac.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/iio/dac/st,stm32-dac.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics STM32 DAC

View file

@ -46,7 +46,7 @@ examples:
dac@4c {
compatible = "ti,dac5571";
reg = <0x4C>;
reg = <0x4c>;
vref-supply = <&vdd_supply>;
};
};

View file

@ -53,16 +53,16 @@ unevaluatedProperties: false
examples:
- |
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;
frequency@0 {
compatible = "adi,adf4371";
reg = <0>;
spi-max-frequency = <1000000>;
clocks = <&adf4371_clkin>;
clock-names = "clkin";
compatible = "adi,adf4371";
reg = <0>;
spi-max-frequency = <1000000>;
clocks = <&adf4371_clkin>;
clock-names = "clkin";
};
};
...

View file

@ -50,13 +50,13 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
gyro@0 {
compatible = "adi,adxrs290";
reg = <0>;
spi-max-frequency = <5000000>;
spi-cpol;
spi-cpha;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
compatible = "adi,adxrs290";
reg = <0>;
spi-max-frequency = <5000000>;
spi-cpol;
spi-cpha;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
};
};
...

View file

@ -65,34 +65,34 @@ examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
i2c {
#address-cells = <1>;
#size-cells = <0>;
gyroscope@20 {
compatible = "nxp,fxas21002c";
reg = <0x20>;
compatible = "nxp,fxas21002c";
reg = <0x20>;
vdd-supply = <&reg_peri_3p15v>;
vddio-supply = <&reg_peri_3p15v>;
vdd-supply = <&reg_peri_3p15v>;
vddio-supply = <&reg_peri_3p15v>;
interrupt-parent = <&gpio1>;
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
interrupt-parent = <&gpio1>;
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
};
};
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;
gyroscope@0 {
compatible = "nxp,fxas21002c";
reg = <0x0>;
compatible = "nxp,fxas21002c";
reg = <0x0>;
spi-max-frequency = <2000000>;
spi-max-frequency = <2000000>;
interrupt-parent = <&gpio2>;
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT2";
interrupt-parent = <&gpio2>;
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT2";
};
};

View file

@ -42,7 +42,7 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
heart_mon@0 {
heart-mon@0 {
compatible = "ti,afe4403";
reg = <0>;
spi-max-frequency = <10000000>;

View file

@ -39,7 +39,7 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
heart_mon@58 {
heart-mon@58 {
compatible = "ti,afe4404";
reg = <0x58>;
tx-supply = <&vbat>;

View file

@ -34,7 +34,7 @@ additionalProperties: false
examples:
- |
humidity_sensor {
humidity-sensor {
compatible = "dht11";
gpios = <&gpio0 6 0>;
};

View file

@ -35,12 +35,12 @@ additionalProperties: false
examples:
- |
i2c0 {
#address-cells = <1>;
#size-cells = <0>;
i2c {
#address-cells = <1>;
#size-cells = <0>;
humidity@40 {
compatible = "ti,hdc2010";
reg = <0x40>;
};
humidity@40 {
compatible = "ti,hdc2010";
reg = <0x40>;
};
};

View file

@ -42,7 +42,7 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;

View file

@ -114,17 +114,17 @@ examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
adis16475: adis16475-3@0 {
compatible = "adi,adis16475-3";
reg = <0>;
spi-cpha;
spi-cpol;
spi-max-frequency = <2000000>;
interrupts = <4 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gpio>;
};
adis16475: adis16475-3@0 {
compatible = "adi,adis16475-3";
reg = <0>;
spi-cpha;
spi-cpol;
spi-max-frequency = <2000000>;
interrupts = <4 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gpio>;
};
};
...

View file

@ -64,16 +64,16 @@ examples:
#size-cells = <0>;
bmi160@68 {
compatible = "bosch,bmi160";
reg = <0x68>;
vdd-supply = <&pm8916_l17>;
vddio-supply = <&pm8916_l6>;
interrupt-parent = <&gpio4>;
interrupts = <12 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
mount-matrix = "0", "1", "0",
"-1", "0", "0",
"0", "0", "1";
compatible = "bosch,bmi160";
reg = <0x68>;
vdd-supply = <&pm8916_l17>;
vddio-supply = <&pm8916_l6>;
interrupt-parent = <&gpio4>;
interrupts = <12 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
mount-matrix = "0", "1", "0",
"-1", "0", "0",
"0", "0", "1";
};
};
- |
@ -84,11 +84,11 @@ examples:
#size-cells = <0>;
bmi160@0 {
compatible = "bosch,bmi160";
reg = <0>;
spi-max-frequency = <10000000>;
interrupt-parent = <&gpio2>;
interrupts = <12 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT2";
compatible = "bosch,bmi160";
reg = <0>;
spi-max-frequency = <10000000>;
interrupt-parent = <&gpio2>;
interrupts = <12 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT2";
};
};

View file

@ -65,35 +65,35 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
i2c {
#address-cells = <1>;
#size-cells = <0>;
icm42605@68 {
compatible = "invensense,icm42605";
reg = <0x68>;
interrupt-parent = <&gpio2>;
interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
vdd-supply = <&vdd>;
vddio-supply = <&vddio>;
compatible = "invensense,icm42605";
reg = <0x68>;
interrupt-parent = <&gpio2>;
interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
vdd-supply = <&vdd>;
vddio-supply = <&vddio>;
};
};
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;
icm42602@0 {
compatible = "invensense,icm42602";
reg = <0>;
spi-max-frequency = <24000000>;
spi-cpha;
spi-cpol;
interrupt-parent = <&gpio1>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
vdd-supply = <&vdd>;
vddio-supply = <&vddio>;
compatible = "invensense,icm42602";
reg = <0>;
spi-max-frequency = <24000000>;
spi-cpha;
spi-cpol;
interrupt-parent = <&gpio1>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
vdd-supply = <&vdd>;
vddio-supply = <&vddio>;
};
};

View file

@ -49,33 +49,33 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
i2c {
#address-cells = <1>;
#size-cells = <0>;
fxos8700@1e {
compatible = "nxp,fxos8700";
reg = <0x1e>;
compatible = "nxp,fxos8700";
reg = <0x1e>;
interrupt-parent = <&gpio2>;
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
interrupt-parent = <&gpio2>;
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
};
};
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
spi {
#address-cells = <1>;
#size-cells = <0>;
fxos8700@0 {
compatible = "nxp,fxos8700";
reg = <0>;
compatible = "nxp,fxos8700";
reg = <0>;
spi-max-frequency = <1000000>;
interrupt-parent = <&gpio1>;
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT2";
spi-max-frequency = <1000000>;
interrupt-parent = <&gpio1>;
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT2";
};
};

View file

@ -63,7 +63,7 @@ properties:
description: if defined provides VDD IO power to the sensor.
st,drdy-int-pin:
$ref: '/schemas/types.yaml#/definitions/uint32'
$ref: /schemas/types.yaml#/definitions/uint32
description: |
The pin on the package that will be used to signal data ready
enum:

View file

@ -0,0 +1,75 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/magnetometer/ti,tmag5273.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI TMAG5273 Low-Power Linear 3D Hall-Effect Sensor
maintainers:
- Gerald Loacker <gerald.loacker@wolfvision.net>
description:
The TI TMAG5273 is a low-power linear 3D Hall-effect sensor. This device
integrates three independent Hall-effect sensors in the X, Y, and Z axes.
The device has an integrated temperature sensor available. The TMAG5273
can be configured through the I2C interface to enable any combination of
magnetic axes and temperature measurements. An integrated angle calculation
engine (CORDIC) provides full 360° angular position information for both
on-axis and off-axis angle measurement topologies. The angle calculation is
performed using two user-selected magnetic axes.
properties:
compatible:
const: ti,tmag5273
reg:
maxItems: 1
"#io-channel-cells":
const: 1
ti,angle-measurement:
$ref: /schemas/types.yaml#/definitions/string
description:
Enables angle measurement in the selected plane.
If not specified, "x-y" will be anables as default.
enum:
- off
- x-y
- y-z
- x-z
vcc-supply:
description:
A regulator providing 1.7 V to 3.6 V supply voltage on the VCC pin,
typically 3.3 V.
interrupts:
description:
The low active interrupt can be configured to be fixed width or latched.
Interrupt events can be configured to be generated from magnetic
thresholds or when a conversion is completed.
maxItems: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
magnetometer@35 {
compatible = "ti,tmag5273";
reg = <0x35>;
#io-channel-cells = <1>;
ti,angle-measurement = "x-z";
vcc-supply = <&vcc3v3>;
};
};
...

View file

@ -91,12 +91,12 @@ examples:
#size-cells = <0>;
magnetometer@2e {
compatible = "yamaha,yas530";
reg = <0x2e>;
vdd-supply = <&ldo1_reg>;
iovdd-supply = <&ldo2_reg>;
reset-gpios = <&gpio6 12 GPIO_ACTIVE_LOW>;
interrupts = <13 IRQ_TYPE_EDGE_RISING>;
compatible = "yamaha,yas530";
reg = <0x2e>;
vdd-supply = <&ldo1_reg>;
iovdd-supply = <&ldo2_reg>;
reset-gpios = <&gpio6 12 GPIO_ACTIVE_LOW>;
interrupts = <13 IRQ_TYPE_EDGE_RISING>;
};
};
@ -105,8 +105,8 @@ examples:
#size-cells = <0>;
magnetometer@2e {
compatible = "yamaha,yas539";
reg = <0x2e>;
vdd-supply = <&ldo1_reg>;
compatible = "yamaha,yas539";
reg = <0x2e>;
vdd-supply = <&ldo1_reg>;
};
};

View file

@ -44,7 +44,7 @@ examples:
potentiometer@2f {
compatible = "adi,ad5272-020";
reg = <0x2F>;
reg = <0x2f>;
reset-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
};
};

View file

@ -39,7 +39,7 @@ examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
i2c {
#address-cells = <1>;
#size-cells = <0>;

View file

@ -60,16 +60,16 @@ examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
#address-cells = <1>;
#size-cells = <0>;
pressure@77 {
compatible = "bosch,bmp085";
reg = <0x77>;
interrupt-parent = <&gpio0>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
vddd-supply = <&foo>;
vdda-supply = <&bar>;
};
i2c {
#address-cells = <1>;
#size-cells = <0>;
pressure@77 {
compatible = "bosch,bmp085";
reg = <0x77>;
interrupt-parent = <&gpio0>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
vddd-supply = <&foo>;
vdda-supply = <&bar>;
};
};

View file

@ -60,7 +60,7 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
lightning@0 {
lightning@0 {
compatible = "ams,as3935";
reg = <0>;
spi-max-frequency = <400000>;

View file

@ -1,7 +1,6 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/proximity/google,cros-ec-mkbp-proximity.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

View file

@ -36,7 +36,7 @@ properties:
const: 1
semtech,resolution:
$ref: /schemas/types.yaml#/definitions/uint32-array
$ref: /schemas/types.yaml#/definitions/uint32
enum: [8, 16, 32, 64, 128, 256, 512, 1024]
description:
Capacitance measurement resolution. For both phases, "reference" and

View file

@ -39,6 +39,7 @@ properties:
- st,lis3lv02dl-accel
- st,lng2dm-accel
- st,lsm303agr-accel
- st,lsm303c-accel
- st,lsm303dl-accel
- st,lsm303dlh-accel
- st,lsm303dlhc-accel
@ -66,6 +67,7 @@ properties:
- st,lis2mdl
- st,lis3mdl-magn
- st,lsm303agr-magn
- st,lsm303c-magn
- st,lsm303dlh-magn
- st,lsm303dlhc-magn
- st,lsm303dlm-magn

View file

@ -472,75 +472,74 @@ examples:
#size-cells = <0>;
temperature-sensor@0 {
compatible = "adi,ltc2983";
reg = <0>;
compatible = "adi,ltc2983";
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
interrupts = <20 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gpio>;
interrupts = <20 IRQ_TYPE_EDGE_RISING>;
interrupt-parent = <&gpio>;
thermocouple@18 {
reg = <18>;
adi,sensor-type = <8>; //Type B
adi,sensor-oc-current-microamp = <10>;
adi,cold-junction-handle = <&diode5>;
};
thermocouple@18 {
reg = <18>;
adi,sensor-type = <8>; //Type B
adi,sensor-oc-current-microamp = <10>;
adi,cold-junction-handle = <&diode5>;
};
diode5: diode@5 {
reg = <5>;
adi,sensor-type = <28>;
};
diode5: diode@5 {
reg = <5>;
adi,sensor-type = <28>;
};
rsense2: rsense@2 {
reg = <2>;
adi,sensor-type = <29>;
adi,rsense-val-milli-ohms = <1200000>; //1.2Kohms
};
rsense2: rsense@2 {
reg = <2>;
adi,sensor-type = <29>;
adi,rsense-val-milli-ohms = <1200000>; //1.2Kohms
};
rtd@14 {
reg = <14>;
adi,sensor-type = <15>; //PT1000
/*2-wire, internal gnd, no current rotation*/
adi,number-of-wires = <2>;
adi,rsense-share;
adi,excitation-current-microamp = <500>;
adi,rsense-handle = <&rsense2>;
};
rtd@14 {
reg = <14>;
adi,sensor-type = <15>; //PT1000
/*2-wire, internal gnd, no current rotation*/
adi,number-of-wires = <2>;
adi,rsense-share;
adi,excitation-current-microamp = <500>;
adi,rsense-handle = <&rsense2>;
};
adc@10 {
reg = <10>;
adi,sensor-type = <30>;
adi,single-ended;
};
adc@10 {
reg = <10>;
adi,sensor-type = <30>;
adi,single-ended;
};
thermistor@12 {
reg = <12>;
adi,sensor-type = <26>; //Steinhart
adi,rsense-handle = <&rsense2>;
adi,custom-steinhart = <0x00F371EC 0x12345678
0x2C0F8733 0x10018C66 0xA0FEACCD
0x90021D99>; //6 entries
};
thermocouple@20 {
reg = <20>;
adi,sensor-type = <9>; //custom thermocouple
adi,single-ended;
adi,custom-thermocouple =
/bits/ 64 <(-50220000) 0>,
/bits/ 64 <(-30200000) 99100000>,
/bits/ 64 <(-5300000) 135400000>,
/bits/ 64 <0 273150000>,
/bits/ 64 <40200000 361200000>,
/bits/ 64 <55300000 522100000>,
/bits/ 64 <88300000 720300000>,
/bits/ 64 <132200000 811200000>,
/bits/ 64 <188700000 922500000>,
/bits/ 64 <460400000 1000000000>; //10 pairs
};
thermistor@12 {
reg = <12>;
adi,sensor-type = <26>; //Steinhart
adi,rsense-handle = <&rsense2>;
adi,custom-steinhart = <0x00f371ec 0x12345678
0x2c0f8733 0x10018c66 0xa0feaccd
0x90021d99>; //6 entries
};
thermocouple@20 {
reg = <20>;
adi,sensor-type = <9>; //custom thermocouple
adi,single-ended;
adi,custom-thermocouple =
/bits/ 64 <(-50220000) 0>,
/bits/ 64 <(-30200000) 99100000>,
/bits/ 64 <(-5300000) 135400000>,
/bits/ 64 <0 273150000>,
/bits/ 64 <40200000 361200000>,
/bits/ 64 <55300000 522100000>,
/bits/ 64 <88300000 720300000>,
/bits/ 64 <132200000 811200000>,
/bits/ 64 <188700000 922500000>,
/bits/ 64 <460400000 1000000000>; //10 pairs
};
};
};
...

View file

@ -43,12 +43,12 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
temp_sensor@0 {
compatible = "maxim,max31865";
reg = <0>;
spi-max-frequency = <400000>;
spi-cpha;
maxim,3-wire;
temperature-sensor@0 {
compatible = "maxim,max31865";
reg = <0>;
spi-max-frequency = <400000>;
spi-cpha;
maxim,3-wire;
};
};
...

View file

@ -1,10 +1,10 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/iio/temperature/ti,tmp117.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
$id: http://devicetree.org/schemas/iio/temperature/ti,tmp117.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: "TI TMP117 - Digital temperature sensor with integrated NV memory"
title: TI TMP117 - Digital temperature sensor with integrated NV memory
description: |
TI TMP117 - Digital temperature sensor with integrated NV memory that supports

View file

@ -2090,8 +2090,10 @@ M: Hartley Sweeten <hsweeten@visionengravers.com>
M: Alexander Sverdlin <alexander.sverdlin@gmail.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/iio/adc/cirrus,ep9301-adc.yaml
F: arch/arm/mach-ep93xx/
F: arch/arm/mach-ep93xx/include/mach/
F: drivers/iio/adc/ep93xx_adc.c
ARM/CLKDEV SUPPORT
M: Russell King <linux@armlinux.org.uk>
@ -15038,14 +15040,16 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/adc/nxp,imx8qxp-adc.yaml
F: drivers/iio/adc/imx8qxp-adc.c
NXP i.MX 7D/6SX/6UL AND VF610 ADC DRIVER
NXP i.MX 7D/6SX/6UL/93 AND VF610 ADC DRIVER
M: Haibo Chen <haibo.chen@nxp.com>
L: linux-iio@vger.kernel.org
L: linux-imx@nxp.com
S: Maintained
F: Documentation/devicetree/bindings/iio/adc/fsl,imx7d-adc.yaml
F: Documentation/devicetree/bindings/iio/adc/fsl,vf610-adc.yaml
F: Documentation/devicetree/bindings/iio/adc/nxp,imx93-adc.yaml
F: drivers/iio/adc/imx7d_adc.c
F: drivers/iio/adc/imx93_adc.c
F: drivers/iio/adc/vf610_adc.c
NXP PF8100/PF8121A/PF8200 PMIC REGULATOR DEVICE DRIVER
@ -20814,6 +20818,13 @@ M: Robert Richter <rric@kernel.org>
S: Odd Fixes
F: drivers/gpio/gpio-thunderx.c
TI ADS7924 ADC DRIVER
M: Hugo Villeneuve <hvilleneuve@dimonoff.com>
L: linux-iio@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/iio/adc/ti,ads7924.yaml
F: drivers/iio/adc/ti-ads7924.c
TI AM437X VPFE DRIVER
M: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
L: linux-media@vger.kernel.org
@ -20934,6 +20945,14 @@ S: Maintained
F: sound/soc/codecs/isabelle*
F: sound/soc/codecs/lm49453*
TI LMP92064 ADC DRIVER
M: Leonard Göhrs <l.goehrs@pengutronix.de>
R: kernel@pengutronix.de
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/adc/ti,lmp92064.yaml
F: drivers/iio/adc/ti-lmp92064.c
TI PCM3060 ASoC CODEC DRIVER
M: Kirill Marinushkin <kmarinushkin@birdec.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
@ -20947,6 +20966,13 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Odd Fixes
F: sound/soc/codecs/tas571x*
TI TMAG5273 MAGNETOMETER DRIVER
M: Gerald Loacker <gerald.loacker@wolfvision.net>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/magnetometer/ti,tmag5273.yaml
F: drivers/iio/magnetometer/tmag5273.c
TI TRF7970A NFC DRIVER
M: Mark Greer <mgreer@animalcreek.com>
L: linux-wireless@vger.kernel.org

View file

@ -380,7 +380,7 @@ config IIO_ST_ACCEL_3AXIS
select IIO_TRIGGERED_BUFFER if (IIO_BUFFER)
help
Say yes here to build support for STMicroelectronics accelerometers:
LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
LSM303C, LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
LIS331DLH, LSM303DL, LSM303DLM, LSM330, LIS2DH12, H3LIS331DL,
LNG2DM, LIS3DE, LIS2DE12, LIS2HH12

View file

@ -141,10 +141,6 @@
#define BMA400_SCALE_MIN 9577
#define BMA400_SCALE_MAX 76617
#define BMA400_NUM_REGULATORS 2
#define BMA400_VDD_REGULATOR 0
#define BMA400_VDDIO_REGULATOR 1
extern const struct regmap_config bma400_regmap_config;
int bma400_probe(struct device *dev, struct regmap *regmap, int irq,

View file

@ -98,7 +98,6 @@ enum bma400_activity {
struct bma400_data {
struct device *dev;
struct regmap *regmap;
struct regulator_bulk_data regulators[BMA400_NUM_REGULATORS];
struct mutex mutex; /* data register lock */
struct iio_mount_matrix orientation;
enum bma400_power_mode power_mode;
@ -832,13 +831,6 @@ static void bma400_init_tables(void)
}
}
static void bma400_regulators_disable(void *data_ptr)
{
struct bma400_data *data = data_ptr;
regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators);
}
static void bma400_power_disable(void *data_ptr)
{
struct bma400_data *data = data_ptr;
@ -868,30 +860,17 @@ static enum iio_modifier bma400_act_to_mod(enum bma400_activity activity)
static int bma400_init(struct bma400_data *data)
{
static const char * const regulator_names[] = { "vdd", "vddio" };
unsigned int val;
int ret;
data->regulators[BMA400_VDD_REGULATOR].supply = "vdd";
data->regulators[BMA400_VDDIO_REGULATOR].supply = "vddio";
ret = devm_regulator_bulk_get(data->dev,
ARRAY_SIZE(data->regulators),
data->regulators);
ret = devm_regulator_bulk_get_enable(data->dev,
ARRAY_SIZE(regulator_names),
regulator_names);
if (ret)
return dev_err_probe(data->dev, ret, "Failed to get regulators: %d\n",
ret);
ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
data->regulators);
if (ret) {
dev_err(data->dev, "Failed to enable regulators: %d\n",
ret);
return ret;
}
ret = devm_add_action_or_reset(data->dev, bma400_regulators_disable, data);
if (ret)
return ret;
/* Try to read chip_id register. It must return 0x90. */
ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val);
if (ret) {

View file

@ -296,9 +296,12 @@ int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
reg, NULL, 0, (u8 *)&v, 2);
if (ret < 0)
return ret;
*val = be16_to_cpu(v);
return ret;
return 0;
}
EXPORT_SYMBOL_NS(mma9551_read_config_word, IIO_MMA9551);
@ -354,9 +357,12 @@ int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
reg, NULL, 0, (u8 *)&v, 2);
if (ret < 0)
return ret;
*val = be16_to_cpu(v);
return ret;
return 0;
}
EXPORT_SYMBOL_NS(mma9551_read_status_word, IIO_MMA9551);

View file

@ -37,6 +37,7 @@
#define LIS2DE12_ACCEL_DEV_NAME "lis2de12"
#define LIS2HH12_ACCEL_DEV_NAME "lis2hh12"
#define LIS302DL_ACCEL_DEV_NAME "lis302dl"
#define LSM303C_ACCEL_DEV_NAME "lsm303c_accel"
#define SC7A20_ACCEL_DEV_NAME "sc7a20"

View file

@ -929,6 +929,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
.sensors_supported = {
[0] = LIS2HH12_ACCEL_DEV_NAME,
[1] = LSM303C_ACCEL_DEV_NAME,
},
.ch = (struct iio_chan_spec *)st_accel_16bit_channels,
.odr = {

View file

@ -111,6 +111,10 @@ static const struct of_device_id st_accel_of_match[] = {
.compatible = "st,lis302dl",
.data = LIS302DL_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm303c-accel",
.data = LSM303C_ACCEL_DEV_NAME,
},
{
.compatible = "silan,sc7a20",
.data = SC7A20_ACCEL_DEV_NAME,
@ -151,6 +155,7 @@ static const struct i2c_device_id st_accel_id_table[] = {
{ LIS2DE12_ACCEL_DEV_NAME },
{ LIS2HH12_ACCEL_DEV_NAME },
{ LIS302DL_ACCEL_DEV_NAME },
{ LSM303C_ACCEL_DEV_NAME },
{ SC7A20_ACCEL_DEV_NAME },
{},
};

View file

@ -96,6 +96,10 @@ static const struct of_device_id st_accel_of_match[] = {
.compatible = "st,lis302dl",
.data = LIS302DL_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm303c-accel",
.data = LSM303C_ACCEL_DEV_NAME,
},
{}
};
MODULE_DEVICE_TABLE(of, st_accel_of_match);
@ -152,6 +156,7 @@ static const struct spi_device_id st_accel_id_table[] = {
{ LIS3DHH_ACCEL_DEV_NAME },
{ LIS3DE_ACCEL_DEV_NAME },
{ LIS302DL_ACCEL_DEV_NAME },
{ LSM303C_ACCEL_DEV_NAME },
{},
};
MODULE_DEVICE_TABLE(spi, st_accel_id_table);

View file

@ -441,7 +441,8 @@ config ENVELOPE_DETECTOR
config EP93XX_ADC
tristate "Cirrus Logic EP93XX ADC driver"
depends on ARCH_EP93XX
depends on ARCH_EP93XX || COMPILE_TEST
depends on HAS_IOMEM
help
Driver for the ADC module on the EP93XX series of SoC from Cirrus Logic.
It's recommended to switch on CONFIG_HIGH_RES_TIMERS option, in this
@ -565,6 +566,16 @@ config IMX8QXP_ADC
This driver can also be built as a module. If so, the module will be
called imx8qxp-adc.
config IMX93_ADC
tristate "IMX93 ADC driver"
depends on ARCH_MXC || COMPILE_TEST
depends on HAS_IOMEM
help
Say yes here to build support for IMX93 ADC.
This driver can also be built as a module. If so, the module will be
called imx93_adc.
config LP8788_ADC
tristate "LP8788 ADC driver"
depends on MFD_LP8788
@ -1207,6 +1218,17 @@ config TI_ADS1015
This driver can also be built as a module. If so, the module will be
called ti-ads1015.
config TI_ADS7924
tristate "Texas Instruments ADS7924 ADC"
depends on I2C
select REGMAP_I2C
help
If you say yes here you get support for Texas Instruments ADS7924
4 channels, 12-bit I2C ADC chip.
This driver can also be built as a module. If so, the module will be
called ti-ads7924.
config TI_ADS7950
tristate "Texas Instruments ADS7950 ADC driver"
depends on SPI && GPIOLIB
@ -1274,6 +1296,16 @@ config TI_AM335X_ADC
To compile this driver as a module, choose M here: the module will be
called ti_am335x_adc.
config TI_LMP92064
tristate "Texas Instruments LMP92064 ADC driver"
depends on SPI
help
Say yes here to build support for the LMP92064 Precision Current and Voltage
sensor.
This driver can also be built as a module. If so, the module will be called
ti-lmp92064.
config TI_TLC4541
tristate "Texas Instruments TLC4541 ADC driver"
depends on SPI

View file

@ -49,6 +49,7 @@ obj-$(CONFIG_HI8435) += hi8435.o
obj-$(CONFIG_HX711) += hx711.o
obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
obj-$(CONFIG_IMX8QXP_ADC) += imx8qxp-adc.o
obj-$(CONFIG_IMX93_ADC) += imx93_adc.o
obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
obj-$(CONFIG_INGENIC_ADC) += ingenic-adc.o
obj-$(CONFIG_INTEL_MRFLD_ADC) += intel_mrfld_adc.o
@ -107,12 +108,14 @@ obj-$(CONFIG_TI_ADC108S102) += ti-adc108s102.o
obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
obj-$(CONFIG_TI_ADS7924) += ti-ads7924.o
obj-$(CONFIG_TI_ADS7950) += ti-ads7950.o
obj-$(CONFIG_TI_ADS8344) += ti-ads8344.o
obj-$(CONFIG_TI_ADS8688) += ti-ads8688.o
obj-$(CONFIG_TI_ADS124S08) += ti-ads124s08.o
obj-$(CONFIG_TI_ADS131E08) += ti-ads131e08.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
obj-$(CONFIG_TI_LMP92064) += ti-lmp92064.o
obj-$(CONFIG_TI_TLC4541) += ti-tlc4541.o
obj-$(CONFIG_TI_TSC2046) += ti-tsc2046.o
obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o

View file

@ -179,7 +179,7 @@ static unsigned int ad7291_threshold_reg(const struct iio_chan_spec *chan,
offset = AD7291_VOLTAGE_OFFSET;
break;
default:
return 0;
return 0;
}
switch (info) {

View file

@ -2181,7 +2181,7 @@ static ssize_t at91_adc_get_fifo_state(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct at91_adc_state *st = iio_priv(indio_dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", !!st->dma_st.dma_chan);
return sysfs_emit(buf, "%d\n", !!st->dma_st.dma_chan);
}
static ssize_t at91_adc_get_watermark(struct device *dev,
@ -2190,7 +2190,7 @@ static ssize_t at91_adc_get_watermark(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct at91_adc_state *st = iio_priv(indio_dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", st->dma_st.watermark);
return sysfs_emit(buf, "%d\n", st->dma_st.watermark);
}
static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,

View file

@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/of.h>
/*
* This code could benefit from real HR Timers, but jiffy granularity would
@ -227,9 +228,16 @@ static int ep93xx_adc_remove(struct platform_device *pdev)
return 0;
}
static const struct of_device_id ep93xx_adc_of_ids[] = {
{ .compatible = "cirrus,ep9301-adc" },
{}
};
MODULE_DEVICE_TABLE(of, ep93xx_adc_of_ids);
static struct platform_driver ep93xx_adc_driver = {
.driver = {
.name = "ep93xx-adc",
.of_match_table = ep93xx_adc_of_ids,
},
.probe = ep93xx_adc_probe,
.remove = ep93xx_adc_remove,

484
drivers/iio/adc/imx93_adc.c Normal file
View file

@ -0,0 +1,484 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* NXP i.MX93 ADC driver
*
* Copyright 2023 NXP
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/iio/iio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#define IMX93_ADC_DRIVER_NAME "imx93-adc"
/* Register map definition */
#define IMX93_ADC_MCR 0x00
#define IMX93_ADC_MSR 0x04
#define IMX93_ADC_ISR 0x10
#define IMX93_ADC_IMR 0x20
#define IMX93_ADC_CIMR0 0x24
#define IMX93_ADC_CTR0 0x94
#define IMX93_ADC_NCMR0 0xA4
#define IMX93_ADC_PCDR0 0x100
#define IMX93_ADC_PCDR1 0x104
#define IMX93_ADC_PCDR2 0x108
#define IMX93_ADC_PCDR3 0x10c
#define IMX93_ADC_PCDR4 0x110
#define IMX93_ADC_PCDR5 0x114
#define IMX93_ADC_PCDR6 0x118
#define IMX93_ADC_PCDR7 0x11c
#define IMX93_ADC_CALSTAT 0x39C
/* ADC bit shift */
#define IMX93_ADC_MCR_MODE_MASK BIT(29)
#define IMX93_ADC_MCR_NSTART_MASK BIT(24)
#define IMX93_ADC_MCR_CALSTART_MASK BIT(14)
#define IMX93_ADC_MCR_ADCLKSE_MASK BIT(8)
#define IMX93_ADC_MCR_PWDN_MASK BIT(0)
#define IMX93_ADC_MSR_CALFAIL_MASK BIT(30)
#define IMX93_ADC_MSR_CALBUSY_MASK BIT(29)
#define IMX93_ADC_MSR_ADCSTATUS_MASK GENMASK(2, 0)
#define IMX93_ADC_ISR_ECH_MASK BIT(0)
#define IMX93_ADC_ISR_EOC_MASK BIT(1)
#define IMX93_ADC_ISR_EOC_ECH_MASK (IMX93_ADC_ISR_EOC_MASK | \
IMX93_ADC_ISR_ECH_MASK)
#define IMX93_ADC_IMR_JEOC_MASK BIT(3)
#define IMX93_ADC_IMR_JECH_MASK BIT(2)
#define IMX93_ADC_IMR_EOC_MASK BIT(1)
#define IMX93_ADC_IMR_ECH_MASK BIT(0)
#define IMX93_ADC_PCDR_CDATA_MASK GENMASK(11, 0)
/* ADC status */
#define IMX93_ADC_MSR_ADCSTATUS_IDLE 0
#define IMX93_ADC_MSR_ADCSTATUS_POWER_DOWN 1
#define IMX93_ADC_MSR_ADCSTATUS_WAIT_STATE 2
#define IMX93_ADC_MSR_ADCSTATUS_BUSY_IN_CALIBRATION 3
#define IMX93_ADC_MSR_ADCSTATUS_SAMPLE 4
#define IMX93_ADC_MSR_ADCSTATUS_CONVERSION 6
#define IMX93_ADC_TIMEOUT msecs_to_jiffies(100)
struct imx93_adc {
struct device *dev;
void __iomem *regs;
struct clk *ipg_clk;
int irq;
struct regulator *vref;
/* lock to protect against multiple access to the device */
struct mutex lock;
struct completion completion;
};
#define IMX93_ADC_CHAN(_idx) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (_idx), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
}
static const struct iio_chan_spec imx93_adc_iio_channels[] = {
IMX93_ADC_CHAN(0),
IMX93_ADC_CHAN(1),
IMX93_ADC_CHAN(2),
IMX93_ADC_CHAN(3),
};
static void imx93_adc_power_down(struct imx93_adc *adc)
{
u32 mcr, msr;
int ret;
mcr = readl(adc->regs + IMX93_ADC_MCR);
mcr |= FIELD_PREP(IMX93_ADC_MCR_PWDN_MASK, 1);
writel(mcr, adc->regs + IMX93_ADC_MCR);
ret = readl_poll_timeout(adc->regs + IMX93_ADC_MSR, msr,
((msr & IMX93_ADC_MSR_ADCSTATUS_MASK) ==
IMX93_ADC_MSR_ADCSTATUS_POWER_DOWN),
1, 50);
if (ret == -ETIMEDOUT)
dev_warn(adc->dev,
"ADC do not in power down mode, current MSR is %x\n",
msr);
}
static void imx93_adc_power_up(struct imx93_adc *adc)
{
u32 mcr;
/* bring ADC out of power down state, in idle state */
mcr = readl(adc->regs + IMX93_ADC_MCR);
mcr &= ~FIELD_PREP(IMX93_ADC_MCR_PWDN_MASK, 1);
writel(mcr, adc->regs + IMX93_ADC_MCR);
}
static void imx93_adc_config_ad_clk(struct imx93_adc *adc)
{
u32 mcr;
/* put adc in power down mode */
imx93_adc_power_down(adc);
/* config the AD_CLK equal to bus clock */
mcr = readl(adc->regs + IMX93_ADC_MCR);
mcr |= FIELD_PREP(IMX93_ADC_MCR_ADCLKSE_MASK, 1);
writel(mcr, adc->regs + IMX93_ADC_MCR);
imx93_adc_power_up(adc);
}
static int imx93_adc_calibration(struct imx93_adc *adc)
{
u32 mcr, msr;
int ret;
/* make sure ADC in power down mode */
imx93_adc_power_down(adc);
/* config SAR controller operating clock */
mcr = readl(adc->regs + IMX93_ADC_MCR);
mcr &= ~FIELD_PREP(IMX93_ADC_MCR_ADCLKSE_MASK, 1);
writel(mcr, adc->regs + IMX93_ADC_MCR);
imx93_adc_power_up(adc);
/*
* TODO: we use the default TSAMP/NRSMPL/AVGEN in MCR,
* can add the setting of these bit if need in future.
*/
/* run calibration */
mcr = readl(adc->regs + IMX93_ADC_MCR);
mcr |= FIELD_PREP(IMX93_ADC_MCR_CALSTART_MASK, 1);
writel(mcr, adc->regs + IMX93_ADC_MCR);
/* wait calibration to be finished */
ret = readl_poll_timeout(adc->regs + IMX93_ADC_MSR, msr,
!(msr & IMX93_ADC_MSR_CALBUSY_MASK), 1000, 2000000);
if (ret == -ETIMEDOUT) {
dev_warn(adc->dev, "ADC do not finish calibration in 2 min!\n");
imx93_adc_power_down(adc);
return ret;
}
/* check whether calbration is success or not */
msr = readl(adc->regs + IMX93_ADC_MSR);
if (msr & IMX93_ADC_MSR_CALFAIL_MASK) {
dev_warn(adc->dev, "ADC calibration failed!\n");
imx93_adc_power_down(adc);
return -EAGAIN;
}
return 0;
}
static int imx93_adc_read_channel_conversion(struct imx93_adc *adc,
int channel_number,
int *result)
{
u32 channel;
u32 imr, mcr, pcda;
long ret;
reinit_completion(&adc->completion);
/* config channel mask register */
channel = 1 << channel_number;
writel(channel, adc->regs + IMX93_ADC_NCMR0);
/* TODO: can config desired sample time in CTRn if need */
/* config interrupt mask */
imr = FIELD_PREP(IMX93_ADC_IMR_EOC_MASK, 1);
writel(imr, adc->regs + IMX93_ADC_IMR);
writel(channel, adc->regs + IMX93_ADC_CIMR0);
/* config one-shot mode */
mcr = readl(adc->regs + IMX93_ADC_MCR);
mcr &= ~FIELD_PREP(IMX93_ADC_MCR_MODE_MASK, 1);
writel(mcr, adc->regs + IMX93_ADC_MCR);
/* start normal conversion */
mcr = readl(adc->regs + IMX93_ADC_MCR);
mcr |= FIELD_PREP(IMX93_ADC_MCR_NSTART_MASK, 1);
writel(mcr, adc->regs + IMX93_ADC_MCR);
ret = wait_for_completion_interruptible_timeout(&adc->completion,
IMX93_ADC_TIMEOUT);
if (ret == 0)
return -ETIMEDOUT;
if (ret < 0)
return ret;
pcda = readl(adc->regs + IMX93_ADC_PCDR0 + channel_number * 4);
*result = FIELD_GET(IMX93_ADC_PCDR_CDATA_MASK, pcda);
return ret;
}
static int imx93_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct imx93_adc *adc = iio_priv(indio_dev);
struct device *dev = adc->dev;
long ret;
u32 vref_uv;
switch (mask) {
case IIO_CHAN_INFO_RAW:
pm_runtime_get_sync(dev);
mutex_lock(&adc->lock);
ret = imx93_adc_read_channel_conversion(adc, chan->channel, val);
mutex_unlock(&adc->lock);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_sync_autosuspend(dev);
if (ret < 0)
return ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
ret = vref_uv = regulator_get_voltage(adc->vref);
if (ret < 0)
return ret;
*val = vref_uv / 1000;
*val2 = 12;
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_SAMP_FREQ:
*val = clk_get_rate(adc->ipg_clk);
return IIO_VAL_INT;
default:
return -EINVAL;
}
}
static irqreturn_t imx93_adc_isr(int irq, void *dev_id)
{
struct imx93_adc *adc = dev_id;
u32 isr, eoc, unexpected;
isr = readl(adc->regs + IMX93_ADC_ISR);
if (FIELD_GET(IMX93_ADC_ISR_EOC_ECH_MASK, isr)) {
eoc = isr & IMX93_ADC_ISR_EOC_ECH_MASK;
writel(eoc, adc->regs + IMX93_ADC_ISR);
complete(&adc->completion);
}
unexpected = isr & ~IMX93_ADC_ISR_EOC_ECH_MASK;
if (unexpected) {
writel(unexpected, adc->regs + IMX93_ADC_ISR);
dev_err(adc->dev, "Unexpected interrupt 0x%08x.\n", unexpected);
return IRQ_NONE;
}
return IRQ_HANDLED;
}
static const struct iio_info imx93_adc_iio_info = {
.read_raw = &imx93_adc_read_raw,
};
static int imx93_adc_probe(struct platform_device *pdev)
{
struct imx93_adc *adc;
struct iio_dev *indio_dev;
struct device *dev = &pdev->dev;
int ret;
indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
if (!indio_dev)
return dev_err_probe(dev, -ENOMEM,
"Failed allocating iio device\n");
adc = iio_priv(indio_dev);
adc->dev = dev;
mutex_init(&adc->lock);
adc->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(adc->regs))
return dev_err_probe(dev, PTR_ERR(adc->regs),
"Failed getting ioremap resource\n");
/* The third irq is for ADC conversion usage */
adc->irq = platform_get_irq(pdev, 2);
if (adc->irq < 0)
return adc->irq;
adc->ipg_clk = devm_clk_get(dev, "ipg");
if (IS_ERR(adc->ipg_clk))
return dev_err_probe(dev, PTR_ERR(adc->ipg_clk),
"Failed getting clock.\n");
adc->vref = devm_regulator_get(dev, "vref");
if (IS_ERR(adc->vref))
return dev_err_probe(dev, PTR_ERR(adc->vref),
"Failed getting reference voltage.\n");
ret = regulator_enable(adc->vref);
if (ret)
return dev_err_probe(dev, ret,
"Failed to enable reference voltage.\n");
platform_set_drvdata(pdev, indio_dev);
init_completion(&adc->completion);
indio_dev->name = "imx93-adc";
indio_dev->info = &imx93_adc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = imx93_adc_iio_channels;
indio_dev->num_channels = ARRAY_SIZE(imx93_adc_iio_channels);
ret = clk_prepare_enable(adc->ipg_clk);
if (ret) {
dev_err_probe(dev, ret,
"Failed to enable ipg clock.\n");
goto error_regulator_disable;
}
ret = request_irq(adc->irq, imx93_adc_isr, 0, IMX93_ADC_DRIVER_NAME, adc);
if (ret < 0) {
dev_err_probe(dev, ret,
"Failed requesting irq, irq = %d\n", adc->irq);
goto error_ipg_clk_disable;
}
ret = imx93_adc_calibration(adc);
if (ret < 0)
goto error_free_adc_irq;
imx93_adc_config_ad_clk(adc);
ret = iio_device_register(indio_dev);
if (ret) {
dev_err_probe(dev, ret,
"Failed to register this iio device.\n");
goto error_adc_power_down;
}
pm_runtime_set_active(dev);
pm_runtime_set_autosuspend_delay(dev, 50);
pm_runtime_use_autosuspend(dev);
pm_runtime_enable(dev);
return 0;
error_adc_power_down:
imx93_adc_power_down(adc);
error_free_adc_irq:
free_irq(adc->irq, adc);
error_ipg_clk_disable:
clk_disable_unprepare(adc->ipg_clk);
error_regulator_disable:
regulator_disable(adc->vref);
return ret;
}
static int imx93_adc_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct imx93_adc *adc = iio_priv(indio_dev);
struct device *dev = adc->dev;
/* adc power down need clock on */
pm_runtime_get_sync(dev);
pm_runtime_disable(dev);
pm_runtime_dont_use_autosuspend(dev);
pm_runtime_put_noidle(dev);
iio_device_unregister(indio_dev);
imx93_adc_power_down(adc);
free_irq(adc->irq, adc);
clk_disable_unprepare(adc->ipg_clk);
regulator_disable(adc->vref);
return 0;
}
static int imx93_adc_runtime_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct imx93_adc *adc = iio_priv(indio_dev);
imx93_adc_power_down(adc);
clk_disable_unprepare(adc->ipg_clk);
regulator_disable(adc->vref);
return 0;
}
static int imx93_adc_runtime_resume(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct imx93_adc *adc = iio_priv(indio_dev);
int ret;
ret = regulator_enable(adc->vref);
if (ret) {
dev_err(dev,
"Can't enable adc reference top voltage, err = %d\n",
ret);
return ret;
}
ret = clk_prepare_enable(adc->ipg_clk);
if (ret) {
dev_err(dev, "Could not prepare or enable clock.\n");
goto err_disable_reg;
}
imx93_adc_power_up(adc);
return 0;
err_disable_reg:
regulator_disable(adc->vref);
return ret;
}
static DEFINE_RUNTIME_DEV_PM_OPS(imx93_adc_pm_ops,
imx93_adc_runtime_suspend,
imx93_adc_runtime_resume, NULL);
static const struct of_device_id imx93_adc_match[] = {
{ .compatible = "nxp,imx93-adc", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx93_adc_match);
static struct platform_driver imx93_adc_driver = {
.probe = imx93_adc_probe,
.remove = imx93_adc_remove,
.driver = {
.name = IMX93_ADC_DRIVER_NAME,
.of_match_table = imx93_adc_match,
.pm = pm_ptr(&imx93_adc_pm_ops),
},
};
module_platform_driver(imx93_adc_driver);
MODULE_DESCRIPTION("NXP i.MX93 ADC driver");
MODULE_AUTHOR("Haibo Chen <haibo.chen@nxp.com>");
MODULE_LICENSE("GPL");

View file

@ -4,7 +4,6 @@
*
* Copyright 2022 Analog Devices Inc.
*/
#include <asm-generic/unaligned.h>
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/device.h>
@ -16,6 +15,8 @@
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <asm/unaligned.h>
#include <linux/iio/buffer.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>

View file

@ -543,6 +543,8 @@ static const struct adc5_channels adc5_chans_pmic[ADC5_MAX_CHANNEL] = {
SCALE_HW_CALIB_DEFAULT)
[ADC5_XO_THERM_100K_PU] = ADC5_CHAN_TEMP("xo_therm", 0,
SCALE_HW_CALIB_XOTHERM)
[ADC5_BAT_ID_100K_PU] = ADC5_CHAN_TEMP("bat_id", 0,
SCALE_HW_CALIB_DEFAULT)
[ADC5_AMUX_THM1_100K_PU] = ADC5_CHAN_TEMP("amux_thm1_100k_pu", 0,
SCALE_HW_CALIB_THERM_100K_PULLUP)
[ADC5_AMUX_THM2_100K_PU] = ADC5_CHAN_TEMP("amux_thm2_100k_pu", 0,
@ -894,10 +896,8 @@ static int adc5_probe(struct platform_device *pdev)
mutex_init(&adc->lock);
ret = adc5_get_fw_data(adc);
if (ret) {
dev_err(dev, "adc get dt data failed\n");
return ret;
}
if (ret)
return dev_err_probe(dev, ret, "adc get dt data failed\n");
irq_eoc = platform_get_irq(pdev, 0);
if (irq_eoc < 0) {

View file

@ -6,6 +6,7 @@
* Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com> for STMicroelectronics.
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
@ -19,7 +20,15 @@
#include "stm32-dfsdm.h"
/**
* struct stm32_dfsdm_dev_data - DFSDM compatible configuration data
* @ipid: DFSDM identification number. Used only if hardware provides identification registers
* @num_filters: DFSDM number of filters. Unused if identification registers are available
* @num_channels: DFSDM number of channels. Unused if identification registers are available
* @regmap_cfg: SAI register map configuration pointer
*/
struct stm32_dfsdm_dev_data {
u32 ipid;
unsigned int num_filters;
unsigned int num_channels;
const struct regmap_config *regmap_cfg;
@ -27,8 +36,6 @@ struct stm32_dfsdm_dev_data {
#define STM32H7_DFSDM_NUM_FILTERS 4
#define STM32H7_DFSDM_NUM_CHANNELS 8
#define STM32MP1_DFSDM_NUM_FILTERS 6
#define STM32MP1_DFSDM_NUM_CHANNELS 8
static bool stm32_dfsdm_volatile_reg(struct device *dev, unsigned int reg)
{
@ -75,8 +82,7 @@ static const struct regmap_config stm32mp1_dfsdm_regmap_cfg = {
};
static const struct stm32_dfsdm_dev_data stm32mp1_dfsdm_data = {
.num_filters = STM32MP1_DFSDM_NUM_FILTERS,
.num_channels = STM32MP1_DFSDM_NUM_CHANNELS,
.ipid = STM32MP15_IPIDR_NUMBER,
.regmap_cfg = &stm32mp1_dfsdm_regmap_cfg,
};
@ -295,6 +301,65 @@ static const struct of_device_id stm32_dfsdm_of_match[] = {
};
MODULE_DEVICE_TABLE(of, stm32_dfsdm_of_match);
static int stm32_dfsdm_probe_identification(struct platform_device *pdev,
struct dfsdm_priv *priv,
const struct stm32_dfsdm_dev_data *dev_data)
{
struct device_node *np = pdev->dev.of_node;
struct device_node *child;
struct stm32_dfsdm *dfsdm = &priv->dfsdm;
const char *compat;
int ret, count = 0;
u32 id, val;
if (!dev_data->ipid) {
dfsdm->num_fls = dev_data->num_filters;
dfsdm->num_chs = dev_data->num_channels;
return 0;
}
ret = regmap_read(dfsdm->regmap, DFSDM_IPIDR, &id);
if (ret)
return ret;
if (id != dev_data->ipid) {
dev_err(&pdev->dev, "Unexpected IP version: 0x%x", id);
return -EINVAL;
}
for_each_child_of_node(np, child) {
ret = of_property_read_string(child, "compatible", &compat);
if (ret)
continue;
/* Count only child nodes with dfsdm compatible */
if (strstr(compat, "dfsdm"))
count++;
}
ret = regmap_read(dfsdm->regmap, DFSDM_HWCFGR, &val);
if (ret)
return ret;
dfsdm->num_fls = FIELD_GET(DFSDM_HWCFGR_NBF_MASK, val);
dfsdm->num_chs = FIELD_GET(DFSDM_HWCFGR_NBT_MASK, val);
if (count > dfsdm->num_fls) {
dev_err(&pdev->dev, "Unexpected child number: %d", count);
return -EINVAL;
}
ret = regmap_read(dfsdm->regmap, DFSDM_VERR, &val);
if (ret)
return ret;
dev_dbg(&pdev->dev, "DFSDM version: %lu.%lu. %d channels/%d filters\n",
FIELD_GET(DFSDM_VERR_MAJREV_MASK, val),
FIELD_GET(DFSDM_VERR_MINREV_MASK, val),
dfsdm->num_chs, dfsdm->num_fls);
return 0;
}
static int stm32_dfsdm_probe(struct platform_device *pdev)
{
struct dfsdm_priv *priv;
@ -311,18 +376,6 @@ static int stm32_dfsdm_probe(struct platform_device *pdev)
dev_data = of_device_get_match_data(&pdev->dev);
dfsdm = &priv->dfsdm;
dfsdm->fl_list = devm_kcalloc(&pdev->dev, dev_data->num_filters,
sizeof(*dfsdm->fl_list), GFP_KERNEL);
if (!dfsdm->fl_list)
return -ENOMEM;
dfsdm->num_fls = dev_data->num_filters;
dfsdm->ch_list = devm_kcalloc(&pdev->dev, dev_data->num_channels,
sizeof(*dfsdm->ch_list),
GFP_KERNEL);
if (!dfsdm->ch_list)
return -ENOMEM;
dfsdm->num_chs = dev_data->num_channels;
ret = stm32_dfsdm_parse_of(pdev, priv);
if (ret < 0)
@ -338,6 +391,20 @@ static int stm32_dfsdm_probe(struct platform_device *pdev)
return ret;
}
ret = stm32_dfsdm_probe_identification(pdev, priv, dev_data);
if (ret < 0)
return ret;
dfsdm->fl_list = devm_kcalloc(&pdev->dev, dfsdm->num_fls,
sizeof(*dfsdm->fl_list), GFP_KERNEL);
if (!dfsdm->fl_list)
return -ENOMEM;
dfsdm->ch_list = devm_kcalloc(&pdev->dev, dfsdm->num_chs,
sizeof(*dfsdm->ch_list), GFP_KERNEL);
if (!dfsdm->ch_list)
return -ENOMEM;
platform_set_drvdata(pdev, dfsdm);
ret = stm32_dfsdm_clk_prepare_enable(dfsdm);

View file

@ -13,25 +13,29 @@
/*
* STM32 DFSDM - global register map
* ________________________________________________________
* | Offset | Registers block |
* --------------------------------------------------------
* | 0x000 | CHANNEL 0 + COMMON CHANNEL FIELDS |
* --------------------------------------------------------
* | 0x020 | CHANNEL 1 |
* --------------------------------------------------------
* | ... | ..... |
* --------------------------------------------------------
* | 0x0E0 | CHANNEL 7 |
* --------------------------------------------------------
* | 0x100 | FILTER 0 + COMMON FILTER FIELDs |
* --------------------------------------------------------
* | 0x200 | FILTER 1 |
* --------------------------------------------------------
* | 0x300 | FILTER 2 |
* --------------------------------------------------------
* | 0x400 | FILTER 3 |
* --------------------------------------------------------
* __________________________________________________________
* | Offset | Registers block |
* ----------------------------------------------------------
* | 0x000 | CHANNEL 0 + COMMON CHANNEL FIELDS |
* ----------------------------------------------------------
* | 0x020 | CHANNEL 1 |
* ----------------------------------------------------------
* | ... | ..... |
* ----------------------------------------------------------
* | 0x20 x n | CHANNEL n |
* ----------------------------------------------------------
* | 0x100 | FILTER 0 + COMMON FILTER FIELDs |
* ----------------------------------------------------------
* | 0x200 | FILTER 1 |
* ----------------------------------------------------------
* | | ..... |
* ----------------------------------------------------------
* | 0x100 x m | FILTER m |
* ----------------------------------------------------------
* | | ..... |
* ----------------------------------------------------------
* | 0x7F0-7FC | Identification registers |
* ----------------------------------------------------------
*/
/*
@ -231,6 +235,24 @@
#define DFSDM_AWCFR_AWHTF_MASK GENMASK(15, 8)
#define DFSDM_AWCFR_AWHTF(v) FIELD_PREP(DFSDM_AWCFR_AWHTF_MASK, v)
/*
* Identification register definitions
*/
#define DFSDM_HWCFGR 0x7F0
#define DFSDM_VERR 0x7F4
#define DFSDM_IPIDR 0x7F8
#define DFSDM_SIDR 0x7FC
/* HWCFGR: Hardware configuration register */
#define DFSDM_HWCFGR_NBT_MASK GENMASK(7, 0)
#define DFSDM_HWCFGR_NBF_MASK GENMASK(15, 8)
/* VERR: Version register */
#define DFSDM_VERR_MINREV_MASK GENMASK(3, 0)
#define DFSDM_VERR_MAJREV_MASK GENMASK(7, 4)
#define STM32MP15_IPIDR_NUMBER 0x00110031
/* DFSDM filter order */
enum stm32_dfsdm_sinc_order {
DFSDM_FASTSINC_ORDER, /* FastSinc filter type */

View file

@ -9,14 +9,13 @@
* https://www.ti.com/lit/ds/symlink/adc124s021.pdf
*/
#include <linux/acpi.h>
#include <linux/err.h>
#include <linux/spi/spi.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/iio/iio.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
struct adc128_configuration {
const struct iio_chan_spec *channels;
@ -139,16 +138,11 @@ static void adc128_disable_regulator(void *reg)
static int adc128_probe(struct spi_device *spi)
{
const struct adc128_configuration *config;
struct iio_dev *indio_dev;
unsigned int config;
struct adc128 *adc;
int ret;
if (dev_fwnode(&spi->dev))
config = (unsigned long) device_get_match_data(&spi->dev);
else
config = spi_get_device_id(spi)->driver_data;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
if (!indio_dev)
return -ENOMEM;
@ -160,8 +154,10 @@ static int adc128_probe(struct spi_device *spi)
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &adc128_info;
indio_dev->channels = adc128_config[config].channels;
indio_dev->num_channels = adc128_config[config].num_channels;
config = spi_get_device_match_data(spi);
indio_dev->channels = config->channels;
indio_dev->num_channels = config->num_channels;
adc->reg = devm_regulator_get(&spi->dev, "vref");
if (IS_ERR(adc->reg))
@ -181,42 +177,40 @@ static int adc128_probe(struct spi_device *spi)
}
static const struct of_device_id adc128_of_match[] = {
{ .compatible = "ti,adc128s052", .data = (void*)0L, },
{ .compatible = "ti,adc122s021", .data = (void*)1L, },
{ .compatible = "ti,adc122s051", .data = (void*)1L, },
{ .compatible = "ti,adc122s101", .data = (void*)1L, },
{ .compatible = "ti,adc124s021", .data = (void*)2L, },
{ .compatible = "ti,adc124s051", .data = (void*)2L, },
{ .compatible = "ti,adc124s101", .data = (void*)2L, },
{ .compatible = "ti,adc128s052", .data = &adc128_config[0] },
{ .compatible = "ti,adc122s021", .data = &adc128_config[1] },
{ .compatible = "ti,adc122s051", .data = &adc128_config[1] },
{ .compatible = "ti,adc122s101", .data = &adc128_config[1] },
{ .compatible = "ti,adc124s021", .data = &adc128_config[2] },
{ .compatible = "ti,adc124s051", .data = &adc128_config[2] },
{ .compatible = "ti,adc124s101", .data = &adc128_config[2] },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, adc128_of_match);
static const struct spi_device_id adc128_id[] = {
{ "adc128s052", 0 }, /* index into adc128_config */
{ "adc122s021", 1 },
{ "adc122s051", 1 },
{ "adc122s101", 1 },
{ "adc124s021", 2 },
{ "adc124s051", 2 },
{ "adc124s101", 2 },
{ "adc128s052", (kernel_ulong_t)&adc128_config[0] },
{ "adc122s021", (kernel_ulong_t)&adc128_config[1] },
{ "adc122s051", (kernel_ulong_t)&adc128_config[1] },
{ "adc122s101", (kernel_ulong_t)&adc128_config[1] },
{ "adc124s021", (kernel_ulong_t)&adc128_config[2] },
{ "adc124s051", (kernel_ulong_t)&adc128_config[2] },
{ "adc124s101", (kernel_ulong_t)&adc128_config[2] },
{ }
};
MODULE_DEVICE_TABLE(spi, adc128_id);
#ifdef CONFIG_ACPI
static const struct acpi_device_id adc128_acpi_match[] = {
{ "AANT1280", 2 }, /* ADC124S021 compatible ACPI ID */
{ "AANT1280", (kernel_ulong_t)&adc128_config[2] },
{ }
};
MODULE_DEVICE_TABLE(acpi, adc128_acpi_match);
#endif
static struct spi_driver adc128_driver = {
.driver = {
.name = "adc128s052",
.of_match_table = adc128_of_match,
.acpi_match_table = ACPI_PTR(adc128_acpi_match),
.acpi_match_table = adc128_acpi_match,
},
.probe = adc128_probe,
.id_table = adc128_id,

View file

@ -0,0 +1,474 @@
// SPDX-License-Identifier: GPL-2.0
/*
* IIO driver for Texas Instruments ADS7924 ADC, 12-bit, 4-Channels, I2C
*
* Author: Hugo Villeneuve <hvilleneuve@dimonoff.com>
* Copyright 2022 DimOnOff
*
* based on iio/adc/ti-ads1015.c
* Copyright (c) 2016, Intel Corporation.
*
* Datasheet: https://www.ti.com/lit/gpn/ads7924
*/
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/iio/iio.h>
#include <linux/iio/types.h>
#define ADS7924_CHANNELS 4
#define ADS7924_BITS 12
#define ADS7924_DATA_SHIFT 4
/* Registers. */
#define ADS7924_MODECNTRL_REG 0x00
#define ADS7924_INTCNTRL_REG 0x01
#define ADS7924_DATA0_U_REG 0x02
#define ADS7924_DATA0_L_REG 0x03
#define ADS7924_DATA1_U_REG 0x04
#define ADS7924_DATA1_L_REG 0x05
#define ADS7924_DATA2_U_REG 0x06
#define ADS7924_DATA2_L_REG 0x07
#define ADS7924_DATA3_U_REG 0x08
#define ADS7924_DATA3_L_REG 0x09
#define ADS7924_ULR0_REG 0x0A
#define ADS7924_LLR0_REG 0x0B
#define ADS7924_ULR1_REG 0x0C
#define ADS7924_LLR1_REG 0x0D
#define ADS7924_ULR2_REG 0x0E
#define ADS7924_LLR2_REG 0x0F
#define ADS7924_ULR3_REG 0x10
#define ADS7924_LLR3_REG 0x11
#define ADS7924_INTCONFIG_REG 0x12
#define ADS7924_SLPCONFIG_REG 0x13
#define ADS7924_ACQCONFIG_REG 0x14
#define ADS7924_PWRCONFIG_REG 0x15
#define ADS7924_RESET_REG 0x16
/*
* Register address INC bit: when set to '1', the register address is
* automatically incremented after every register read which allows convenient
* reading of multiple registers. Set INC to '0' when reading a single register.
*/
#define ADS7924_AUTO_INCREMENT_BIT BIT(7)
#define ADS7924_MODECNTRL_MODE_MASK GENMASK(7, 2)
#define ADS7924_MODECNTRL_SEL_MASK GENMASK(1, 0)
#define ADS7924_CFG_INTPOL_BIT 1
#define ADS7924_CFG_INTTRIG_BIT 0
#define ADS7924_CFG_INTPOL_MASK BIT(ADS7924_CFG_INTPOL_BIT)
#define ADS7924_CFG_INTTRIG_MASK BIT(ADS7924_CFG_INTTRIG_BIT)
/* Interrupt pin polarity */
#define ADS7924_CFG_INTPOL_LOW 0
#define ADS7924_CFG_INTPOL_HIGH 1
/* Interrupt pin signaling */
#define ADS7924_CFG_INTTRIG_LEVEL 0
#define ADS7924_CFG_INTTRIG_EDGE 1
/* Mode control values */
#define ADS7924_MODECNTRL_IDLE 0x00
#define ADS7924_MODECNTRL_AWAKE 0x20
#define ADS7924_MODECNTRL_MANUAL_SINGLE 0x30
#define ADS7924_MODECNTRL_MANUAL_SCAN 0x32
#define ADS7924_MODECNTRL_AUTO_SINGLE 0x31
#define ADS7924_MODECNTRL_AUTO_SCAN 0x33
#define ADS7924_MODECNTRL_AUTO_SINGLE_SLEEP 0x39
#define ADS7924_MODECNTRL_AUTO_SCAN_SLEEP 0x3B
#define ADS7924_MODECNTRL_AUTO_BURST_SLEEP 0x3F
#define ADS7924_ACQTIME_MASK GENMASK(4, 0)
#define ADS7924_PWRUPTIME_MASK GENMASK(4, 0)
/*
* The power-up time is allowed to elapse whenever the device has been shutdown
* in idle mode. Power-up time can allow external circuits, such as an
* operational amplifier, between the MUXOUT and ADCIN pins to turn on.
* The nominal time programmed by the PUTIME[4:0] register bits is given by:
* t PU = PWRUPTIME[4:0] × 2 μs
* If a power-up time is not required, set the bits to '0' to effectively bypass.
*/
#define ADS7924_PWRUPTIME_US 0 /* Bypass (0us). */
/*
* Acquisition Time according to ACQTIME[4:0] register bits.
* The Acquisition Time is given by:
* t ACQ = (ACQTIME[4:0] × 2 μs) + 6 μs
* Using default value of 0 for ACQTIME[4:0] results in a minimum acquisition
* time of 6us.
*/
#define ADS7924_ACQTIME_US 6
/* The conversion time is always 4μs and cannot be programmed by the user. */
#define ADS7924_CONVTIME_US 4
#define ADS7924_TOTAL_CONVTIME_US (ADS7924_PWRUPTIME_US + ADS7924_ACQTIME_US + \
ADS7924_CONVTIME_US)
#define ADS7924_V_CHAN(_chan, _addr) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = _chan, \
.address = _addr, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.datasheet_name = "AIN"#_chan, \
}
struct ads7924_data {
struct device *dev;
struct regmap *regmap;
struct regulator *vref_reg;
/* GPIO descriptor for device hard-reset pin. */
struct gpio_desc *reset_gpio;
/*
* Protects ADC ops, e.g: concurrent sysfs/buffered
* data reads, configuration updates
*/
struct mutex lock;
/*
* Set to true when the ADC is switched to the continuous-conversion
* mode and exits from a power-down state. This flag is used to avoid
* getting the stale result from the conversion register.
*/
bool conv_invalid;
};
static bool ads7924_is_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case ADS7924_MODECNTRL_REG:
case ADS7924_INTCNTRL_REG:
case ADS7924_ULR0_REG:
case ADS7924_LLR0_REG:
case ADS7924_ULR1_REG:
case ADS7924_LLR1_REG:
case ADS7924_ULR2_REG:
case ADS7924_LLR2_REG:
case ADS7924_ULR3_REG:
case ADS7924_LLR3_REG:
case ADS7924_INTCONFIG_REG:
case ADS7924_SLPCONFIG_REG:
case ADS7924_ACQCONFIG_REG:
case ADS7924_PWRCONFIG_REG:
case ADS7924_RESET_REG:
return true;
default:
return false;
}
}
static const struct regmap_config ads7924_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = ADS7924_RESET_REG,
.writeable_reg = ads7924_is_writeable_reg,
};
static const struct iio_chan_spec ads7924_channels[] = {
ADS7924_V_CHAN(0, ADS7924_DATA0_U_REG),
ADS7924_V_CHAN(1, ADS7924_DATA1_U_REG),
ADS7924_V_CHAN(2, ADS7924_DATA2_U_REG),
ADS7924_V_CHAN(3, ADS7924_DATA3_U_REG),
};
static int ads7924_get_adc_result(struct ads7924_data *data,
struct iio_chan_spec const *chan, int *val)
{
int ret;
__be16 be_val;
if (chan->channel < 0 || chan->channel >= ADS7924_CHANNELS)
return -EINVAL;
if (data->conv_invalid) {
int conv_time;
conv_time = ADS7924_TOTAL_CONVTIME_US;
/* Allow 10% for internal clock inaccuracy. */
conv_time += conv_time / 10;
usleep_range(conv_time, conv_time + 1);
data->conv_invalid = false;
}
ret = regmap_raw_read(data->regmap, ADS7924_AUTO_INCREMENT_BIT |
chan->address, &be_val, sizeof(be_val));
if (ret)
return ret;
*val = be16_to_cpu(be_val) >> ADS7924_DATA_SHIFT;
return 0;
}
static int ads7924_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
{
int ret, vref_uv;
struct ads7924_data *data = iio_priv(indio_dev);
switch (mask) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&data->lock);
ret = ads7924_get_adc_result(data, chan, val);
mutex_unlock(&data->lock);
if (ret < 0)
return ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
vref_uv = regulator_get_voltage(data->vref_reg);
if (vref_uv < 0)
return vref_uv;
*val = vref_uv / 1000; /* Convert reg voltage to mV */
*val2 = ADS7924_BITS;
return IIO_VAL_FRACTIONAL_LOG2;
default:
return -EINVAL;
}
}
static const struct iio_info ads7924_info = {
.read_raw = ads7924_read_raw,
};
static int ads7924_get_channels_config(struct i2c_client *client,
struct iio_dev *indio_dev)
{
struct ads7924_data *priv = iio_priv(indio_dev);
struct device *dev = priv->dev;
struct fwnode_handle *node;
int num_channels = 0;
device_for_each_child_node(dev, node) {
u32 pval;
unsigned int channel;
if (fwnode_property_read_u32(node, "reg", &pval)) {
dev_err(dev, "invalid reg on %pfw\n", node);
continue;
}
channel = pval;
if (channel >= ADS7924_CHANNELS) {
dev_err(dev, "invalid channel index %d on %pfw\n",
channel, node);
continue;
}
num_channels++;
}
if (!num_channels)
return -EINVAL;
return 0;
}
static int ads7924_set_conv_mode(struct ads7924_data *data, int mode)
{
int ret;
unsigned int mode_field;
struct device *dev = data->dev;
/*
* When switching between modes, be sure to first select the Awake mode
* and then switch to the desired mode. This procedure ensures the
* internal control logic is properly synchronized.
*/
if (mode != ADS7924_MODECNTRL_IDLE) {
mode_field = FIELD_PREP(ADS7924_MODECNTRL_MODE_MASK,
ADS7924_MODECNTRL_AWAKE);
ret = regmap_update_bits(data->regmap, ADS7924_MODECNTRL_REG,
ADS7924_MODECNTRL_MODE_MASK,
mode_field);
if (ret) {
dev_err(dev, "failed to set awake mode (%pe)\n",
ERR_PTR(ret));
return ret;
}
}
mode_field = FIELD_PREP(ADS7924_MODECNTRL_MODE_MASK, mode);
ret = regmap_update_bits(data->regmap, ADS7924_MODECNTRL_REG,
ADS7924_MODECNTRL_MODE_MASK, mode_field);
if (ret)
dev_err(dev, "failed to set mode %d (%pe)\n", mode,
ERR_PTR(ret));
return ret;
}
static int ads7924_reset(struct iio_dev *indio_dev)
{
struct ads7924_data *data = iio_priv(indio_dev);
if (data->reset_gpio) {
gpiod_set_value(data->reset_gpio, 1); /* Assert. */
/* Educated guess: assert time not specified in datasheet... */
mdelay(100);
gpiod_set_value(data->reset_gpio, 0); /* Deassert. */
return 0;
}
/*
* A write of 10101010 to this register will generate a
* software reset of the ADS7924.
*/
return regmap_write(data->regmap, ADS7924_RESET_REG, 0b10101010);
};
static void ads7924_reg_disable(void *data)
{
regulator_disable(data);
}
static void ads7924_set_idle_mode(void *data)
{
ads7924_set_conv_mode(data, ADS7924_MODECNTRL_IDLE);
}
static int ads7924_probe(struct i2c_client *client)
{
struct iio_dev *indio_dev;
struct ads7924_data *data;
struct device *dev = &client->dev;
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return dev_err_probe(dev, -ENOMEM,
"failed to allocate iio device\n");
data = iio_priv(indio_dev);
data->dev = dev;
/* Initialize the reset GPIO as output with an initial value of 0. */
data->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
if (IS_ERR(data->reset_gpio))
return dev_err_probe(dev, PTR_ERR(data->reset_gpio),
"failed to get request reset GPIO\n");
mutex_init(&data->lock);
indio_dev->name = "ads7924";
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = ads7924_channels;
indio_dev->num_channels = ARRAY_SIZE(ads7924_channels);
indio_dev->info = &ads7924_info;
ret = ads7924_get_channels_config(client, indio_dev);
if (ret < 0)
return dev_err_probe(dev, ret,
"failed to get channels configuration\n");
data->regmap = devm_regmap_init_i2c(client, &ads7924_regmap_config);
if (IS_ERR(data->regmap))
return dev_err_probe(dev, PTR_ERR(data->regmap),
"failed to init regmap\n");
data->vref_reg = devm_regulator_get(dev, "vref");
if (IS_ERR(data->vref_reg))
return dev_err_probe(dev, PTR_ERR(data->vref_reg),
"failed to get vref regulator\n");
ret = regulator_enable(data->vref_reg);
if (ret)
return dev_err_probe(dev, ret,
"failed to enable regulator\n");
ret = devm_add_action_or_reset(dev, ads7924_reg_disable, data->vref_reg);
if (ret)
return dev_err_probe(dev, ret,
"failed to add regulator disable action\n");
ret = ads7924_reset(indio_dev);
if (ret < 0)
return dev_err_probe(dev, ret,
"failed to reset device\n");
ret = ads7924_set_conv_mode(data, ADS7924_MODECNTRL_AUTO_SCAN);
if (ret)
return dev_err_probe(dev, ret,
"failed to set conversion mode\n");
ret = devm_add_action_or_reset(dev, ads7924_set_idle_mode, data);
if (ret)
return dev_err_probe(dev, ret,
"failed to add idle mode action\n");
/* Use minimum signal acquire time. */
ret = regmap_update_bits(data->regmap, ADS7924_ACQCONFIG_REG,
ADS7924_ACQTIME_MASK,
FIELD_PREP(ADS7924_ACQTIME_MASK, 0));
if (ret < 0)
return dev_err_probe(dev, ret,
"failed to configure signal acquire time\n");
/* Disable power-up time. */
ret = regmap_update_bits(data->regmap, ADS7924_PWRCONFIG_REG,
ADS7924_PWRUPTIME_MASK,
FIELD_PREP(ADS7924_PWRUPTIME_MASK, 0));
if (ret < 0)
return dev_err_probe(dev, ret,
"failed to configure power-up time\n");
data->conv_invalid = true;
ret = devm_iio_device_register(dev, indio_dev);
if (ret < 0)
return dev_err_probe(dev, ret,
"failed to register IIO device\n");
return 0;
}
static const struct i2c_device_id ads7924_id[] = {
{ "ads7924", 0 },
{}
};
MODULE_DEVICE_TABLE(i2c, ads7924_id);
static const struct of_device_id ads7924_of_match[] = {
{ .compatible = "ti,ads7924", },
{}
};
MODULE_DEVICE_TABLE(of, ads7924_of_match);
static struct i2c_driver ads7924_driver = {
.driver = {
.name = "ads7924",
.of_match_table = ads7924_of_match,
},
.probe_new = ads7924_probe,
.id_table = ads7924_id,
};
module_i2c_driver(ads7924_driver);
MODULE_AUTHOR("Hugo Villeneuve <hvilleneuve@dimonoff.com>");
MODULE_DESCRIPTION("Texas Instruments ADS7924 ADC I2C driver");
MODULE_LICENSE("GPL");

View file

@ -0,0 +1,332 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Texas Instruments LMP92064 SPI ADC driver
*
* Copyright (c) 2022 Leonard Göhrs <kernel@pengutronix.de>, Pengutronix
*
* Based on linux/drivers/iio/adc/ti-tsc2046.c
* Copyright (c) 2021 Oleksij Rempel <kernel@pengutronix.de>, Pengutronix
*/
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <linux/iio/iio.h>
#include <linux/iio/driver.h>
#define TI_LMP92064_REG_CONFIG_A 0x0000
#define TI_LMP92064_REG_CONFIG_B 0x0001
#define TI_LMP92064_REG_CHIP_REV 0x0006
#define TI_LMP92064_REG_MFR_ID1 0x000C
#define TI_LMP92064_REG_MFR_ID2 0x000D
#define TI_LMP92064_REG_REG_UPDATE 0x000F
#define TI_LMP92064_REG_CONFIG_REG 0x0100
#define TI_LMP92064_REG_STATUS 0x0103
#define TI_LMP92064_REG_DATA_VOUT_LSB 0x0200
#define TI_LMP92064_REG_DATA_VOUT_MSB 0x0201
#define TI_LMP92064_REG_DATA_COUT_LSB 0x0202
#define TI_LMP92064_REG_DATA_COUT_MSB 0x0203
#define TI_LMP92064_VAL_CONFIG_A 0x99
#define TI_LMP92064_VAL_CONFIG_B 0x00
#define TI_LMP92064_VAL_STATUS_OK 0x01
/*
* Channel number definitions for the two channels of the device
* - IN Current (INC)
* - IN Voltage (INV)
*/
#define TI_LMP92064_CHAN_INC 0
#define TI_LMP92064_CHAN_INV 1
static const struct regmap_range lmp92064_readable_reg_ranges[] = {
regmap_reg_range(TI_LMP92064_REG_CONFIG_A, TI_LMP92064_REG_CHIP_REV),
regmap_reg_range(TI_LMP92064_REG_MFR_ID1, TI_LMP92064_REG_MFR_ID2),
regmap_reg_range(TI_LMP92064_REG_REG_UPDATE, TI_LMP92064_REG_REG_UPDATE),
regmap_reg_range(TI_LMP92064_REG_CONFIG_REG, TI_LMP92064_REG_CONFIG_REG),
regmap_reg_range(TI_LMP92064_REG_STATUS, TI_LMP92064_REG_STATUS),
regmap_reg_range(TI_LMP92064_REG_DATA_VOUT_LSB, TI_LMP92064_REG_DATA_COUT_MSB),
};
static const struct regmap_access_table lmp92064_readable_regs = {
.yes_ranges = lmp92064_readable_reg_ranges,
.n_yes_ranges = ARRAY_SIZE(lmp92064_readable_reg_ranges),
};
static const struct regmap_range lmp92064_writable_reg_ranges[] = {
regmap_reg_range(TI_LMP92064_REG_CONFIG_A, TI_LMP92064_REG_CONFIG_B),
regmap_reg_range(TI_LMP92064_REG_REG_UPDATE, TI_LMP92064_REG_REG_UPDATE),
regmap_reg_range(TI_LMP92064_REG_CONFIG_REG, TI_LMP92064_REG_CONFIG_REG),
};
static const struct regmap_access_table lmp92064_writable_regs = {
.yes_ranges = lmp92064_writable_reg_ranges,
.n_yes_ranges = ARRAY_SIZE(lmp92064_writable_reg_ranges),
};
static const struct regmap_config lmp92064_spi_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.max_register = TI_LMP92064_REG_DATA_COUT_MSB,
.rd_table = &lmp92064_readable_regs,
.wr_table = &lmp92064_writable_regs,
};
struct lmp92064_adc_priv {
int shunt_resistor_uohm;
struct spi_device *spi;
struct regmap *regmap;
};
static const struct iio_chan_spec lmp92064_adc_channels[] = {
{
.type = IIO_CURRENT,
.address = TI_LMP92064_CHAN_INC,
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.datasheet_name = "INC",
},
{
.type = IIO_VOLTAGE,
.address = TI_LMP92064_CHAN_INV,
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.datasheet_name = "INV",
},
};
static int lmp92064_read_meas(struct lmp92064_adc_priv *priv, u16 *res)
{
__be16 raw[2];
int ret;
/*
* The ADC only latches in new samples if all DATA registers are read
* in descending sequential order.
* The ADC auto-decrements the register index with each clocked byte.
* Read both channels in single SPI transfer by selecting the highest
* register using the command below and clocking out all four data
* bytes.
*/
ret = regmap_bulk_read(priv->regmap, TI_LMP92064_REG_DATA_COUT_MSB,
&raw, sizeof(raw));
if (ret) {
dev_err(&priv->spi->dev, "regmap_bulk_read failed: %pe\n",
ERR_PTR(ret));
return ret;
}
res[0] = be16_to_cpu(raw[0]);
res[1] = be16_to_cpu(raw[1]);
return 0;
}
static int lmp92064_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
{
struct lmp92064_adc_priv *priv = iio_priv(indio_dev);
u16 raw[2];
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = lmp92064_read_meas(priv, raw);
if (ret < 0)
return ret;
*val = (chan->address == TI_LMP92064_CHAN_INC) ? raw[0] : raw[1];
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if (chan->address == TI_LMP92064_CHAN_INC) {
/*
* processed (mA) = raw * current_lsb (mA)
* current_lsb (mA) = shunt_voltage_lsb (nV) / shunt_resistor (uOhm)
* shunt_voltage_lsb (nV) = 81920000 / 4096 = 20000
*/
*val = 20000;
*val2 = priv->shunt_resistor_uohm;
} else {
/*
* processed (mV) = raw * voltage_lsb (mV)
* voltage_lsb (mV) = 2048 / 4096
*/
*val = 2048;
*val2 = 4096;
}
return IIO_VAL_FRACTIONAL;
default:
return -EINVAL;
}
}
static int lmp92064_reset(struct lmp92064_adc_priv *priv,
struct gpio_desc *gpio_reset)
{
unsigned int status;
int ret, i;
if (gpio_reset) {
/*
* Perform a hard reset if gpio_reset is available.
* The datasheet specifies a very low 3.5ns reset pulse duration and does not
* specify how long to wait after a reset to access the device.
* Use more conservative pulse lengths to allow analog RC filtering of the
* reset line at the board level (as recommended in the datasheet).
*/
gpiod_set_value_cansleep(gpio_reset, 1);
usleep_range(1, 10);
gpiod_set_value_cansleep(gpio_reset, 0);
usleep_range(500, 750);
} else {
/*
* Perform a soft-reset if not.
* Also write default values to the config registers that are not
* affected by soft reset.
*/
ret = regmap_write(priv->regmap, TI_LMP92064_REG_CONFIG_A,
TI_LMP92064_VAL_CONFIG_A);
if (ret < 0)
return ret;
ret = regmap_write(priv->regmap, TI_LMP92064_REG_CONFIG_B,
TI_LMP92064_VAL_CONFIG_B);
if (ret < 0)
return ret;
}
/*
* Wait for the device to signal readiness to prevent reading bogus data
* and make sure device is actually connected.
* The datasheet does not specify how long this takes but usually it is
* not more than 3-4 iterations of this loop.
*/
for (i = 0; i < 10; i++) {
ret = regmap_read(priv->regmap, TI_LMP92064_REG_STATUS, &status);
if (ret < 0)
return ret;
if (status == TI_LMP92064_VAL_STATUS_OK)
return 0;
usleep_range(1000, 2000);
}
/*
* No (correct) response received.
* Device is mostly likely not connected to the bus.
*/
return -ENXIO;
}
static const struct iio_info lmp92064_adc_info = {
.read_raw = lmp92064_read_raw,
};
static int lmp92064_adc_probe(struct spi_device *spi)
{
struct device *dev = &spi->dev;
struct lmp92064_adc_priv *priv;
struct gpio_desc *gpio_reset;
struct iio_dev *indio_dev;
u32 shunt_resistor_uohm;
struct regmap *regmap;
int ret;
ret = spi_setup(spi);
if (ret < 0)
return dev_err_probe(dev, ret, "Error in SPI setup\n");
regmap = devm_regmap_init_spi(spi, &lmp92064_spi_regmap_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap),
"Failed to set up SPI regmap\n");
indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));
if (!indio_dev)
return -ENOMEM;
priv = iio_priv(indio_dev);
priv->spi = spi;
priv->regmap = regmap;
ret = device_property_read_u32(dev, "shunt-resistor-micro-ohms",
&shunt_resistor_uohm);
if (ret < 0)
return dev_err_probe(dev, ret,
"Failed to get shunt-resistor value\n");
/*
* The shunt resistance is passed to userspace as the denominator of an iio
* fraction. Make sure it is in range for that.
*/
if (shunt_resistor_uohm == 0 || shunt_resistor_uohm > INT_MAX) {
dev_err(dev, "Shunt resistance is out of range\n");
return -EINVAL;
}
priv->shunt_resistor_uohm = shunt_resistor_uohm;
ret = devm_regulator_get_enable(dev, "vdd");
if (ret)
return ret;
ret = devm_regulator_get_enable(dev, "vdig");
if (ret)
return ret;
gpio_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(gpio_reset))
return dev_err_probe(dev, PTR_ERR(gpio_reset),
"Failed to get GPIO reset pin\n");
ret = lmp92064_reset(priv, gpio_reset);
if (ret < 0)
return dev_err_probe(dev, ret, "Failed to reset device\n");
indio_dev->name = "lmp92064";
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = lmp92064_adc_channels;
indio_dev->num_channels = ARRAY_SIZE(lmp92064_adc_channels);
indio_dev->info = &lmp92064_adc_info;
return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id lmp92064_id_table[] = {
{ "lmp92064" },
{}
};
MODULE_DEVICE_TABLE(spi, lmp92064_id_table);
static const struct of_device_id lmp92064_of_table[] = {
{ .compatible = "ti,lmp92064" },
{}
};
MODULE_DEVICE_TABLE(of, lmp92064_of_table);
static struct spi_driver lmp92064_adc_driver = {
.driver = {
.name = "lmp92064",
.of_match_table = lmp92064_of_table,
},
.probe = lmp92064_adc_probe,
.id_table = lmp92064_id_table,
};
module_spi_driver(lmp92064_adc_driver);
MODULE_AUTHOR("Leonard Göhrs <kernel@pengutronix.de>");
MODULE_DESCRIPTION("TI LMP92064 ADC");
MODULE_LICENSE("GPL");

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