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

Jonathan writes:

2nd set of IIO device support, features, cleanups and yaml conversions for 5.11

v2: Fix some missing Sign offs from me that Greg found in v1.

Includes low priority/late breaking/long standing bug fixes.

Note this includes the last few patches that were listed in the description
for the previous pull request but weren't actually in the PULL.

New devices support
* bosch,bmc150-accel
  - Support for BMA222, including adding binding doc that was previously
    missing.
* st,lsm6dsx
  - Support LSM6DSOP accelerometer + gyroscope sensor.

yaml-conversions by manufacturer
* core
  - adc
  - iio-binding (drop as now in dt-schema)
  - temperature (drop as not clear it is generic)
* generic (no specific manufacturer)
  - dpot-dac
  - current-sense-amplifier
  - current-sense-shunt
  - envelope-detector
  - voltage-divider
* adi,ad5592r adi,ad7124 adi,ad7292 adi,adf4350
* atmel,sama9260-adc
* bosch,bma180 bosch,bmg180
* brcm,iproc-static-adc
* capella,cm3605
* fsl,mma8452
* kionix,kxcjk1013
* maxim,max1027 (from trivial)
* mediatek,mt2701-auxdac
* microchip,mcp4531 (from trivial)
* qcom,pm8018-adc qcom,spi-iadc
* st,st-sensors
* ti,ads124s08 ti,afe4403 ti,afe4404 ti,lmp91000 ti,palmas-gpadc

Features
* bosch,bmc150
  - Handle unusual ACPI binding where two devices are provided in a single
    ACPI device (BOSC0200).
  - ACPI based mount matrix handling
* st,hts221
  - regulator control
* st,lsm6dsx
  - regulator control

Cleanup + minor fixes
* core
  - Reduce duplication in iio_format_avail_{list,range}() and iio_format_list()
  - Fix an issue in the demux update code that could lead to misaligned data.
    Possible no existing driver hits this. Been there a very long time with
    no bug reports.
  - Improve iio_map_array_register() error handling.
  - Avoid polling driver again if try_reenable() callback returns non 0.
    Only users of this were bugs so also drop the return value.
* core/cb_buffer
  - Return an error if no callback provided (include adding a dummy for one
    unusual case where no callback is valid).
* trigger/hrtimer-trig, sysfs-trig
  - Fix an issue seen with PREEMPT_RT by marking irq_work as expiring in hard
    interrupt context.
* adi,ad_sigma_delta library
  - Avoid putting SPI transfer buffers on stack for DMA safety reasons
* adi,ad5272
  - Fix discrepancy in polarity of reset line between binding documentation
    (which was right) and driver.
* adi,ad7298
  - Use devm for all of probe
* atmel,at91_adc
  - Drop at91_adc_ids as only support DT probe
  - Simplify resolution selection and bindings
  - Drop binding for triggers and move into driver based on compatible.
  - Merge at91_adc_probe_dt() into main at91_adc_probe()
* bosch,bmc150
  - Drop unused structure member.
* bosch,bmi160
  - Fix overly long buffer due to wrong channel count.
  - Fix potential buffer alignment into iio_push_to_buffers_with_timestamp()
* fsl,mag3110
  - Fix potential buffer alignment into iio_push_to_buffers_with_timestamp()
* fsl,mpl3115
  - Fix potential buffer alignment into iio_push_to_buffers_with_timestamp()
* invn,mpu3050
  - Use 64 bit local variable and FIELD_GET to simplify code that extracts
    values from OTP.
* qcom,spmi-vadc
  - Drop wrong use of io-channel-ranges in binding doc.
* rockchip,saradc
  - Fix a missing clk_disable_unprepare() in an error path.
* rohm,rpr0521
  - Fix potential buffer alignment into iio_push_to_buffers_with_timestamp()
* samsung,exynos-adc
  - Drop wrong use of io-channel-ranges in binding doc.
* st,lsm6dsx
  - Reduce duplication in the chip model specific tables.
  - Fix an issue with missed edge-interrupts that can occur when using
    the FIFO.
* st,uvis21
  - Fix potential buffer alignment into iio_push_to_buffers_with_timestamp()
* ti,adc084s021
  - Tidy up endian types to clear a warning.
* ti,ads124s08
  - Fix too long a buffer.
  - Fix potential buffer alignment into iio_push_to_buffers_with_timestamp()

Counter
* microchip,tcb-counter
  - Add Kamel Bouhara to MAINTAINERS
  - Fix CMR value check

* tag 'iio-for-5.11b-take2' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (80 commits)
  iio: adc: rockchip_saradc: fix missing clk_disable_unprepare() on error in rockchip_saradc_resume
  iio: imu: st_lsm6dsx: fix edge-trigger interrupts
  counter: microchip-tcb-capture: Fix CMR value check
  iio: sysfs-trigger: Mark irq_work to expire in hardirq context
  iio: hrtimer-trigger: Mark hrtimer to expire in hard interrupt context
  iio: accel: bmc150: Get mount-matrix from ACPI
  iio: accel: bmc150: Check for a second ACPI device for BOSC0200
  iio: accel: bmc150: Removed unused bmc150_accel_dat irq member
  iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
  iio:adc:ti-ads124s08: Fix alignment and data leak issues.
  iio:adc:ti-ads124s08: Fix buffer being too long.
  iio:pressure:mpl3115: Force alignment of buffer
  iio:imu:bmi160: Fix alignment and data leak issues
  iio:imu:bmi160: Fix too large a buffer.
  iio:magnetometer:mag3110: Fix alignment and data leak issues.
  iio:light:st_uvis25: Fix timestamp alignment and prevent data leak.
  iio:light:rpr0521: Fix timestamp alignment and prevent data leak.
  iio:adc:ti-adc084s021 Tidy up endian types
  iio:trigger: rename try_reenable() to reenable() plus return void
  iio: Fix: Do not poll the driver again if try_reenable() callback returns non 0.
  ...
This commit is contained in:
Greg Kroah-Hartman
2020-12-03 22:10:58 +01:00
107 changed files with 3183 additions and 2542 deletions

View File

@@ -1,35 +0,0 @@
* Bosch BMA023 / BMA150/ BMA180 / BMA25x / SMB380 triaxial acceleration sensor
https://media.digikey.com/pdf/Data%20Sheets/Bosch/BMA150.pdf
http://omapworld.com/BMA180_111_1002839.pdf
http://ae-bst.resource.bosch.com/media/products/dokumente/bma250/bst-bma250-ds002-05.pdf
Required properties:
- compatible : should be one of:
"bosch,bma023"
"bosch,bma150"
"bosch,bma180"
"bosch,bma250"
"bosch,bma254"
"bosch,smb380"
- reg : the I2C address of the sensor
- vdd-supply : regulator phandle connected to the VDD pin
- vddio-supply : regulator phandle connected to the VDDIO pin
Optional properties:
- interrupts : interrupt mapping for GPIO IRQ, it should by configured with
flags IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING
For the bma250 the first interrupt listed must be the one
connected to the INT1 pin, the second (optional) interrupt
listed must be the one connected to the INT2 pin.
Example:
bma180@40 {
compatible = "bosch,bma180";
reg = <0x40>;
interrupt-parent = <&gpio6>;
interrupts = <18 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>;
};

View File

@@ -0,0 +1,62 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/accel/bosch,bma180.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Bosch BMA023 / BMA150/ BMA180 / BMA25x / SMB380 triaxial accelerometers
maintainers:
- Jonathan Cameron <jic23@kernel.org>
description: |
https://media.digikey.com/pdf/Data%20Sheets/Bosch/BMA150.pdf
http://omapworld.com/BMA180_111_1002839.pdf
http://ae-bst.resource.bosch.com/media/products/dokumente/bma250/bst-bma250-ds002-05.pdf
properties:
compatible:
enum:
- bosch,bma023
- bosch,bma150
- bosch,bma180
- bosch,bma250
- bosch,bma254
- bosch,smb380
reg:
maxItems: 1
vdd-supply: true
vddio-supply: true
interrupts:
minItems: 1
maxItems: 2
description: |
Type should be either IRQ_TYPE_LEVEL_HIGH or IRQ_TYPE_EDGE_RISING.
For the bma250 the first interrupt listed must be the one
connected to the INT1 pin, the second (optional) interrupt
listed must be the one connected to the INT2 pin.
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
accel@40 {
compatible = "bosch,bma180";
reg = <0x40>;
interrupt-parent = <&gpio6>;
interrupts = <18 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>;
};
};
...

View File

@@ -0,0 +1,73 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/accel/bosch,bma255.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Bosch BMA255 and Similar Accelerometers
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
description:
3 axis accelerometers with varying range and I2C or SPI
4-wire interface.
properties:
compatible:
enum:
- bosch,bmc150
- bosch,bmi055
- bosch,bma255
- bosch,bma250e
- bosch,bma222
- bosch,bma222e
- bosch,bma280
reg:
maxItems: 1
vdd-supply: true
vddio-supply: true
interrupts:
maxItems: 1
mount-matrix:
description: an optional 3x3 mounting rotation matrix.
spi-max-frequency:
maximum: 10000000
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
accelerometer@8 {
compatible = "bosch,bma222";
reg = <0x08>;
vddio-supply = <&vddio>;
vdd-supply = <&vdd>;
interrupts = <57 IRQ_TYPE_EDGE_FALLING>;
};
};
- |
# include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
accel@0 {
compatible = "bosch,bma222";
reg = <0>;
spi-max-frequency = <10000000>;
};
};
...

View File

@@ -0,0 +1,65 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/accel/fsl,mma8452.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title:
Freescale MMA8451Q, MMA8452Q, MMA8453Q, MMA8652FC, MMA8653FC or FXLS8471Q
triaxial accelerometer
maintainers:
- Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
properties:
compatible:
enum:
- fsl,mma8451
- fsl,mma8452
- fsl,mma8453
- fsl,mma8652
- fsl,mma8653
- fsl,fxls8471
reg:
maxItems: 1
interrupts:
description:
2 highly configurable interrupt lines exist.
minItems: 1
maxItems: 2
interrupt-names:
description: Specify which interrupt line is in use.
items:
enum:
- INT1
- INT2
minItems: 1
maxItems: 2
vdd-supply: true
vddio-supply: true
required:
- compatible
- reg
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
accel@1d {
compatible = "fsl,mma8453";
reg = <0x1d>;
interrupt-parent = <&gpio1>;
interrupts = <5 0>;
interrupt-names = "INT2";
};
};
...

View File

@@ -1,24 +0,0 @@
Kionix KXCJK-1013 Accelerometer device tree bindings
Required properties:
- compatible: Must be one of:
"kionix,kxcjk1013"
"kionix,kxcj91008"
"kionix,kxtj21009"
"kionix,kxtf9"
- reg: i2c slave address
Optional properties:
- mount-matrix: an optional 3x3 mounting rotation matrix
Example:
kxtf9@f {
compatible = "kionix,kxtf9";
reg = <0x0F>;
mount-matrix = "0", "1", "0",
"1", "0", "0",
"0", "0", "1";
};

View File

@@ -0,0 +1,46 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/accel/kionix,kxcjk1013.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Kionix KXCJK-1013 Accelerometer
maintainers:
- Robert Yang <decatf@gmail.com>
properties:
compatible:
enum:
- kionix,kxcjk1013
- kionix,kxcj91008
- kionix,kxtj21009
- kionix,kxtf9
reg:
maxItems: 1
mount-matrix:
description: an optional 3x3 mounting rotation matrix.
required:
- compatible
- reg
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
accel@f {
compatible = "kionix,kxtf9";
reg = <0x0F>;
mount-matrix = "0", "1", "0",
"1", "0", "0",
"0", "0", "1";
};
};
...

View File

@@ -1,35 +0,0 @@
Freescale MMA8451Q, MMA8452Q, MMA8453Q, MMA8652FC, MMA8653FC or FXLS8471Q
triaxial accelerometer
Required properties:
- compatible: should contain one of
* "fsl,mma8451"
* "fsl,mma8452"
* "fsl,mma8453"
* "fsl,mma8652"
* "fsl,mma8653"
* "fsl,fxls8471"
- reg: the I2C address of the chip
Optional properties:
- interrupts: interrupt mapping for GPIO IRQ
- interrupt-names: should contain "INT1" and/or "INT2", the accelerometer's
interrupt line in use.
- vdd-supply: phandle to the regulator that provides vdd power to the accelerometer.
- vddio-supply: phandle to the regulator that provides vddio power to the accelerometer.
Example:
mma8453fc@1d {
compatible = "fsl,mma8453";
reg = <0x1d>;
interrupt-parent = <&gpio1>;
interrupts = <5 0>;
interrupt-names = "INT2";
};

View File

@@ -1,29 +0,0 @@
Common ADCs properties
Optional properties for child nodes:
- bipolar : Boolean, if set the channel is used in bipolar mode.
- diff-channels : Differential channels muxed for this ADC. The first value
specifies the positive input pin, the second value the negative
input pin.
- reg: The channel number.
- label: Unique name to identify which channel this is.
Example:
adc@0 {
compatible = "some,adc";
...
channel@0 {
reg = <0>;
label = "channel_0_name";
bipolar;
diff-channels = <0 1>;
...
};
channel@1 {
reg = <1>;
label = "channel_1_name";
diff-channels = <2 3>;
...
};
};

View File

@@ -0,0 +1,42 @@
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Generic IIO bindings for ADC channels
maintainers:
- Jonathan Cameron <jic23@kernel.org>
description:
A few properties are defined in a common way ADC channels.
properties:
$nodename:
pattern: "^channel(@[0-9a-f]+)?$"
description:
A channel index should match reg.
reg:
maxItems: 1
label:
$ref: /schemas/types.yaml#/definitions/string
description: Unique name to identify which channel this is.
bipolar:
$ref: /schemas/types.yaml#/definitions/flag
description: If provided, the channel is to be used in bipolar mode.
diff-channels:
$ref: /schemas/types.yaml#/definitions/uint32-array
maxItems: 2
minItems: 2
description:
Many ADCs have dual Muxes to allow different input pins to be routed
to both the positive and negative inputs of a differential ADC.
The first value specifies the positive input pin, the second
specifies the negative input pin.
additionalProperties: true

View File

@@ -63,10 +63,10 @@ required:
patternProperties:
"^channel@([0-9]|1[0-5])$":
$ref: "adc.yaml"
type: object
description: |
Represents the external channels which are connected to the ADC.
See Documentation/devicetree/bindings/iio/adc/adc.txt.
properties:
reg:
@@ -88,15 +88,9 @@ patternProperties:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 3]
diff-channels:
description: see Documentation/devicetree/bindings/iio/adc/adc.txt
items:
minimum: 0
maximum: 15
diff-channels: true
bipolar:
description: see Documentation/devicetree/bindings/iio/adc/adc.txt
type: boolean
bipolar: true
adi,buffered-positive:
description: Enable buffered mode for positive input.
@@ -110,6 +104,8 @@ patternProperties:
- reg
- diff-channels
additionalProperties: false
additionalProperties: false
examples:

View File

@@ -45,10 +45,10 @@ required:
patternProperties:
"^channel@[0-7]$":
$ref: "adc.yaml"
type: object
description: |
Represents the external channels which are connected to the ADC.
See Documentation/devicetree/bindings/iio/adc/adc.txt.
properties:
reg:
@@ -58,13 +58,13 @@ patternProperties:
- minimum: 0
maximum: 7
diff-channels:
description: see Documentation/devicetree/bindings/iio/adc/adc.txt
maxItems: 1
diff-channels: true
required:
- reg
additionalProperties: true
additionalProperties: false
examples:

View File

@@ -1,83 +0,0 @@
* AT91's Analog to Digital Converter (ADC)
Required properties:
- compatible: Should be "atmel,<chip>-adc"
<chip> can be "at91sam9260", "at91sam9g45" or "at91sam9x5"
- reg: Should contain ADC registers location and length
- interrupts: Should contain the IRQ line for the ADC
- clock-names: tuple listing input clock names.
Required elements: "adc_clk", "adc_op_clk".
- clocks: phandles to input clocks.
- atmel,adc-channels-used: Bitmask of the channels muxed and enabled for this
device
- atmel,adc-startup-time: Startup Time of the ADC in microseconds as
defined in the datasheet
- atmel,adc-vref: Reference voltage in millivolts for the conversions
- atmel,adc-res: List of resolutions in bits supported by the ADC. List size
must be two at least.
- atmel,adc-res-names: Contains one identifier string for each resolution
in atmel,adc-res property. "lowres" and "highres"
identifiers are required.
Optional properties:
- atmel,adc-use-external-triggers: Boolean to enable the external triggers
- atmel,adc-use-res: String corresponding to an identifier from
atmel,adc-res-names property. If not specified, the highest
resolution will be used.
- atmel,adc-sleep-mode: Boolean to enable sleep mode when no conversion
- atmel,adc-sample-hold-time: Sample and Hold Time in microseconds
- atmel,adc-ts-wires: Number of touchscreen wires. Should be 4 or 5. If this
value is set, then the adc driver will enable touchscreen
support.
NOTE: when adc touchscreen is enabled, the adc hardware trigger will be
disabled. Since touchscreen will occupy the trigger register.
- atmel,adc-ts-pressure-threshold: a pressure threshold for touchscreen. It
makes touch detection more precise.
Optional trigger Nodes:
- Required properties:
* trigger-name: Name of the trigger exposed to the user
* trigger-value: Value to put in the Trigger register
to activate this trigger
- Optional properties:
* trigger-external: Is the trigger an external trigger?
Examples:
adc0: adc@fffb0000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "atmel,at91sam9260-adc";
reg = <0xfffb0000 0x100>;
interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&adc_clk>, <&adc_op_clk>;
clock-names = "adc_clk", "adc_op_clk";
atmel,adc-channels-used = <0xff>;
atmel,adc-startup-time = <40>;
atmel,adc-use-external-triggers;
atmel,adc-vref = <3300>;
atmel,adc-res = <8 10>;
atmel,adc-res-names = "lowres", "highres";
atmel,adc-use-res = "lowres";
trigger0 {
trigger-name = "external-rising";
trigger-value = <0x1>;
trigger-external;
};
trigger1 {
trigger-name = "external-falling";
trigger-value = <0x2>;
trigger-external;
};
trigger2 {
trigger-name = "external-any";
trigger-value = <0x3>;
trigger-external;
};
trigger3 {
trigger-name = "continuous";
trigger-value = <0x6>;
};
};

View File

@@ -0,0 +1,121 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/atmel,sama9260-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: AT91 sama9260 and similar Analog to Digital Converter (ADC)
maintainers:
- Alexandre Belloni <alexandre.belloni@bootlin.com>
properties:
compatible:
enum:
- atmel,at91sam9260-adc
- atmel,at91sam9rl-adc
- atmel,at91sam9g45-adc
- atmel,at91sam9x5-adc
- atmel,at91sama5d3-adc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
minItems: 2
maxItems: 2
clock-names:
items:
- const: adc_clk
- const: adc_op_clk
atmel,adc-channels-used:
$ref: /schemas/types.yaml#/definitions/uint32
description: Bitmask of the channels muxed and enabled for this device
atmel,adc-startup-time:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Startup Time of the ADC in microseconds as defined in the datasheet
atmel,adc-vref:
$ref: /schemas/types.yaml#/definitions/uint32
description: Reference voltage in millivolts for the conversions
atmel,adc-use-external-triggers:
$ref: /schemas/types.yaml#/definitions/flag
description: Enable the external triggers
atmel,adc-use-res:
$ref: /schemas/types.yaml#/definitions/string
description:
String corresponding to an identifier from atmel,adc-res-names property.
If not specified, the highest resolution will be used.
enum:
- "lowres"
- "highres"
atmel,adc-sleep-mode:
$ref: /schemas/types.yaml#/definitions/flag
description: Enable sleep mode when no conversion
atmel,adc-sample-hold-time:
$ref: /schemas/types.yaml#/definitions/uint32
description: Sample and Hold Time in microseconds
atmel,adc-ts-wires:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Number of touchscreen wires. Must be set to enable touchscreen.
NOTE: when adc touchscreen is enabled, the adc hardware trigger will be
disabled. Since touchscreen will occupy the trigger register.
enum:
- 4
- 5
atmel,adc-ts-pressure-threshold:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Pressure threshold for touchscreen.
"#io-channel-cells":
const: 1
additionalProperties: false
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- atmel,adc-channels-used
- atmel,adc-startup-time
- atmel,adc-vref
examples:
- |
#include <dt-bindings/dma/at91.h>
#include <dt-bindings/interrupt-controller/irq.h>
soc {
#address-cells = <1>;
#size-cells = <1>;
adc@fffb0000 {
compatible = "atmel,at91sam9260-adc";
reg = <0xfffb0000 0x100>;
interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&adc_clk>, <&adc_op_clk>;
clock-names = "adc_clk", "adc_op_clk";
atmel,adc-channels-used = <0xff>;
atmel,adc-startup-time = <40>;
atmel,adc-use-external-triggers;
atmel,adc-vref = <3300>;
atmel,adc-use-res = "lowres";
};
};
...

View File

@@ -1,40 +0,0 @@
* Broadcom's IPROC Static ADC controller
Broadcom iProc ADC controller has 8 channels 10bit ADC.
Allows user to convert analog input voltage values to digital.
Required properties:
- compatible: Must be "brcm,iproc-static-adc"
- adc-syscon: Handler of syscon node defining physical base address of the
controller and length of memory mapped region.
- #io-channel-cells = <1>; As ADC has multiple outputs
refer to Documentation/devicetree/bindings/iio/iio-bindings.txt for details.
- io-channel-ranges:
refer to Documentation/devicetree/bindings/iio/iio-bindings.txt for details.
- clocks: Clock used for this block.
- clock-names: Clock name should be given as tsc_clk.
- interrupts: interrupt line number.
For example:
ts_adc_syscon: ts_adc_syscon@180a6000 {
compatible = "brcm,iproc-ts-adc-syscon","syscon";
reg = <0x180a6000 0xc30>;
};
adc: adc@180a6000 {
compatible = "brcm,iproc-static-adc";
adc-syscon = <&ts_adc_syscon>;
#io-channel-cells = <1>;
io-channel-ranges;
clocks = <&asiu_clks BCM_CYGNUS_ASIU_ADC_CLK>;
clock-names = "tsc_clk";
interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
};

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/brcm,iproc-static-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Broadcom's IPROC Static ADC controller
maintainers:
- Raveendra Padasalagi <raveendra.padasalagi@broadcom.com>
description: |
Broadcom iProc ADC controller has 8 10bit channels
properties:
compatible:
const: brcm,iproc-static-adc
adc-syscon:
$ref: /schemas/types.yaml#/definitions/phandle
description:
syscon node defining physical base address of the controller and length
of memory mapped region.
"#io-channel-cells":
const: 1
clocks:
maxItems: 1
clock-names:
const: tsc_clk
interrupts:
maxItems: 1
additionalProperties: false
required:
- compatible
- adc-syscon
- "#io-channel-cells"
- clocks
- clock-names
- interrupts
examples:
- |
#include <dt-bindings/clock/bcm-cygnus.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
soc {
#address-cells = <1>;
#size-cells = <1>;
ts_adc_syscon: ts_adc_syscon@180a6000 {
compatible = "brcm,iproc-ts-adc-syscon","syscon";
reg = <0x180a6000 0xc30>;
};
adc {
compatible = "brcm,iproc-static-adc";
adc-syscon = <&ts_adc_syscon>;
#io-channel-cells = <1>;
clocks = <&asiu_clks BCM_CYGNUS_ASIU_ADC_CLK>;
clock-names = "tsc_clk";
interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
};
};
...

View File

@@ -1,54 +0,0 @@
Bindings for ADC envelope detector using a DAC and a comparator
The DAC is used to find the peak level of an alternating voltage input
signal by a binary search using the output of a comparator wired to
an interrupt pin. Like so:
_
| \
input +------>-------|+ \
| \
.-------. | }---.
| | | / |
| dac|-->--|- / |
| | |_/ |
| | |
| | |
| irq|------<-------'
| |
'-------'
Required properties:
- compatible: Should be "axentia,tse850-envelope-detector"
- io-channels: Channel node of the dac to be used for comparator input.
- io-channel-names: Should be "dac".
- interrupt specification for one client interrupt,
see ../../interrupt-controller/interrupts.txt for details.
- interrupt-names: Should be "comp".
Example:
&i2c {
dpot: mcp4651-104@28 {
compatible = "microchip,mcp4651-104";
reg = <0x28>;
#io-channel-cells = <1>;
};
};
dac: dac {
compatible = "dpot-dac";
vref-supply = <&reg_3v3>;
io-channels = <&dpot 0>;
io-channel-names = "dpot";
#io-channel-cells = <1>;
};
envelope-detector {
compatible = "axentia,tse850-envelope-detector";
io-channels = <&dac 0>;
io-channel-names = "dac";
interrupt-parent = <&gpio>;
interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
interrupt-names = "comp";
};

View File

@@ -0,0 +1,86 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/envelope-detector.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ADC envelope detector using a DAC and a comparator
maintainers:
- Peter Rosin <peda@axentia.se>
description: |
The DAC is used to find the peak level of an alternating voltage input
signal by a binary search using the output of a comparator wired to
an interrupt pin. Like so:
_
| \
input +------>-------|+ \
| \
.-------. | }---.
| | | / |
| dac|-->--|- / |
| | |_/ |
| | |
| | |
| irq|------<-------'
| |
'-------'
properties:
compatible:
const: axentia,tse850-envelope-detector
io-channels:
maxItems: 1
description: Channel node of the dac to be used for comparator input.
io-channel-names:
const: dac
interrupts:
maxItems: 1
interrupt-names:
const: comp
required:
- compatible
- io-channels
- io-channel-names
- interrupts
- interrupt-names
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
dpot: dpot@28 {
compatible = "microchip,mcp4651-104";
reg = <0x28>;
#io-channel-cells = <1>;
};
};
dac: dac {
compatible = "dpot-dac";
vref-supply = <&reg_3v3>;
io-channels = <&dpot 0>;
io-channel-names = "dpot";
#io-channel-cells = <1>;
};
envelope-detector {
compatible = "axentia,tse850-envelope-detector";
io-channels = <&dac 0>;
io-channel-names = "dac";
interrupt-parent = <&gpio>;
interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
interrupt-names = "comp";
};
...

View File

@@ -0,0 +1,65 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/maxim,max1027.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Maxim MAX1027 and similar ADCs
maintainers:
- Miquel Raynal <miquel.raynal@bootlin.com>
- Philippe Reynes <tremyfr@yahoo.fr>
description: |
300ks/s SPI ADCs with temperature sensors.
properties:
compatible:
enum:
# 10-bit 8 channels
- maxim,max1027
# 10-bit 12 channels
- maxim,max1029
# 10-bit 16 channels
- maxim,max1031
# 12-bit 8 channels
- maxim,max1227
# 12-bit 12 channels
- maxim,max1229
# 12-bit 16 channels
- maxim,max1231
reg:
maxItems: 1
interrupts:
maxItems: 1
spi-max-frequency:
maximum: 10000000
"#io-channel-cells":
const: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
maxadc: adc@0 {
compatible = "maxim,max1027";
reg = <0>;
#io-channel-cells = <1>;
interrupt-parent = <&gpio5>;
interrupts = <15 IRQ_TYPE_EDGE_RISING>;
spi-max-frequency = <1000000>;
};
};
...

View File

@@ -0,0 +1,77 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/mediatek,mt2701-auxadc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek AUXADC - ADC on Mediatek mobile SoC (mt65xx/mt81xx/mt27xx)
maintainers:
- Zhiyong Tao <zhiyong.tao@mediatek.com>
- Matthias Brugger <matthias.bgg@gmail.com>
description: |
The Auxiliary Analog/Digital Converter (AUXADC) is an ADC found
in some Mediatek SoCs which among other things measures the temperatures
in the SoC. It can be used directly with register accesses, but it is also
used by thermal controller which reads the temperatures from the AUXADC
directly via its own bus interface. See mediatek-thermal bindings
for the Thermal Controller which holds a phandle to the AUXADC.
properties:
compatible:
oneOf:
- enum:
- mediatek,mt2701-auxadc
- mediatek,mt2712-auxadc
- mediatek,mt6765-auxadc
- mediatek,mt7622-auxadc
- mediatek,mt8173-auxadc
- items:
- enum:
- mediatek,mt7623-auxadc
- const: mediatek,mt2701-auxadc
- items:
- enum:
- mediatek,mt8183-auxadc
- mediatek,mt8516-auxadc
- const: mediatek,mt8173-auxadc
reg:
maxItems: 1
clocks:
maxItems: 1
clock-names:
const: main
"#io-channel-cells":
const: 1
additionalProperties: false
required:
- compatible
- reg
- clocks
- clock-names
- "#io-channel-cells"
examples:
- |
#include <dt-bindings/clock/mt8183-clk.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
adc@11001000 {
compatible = "mediatek,mt8183-auxadc",
"mediatek,mt8173-auxadc";
reg = <0 0x11001000 0 0x1000>;
clocks = <&infracfg CLK_INFRA_AUXADC>;
clock-names = "main";
#io-channel-cells = <1>;
};
};
...

View File

@@ -1,34 +0,0 @@
* Mediatek AUXADC - Analog to Digital Converter on Mediatek mobile soc (mt65xx/mt81xx/mt27xx)
===============
The Auxiliary Analog/Digital Converter (AUXADC) is an ADC found
in some Mediatek SoCs which among other things measures the temperatures
in the SoC. It can be used directly with register accesses, but it is also
used by thermal controller which reads the temperatures from the AUXADC
directly via its own bus interface. See
Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
for the Thermal Controller which holds a phandle to the AUXADC.
Required properties:
- compatible: Should be one of:
- "mediatek,mt2701-auxadc": For MT2701 family of SoCs
- "mediatek,mt2712-auxadc": For MT2712 family of SoCs
- "mediatek,mt6765-auxadc": For MT6765 family of SoCs
- "mediatek,mt7622-auxadc": For MT7622 family of SoCs
- "mediatek,mt8173-auxadc": For MT8173 family of SoCs
- "mediatek,mt8183-auxadc", "mediatek,mt8173-auxadc": For MT8183 family of SoCs
- "mediatek,mt8516-auxadc", "mediatek,mt8173-auxadc": For MT8516 family of SoCs
- reg: Address range of the AUXADC unit.
- clocks: Should contain a clock specifier for each entry in clock-names
- clock-names: Should contain "main".
- #io-channel-cells: Should be 1, see ../iio-bindings.txt
Example:
auxadc: adc@11001000 {
compatible = "mediatek,mt2701-auxadc";
reg = <0 0x11001000 0 0x1000>;
clocks = <&pericfg CLK_PERI_AUXADC>;
clock-names = "main";
#io-channel-cells = <1>;
};

View File

@@ -1,48 +0,0 @@
* Palmas general purpose ADC IP block devicetree bindings
Channels list:
0 battery type
1 battery temp NTC (optional current source)
2 GP
3 temp (with ext. diode, optional current source)
4 GP
5 GP
6 VBAT_SENSE
7 VCC_SENSE
8 Backup Battery voltage
9 external charger (VCHG)
10 VBUS
11 DC-DC current probe (how does this work?)
12 internal die temp
13 internal die temp
14 USB ID pin voltage
15 test network
Required properties:
- compatible : Must be "ti,palmas-gpadc".
- #io-channel-cells: Should be set to <1>.
Optional sub-nodes:
ti,channel0-current-microamp: Channel 0 current in uA.
Values are rounded to derive 0uA, 5uA, 15uA, 20uA.
ti,channel3-current-microamp: Channel 3 current in uA.
Values are rounded to derive 0uA, 10uA, 400uA, 800uA.
ti,enable-extended-delay: Enable extended delay.
Example:
pmic {
compatible = "ti,twl6035-pmic", "ti,palmas-pmic";
...
gpadc {
compatible = "ti,palmas-gpadc";
interrupts = <18 0
16 0
17 0>;
#io-channel-cells = <1>;
ti,channel0-current-microamp = <5>;
ti,channel3-current-microamp = <10>;
};
};
...
};

View File

@@ -0,0 +1,166 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/qcom,pm8018-adc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm's PM8xxx voltage XOADC
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
description: |
The Qualcomm PM8xxx PMICs contain a HK/XO ADC (Housekeeping/Crystal
oscillator ADC) encompassing PM8018, PM8038, PM8058 and PM8921.
properties:
compatible:
enum:
- qcom,pm8018-adc
- qcom,pm8038-adc
- qcom,pm8058-adc
- qcom,pm8921-adc
reg:
maxItems: 1
description:
ADC base address in the PMIC, typically 0x197.
xoadc-ref-supply:
description:
The reference voltage may vary with PMIC variant but is typically
something like 2.2 or 1.8V.
interrupts:
maxItems: 1
"#address-cells":
const: 2
description:
The first cell is the prescaler (on PM8058) or premux (on PM8921)
with two valid bits so legal values are 0x00, 0x01 or 0x02.
The second cell is the main analog mux setting (0x00..0x0f).
The combination of prescaler/premux and analog mux uniquely addresses
a hardware channel on all systems.
"#size-cells":
const: 0
"#io-channel-cells":
const: 2
description:
The cells are precaler or premux followed by the analog muxing line.
additionalProperties: false
required:
- compatible
- reg
- "#io-channel-cells"
- "#address-cells"
- "#size-cells"
- adc-channel@c
- adc-channel@d
- adc-channel@f
patternProperties:
"^(adc-channel@)[0-9a-f]$":
type: object
description: |
ADC channel specific configuration.
Note that channels c, d and f must be present for calibration.
These three nodes are used for absolute and ratiometric calibration
and only need to have these reg values: they are by hardware definition
1:1 ratio converters that sample 625, 1250 and 0 milliV and create
an interpolation calibration for all other ADCs.
properties:
reg:
maxItems: 1
qcom,decimation:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
This parameter is used to decrease the ADC sampling rate.
Quicker measurements can be made by reducing the decimation ratio.
Valid values are 512, 1024, 2048, 4096.
If the property is not found, a default value of 512 will be used.
qcom,ratiometric:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Channel calibration type. If this property is specified
VADC will use a special voltage references for channel
calibration. The available references are specified in the
as a u32 value setting (see below) and it is compulsory
to also specify this reference if ratiometric calibration
is selected.
If the property is not found, the channel will be
calibrated with the 0.625V and 1.25V reference channels, also
known as an absolute calibration.
The reference voltage pairs when using ratiometric calibration:
0 = XO_IN/XOADC_GND
1 = PMIC_IN/XOADC_GND
2 = PMIC_IN/BMS_CSP
3 (invalid)
4 = XOADC_GND/XOADC_GND
5 = XOADC_VREF/XOADC_GND
additionalProperties: false
required:
- reg
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
pmic {
#address-cells = <1>;
#size-cells = <0>;
adc@197 {
compatible = "qcom,pm8058-adc";
reg = <0x197>;
interrupts-extended = <&pm8058 76 IRQ_TYPE_EDGE_RISING>;
#address-cells = <2>;
#size-cells = <0>;
#io-channel-cells = <2>;
vcoin: adc-channel@0 {
reg = <0x00 0x00>;
};
vbat: adc-channel@1 {
reg = <0x00 0x01>;
};
dcin: adc-channel@2 {
reg = <0x00 0x02>;
};
ichg: adc-channel@3 {
reg = <0x00 0x03>;
};
vph_pwr: adc-channel@4 {
reg = <0x00 0x04>;
};
usb_vbus: adc-channel@a {
reg = <0x00 0x0a>;
};
die_temp: adc-channel@b {
reg = <0x00 0x0b>;
};
ref_625mv: adc-channel@c {
reg = <0x00 0x0c>;
};
ref_1250mv: adc-channel@d {
reg = <0x00 0x0d>;
};
ref_325mv: adc-channel@e {
reg = <0x00 0x0e>;
};
ref_muxoff: adc-channel@f {
reg = <0x00 0x0f>;
};
};
};
...

View File

@@ -1,157 +0,0 @@
Qualcomm's PM8xxx voltage XOADC
The Qualcomm PM8xxx PMICs contain a HK/XO ADC (Housekeeping/Crystal
oscillator ADC) encompassing PM8018, PM8038, PM8058 and PM8921.
Required properties:
- compatible: should be one of:
"qcom,pm8018-adc"
"qcom,pm8038-adc"
"qcom,pm8058-adc"
"qcom,pm8921-adc"
- reg: should contain the ADC base address in the PMIC, typically
0x197.
- xoadc-ref-supply: should reference a regulator that can supply
a reference voltage on demand. The reference voltage may vary
with PMIC variant but is typically something like 2.2 or 1.8V.
The following required properties are standard for IO channels, see
iio-bindings.txt for more details, but notice that this particular
ADC has a special addressing scheme that require two cells for
identifying each ADC channel:
- #address-cells: should be set to <2>, the first cell is the
prescaler (on PM8058) or premux (on PM8921) with two valid bits
so legal values are 0x00, 0x01 or 0x02. The second cell
is the main analog mux setting (0x00..0x0f). The combination
of prescaler/premux and analog mux uniquely addresses a hardware
channel on all systems.
- #size-cells: should be set to <0>
- #io-channel-cells: should be set to <2>, again the cells are
precaler or premux followed by the analog muxing line.
- interrupts: should refer to the parent PMIC interrupt controller
and reference the proper ADC interrupt.
Required subnodes:
The ADC channels are configured as subnodes of the ADC.
Since some of them are used for calibrating the ADC, these nodes are
compulsory:
adc-channel@c {
reg = <0x00 0x0c>;
};
adc-channel@d {
reg = <0x00 0x0d>;
};
adc-channel@f {
reg = <0x00 0x0f>;
};
These three nodes are used for absolute and ratiometric calibration
and only need to have these reg values: they are by hardware definition
1:1 ratio converters that sample 625, 1250 and 0 milliV and create
an interpolation calibration for all other ADCs.
Optional subnodes: any channels other than channels [0x00 0x0c],
[0x00 0x0d] and [0x00 0x0f] are optional.
Required channel node properties:
- reg: should contain the hardware channel number in the range
0 .. 0xff (8 bits).
Optional channel node properties:
- qcom,decimation:
Value type: <u32>
Definition: This parameter is used to decrease the ADC sampling rate.
Quicker measurements can be made by reducing the decimation ratio.
Valid values are 512, 1024, 2048, 4096.
If the property is not found, a default value of 512 will be used.
- qcom,ratiometric:
Value type: <u32>
Definition: Channel calibration type. If this property is specified
VADC will use a special voltage references for channel
calibration. The available references are specified in the
as a u32 value setting (see below) and it is compulsory
to also specify this reference if ratiometric calibration
is selected.
If the property is not found, the channel will be
calibrated with the 0.625V and 1.25V reference channels, also
known as an absolute calibration.
The reference voltage pairs when using ratiometric calibration:
0 = XO_IN/XOADC_GND
1 = PMIC_IN/XOADC_GND
2 = PMIC_IN/BMS_CSP
3 (invalid)
4 = XOADC_GND/XOADC_GND
5 = XOADC_VREF/XOADC_GND
Example:
xoadc: xoadc@197 {
compatible = "qcom,pm8058-adc";
reg = <0x197>;
interrupts-extended = <&pm8058 76 IRQ_TYPE_EDGE_RISING>;
#address-cells = <2>;
#size-cells = <0>;
#io-channel-cells = <2>;
vcoin: adc-channel@0 {
reg = <0x00 0x00>;
};
vbat: adc-channel@1 {
reg = <0x00 0x01>;
};
dcin: adc-channel@2 {
reg = <0x00 0x02>;
};
ichg: adc-channel@3 {
reg = <0x00 0x03>;
};
vph_pwr: adc-channel@4 {
reg = <0x00 0x04>;
};
usb_vbus: adc-channel@a {
reg = <0x00 0x0a>;
};
die_temp: adc-channel@b {
reg = <0x00 0x0b>;
};
ref_625mv: adc-channel@c {
reg = <0x00 0x0c>;
};
ref_1250mv: adc-channel@d {
reg = <0x00 0x0d>;
};
ref_325mv: adc-channel@e {
reg = <0x00 0x0e>;
};
ref_muxoff: adc-channel@f {
reg = <0x00 0x0f>;
};
};
/* IIO client node */
iio-hwmon {
compatible = "iio-hwmon";
io-channels = <&xoadc 0x00 0x01>, /* Battery */
<&xoadc 0x00 0x02>, /* DC in (charger) */
<&xoadc 0x00 0x04>, /* VPH the main system voltage */
<&xoadc 0x00 0x0b>, /* Die temperature */
<&xoadc 0x00 0x0c>, /* Reference voltage 1.25V */
<&xoadc 0x00 0x0d>, /* Reference voltage 0.625V */
<&xoadc 0x00 0x0e>; /* Reference voltage 0.325V */
};

View File

@@ -1,46 +0,0 @@
Qualcomm's SPMI PMIC current ADC
QPNP PMIC current ADC (IADC) provides interface to clients to read current.
A 16 bit ADC is used for current measurements. IADC can measure the current
through an external resistor (channel 1) or internal (built-in) resistor
(channel 0). When using an external resistor it is to be described by
qcom,external-resistor-micro-ohms property.
IADC node:
- compatible:
Usage: required
Value type: <string>
Definition: Should contain "qcom,spmi-iadc".
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: IADC base address and length in the SPMI PMIC register map
- interrupts:
Usage: optional
Value type: <prop-encoded-array>
Definition: End of ADC conversion.
- qcom,external-resistor-micro-ohms:
Usage: optional
Value type: <u32>
Definition: Sense resister value in micro Ohm.
If not defined value of 10000 micro Ohms will be used.
Example:
/* IADC node */
pmic_iadc: iadc@3600 {
compatible = "qcom,spmi-iadc";
reg = <0x3600 0x100>;
interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>;
qcom,external-resistor-micro-ohms = <10000>;
#io-channel-cells = <1>;
};
/* IIO client node */
bat {
io-channels = <&pmic_iadc 0>;
io-channel-names = "iadc";
};

View File

@@ -0,0 +1,60 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/qcom,spmi-iadc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm's SPMI PMIC current ADC
maintainers:
- Jonathan Cameron <jic23@kernel.org>
description: |
QPNP PMIC current ADC (IADC) provides interface to clients to read current.
A 16 bit ADC is used for current measurements. IADC can measure the current
through an external resistor (channel 1) or internal (built-in) resistor
(channel 0). When using an external resistor it is to be described by
qcom,external-resistor-micro-ohms property.
properties:
compatible:
const: qcom,spmi-iadc
reg:
description: IADC base address and length in the SPMI PMIC register map
maxItems: 1
qcom,external-resistor-micro-ohms:
description:
Sensor resistor value. If not defined value of 10000 micro Ohms
will be used.
interrupts:
maxItems: 1
description:
End of conversion interrupt.
"#io-channel-cells":
const: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
spmi_bus {
#address-cells = <1>;
#size-cells = <0>;
pmic_iadc: adc@3600 {
compatible = "qcom,spmi-iadc";
reg = <0x3600 0x100>;
interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>;
qcom,external-resistor-micro-ohms = <10000>;
#io-channel-cells = <1>;
};
};
...

View File

@@ -48,8 +48,6 @@ properties:
description:
End of conversion interrupt.
io-channel-ranges: true
required:
- compatible
- reg
@@ -249,7 +247,6 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
#io-channel-cells = <1>;
io-channel-ranges;
/* Channel node */
adc-chan@39 {

View File

@@ -49,8 +49,6 @@ properties:
"#io-channel-cells":
const: 1
io-channel-ranges: true
vdd-supply: true
samsung,syscon-phandle:
@@ -130,7 +128,6 @@ examples:
reg = <0x12d10000 0x100>;
interrupts = <0 106 0>;
#io-channel-cells = <1>;
io-channel-ranges;
clocks = <&clock 303>;
clock-names = "adc";
@@ -156,7 +153,6 @@ examples:
reg = <0x126C0000 0x100>;
interrupts = <0 137 0>;
#io-channel-cells = <1>;
io-channel-ranges;
clocks = <&cmu CLK_TSADC>,
<&cmu CLK_SCLK_TSADC>;

View File

@@ -0,0 +1,52 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,ads124s08.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments' ads124s08 and ads124s06 ADC chip
maintainers:
- Dan Murphy <dmurphy@ti.com>
properties:
compatible:
enum:
- ti,ads124s06
- ti,ads124s08
reg:
maxItems: 1
spi-max-frequency: true
spi-cpha: true
reset-gpios:
maxItems: 1
"#io-channel-cells":
const: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "ti,ads124s08";
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpha;
reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
};
...

View File

@@ -0,0 +1,87 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,palmas-gpadc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Palmas general purpose ADC IP block devicetree bindings
maintainers:
- Tony Lindgren <tony@atomide.com>
description: |
This ADC is often used to provide channels via the io-channels
consumer framework.
Channels list:
0 battery type
1 battery temp NTC (optional current source)
2 GP
3 temp (with ext. diode, optional current source)
4 GP
5 GP
6 VBAT_SENSE
7 VCC_SENSE
8 Backup Battery voltage
9 external charger (VCHG)
10 VBUS
11 DC-DC current probe (how does this work?)
12 internal die temp
13 internal die temp
14 USB ID pin voltage
15 test network
properties:
compatible:
const: ti,palmas-gpadc
interrupts:
minItems: 1
maxItems: 3
"#io-channel-cells":
const: 1
ti,channel0-current-microamp:
$ref: /schemas/types.yaml#/definitions/uint32
description: Channel 0 current in uA.
enum:
- 0
- 5
- 15
- 20
ti,channel3-current-microamp:
$ref: /schemas/types.yaml#/definitions/uint32
description: Channel 3 current in uA.
enum:
- 0
- 10
- 400
- 800
ti,enable-extended-delay:
$ref: /schemas/types.yaml#/definitions/flag
description: Enable extended delay.
additionalProperties: false
required:
- compatible
- "#io-channel-cells"
examples:
- |
#include <dt-bindings/clock/mt8183-clk.h>
pmic {
compatible = "ti,twl6035-pmic", "ti,palmas-pmic";
adc {
compatible = "ti,palmas-gpadc";
interrupts = <18 0
16 0
17 0>;
#io-channel-cells = <1>;
ti,channel0-current-microamp = <5>;
ti,channel3-current-microamp = <10>;
};
};
...

View File

@@ -1,25 +0,0 @@
* Texas Instruments' ads124s08 and ads124s06 ADC chip
Required properties:
- compatible :
"ti,ads124s08"
"ti,ads124s06"
- reg : spi chip select number for the device
Recommended properties:
- spi-max-frequency : Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
- spi-cpha : Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
Optional properties:
- reset-gpios : GPIO pin used to reset the device.
Example:
adc@0 {
compatible = "ti,ads124s08";
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpha;
reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};

View File

@@ -1,26 +0,0 @@
Current Sense Amplifier
=======================
When an io-channel measures the output voltage from a current sense
amplifier, the interesting measurement is almost always the current
through the sense resistor, not the voltage output. This binding
describes such a current sense circuit.
Required properties:
- compatible : "current-sense-amplifier"
- io-channels : Channel node of a voltage io-channel.
- sense-resistor-micro-ohms : The sense resistance in microohms.
Optional properties:
- sense-gain-mult: Amplifier gain multiplier. The default is <1>.
- sense-gain-div: Amplifier gain divider. The default is <1>.
Example:
sysi {
compatible = "current-sense-amplifier";
io-channels = <&tiadc 0>;
sense-resistor-micro-ohms = <20000>;
sense-gain-mul = <50>;
};

View File

@@ -0,0 +1,54 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/afe/current-sense-amplifier.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Current Sense Amplifier
maintainers:
- Peter Rosin <peda@axentia.se>
description: |
When an io-channel measures the output voltage from a current sense
amplifier, the interesting measurement is almost always the current
through the sense resistor, not the voltage output. This binding
describes such a current sense circuit.
properties:
compatible:
const: current-sense-amplifier
io-channels:
maxItems: 1
description: |
Channel node of a voltage io-channel.
sense-resistor-micro-ohms:
description: The sense resistance.
sense-gain-mult:
$ref: /schemas/types.yaml#/definitions/uint32
description: Amplifier gain multiplier. The default is <1>.
sense-gain-div:
$ref: /schemas/types.yaml#/definitions/uint32
description: Amplifier gain divider. The default is <1>.
required:
- compatible
- io-channels
- sense-resistor-micro-ohms
additionalProperties: false
examples:
- |
sysi {
compatible = "current-sense-amplifier";
io-channels = <&tiadc 0>;
sense-resistor-micro-ohms = <20000>;
sense-gain-mult = <50>;
};
...

View File

@@ -1,41 +0,0 @@
Current Sense Shunt
===================
When an io-channel measures the voltage over a current sense shunt,
the interesting measurement is almost always the current through the
shunt, not the voltage over it. This binding describes such a current
sense circuit.
Required properties:
- compatible : "current-sense-shunt"
- io-channels : Channel node of a voltage io-channel.
- shunt-resistor-micro-ohms : The shunt resistance in microohms.
Example:
The system current is measured by measuring the voltage over a
3.3 ohms shunt resistor.
sysi {
compatible = "current-sense-shunt";
io-channels = <&tiadc 0>;
/* Divide the voltage by 3300000/1000000 (or 3.3) for the current. */
shunt-resistor-micro-ohms = <3300000>;
};
&i2c {
tiadc: adc@48 {
compatible = "ti,ads1015";
reg = <0x48>;
#io-channel-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 { /* IN0,IN1 differential */
reg = <0>;
ti,gain = <1>;
ti,datarate = <4>;
};
};
};

View File

@@ -0,0 +1,64 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/afe/current-sense-shunt.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Current Sense Shunt
maintainers:
- Peter Rosin <peda@axentia.se>
description: |
When an io-channel measures the voltage over a current sense shunt,
the interesting measurement is almost always the current through the
shunt, not the voltage over it. This binding describes such a current
sense circuit.
properties:
compatible:
const: current-sense-shunt
io-channels:
maxItems: 1
description: |
Channel node of a voltage io-channel.
shunt-resistor-micro-ohms:
description: The shunt resistance.
required:
- compatible
- io-channels
- shunt-resistor-micro-ohms
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
tiadc: adc@48 {
compatible = "ti,ads1015";
reg = <0x48>;
#io-channel-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 { /* IN0,IN1 differential */
reg = <0>;
ti,gain = <1>;
ti,datarate = <4>;
};
};
};
sysi {
compatible = "current-sense-shunt";
io-channels = <&tiadc 0>;
/* Divide the voltage by 3300000/1000000 (or 3.3) for the current. */
shunt-resistor-micro-ohms = <3300000>;
};
...

View File

@@ -1,53 +0,0 @@
Voltage divider
===============
When an io-channel measures the midpoint of a voltage divider, the
interesting voltage is often the voltage over the full resistance
of the divider. This binding describes the voltage divider in such
a curcuit.
Vin ----.
|
.-----.
| R |
'-----'
|
+---- Vout
|
.-----.
| Rout|
'-----'
|
GND
Required properties:
- compatible : "voltage-divider"
- io-channels : Channel node of a voltage io-channel measuring Vout.
- output-ohms : Resistance Rout over which the output voltage is measured.
See full-ohms.
- full-ohms : Resistance R + Rout for the full divider. The io-channel
is scaled by the Rout / (R + Rout) quotient.
Example:
The system voltage is circa 12V, but divided down with a 22/222
voltage divider (R = 200 Ohms, Rout = 22 Ohms) and fed to an ADC.
sysv {
compatible = "voltage-divider";
io-channels = <&maxadc 1>;
/* Scale the system voltage by 22/222 to fit the ADC range. */
output-ohms = <22>;
full-ohms = <222>; /* 200 + 22 */
};
&spi {
maxadc: adc@0 {
compatible = "maxim,max1027";
reg = <0>;
#io-channel-cells = <1>;
interrupt-parent = <&gpio5>;
interrupts = <15 IRQ_TYPE_EDGE_RISING>;
spi-max-frequency = <1000000>;
};
};

View File

@@ -0,0 +1,86 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/afe/voltage-divider.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Voltage divider
maintainers:
- Peter Rosin <peda@axentia.se>
description: |
When an io-channel measures the midpoint of a voltage divider, the
interesting voltage is often the voltage over the full resistance
of the divider. This binding describes the voltage divider in such
a curcuit.
Vin ----.
|
.-----.
| R |
'-----'
|
+---- Vout
|
.-----.
| Rout|
'-----'
|
GND
properties:
compatible:
const: voltage-divider
io-channels:
maxItems: 1
description: |
Channel node of a voltage io-channel.
output-ohms:
description:
Resistance Rout over which the output voltage is measured. See full-ohms.
full-ohms:
description:
Resistance R + Rout for the full divider. The io-channel is scaled by
the Rout / (R + Rout) quotient.
required:
- compatible
- io-channels
- output-ohms
- full-ohms
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
/*
* The system voltage is circa 12V, but divided down with a 22/222
* voltage divider (R = 200 Ohms, Rout = 22 Ohms) and fed to an ADC.
*/
spi {
#address-cells = <1>;
#size-cells = <0>;
maxadc: adc@0 {
compatible = "maxim,max1027";
reg = <0>;
#io-channel-cells = <1>;
interrupt-parent = <&gpio5>;
interrupts = <15 IRQ_TYPE_EDGE_RISING>;
spi-max-frequency = <1000000>;
};
};
sysv {
compatible = "voltage-divider";
io-channels = <&maxadc 1>;
/* Scale the system voltage by 22/222 to fit the ADC range. */
output-ohms = <22>;
full-ohms = <222>; /* 200 + 22 */
};
...

View File

@@ -1,155 +0,0 @@
Analog Devices AD5592R/AD5593R DAC/ADC device driver
Required properties for the AD5592R:
- compatible: Must be "adi,ad5592r"
- reg: SPI chip select number for the device
- spi-max-frequency: Max SPI frequency to use (< 30000000)
- spi-cpol: The AD5592R requires inverse clock polarity (CPOL) mode
Required properties for the AD5593R:
- compatible: Must be "adi,ad5593r"
- reg: I2C address of the device
Required properties for all supported chips:
- #address-cells: Should be 1.
- #size-cells: Should be 0.
- channel nodes:
Each child node represents one channel and has the following
Required properties:
* reg: Pin on which this channel is connected to.
* adi,mode: Mode or function of this channel.
Macros specifying the valid values
can be found in <dt-bindings/iio/adi,ad5592r.h>.
The following values are currently supported:
* CH_MODE_UNUSED (the pin is unused)
* CH_MODE_ADC (the pin is ADC input)
* CH_MODE_DAC (the pin is DAC output)
* CH_MODE_DAC_AND_ADC (the pin is DAC output
but can be monitored by an ADC, since
there is no disadvantage this
this should be considered as the
preferred DAC mode)
* CH_MODE_GPIO (the pin is registered
with GPIOLIB)
Optional properties:
* adi,off-state: State of this channel when unused or the
device gets removed. Macros specifying the
valid values can be found in
<dt-bindings/iio/adi,ad5592r.h>.
* CH_OFFSTATE_PULLDOWN (the pin is pulled down)
* CH_OFFSTATE_OUT_LOW (the pin is output low)
* CH_OFFSTATE_OUT_HIGH (the pin is output high)
* CH_OFFSTATE_OUT_TRISTATE (the pin is
tristated output)
Optional properties:
- vref-supply: Phandle to the external reference voltage supply. This should
only be set if there is an external reference voltage connected to the VREF
pin. If the property is not set the internal 2.5V reference is used.
- reset-gpios : GPIO spec for the RESET pin. If specified, it will be
asserted during driver probe.
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells: Should be 2. The first cell is the GPIO number and the second
cell specifies GPIO flags, as defined in <dt-bindings/gpio/gpio.h>.
AD5592R Example:
#include <dt-bindings/iio/adi,ad5592r.h>
vref: regulator-vref {
compatible = "regulator-fixed";
regulator-name = "vref-ad559x";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
ad5592r@0 {
#size-cells = <0>;
#address-cells = <1>;
#gpio-cells = <2>;
compatible = "adi,ad5592r";
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpol;
vref-supply = <&vref>; /* optional */
reset-gpios = <&gpio0 86 0>; /* optional */
gpio-controller;
channel@0 {
reg = <0>;
adi,mode = <CH_MODE_DAC>;
};
channel@1 {
reg = <1>;
adi,mode = <CH_MODE_ADC>;
};
channel@2 {
reg = <2>;
adi,mode = <CH_MODE_DAC_AND_ADC>;
};
channel@3 {
reg = <3>;
adi,mode = <CH_MODE_DAC_AND_ADC>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@4 {
reg = <4>;
adi,mode = <CH_MODE_UNUSED>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@5 {
reg = <5>;
adi,mode = <CH_MODE_GPIO>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@6 {
reg = <6>;
adi,mode = <CH_MODE_GPIO>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@7 {
reg = <7>;
adi,mode = <CH_MODE_GPIO>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
};
AD5593R Example:
#include <dt-bindings/iio/adi,ad5592r.h>
ad5593r@10 {
#size-cells = <0>;
#address-cells = <1>;
#gpio-cells = <2>;
compatible = "adi,ad5593r";
reg = <0x10>;
gpio-controller;
channel@0 {
reg = <0>;
adi,mode = <CH_MODE_DAC>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@1 {
reg = <1>;
adi,mode = <CH_MODE_ADC>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@2 {
reg = <2>;
adi,mode = <CH_MODE_DAC_AND_ADC>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@6 {
reg = <6>;
adi,mode = <CH_MODE_GPIO>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
};

View File

@@ -0,0 +1,204 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5592r.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5592R/AD5593R DAC/ADC
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
properties:
compatible:
enum:
- adi,ad5592r
- adi,ad5593r
reg:
maxItems: 1
spi-max-frequency:
maximum: 30000000
spi-cpol: true
"#address-cells":
const: 1
"#size-cells":
const: 0
"#io-channel-cells":
const: 1
vref-supply:
description: If not set internal 2.5V reference used.
reset-gpios:
maxItems: 1
gpio-controller:
description: Marks the device node as a GPIO controller.
"#gpio-cells":
const: 2
description:
The first cell is the GPIO number and the second cell specifies
GPIO flags, as defined in <dt-bindings/gpio/gpio.h>.
required:
- compatible
- reg
- "#address-cells"
- "#size-cells"
allOf:
- if:
properties:
compatible:
contains:
const: adi,ad5592r
then:
required:
- spi-cpol
else:
properties:
spi-cpol: false
additionalProperties: false
patternProperties:
"^(channel@)[0-7]$":
type: object
description: Child node to describe a channel
properties:
reg:
minimum: 0
maximum: 7
adi,mode:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3, 8]
description: |
Mode or function of this channel.
Macros specifying the valid values can be found in
<dt-bindings/iio/adi,ad5592r.h>.
The following values are currently supported:
* CH_MODE_UNUSED (the pin is unused)
* CH_MODE_ADC (the pin is ADC input)
* CH_MODE_DAC (the pin is DAC output)
* CH_MODE_DAC_AND_ADC (the pin is DAC output but can be monitored
by an ADC, since there is no disadvantage this should be
considered as the preferred DAC mode)
* CH_MODE_GPIO (the pin is registered with GPIOLIB)
adi,off-state:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
description: |
State of this channel when unused or the device gets removed.
Macros specifying the valid values can be found in
<dt-bindings/iio/adi,ad5592r.h>.
* CH_OFFSTATE_PULLDOWN (the pin is pulled down)
* CH_OFFSTATE_OUT_LOW (the pin is output low)
* CH_OFFSTATE_OUT_HIGH (the pin is output high)
* CH_OFFSTATE_OUT_TRISTATE (the pin is tristated output)
required:
- reg
- adi,mode
additionalProperties: false
examples:
- |
#include <dt-bindings/iio/adi,ad5592r.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
addac@0 {
compatible = "adi,ad5592r";
#size-cells = <0>;
#address-cells = <1>;
#gpio-cells = <2>;
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpol;
vref-supply = <&vref>;
reset-gpios = <&gpio0 86 0>;
gpio-controller;
channel@0 {
reg = <0>;
adi,mode = <CH_MODE_DAC>;
};
channel@1 {
reg = <1>;
adi,mode = <CH_MODE_ADC>;
};
channel@2 {
reg = <2>;
adi,mode = <CH_MODE_DAC_AND_ADC>;
};
channel@3 {
reg = <3>;
adi,mode = <CH_MODE_DAC_AND_ADC>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@4 {
reg = <4>;
adi,mode = <CH_MODE_UNUSED>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@5 {
reg = <5>;
adi,mode = <CH_MODE_GPIO>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@6 {
reg = <6>;
adi,mode = <CH_MODE_GPIO>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@7 {
reg = <7>;
adi,mode = <CH_MODE_GPIO>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
};
ad5593r@10 {
compatible = "adi,ad5593r";
#size-cells = <0>;
#address-cells = <1>;
#gpio-cells = <2>;
reg = <0x10>;
gpio-controller;
channel@0 {
reg = <0>;
adi,mode = <CH_MODE_DAC>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@1 {
reg = <1>;
adi,mode = <CH_MODE_ADC>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@2 {
reg = <2>;
adi,mode = <CH_MODE_DAC_AND_ADC>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
channel@6 {
reg = <6>;
adi,mode = <CH_MODE_GPIO>;
adi,off-state = <CH_OFFSTATE_PULLDOWN>;
};
};
};
...

View File

@@ -1,41 +0,0 @@
Bindings for DAC emulation using a digital potentiometer
It is assumed that the dpot is used as a voltage divider between the
current dpot wiper setting and the maximum resistance of the dpot. The
divided voltage is provided by a vref regulator.
.------.
.-----------. | |
| vref |--' .---.
| regulator |--. | |
'-----------' | | d |
| | p |
| | o | wiper
| | t |<---------+
| | |
| '---' dac output voltage
| |
'------+------------+
Required properties:
- compatible: Should be "dpot-dac"
- vref-supply: The regulator supplying the voltage divider.
- io-channels: Channel node of the dpot to be used for the voltage division.
- io-channel-names: Should be "dpot".
Example:
&i2c {
dpot: mcp4651-503@28 {
compatible = "microchip,mcp4651-503";
reg = <0x28>;
#io-channel-cells = <1>;
};
};
dac {
compatible = "dpot-dac";
vref-supply = <&reg_3v3>;
io-channels = <&dpot 0>;
io-channel-names = "dpot";
};

View File

@@ -0,0 +1,64 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/dpot-dac.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: DAC emulation using a digital potentiometer
maintainers:
- Peter Rosin <peda@axentia.se>
description: |
It is assumed that the dpot is used as a voltage divider between the
current dpot wiper setting and the maximum resistance of the dpot. The
divided voltage is provided by a vref regulator.
.------.
.-----------. | |
| vref |--' .---.
| regulator |--. | |
'-----------' | | d |
| | p |
| | o | wiper
| | t |<---------+
| | |
| '---' dac output voltage
| |
'------+------------+
properties:
compatible:
const: dpot-dac
vref-supply:
description: Regulator supplying the voltage divider.
io-channels:
maxItems: 1
description: |
Channel node of the dpot to be used for the voltage division.
io-channel-names:
const: dpot
"#io-channel-cells":
const: 1
required:
- compatible
- vref-supply
- io-channels
- io-channel-names
additionalProperties: false
examples:
- |
dac {
compatible = "dpot-dac";
vref-supply = <&reg_3v3>;
io-channels = <&dpot 0>;
io-channel-names = "dpot";
};
...

View File

@@ -1,86 +0,0 @@
Analog Devices ADF4350/ADF4351 device driver
Required properties:
- compatible: Should be one of
* "adi,adf4350": When using the ADF4350 device
* "adi,adf4351": When using the ADF4351 device
- reg: SPI chip select numbert for the device
- spi-max-frequency: Max SPI frequency to use (< 20000000)
- clocks: From common clock binding. Clock is phandle to clock for
ADF435x Reference Clock (CLKIN).
Optional properties:
- gpios: GPIO Lock detect - If set with a valid phandle and GPIO number,
pll lock state is tested upon read.
- adi,channel-spacing: Channel spacing in Hz (influences MODULUS).
- adi,power-up-frequency: If set in Hz the PLL tunes to
the desired frequency on probe.
- adi,reference-div-factor: If set the driver skips dynamic calculation
and uses this default value instead.
- adi,reference-doubler-enable: Enables reference doubler.
- adi,reference-div2-enable: Enables reference divider.
- adi,phase-detector-polarity-positive-enable: Enables positive phase
detector polarity. Default = negative.
- adi,lock-detect-precision-6ns-enable: Enables 6ns lock detect precision.
Default = 10ns.
- adi,lock-detect-function-integer-n-enable: Enables lock detect
for integer-N mode. Default = factional-N mode.
- adi,charge-pump-current: Charge pump current in mA.
Default = 2500mA.
- adi,muxout-select: On chip multiplexer output selection.
Valid values for the multiplexer output are:
0: Three-State Output (default)
1: DVDD
2: DGND
3: R-Counter output
4: N-Divider output
5: Analog lock detect
6: Digital lock detect
- adi,low-spur-mode-enable: Enables low spur mode.
Default = Low noise mode.
- adi,cycle-slip-reduction-enable: Enables cycle slip reduction.
- adi,charge-cancellation-enable: Enabled charge pump
charge cancellation for integer-N modes.
- adi,anti-backlash-3ns-enable: Enables 3ns antibacklash pulse width
for integer-N modes.
- adi,band-select-clock-mode-high-enable: Enables faster band
selection logic.
- adi,12bit-clk-divider: Clock divider value used when
adi,12bit-clkdiv-mode != 0
- adi,clk-divider-mode:
Valid values for the clkdiv mode are:
0: Clock divider off (default)
1: Fast lock enable
2: Phase resync enable
- adi,aux-output-enable: Enables auxiliary RF output.
- adi,aux-output-fundamental-enable: Selects fundamental VCO output on
the auxiliary RF output. Default = Output of RF dividers.
- adi,mute-till-lock-enable: Enables Mute-Till-Lock-Detect function.
- adi,output-power: Output power selection.
Valid values for the power mode are:
0: -4dBm (default)
1: -1dBm
2: +2dBm
3: +5dBm
- adi,aux-output-power: Auxiliary output power selection.
Valid values for the power mode are:
0: -4dBm (default)
1: -1dBm
2: +2dBm
3: +5dBm
Example:
lo_pll0_rx_adf4351: adf4351-rx-lpc@4 {
compatible = "adi,adf4351";
reg = <4>;
spi-max-frequency = <10000000>;
clocks = <&clk0_ad9523 9>;
clock-names = "clkin";
adi,channel-spacing = <10000>;
adi,power-up-frequency = <2400000000>;
adi,phase-detector-polarity-positive-enable;
adi,charge-pump-current = <2500>;
adi,output-power = <3>;
adi,mute-till-lock-enable;
};

View File

@@ -0,0 +1,190 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/frequency/adi,adf4350.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices ADF4350/ADF4351 wideband synthesizer
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
properties:
compatible:
enum:
- adi,adf4350
- adi,adf4351
reg:
maxItems: 1
spi-max-frequency:
maximum: 20000000
clocks:
maxItems: 1
description: Clock to provide CLKIN reference clock signal.
clock-names:
const: clkin
gpios:
maxItems: 1
description: Lock detect GPIO.
adi,channel-spacing:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Channel spacing in Hz (influences MODULUS).
adi,power-up-frequency:
$ref: /schemas/types.yaml#/definitions/uint32
description:
If set the PLL tunes to this frequency (in Hz) on driver probe.
adi,reference-div-factor:
$ref: /schemas/types.yaml#/definitions/uint32
description:
If set the driver skips dynamic calculation and uses this default
value instead.
adi,reference-doubler-enable:
$ref: /schemas/types.yaml#/definitions/flag
description: Enables reference doubler.
adi,reference-div2-enable:
$ref: /schemas/types.yaml#/definitions/flag
description: Enables reference divider.
adi,phase-detector-polarity-positive-enable:
$ref: /schemas/types.yaml#/definitions/flag
description: Enables positive phase detector polarity. Default negative.
adi,lock-detect-precision-6ns-enable:
$ref: /schemas/types.yaml#/definitions/flag
description: Enables 6ns lock detect precision. Default = 10ns.
adi,lock-detect-function-integer-n-enable:
$ref: /schemas/types.yaml#/definitions/flag
description:
Enables lock detect for integer-N mode. Default = factional-N mode.
adi,charge-pump-current:
$ref: /schemas/types.yaml#/definitions/uint32
description: Charge pump current in mA. Default = 2500mA.
adi,muxout-select:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
maximum: 6
description: |
On chip multiplexer output selection.
Valid values for the multiplexer output are:
0: Three-State Output (default)
1: DVDD
2: DGND
3: R-Counter output
4: N-Divider output
5: Analog lock detect
6: Digital lock detect
adi,low-spur-mode-enable:
$ref: /schemas/types.yaml#/definitions/flag
description: Enables low spur mode. Default = Low noise mode.
adi,cycle-slip-reduction-enable:
$ref: /schemas/types.yaml#/definitions/flag
description: Enables cycle slip reduction.
adi,charge-cancellation-enable:
$ref: /schemas/types.yaml#/definitions/flag
description:
Enabled charge pump charge cancellation for integer-N modes.
adi,anti-backlash-3ns-enable:
$ref: /schemas/types.yaml#/definitions/flag
description:
Enables 3ns antibacklash pulse width for integer-N modes.
adi,band-select-clock-mode-high-enable:
$ref: /schemas/types.yaml#/definitions/flag
description: Enables faster band selection logic.
adi,12bit-clk-divider:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Clock divider value used when adi,12bit-clkdiv-mode != 0
adi,clk-divider-mode:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2]
description: |
Valid values for the clkdiv mode are:
0: Clock divider off (default)
1: Fast lock enable
2: Phase resync enable
adi,aux-output-enable:
$ref: /schemas/types.yaml#/definitions/flag
description: Enables auxiliary RF output.
adi,aux-output-fundamental-enable:
$ref: /schemas/types.yaml#/definitions/flag
description: |
Selects fundamental VCO output on the auxiliary RF output.
Default = Output of RF dividers.
adi,mute-till-lock-enable:
$ref: /schemas/types.yaml#/definitions/flag
description: Enables Mute-Till-Lock-Detect function.
adi,output-power:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
description: |
Output power selection.
Valid values for the power mode are:
0: -4dBm (default)
1: -1dBm
2: +2dBm
3: +5dBm
adi,aux-output-power:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2, 3]
description: |
Auxiliary output power selection.
Valid values for the power mode are:
0: -4dBm (default)
1: -1dBm
2: +2dBm
3: +5dBm
additionalProperties: false
required:
- compatible
- reg
- clocks
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
pll@4 {
compatible = "adi,adf4351";
reg = <4>;
spi-max-frequency = <10000000>;
clocks = <&clk0_ad9523 9>;
clock-names = "clkin";
adi,channel-spacing = <10000>;
adi,power-up-frequency = <2400000000>;
adi,phase-detector-polarity-positive-enable;
adi,charge-pump-current = <2500>;
adi,output-power = <3>;
adi,mute-till-lock-enable;
};
};
...

View File

@@ -1,20 +0,0 @@
* Bosch BMG160 triaxial rotation sensor (gyroscope)
Required properties:
- compatible : should be "bosch,bmg160", "bosch,bmi055_gyro" or "bosch,bmi088_gyro"
- reg : the I2C address of the sensor (0x69)
Optional properties:
- interrupts : interrupt mapping for GPIO IRQ, it should by configured with
flags IRQ_TYPE_EDGE_RISING
Example:
bmg160@69 {
compatible = "bosch,bmg160";
reg = <0x69>;
interrupt-parent = <&gpio6>;
interrupts = <18 (IRQ_TYPE_EDGE_RISING)>;
};

View File

@@ -0,0 +1,46 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/gyroscope/bosch,bmg160.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Bosch BMG160 triaxial rotation sensor (gyroscope)
maintainers:
- H. Nikolaus Schaller <hns@goldelico.com>
properties:
compatible:
enum:
- bosch,bmg160
- bosch,bmi055_gyro
- bosch,bmi088_gyro
reg:
maxItems: 1
interrupts:
minItems: 1
description:
Should be configured with type IRQ_TYPE_EDGE_RISING.
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
gyroscope@69 {
compatible = "bosch,bmg160";
reg = <0x69>;
interrupt-parent = <&gpio6>;
interrupts = <18 IRQ_TYPE_EDGE_RISING>;
};
};
...

View File

@@ -1,33 +0,0 @@
Texas Instruments AFE4403 Heart rate and Pulse Oximeter
Required properties:
- compatible : Should be "ti,afe4403".
- reg : SPI chip select address of device.
- tx-supply : Regulator supply to transmitting LEDs.
- interrupts : The interrupt line the device ADC_RDY pin is
connected to. For details refer to,
../../interrupt-controller/interrupts.txt.
Optional properties:
- reset-gpios : GPIO used to reset the device.
For details refer to, ../../gpio/gpio.txt.
For other required and optional properties of SPI slave nodes
please refer to ../../spi/spi-bus.txt.
Example:
&spi0 {
heart_mon@0 {
compatible = "ti,afe4403";
reg = <0>;
spi-max-frequency = <10000000>;
tx-supply = <&vbat>;
interrupt-parent = <&gpio1>;
interrupts = <28 IRQ_TYPE_EDGE_RISING>;
reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
};

View File

@@ -1,29 +0,0 @@
Texas Instruments AFE4404 Heart rate and Pulse Oximeter
Required properties:
- compatible : Should be "ti,afe4404".
- reg : I2C address of the device.
- tx-supply : Regulator supply to transmitting LEDs.
- interrupts : The interrupt line the device ADC_RDY pin is
connected to. For details refer to,
../interrupt-controller/interrupts.txt.
Optional properties:
- reset-gpios : GPIO used to reset the device.
For details refer to, ../gpio/gpio.txt.
Example:
&i2c2 {
heart_mon@58 {
compatible = "ti,afe4404";
reg = <0x58>;
tx-supply = <&vbat>;
interrupt-parent = <&gpio1>;
interrupts = <28 IRQ_TYPE_EDGE_RISING>;
reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
};

View File

@@ -0,0 +1,54 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/health/ti,afe4403.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments AFE4403 Heart rate and Pulse Oximeter
maintainers:
- Jonathan Cameron <jic23@kernel.org>
properties:
compatible:
const: ti,afe4403
reg:
maxItems: 1
tx-supply:
description: Supply to transmitting LEDs.
interrupts:
maxItems: 1
description: Connected to ADC_RDY pin.
reset-gpios: true
spi-max-frequency: true
additionalProperties: false
required:
- compatible
- reg
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
heart_mon@0 {
compatible = "ti,afe4403";
reg = <0>;
spi-max-frequency = <10000000>;
tx-supply = <&vbat>;
interrupt-parent = <&gpio1>;
interrupts = <28 IRQ_TYPE_EDGE_RISING>;
reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
};
...

View File

@@ -0,0 +1,51 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/health/ti,afe4404.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments AFE4404 Heart rate and Pulse Oximeter
maintainers:
- Jonathan Cameron <jic23@kernel.org>
properties:
compatible:
const: ti,afe4403
reg:
maxItems: 1
tx-supply:
description: Supply to transmitting LEDs.
interrupts:
maxItems: 1
description: Connected to ADC_RDY pin.
reset-gpios: true
additionalProperties: false
required:
- compatible
- reg
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
heart_mon@58 {
compatible = "ti,afe4404";
reg = <0x58>;
tx-supply = <&vbat>;
interrupt-parent = <&gpio1>;
interrupts = <28 IRQ_TYPE_EDGE_RISING>;
reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
};
};
...

View File

@@ -26,6 +26,8 @@ properties:
The interrupt/data ready line will be configured as open drain, which
is useful if several sensors share the same interrupt line.
vdd-supply: true
interrupts:
maxItems: 1

View File

@@ -1,102 +0,0 @@
This binding is derived from clock bindings, and based on suggestions
from Lars-Peter Clausen [1].
Sources of IIO channels can be represented by any node in the device
tree. Those nodes are designated as IIO providers. IIO consumer
nodes use a phandle and IIO specifier pair to connect IIO provider
outputs to IIO inputs. Similar to the gpio specifiers, an IIO
specifier is an array of one or more cells identifying the IIO
output on a device. The length of an IIO specifier is defined by the
value of a #io-channel-cells property in the IIO provider node.
[1] https://marc.info/?l=linux-iio&m=135902119507483&w=2
==IIO providers==
Required properties:
#io-channel-cells: Number of cells in an IIO specifier; Typically 0 for nodes
with a single IIO output and 1 for nodes with multiple
IIO outputs.
Optional properties:
label: A symbolic name for the device.
Example for a simple configuration with no trigger:
adc: voltage-sensor@35 {
compatible = "maxim,max1139";
reg = <0x35>;
#io-channel-cells = <1>;
label = "voltage_feedback_group1";
};
Example for a configuration with trigger:
adc@35 {
compatible = "some-vendor,some-adc";
reg = <0x35>;
adc1: iio-device@0 {
#io-channel-cells = <1>;
/* other properties */
};
adc2: iio-device@1 {
#io-channel-cells = <1>;
/* other properties */
};
};
==IIO consumers==
Required properties:
io-channels: List of phandle and IIO specifier pairs, one pair
for each IIO input to the device. Note: if the
IIO provider specifies '0' for #io-channel-cells,
then only the phandle portion of the pair will appear.
Optional properties:
io-channel-names:
List of IIO input name strings sorted in the same
order as the io-channels property. Consumers drivers
will use io-channel-names to match IIO input names
with IIO specifiers.
io-channel-ranges:
Empty property indicating that child nodes can inherit named
IIO channels from this node. Useful for bus nodes to provide
and IIO channel to their children.
For example:
device {
io-channels = <&adc 1>, <&ref 0>;
io-channel-names = "vcc", "vdd";
};
This represents a device with two IIO inputs, named "vcc" and "vdd".
The vcc channel is connected to output 1 of the &adc device, and the
vdd channel is connected to output 0 of the &ref device.
==Example==
adc: max1139@35 {
compatible = "maxim,max1139";
reg = <0x35>;
#io-channel-cells = <1>;
};
...
iio-hwmon {
compatible = "iio-hwmon";
io-channels = <&adc 0>, <&adc 1>, <&adc 2>,
<&adc 3>, <&adc 4>, <&adc 5>,
<&adc 6>, <&adc 7>, <&adc 8>,
<&adc 9>;
};
some_consumer {
compatible = "some-consumer";
io-channels = <&adc 10>, <&adc 11>;
io-channel-names = "adc1", "adc2";
};

View File

@@ -30,6 +30,7 @@ properties:
- st,lsm6ds0
- st,lsm6dsrx
- st,lsm6dst
- st,lsm6dsop
reg:
maxItems: 1
@@ -42,6 +43,12 @@ properties:
spi-max-frequency: true
vdd-supply:
description: if defined provides VDD power to the sensor.
vddio-supply:
description: if defined provides VDD IO power to the sensor.
st,drdy-int-pin:
$ref: '/schemas/types.yaml#/definitions/uint32'
description: |

View File

@@ -0,0 +1,79 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/light/capella,cm3605.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title:
Capella Microsystems CM3605 Ambient Light and Short Distance Proximity Sensor
maintainers:
- Linus Walleij <linus.walleij@linaro.org>
- Kevin Tsai <ktsai@capellamicro.com>
description: |
The CM3605 is an entirely analog part. However, it requires quite a bit of
software logic to interface a host operating system.
This ALS and proximity sensor was one of the very first deployed in mobile
handsets, notably it is used in the very first Nexus One Android phone from
2010.
properties:
compatible:
const: capella,cm3605
aset-gpios:
maxItems: 1
description:
ASET line (drive low to activate the ALS, should be flagged
GPIO_ACTIVE_LOW)
interrupts:
maxItems: 1
description:
Connected to the POUT (proximity sensor out) line. The edge
detection must be set to IRQ_TYPE_EDGE_BOTH so as to detect
movements toward and away from the proximity sensor.
io-channels:
maxItems: 1
description:
ADC channel used for converting the voltage from AOUT to a digital
representation.
io-channel-names:
const: aout
vdd-supply: true
capella,aset-resistance-ohms:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [50000, 100000, 300000, 600000]
description: >
Sensitivity calibration resistance. Note that calibration curves
are only provided for specific allowed values. Default: 100 kOhms.
required:
- compatible
- aset-gpios
- interrupts
- io-channels
- io-channel-names
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
light-sensor {
compatible = "capella,cm3605";
vdd-supply = <&foo_reg>;
aset-gpios = <&foo_gpio 1 GPIO_ACTIVE_LOW>;
capella,aset-resistance-ohms = <100000>;
interrupts = <1 IRQ_TYPE_EDGE_BOTH>;
io-channels = <&adc 0x01>;
io-channel-names = "aout";
};
...

View File

@@ -1,41 +0,0 @@
Capella Microsystems CM3605
Ambient Light and Short Distance Proximity Sensor
The CM3605 is an entirely analog part which however require quite a bit of
software logic to interface a host operating system.
This ALS and proximity sensor was one of the very first deployed in mobile
handsets, notably it is used in the very first Nexus One Android phone from
2010.
Required properties:
- compatible: must be: "capella,cm3605"
- aset-gpios: GPIO line controlling the ASET line (drive low
to activate the ALS, should be flagged GPIO_ACTIVE_LOW)
- interrupts: the IRQ line (such as a GPIO) that is connected to
the POUT (proximity sensor out) line. The edge detection must
be set to IRQ_TYPE_EDGE_BOTH so as to detect movements toward
and away from the proximity sensor.
- io-channels: the ADC channel used for converting the voltage from
AOUT to a digital representation.
- io-channel-names: must be "aout"
Optional properties:
- vdd-supply: regulator supplying VDD power to the component.
- capella,aset-resistance-ohms: the sensitivity calibration resistance,
in Ohms. Valid values are: 50000, 100000, 300000 and 600000,
as these are the resistance values that we are supplied with
calibration curves for. If not supplied, 100 kOhm will be assumed
but it is strongly recommended to supply this.
Example:
cm3605 {
compatible = "capella,cm3605";
vdd-supply = <&foo_reg>;
aset-gpios = <&foo_gpio 1 GPIO_ACTIVE_LOW>;
capella,aset-resistance-ohms = <100000>;
interrupts = <1 IRQ_TYPE_EDGE_BOTH>;
io-channels = <&adc 0x01>;
io-channel-names = "aout";
};

View File

@@ -0,0 +1,116 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/potentiometer/microchip,mcp4531.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip mcp4531 and similar potentiometers.
maintainers:
- Peter Rosin <peda@axentia.se>
description: |
Family of I2C digital potentiometer
Datasheets at:
* volatile https://ww1.microchip.com/downloads/en/DeviceDoc/22096b.pdf
* non-volatile https://ww1.microchip.com/downloads/en/DeviceDoc/22107B.pdf
Part numbers as follows: mcp4ABC-XXX where
A = 5 (1 wiper), 6 (2 wipers)
B = 3 (7-bit, volatile), 4 (7-bit, non-volatile),
5 (8-bit, volatile), 6 (8-bit, non-volatile),
C: 1 (potentiometer), 2 (rheostat)
XXX = 502 (5 kOhms), 103 (10 kOhms), 503 (50 kOhms), 104 (100 kOhms)
properties:
compatible:
enum:
# Ordering reflects part number + range, so 502 < 103 etc
- microchip,mcp4531-502
- microchip,mcp4531-103
- microchip,mcp4531-503
- microchip,mcp4531-104
- microchip,mcp4532-502
- microchip,mcp4532-103
- microchip,mcp4532-503
- microchip,mcp4532-104
- microchip,mcp4541-502
- microchip,mcp4541-103
- microchip,mcp4541-503
- microchip,mcp4541-104
- microchip,mcp4542-502
- microchip,mcp4542-103
- microchip,mcp4542-503
- microchip,mcp4542-104
- microchip,mcp4551-502
- microchip,mcp4551-103
- microchip,mcp4551-503
- microchip,mcp4551-104
- microchip,mcp4552-502
- microchip,mcp4552-103
- microchip,mcp4552-503
- microchip,mcp4552-104
- microchip,mcp4561-502
- microchip,mcp4561-103
- microchip,mcp4561-503
- microchip,mcp4561-104
- microchip,mcp4562-502
- microchip,mcp4562-103
- microchip,mcp4562-503
- microchip,mcp4562-104
- microchip,mcp4631-502
- microchip,mcp4631-103
- microchip,mcp4631-503
- microchip,mcp4631-104
- microchip,mcp4632-502
- microchip,mcp4632-103
- microchip,mcp4632-503
- microchip,mcp4632-104
- microchip,mcp4641-502
- microchip,mcp4641-103
- microchip,mcp4641-503
- microchip,mcp4641-104
- microchip,mcp4642-502
- microchip,mcp4642-103
- microchip,mcp4642-503
- microchip,mcp4642-104
- microchip,mcp4651-502
- microchip,mcp4651-103
- microchip,mcp4651-503
- microchip,mcp4651-104
- microchip,mcp4652-502
- microchip,mcp4652-103
- microchip,mcp4652-503
- microchip,mcp4652-104
- microchip,mcp4661-502
- microchip,mcp4661-103
- microchip,mcp4661-503
- microchip,mcp4661-104
- microchip,mcp4662-502
- microchip,mcp4662-103
- microchip,mcp4662-503
- microchip,mcp4662-104
reg:
maxItems: 1
"#io-channel-cells":
const: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
dpot: dpot@28 {
compatible = "microchip,mcp4651-104";
reg = <0x28>;
#io-channel-cells = <1>;
};
};
...

View File

@@ -1,33 +0,0 @@
* Texas Instruments LMP91000 series of potentiostats
LMP91000: https://www.ti.com/lit/ds/symlink/lmp91000.pdf
LMP91002: https://www.ti.com/lit/ds/symlink/lmp91002.pdf
Required properties:
- compatible: should be one of the following:
"ti,lmp91000"
"ti,lmp91002"
- reg: the I2C address of the device
- io-channels: the phandle of the iio provider
- ti,external-tia-resistor: if the property ti,tia-gain-ohm is not defined this
needs to be set to signal that an external resistor value is being used.
Optional properties:
- ti,tia-gain-ohm: ohm value of the internal resistor for the transimpedance
amplifier. Must be 2750, 3500, 7000, 14000, 35000, 120000, or 350000 ohms.
- ti,rload-ohm: ohm value of the internal resistor load applied to the gas
sensor. Must be 10, 33, 50, or 100 (default) ohms.
Example:
lmp91000@48 {
compatible = "ti,lmp91000";
reg = <0x48>;
ti,tia-gain-ohm = <7500>;
ti,rload = <100>;
io-channels = <&adc>;
};

View File

@@ -0,0 +1,68 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/potentiostat/ti,lmp91000.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments LMP91000 series of potentiostats with I2C control
maintainers:
- Matt Ranostay <matt.ranostay@konsulko.com>
description: |
Typically used as a signal conditioner for chemical sensors.
LMP91000: https://www.ti.com/lit/ds/symlink/lmp91000.pdf
LMP91002: https://www.ti.com/lit/ds/symlink/lmp91002.pdf
properties:
compatible:
enum:
- ti,lmp91000
- ti,lmp91002
reg:
maxItems: 1
io-channels:
maxItems: 1
ti,external-tia-resistor:
$ref: /schemas/types.yaml#/definitions/flag
description:
If the property ti,tia-gain-ohm is not defined this needs to be set to
signal that an external resistor value is being used.
ti,tia-gain-ohm:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [2750, 3500, 7000, 14000, 35000, 120000, 350000]
description:
Internal resistor for the transimpedance amplifier.
ti,rload-ohm:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [10, 33, 50, 100]
description:
Internal resistor load applied to the gas sensor.
Default 100 Ohms.
required:
- compatible
- reg
- io-channels
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
lmp91000@48 {
compatible = "ti,lmp91000";
reg = <0x48>;
ti,tia-gain-ohm = <7000>;
ti,rload-ohm = <100>;
io-channels = <&adc>;
};
};
...

View File

@@ -0,0 +1,123 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/st,st-sensors.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics MEMS sensors
description: |
Note that whilst this covers many STMicro MEMs sensors, some more complex
IMUs need their own bindings.
The STMicroelectronics sensor devices are pretty straight-forward I2C or
SPI devices, all sharing the same device tree descriptions no matter what
type of sensor it is.
maintainers:
- Denis Ciocca <denis.ciocca@st.com>
properties:
compatible:
description: |
Some values are deprecated.
st,lis3lv02d (deprecated, use st,lis3lv02dl-accel)
st,lis302dl-spi (deprecated, use st,lis3lv02dl-accel)
enum:
# Accelerometers
- st,lis3lv02d
- st,lis302dl-spi
- st,lis3lv02dl-accel
- st,lsm303dlh-accel
- st,lsm303dlhc-accel
- st,lis3dh-accel
- st,lsm330d-accel
- st,lsm330dl-accel
- st,lsm330dlc-accel
- st,lis331dl-accel
- st,lis331dlh-accel
- st,lsm303dl-accel
- st,lsm303dlm-accel
- st,lsm330-accel
- st,lsm303agr-accel
- st,lis2dh12-accel
- st,h3lis331dl-accel
- st,lng2dm-accel
- st,lis3l02dq
- st,lis2dw12
- st,lis3dhh
- st,lis3de
- st,lis2de12
- st,lis2hh12
# Gyroscopes
- st,l3g4200d-gyro
- st,lsm330d-gyro
- st,lsm330dl-gyro
- st,lsm330dlc-gyro
- st,l3gd20-gyro
- st,l3gd20h-gyro
- st,l3g4is-gyro
- st,lsm330-gyro
- st,lsm9ds0-gyro
# Magnetometers
- st,lsm303agr-magn
- st,lsm303dlh-magn
- st,lsm303dlhc-magn
- st,lsm303dlm-magn
- st,lis3mdl-magn
- st,lis2mdl
- st,lsm9ds1-magn
# Pressure sensors
- st,lps001wp-press
- st,lps25h-press
- st,lps331ap-press
- st,lps22hb-press
- st,lps33hw
- st,lps35hw
- st,lps22hh
reg:
maxItems: 1
interrupts:
minItems: 1
vdd-supply: true
vddio-supply: true
st,drdy-int-pin:
$ref: /schemas/types.yaml#/definitions/uint32
description:
Some sensors have multiple possible pins via which they can provide
a data ready interrupt. This selects which one.
enum:
- 1
- 2
drive-open-drain:
$ref: /schemas/types.yaml#/definitions/flag
description: |
The interrupt/data ready line will be configured as open drain, which
is useful if several sensors share the same interrupt line.
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
accelerometer@1d {
compatible = "st,lis3lv02dl-accel";
reg = <0x1d>;
interrupt-parent = <&gpio2>;
interrupts = <18 IRQ_TYPE_EDGE_RISING>;
pinctrl-0 = <&lis3lv02dl_nhk_mode>;
pinctrl-names = "default";
};
};
...

View File

@@ -1,82 +0,0 @@
STMicroelectronics MEMS sensors
The STMicroelectronics sensor devices are pretty straight-forward I2C or
SPI devices, all sharing the same device tree descriptions no matter what
type of sensor it is.
Required properties:
- compatible: see the list of valid compatible strings below
- reg: the I2C or SPI address the device will respond to
Optional properties:
- vdd-supply: an optional regulator that needs to be on to provide VDD
power to the sensor.
- vddio-supply: an optional regulator that needs to be on to provide the
VDD IO power to the sensor.
- st,drdy-int-pin: the pin on the package that will be used to signal
"data ready" (valid values: 1 or 2). This property is not configurable
on all sensors.
- drive-open-drain: the interrupt/data ready line will be configured
as open drain, which is useful if several sensors share the same
interrupt line. (This binding is taken from pinctrl/pinctrl-bindings.txt)
This is a boolean property.
Sensors may also have applicable pin control settings, those use the
standard bindings from pinctrl/pinctrl-bindings.txt.
Valid compatible strings:
Accelerometers:
- st,lis3lv02d (deprecated, use st,lis3lv02dl-accel)
- st,lis302dl-spi (deprecated, use st,lis3lv02dl-accel)
- st,lis3lv02dl-accel
- st,lsm303dlh-accel
- st,lsm303dlhc-accel
- st,lis3dh-accel
- st,lsm330d-accel
- st,lsm330dl-accel
- st,lsm330dlc-accel
- st,lis331dl-accel
- st,lis331dlh-accel
- st,lsm303dl-accel
- st,lsm303dlm-accel
- st,lsm330-accel
- st,lsm303agr-accel
- st,lis2dh12-accel
- st,h3lis331dl-accel
- st,lng2dm-accel
- st,lis3l02dq
- st,lis2dw12
- st,lis3dhh
- st,lis3de
- st,lis2de12
- st,lis2hh12
Gyroscopes:
- st,l3g4200d-gyro
- st,lsm330d-gyro
- st,lsm330dl-gyro
- st,lsm330dlc-gyro
- st,l3gd20-gyro
- st,l3gd20h-gyro
- st,l3g4is-gyro
- st,lsm330-gyro
- st,lsm9ds0-gyro
Magnetometers:
- st,lsm303agr-magn
- st,lsm303dlh-magn
- st,lsm303dlhc-magn
- st,lsm303dlm-magn
- st,lis3mdl-magn
- st,lis2mdl
- st,lsm9ds1-magn
Pressure sensors:
- st,lps001wp-press
- st,lps25h-press
- st,lps331ap-press
- st,lps22hb-press
- st,lps33hw
- st,lps35hw
- st,lps22hh

View File

@@ -1,7 +0,0 @@
If the temperature sensor device can be configured to use some specific
thermocouple type, you can use the defined types provided in the file
"include/dt-bindings/iio/temperature/thermocouple.h".
Property:
thermocouple-type: A single cell representing the type of the thermocouple
used by the device.

View File

@@ -122,18 +122,6 @@ properties:
- maxim,ds1803-050
# 100 kOhm digital potentiometer with I2C interface
- maxim,ds1803-100
# 10-bit 8 channels 300ks/s SPI ADC with temperature sensor
- maxim,max1027
# 10-bit 12 channels 300ks/s SPI ADC with temperature sensor
- maxim,max1029
# 10-bit 16 channels 300ks/s SPI ADC with temperature sensor
- maxim,max1031
# 12-bit 8 channels 300ks/s SPI ADC with temperature sensor
- maxim,max1227
# 12-bit 12 channels 300ks/s SPI ADC with temperature sensor
- maxim,max1229
# 12-bit 16 channels 300ks/s SPI ADC with temperature sensor
- maxim,max1231
# Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
- maxim,max1237
# 10-bit 10 kOhm linear programable voltage divider
@@ -210,134 +198,6 @@ properties:
- microchip,mcp4019-503
# Microchip 7-bit Single I2C Digital POT (100k)
- microchip,mcp4019-104
# Microchip 7-bit Single I2C Digital Potentiometer (5k)
- microchip,mcp4531-502
# Microchip 7-bit Single I2C Digital Potentiometer (10k)
- microchip,mcp4531-103
# Microchip 7-bit Single I2C Digital Potentiometer (50k)
- microchip,mcp4531-503
# Microchip 7-bit Single I2C Digital Potentiometer (100k)
- microchip,mcp4531-104
# Microchip 7-bit Single I2C Digital Potentiometer (5k)
- microchip,mcp4532-502
# Microchip 7-bit Single I2C Digital Potentiometer (10k)
- microchip,mcp4532-103
# Microchip 7-bit Single I2C Digital Potentiometer (50k)
- microchip,mcp4532-503
# Microchip 7-bit Single I2C Digital Potentiometer (100k)
- microchip,mcp4532-104
# Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (5k)
- microchip,mcp4541-502
# Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (10k)
- microchip,mcp4541-103
# Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (50k)
- microchip,mcp4541-503
# Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (100k)
- microchip,mcp4541-104
# Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (5k)
- microchip,mcp4542-502
# Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (10k)
- microchip,mcp4542-103
# Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (50k)
- microchip,mcp4542-503
# Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (100k)
- microchip,mcp4542-104
# Microchip 8-bit Single I2C Digital Potentiometer (5k)
- microchip,mcp4551-502
# Microchip 8-bit Single I2C Digital Potentiometer (10k)
- microchip,mcp4551-103
# Microchip 8-bit Single I2C Digital Potentiometer (50k)
- microchip,mcp4551-503
# Microchip 8-bit Single I2C Digital Potentiometer (100k)
- microchip,mcp4551-104
# Microchip 8-bit Single I2C Digital Potentiometer (5k)
- microchip,mcp4552-502
# Microchip 8-bit Single I2C Digital Potentiometer (10k)
- microchip,mcp4552-103
# Microchip 8-bit Single I2C Digital Potentiometer (50k)
- microchip,mcp4552-503
# Microchip 8-bit Single I2C Digital Potentiometer (100k)
- microchip,mcp4552-104
# Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (5k)
- microchip,mcp4561-502
# Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (10k)
- microchip,mcp4561-103
# Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (50k)
- microchip,mcp4561-503
# Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (100k)
- microchip,mcp4561-104
# Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (5k)
- microchip,mcp4562-502
# Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (10k)
- microchip,mcp4562-103
# Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (50k)
- microchip,mcp4562-503
# Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (100k)
- microchip,mcp4562-104
# Microchip 7-bit Dual I2C Digital Potentiometer (5k)
- microchip,mcp4631-502
# Microchip 7-bit Dual I2C Digital Potentiometer (10k)
- microchip,mcp4631-103
# Microchip 7-bit Dual I2C Digital Potentiometer (50k)
- microchip,mcp4631-503
# Microchip 7-bit Dual I2C Digital Potentiometer (100k)
- microchip,mcp4631-104
# Microchip 7-bit Dual I2C Digital Potentiometer (5k)
- microchip,mcp4632-502
# Microchip 7-bit Dual I2C Digital Potentiometer (10k)
- microchip,mcp4632-103
# Microchip 7-bit Dual I2C Digital Potentiometer (50k)
- microchip,mcp4632-503
# Microchip 7-bit Dual I2C Digital Potentiometer (100k)
- microchip,mcp4632-104
# Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (5k)
- microchip,mcp4641-502
# Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (10k)
- microchip,mcp4641-103
# Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (50k)
- microchip,mcp4641-503
# Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (100k)
- microchip,mcp4641-104
# Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (5k)
- microchip,mcp4642-502
# Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (10k)
- microchip,mcp4642-103
# Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (50k)
- microchip,mcp4642-503
# Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (100k)
- microchip,mcp4642-104
# Microchip 8-bit Dual I2C Digital Potentiometer (5k)
- microchip,mcp4651-502
# Microchip 8-bit Dual I2C Digital Potentiometer (10k)
- microchip,mcp4651-103
# Microchip 8-bit Dual I2C Digital Potentiometer (50k)
- microchip,mcp4651-503
# Microchip 8-bit Dual I2C Digital Potentiometer (100k)
- microchip,mcp4651-104
# Microchip 8-bit Dual I2C Digital Potentiometer (5k)
- microchip,mcp4652-502
# Microchip 8-bit Dual I2C Digital Potentiometer (10k)
- microchip,mcp4652-103
# Microchip 8-bit Dual I2C Digital Potentiometer (50k)
- microchip,mcp4652-503
# Microchip 8-bit Dual I2C Digital Potentiometer (100k)
- microchip,mcp4652-104
# Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (5k)
- microchip,mcp4661-502
# Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (10k)
- microchip,mcp4661-103
# Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (50k)
- microchip,mcp4661-503
# Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k)
- microchip,mcp4661-104
# Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (5k)
- microchip,mcp4662-502
# Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (10k)
- microchip,mcp4662-103
# Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (50k)
- microchip,mcp4662-503
# Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k)
- microchip,mcp4662-104
# PWM Fan Speed Controller With Fan Fault Detection
- microchip,tc654
# PWM Fan Speed Controller With Fan Fault Detection

View File

@@ -2110,6 +2110,13 @@ T: git git://github.com/microchip-ung/linux-upstream.git
F: arch/arm64/boot/dts/microchip/
N: sparx5
Microchip Timer Counter Block (TCB) Capture Driver
M: Kamel Bouhara <kamel.bouhara@bootlin.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-iio@vger.kernel.org
S: Maintained
F: drivers/counter/microchip-tcb-capture.c
ARM/MIOA701 MACHINE SUPPORT
M: Robert Jarzmik <robert.jarzmik@free.fr>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)

View File

@@ -183,16 +183,20 @@ static int mchp_tc_count_action_get(struct counter_device *counter,
regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr);
*action = MCHP_TC_SYNAPSE_ACTION_NONE;
if (cmr & ATMEL_TC_ETRGEDG_NONE)
switch (cmr & ATMEL_TC_ETRGEDG) {
default:
*action = MCHP_TC_SYNAPSE_ACTION_NONE;
else if (cmr & ATMEL_TC_ETRGEDG_RISING)
break;
case ATMEL_TC_ETRGEDG_RISING:
*action = MCHP_TC_SYNAPSE_ACTION_RISING_EDGE;
else if (cmr & ATMEL_TC_ETRGEDG_FALLING)
break;
case ATMEL_TC_ETRGEDG_FALLING:
*action = MCHP_TC_SYNAPSE_ACTION_FALLING_EDGE;
else if (cmr & ATMEL_TC_ETRGEDG_BOTH)
break;
case ATMEL_TC_ETRGEDG_BOTH:
*action = MCHP_TC_SYNAPSE_ACTION_BOTH_EDGE;
break;
}
return 0;
}

View File

@@ -959,17 +959,20 @@ static int bma180_data_rdy_trigger_set_state(struct iio_trigger *trig,
return bma180_set_new_data_intr_state(data, state);
}
static int bma180_trig_try_reen(struct iio_trigger *trig)
static void bma180_trig_reen(struct iio_trigger *trig)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct bma180_data *data = iio_priv(indio_dev);
int ret;
return bma180_reset_intr(data);
ret = bma180_reset_intr(data);
if (ret)
dev_err(&data->client->dev, "failed to reset interrupt\n");
}
static const struct iio_trigger_ops bma180_trigger_ops = {
.set_trigger_state = bma180_data_rdy_trigger_set_state,
.try_reenable = bma180_trig_try_reen,
.reenable = bma180_trig_reen,
};
static int bma180_probe(struct i2c_client *client,

View File

@@ -5,6 +5,7 @@
* - BMI055
* - BMA255
* - BMA250E
* - BMA222
* - BMA222E
* - BMA280
*
@@ -27,6 +28,7 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include "bmc150-accel.h"
@@ -183,7 +185,7 @@ enum bmc150_accel_trigger_id {
struct bmc150_accel_data {
struct regmap *regmap;
int irq;
struct regulator_bulk_data regulators[2];
struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
struct mutex mutex;
@@ -204,6 +206,7 @@ struct bmc150_accel_data {
int ev_enable_state;
int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
const struct bmc150_accel_chip_info *chip_info;
struct i2c_client *second_device;
struct iio_mount_matrix orientation;
};
@@ -410,6 +413,103 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
}
#endif
#ifdef CONFIG_ACPI
/*
* Support for getting accelerometer information from BOSC0200 ACPI nodes.
*
* There are 2 variants of the BOSC0200 ACPI node. Some 2-in-1s with 360 degree
* hinges declare 2 I2C ACPI-resources for 2 accelerometers, 1 in the display
* and 1 in the base of the 2-in-1. On these 2-in-1s the ROMS ACPI object
* contains the mount-matrix for the sensor in the display and ROMK contains
* the mount-matrix for the sensor in the base. On devices using a single
* sensor there is a ROTM ACPI object which contains the mount-matrix.
*
* Here is an incomplete list of devices known to use 1 of these setups:
*
* Yoga devices with 2 accelerometers using ROMS + ROMK for the mount-matrices:
* Lenovo Thinkpad Yoga 11e 3th gen
* Lenovo Thinkpad Yoga 11e 4th gen
*
* Tablets using a single accelerometer using ROTM for the mount-matrix:
* Chuwi Hi8 Pro (CWI513)
* Chuwi Vi8 Plus (CWI519)
* Chuwi Hi13
* Irbis TW90
* Jumper EZpad mini 3
* Onda V80 plus
* Predia Basic Tablet
*/
static bool bmc150_apply_acpi_orientation(struct device *dev,
struct iio_mount_matrix *orientation)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
struct acpi_device *adev = ACPI_COMPANION(dev);
union acpi_object *obj, *elements;
char *name, *alt_name, *str;
acpi_status status;
int i, j, val[3];
if (!adev || !acpi_dev_hid_uid_match(adev, "BOSC0200", NULL))
return false;
if (strcmp(dev_name(dev), "i2c-BOSC0200:base") == 0)
alt_name = "ROMK";
else
alt_name = "ROMS";
if (acpi_has_method(adev->handle, "ROTM"))
name = "ROTM";
else if (acpi_has_method(adev->handle, alt_name))
name = alt_name;
else
return false;
status = acpi_evaluate_object(adev->handle, name, NULL, &buffer);
if (ACPI_FAILURE(status)) {
dev_warn(dev, "Failed to get ACPI mount matrix: %d\n", status);
return false;
}
obj = buffer.pointer;
if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3)
goto unknown_format;
elements = obj->package.elements;
for (i = 0; i < 3; i++) {
if (elements[i].type != ACPI_TYPE_STRING)
goto unknown_format;
str = elements[i].string.pointer;
if (sscanf(str, "%d %d %d", &val[0], &val[1], &val[2]) != 3)
goto unknown_format;
for (j = 0; j < 3; j++) {
switch (val[j]) {
case -1: str = "-1"; break;
case 0: str = "0"; break;
case 1: str = "1"; break;
default: goto unknown_format;
}
orientation->rotation[i * 3 + j] = str;
}
}
kfree(buffer.pointer);
return true;
unknown_format:
dev_warn(dev, "Unknown ACPI mount matrix format, ignoring\n");
kfree(buffer.pointer);
return false;
}
#else
static bool bmc150_apply_acpi_orientation(struct device *dev,
struct iio_mount_matrix *orientation)
{
return false;
}
#endif
static const struct bmc150_accel_interrupt_info {
u8 map_reg;
u8 map_bitmask;
@@ -1063,6 +1163,20 @@ static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
{153277, BMC150_ACCEL_DEF_RANGE_8G},
{306457, BMC150_ACCEL_DEF_RANGE_16G} },
},
[bma222] = {
.name = "BMA222",
.chip_id = 0x03,
.channels = bma222e_accel_channels,
.num_channels = ARRAY_SIZE(bma222e_accel_channels),
/*
* The datasheet page 17 says:
* 15.6, 31.3, 62.5 and 125 mg per LSB.
*/
.scale_table = { {156000, BMC150_ACCEL_DEF_RANGE_2G},
{313000, BMC150_ACCEL_DEF_RANGE_4G},
{625000, BMC150_ACCEL_DEF_RANGE_8G},
{1250000, BMC150_ACCEL_DEF_RANGE_16G} },
},
[bma222e] = {
.name = "BMA222E",
.chip_id = 0xF8,
@@ -1134,7 +1248,7 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
return IRQ_HANDLED;
}
static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
static void bmc150_accel_trig_reen(struct iio_trigger *trig)
{
struct bmc150_accel_trigger *t = iio_trigger_get_drvdata(trig);
struct bmc150_accel_data *data = t->data;
@@ -1143,7 +1257,7 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
/* new data interrupts don't need ack */
if (t == &t->data->triggers[BMC150_ACCEL_TRIGGER_DATA_READY])
return 0;
return;
mutex_lock(&data->mutex);
/* clear any latched interrupt */
@@ -1151,12 +1265,8 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
BMC150_ACCEL_INT_MODE_LATCH_INT |
BMC150_ACCEL_INT_MODE_LATCH_RESET);
mutex_unlock(&data->mutex);
if (ret < 0) {
if (ret < 0)
dev_err(dev, "Error writing reg_int_rst_latch\n");
return ret;
}
return 0;
}
static int bmc150_accel_trigger_set_state(struct iio_trigger *trig,
@@ -1196,7 +1306,7 @@ static int bmc150_accel_trigger_set_state(struct iio_trigger *trig,
static const struct iio_trigger_ops bmc150_accel_trigger_ops = {
.set_trigger_state = bmc150_accel_trigger_set_state,
.try_reenable = bmc150_accel_trig_try_reen,
.reenable = bmc150_accel_trig_reen,
};
static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
@@ -1569,18 +1679,43 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
data = iio_priv(indio_dev);
dev_set_drvdata(dev, indio_dev);
data->irq = irq;
data->regmap = regmap;
ret = iio_read_mount_matrix(dev, "mount-matrix",
&data->orientation);
if (!bmc150_apply_acpi_orientation(dev, &data->orientation)) {
ret = iio_read_mount_matrix(dev, "mount-matrix",
&data->orientation);
if (ret)
return ret;
}
/*
* VDD is the analog and digital domain voltage supply
* VDDIO is the digital I/O voltage supply
*/
data->regulators[0].supply = "vdd";
data->regulators[1].supply = "vddio";
ret = devm_regulator_bulk_get(dev,
ARRAY_SIZE(data->regulators),
data->regulators);
if (ret)
return dev_err_probe(dev, ret, "failed to get regulators\n");
ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
data->regulators);
if (ret) {
dev_err(dev, "failed to enable regulators: %d\n", ret);
return ret;
}
/*
* 2ms or 3ms power-on time according to datasheets, let's better
* be safe than sorry and set this delay to 5ms.
*/
msleep(5);
ret = bmc150_accel_chip_init(data);
if (ret < 0)
return ret;
goto err_disable_regulators;
mutex_init(&data->mutex);
@@ -1606,12 +1741,11 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
fifo_attrs);
if (ret < 0) {
dev_err(dev, "Failed: iio triggered buffer setup\n");
return ret;
goto err_disable_regulators;
}
if (data->irq > 0) {
ret = devm_request_threaded_irq(
dev, data->irq,
if (irq > 0) {
ret = devm_request_threaded_irq(dev, irq,
bmc150_accel_irq_handler,
bmc150_accel_irq_thread_handler,
IRQF_TRIGGER_RISING,
@@ -1660,11 +1794,34 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1);
err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
err_disable_regulators:
regulator_bulk_disable(ARRAY_SIZE(data->regulators),
data->regulators);
return ret;
}
EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
struct i2c_client *bmc150_get_second_device(struct i2c_client *client)
{
struct bmc150_accel_data *data = i2c_get_clientdata(client);
if (!data)
return NULL;
return data->second_device;
}
EXPORT_SYMBOL_GPL(bmc150_get_second_device);
void bmc150_set_second_device(struct i2c_client *client)
{
struct bmc150_accel_data *data = i2c_get_clientdata(client);
if (data)
data->second_device = client;
}
EXPORT_SYMBOL_GPL(bmc150_set_second_device);
int bmc150_accel_core_remove(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
@@ -1684,6 +1841,9 @@ int bmc150_accel_core_remove(struct device *dev)
bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_DEEP_SUSPEND, 0);
mutex_unlock(&data->mutex);
regulator_bulk_disable(ARRAY_SIZE(data->regulators),
data->regulators);
return 0;
}
EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);

View File

@@ -5,6 +5,7 @@
* - BMI055
* - BMA255
* - BMA250E
* - BMA222
* - BMA222E
* - BMA280
*
@@ -29,6 +30,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_I2C_BLOCK);
struct acpi_device __maybe_unused *adev;
int ret;
regmap = devm_regmap_init_i2c(client, &bmc150_regmap_conf);
if (IS_ERR(regmap)) {
@@ -39,12 +42,47 @@ static int bmc150_accel_probe(struct i2c_client *client,
if (id)
name = id->name;
return bmc150_accel_core_probe(&client->dev, regmap, client->irq, name,
block_supported);
ret = bmc150_accel_core_probe(&client->dev, regmap, client->irq, name, block_supported);
if (ret)
return ret;
/*
* Some BOSC0200 acpi_devices describe 2 accelerometers in a single ACPI
* device, try instantiating a second i2c_client for an I2cSerialBusV2
* ACPI resource with index 1. The !id check avoids recursion when
* bmc150_accel_probe() gets called for the second client.
*/
#ifdef CONFIG_ACPI
adev = ACPI_COMPANION(&client->dev);
if (!id && adev && strcmp(acpi_device_hid(adev), "BOSC0200") == 0) {
struct i2c_board_info board_info = {
.type = "bmc150_accel",
/*
* The 2nd accel sits in the base of 2-in-1s. Note this
* name is static, as there should never be more then 1
* BOSC0200 ACPI node with 2 accelerometers in it.
*/
.dev_name = "BOSC0200:base",
.fwnode = client->dev.fwnode,
.irq = -ENOENT,
};
struct i2c_client *second_dev;
second_dev = i2c_acpi_new_device(&client->dev, 1, &board_info);
if (!IS_ERR(second_dev))
bmc150_set_second_device(second_dev);
}
#endif
return 0;
}
static int bmc150_accel_remove(struct i2c_client *client)
{
struct i2c_client *second_dev = bmc150_get_second_device(client);
i2c_unregister_device(second_dev);
return bmc150_accel_core_remove(&client->dev);
}
@@ -54,6 +92,7 @@ static const struct acpi_device_id bmc150_accel_acpi_match[] = {
{"BMI055A", bmi055},
{"BMA0255", bma255},
{"BMA250E", bma250e},
{"BMA222", bma222},
{"BMA222E", bma222e},
{"BMA0280", bma280},
{"BOSC0200"},
@@ -66,6 +105,7 @@ static const struct i2c_device_id bmc150_accel_id[] = {
{"bmi055_accel", bmi055},
{"bma255", bma255},
{"bma250e", bma250e},
{"bma222", bma222},
{"bma222e", bma222e},
{"bma280", bma280},
{}
@@ -78,6 +118,7 @@ static const struct of_device_id bmc150_accel_of_match[] = {
{ .compatible = "bosch,bmi055_accel" },
{ .compatible = "bosch,bma255" },
{ .compatible = "bosch,bma250e" },
{ .compatible = "bosch,bma222" },
{ .compatible = "bosch,bma222e" },
{ .compatible = "bosch,bma280" },
{ },

View File

@@ -39,6 +39,7 @@ static const struct acpi_device_id bmc150_accel_acpi_match[] = {
{"BMI055A", bmi055},
{"BMA0255", bma255},
{"BMA250E", bma250e},
{"BMA222", bma222},
{"BMA222E", bma222e},
{"BMA0280", bma280},
{ },
@@ -50,6 +51,7 @@ static const struct spi_device_id bmc150_accel_id[] = {
{"bmi055_accel", bmi055},
{"bma255", bma255},
{"bma250e", bma250e},
{"bma222", bma222},
{"bma222e", bma222e},
{"bma280", bma280},
{}

View File

@@ -9,6 +9,7 @@ enum {
bmi055,
bma255,
bma250e,
bma222,
bma222e,
bma280,
};
@@ -16,6 +17,8 @@ enum {
int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name, bool block_supported);
int bmc150_accel_core_remove(struct device *dev);
struct i2c_client *bmc150_get_second_device(struct i2c_client *second_device);
void bmc150_set_second_device(struct i2c_client *second_device);
extern const struct dev_pm_ops bmc150_accel_pm_ops;
extern const struct regmap_config bmc150_regmap_conf;

View File

@@ -1105,19 +1105,15 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p)
return IRQ_HANDLED;
}
static int kxcjk1013_trig_try_reen(struct iio_trigger *trig)
static void kxcjk1013_trig_reen(struct iio_trigger *trig)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct kxcjk1013_data *data = iio_priv(indio_dev);
int ret;
ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_INT_REL);
if (ret < 0) {
if (ret < 0)
dev_err(&data->client->dev, "Error reading reg_int_rel\n");
return ret;
}
return 0;
}
static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig,
@@ -1161,7 +1157,7 @@ static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig,
static const struct iio_trigger_ops kxcjk1013_trigger_ops = {
.set_trigger_state = kxcjk1013_data_rdy_trigger_set_state,
.try_reenable = kxcjk1013_trig_try_reen,
.reenable = kxcjk1013_trig_reen,
};
static void kxcjk1013_report_motion_event(struct iio_dev *indio_dev)

View File

@@ -310,19 +310,15 @@ static irqreturn_t mxc4005_trigger_handler(int irq, void *private)
return IRQ_HANDLED;
}
static int mxc4005_clr_intr(struct mxc4005_data *data)
static void mxc4005_clr_intr(struct mxc4005_data *data)
{
int ret;
/* clear interrupt */
ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1,
MXC4005_REG_INT_CLR1_BIT_DRDYC);
if (ret < 0) {
if (ret < 0)
dev_err(data->dev, "failed to write to reg_int_clr1\n");
return ret;
}
return 0;
}
static int mxc4005_set_trigger_state(struct iio_trigger *trig,
@@ -353,20 +349,20 @@ static int mxc4005_set_trigger_state(struct iio_trigger *trig,
return 0;
}
static int mxc4005_trigger_try_reen(struct iio_trigger *trig)
static void mxc4005_trigger_reen(struct iio_trigger *trig)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct mxc4005_data *data = iio_priv(indio_dev);
if (!data->dready_trig)
return 0;
return;
return mxc4005_clr_intr(data);
mxc4005_clr_intr(data);
}
static const struct iio_trigger_ops mxc4005_trigger_ops = {
.set_trigger_state = mxc4005_set_trigger_state,
.try_reenable = mxc4005_trigger_try_reen,
.reenable = mxc4005_trigger_reen,
};
static int mxc4005_chip_init(struct mxc4005_data *data)

View File

@@ -214,7 +214,7 @@ static int ad7298_get_ref_voltage(struct ad7298_state *st)
{
int vref;
if (st->ext_ref) {
if (st->reg) {
vref = regulator_get_voltage(st->reg);
if (vref < 0)
return vref;
@@ -279,6 +279,13 @@ static const struct iio_info ad7298_info = {
.update_scan_mode = ad7298_update_scan_mode,
};
static void ad7298_reg_disable(void *data)
{
struct regulator *reg = data;
regulator_disable(reg);
}
static int ad7298_probe(struct spi_device *spi)
{
struct ad7298_state *st;
@@ -306,9 +313,12 @@ static int ad7298_probe(struct spi_device *spi)
ret = regulator_enable(st->reg);
if (ret)
return ret;
}
spi_set_drvdata(spi, indio_dev);
ret = devm_add_action_or_reset(&spi->dev, ad7298_reg_disable,
st->reg);
if (ret)
return ret;
}
st->spi = spi;
@@ -334,37 +344,12 @@ static int ad7298_probe(struct spi_device *spi)
spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg);
ret = iio_triggered_buffer_setup(indio_dev, NULL,
ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL,
&ad7298_trigger_handler, NULL);
if (ret)
goto error_disable_reg;
return ret;
ret = iio_device_register(indio_dev);
if (ret)
goto error_cleanup_ring;
return 0;
error_cleanup_ring:
iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
if (st->ext_ref)
regulator_disable(st->reg);
return ret;
}
static int ad7298_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ad7298_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
if (st->ext_ref)
regulator_disable(st->reg);
return 0;
return devm_iio_device_register(&spi->dev, indio_dev);
}
static const struct spi_device_id ad7298_id[] = {
@@ -378,7 +363,6 @@ static struct spi_driver ad7298_driver = {
.name = "ad7298",
},
.probe = ad7298_probe,
.remove = ad7298_remove,
.id_table = ad7298_id,
};
module_spi_driver(ad7298_driver);

View File

@@ -57,7 +57,7 @@ EXPORT_SYMBOL_GPL(ad_sd_set_comm);
int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
unsigned int size, unsigned int val)
{
uint8_t *data = sigma_delta->data;
uint8_t *data = sigma_delta->tx_buf;
struct spi_transfer t = {
.tx_buf = data,
.len = size + 1,
@@ -99,7 +99,7 @@ EXPORT_SYMBOL_GPL(ad_sd_write_reg);
static int ad_sd_read_reg_raw(struct ad_sigma_delta *sigma_delta,
unsigned int reg, unsigned int size, uint8_t *val)
{
uint8_t *data = sigma_delta->data;
uint8_t *data = sigma_delta->tx_buf;
int ret;
struct spi_transfer t[] = {
{
@@ -146,22 +146,22 @@ int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta,
{
int ret;
ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->data);
ret = ad_sd_read_reg_raw(sigma_delta, reg, size, sigma_delta->rx_buf);
if (ret < 0)
goto out;
switch (size) {
case 4:
*val = get_unaligned_be32(sigma_delta->data);
*val = get_unaligned_be32(sigma_delta->rx_buf);
break;
case 3:
*val = get_unaligned_be24(&sigma_delta->data[0]);
*val = get_unaligned_be24(sigma_delta->rx_buf);
break;
case 2:
*val = get_unaligned_be16(sigma_delta->data);
*val = get_unaligned_be16(sigma_delta->rx_buf);
break;
case 1:
*val = sigma_delta->data[0];
*val = sigma_delta->rx_buf[0];
break;
default:
ret = -EINVAL;
@@ -395,11 +395,9 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
uint8_t *data = sigma_delta->rx_buf;
unsigned int reg_size;
unsigned int data_reg;
uint8_t data[16];
memset(data, 0x00, 16);
reg_size = indio_dev->channels[0].scan_type.realbits +
indio_dev->channels[0].scan_type.shift;

View File

@@ -742,26 +742,24 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
return 0;
}
static int at91_adc_reenable_trigger(struct iio_trigger *trig)
static void at91_adc_reenable_trigger(struct iio_trigger *trig)
{
struct iio_dev *indio = iio_trigger_get_drvdata(trig);
struct at91_adc_state *st = iio_priv(indio);
/* if we are using DMA, we must not reenable irq after each trigger */
if (st->dma_st.dma_chan)
return 0;
return;
enable_irq(st->irq);
/* Needed to ACK the DRDY interruption */
at91_adc_readl(st, AT91_SAMA5D2_LCDR);
return 0;
}
static const struct iio_trigger_ops at91_adc_trigger_ops = {
.set_trigger_state = &at91_adc_configure_trigger,
.try_reenable = &at91_adc_reenable_trigger,
.reenable = &at91_adc_reenable_trigger,
.validate_device = iio_trigger_validate_own_device,
};

View File

@@ -204,6 +204,11 @@ struct at91_adc_caps {
u32 (*calc_startup_ticks)(u32 startup_time, u32 adc_clk_khz);
u8 num_channels;
u8 low_res_bits;
u8 high_res_bits;
u32 trigger_number;
const struct at91_adc_trigger *triggers;
struct at91_adc_reg_desc registers;
};
@@ -224,12 +229,9 @@ struct at91_adc_state {
u8 sample_hold_time;
bool sleep_mode;
struct iio_trigger **trig;
struct at91_adc_trigger *trigger_list;
u32 trigger_number;
bool use_external;
u32 vref_mv;
u32 res; /* resolution used for convertions */
bool low_res; /* the resolution corresponds to the lowest one */
wait_queue_head_t wq_data_avail;
const struct at91_adc_caps *caps;
@@ -535,13 +537,13 @@ static int at91_adc_channel_init(struct iio_dev *idev)
}
static int at91_adc_get_trigger_value_by_name(struct iio_dev *idev,
struct at91_adc_trigger *triggers,
const struct at91_adc_trigger *triggers,
const char *trigger_name)
{
struct at91_adc_state *st = iio_priv(idev);
int i;
for (i = 0; i < st->trigger_number; i++) {
for (i = 0; i < st->caps->trigger_number; i++) {
char *name = kasprintf(GFP_KERNEL,
"%s-dev%d-%s",
idev->name,
@@ -573,7 +575,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
u8 bit;
value = at91_adc_get_trigger_value_by_name(idev,
st->trigger_list,
st->caps->triggers,
idev->trig->name);
if (value < 0)
return value;
@@ -618,7 +620,7 @@ static const struct iio_trigger_ops at91_adc_trigger_ops = {
};
static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *idev,
struct at91_adc_trigger *trigger)
const struct at91_adc_trigger *trigger)
{
struct iio_trigger *trig;
int ret;
@@ -645,7 +647,7 @@ static int at91_adc_trigger_init(struct iio_dev *idev)
int i, ret;
st->trig = devm_kcalloc(&idev->dev,
st->trigger_number, sizeof(*st->trig),
st->caps->trigger_number, sizeof(*st->trig),
GFP_KERNEL);
if (st->trig == NULL) {
@@ -653,12 +655,12 @@ static int at91_adc_trigger_init(struct iio_dev *idev)
goto error_ret;
}
for (i = 0; i < st->trigger_number; i++) {
if (st->trigger_list[i].is_external && !(st->use_external))
for (i = 0; i < st->caps->trigger_number; i++) {
if (st->caps->triggers[i].is_external && !(st->use_external))
continue;
st->trig[i] = at91_adc_allocate_trigger(idev,
st->trigger_list + i);
st->caps->triggers + i);
if (st->trig[i] == NULL) {
dev_err(&idev->dev,
"Could not allocate trigger %d\n", i);
@@ -683,7 +685,7 @@ static void at91_adc_trigger_remove(struct iio_dev *idev)
struct at91_adc_state *st = iio_priv(idev);
int i;
for (i = 0; i < st->trigger_number; i++) {
for (i = 0; i < st->caps->trigger_number; i++) {
iio_trigger_unregister(st->trig[i]);
iio_trigger_free(st->trig[i]);
}
@@ -754,58 +756,6 @@ static int at91_adc_read_raw(struct iio_dev *idev,
return -EINVAL;
}
static int at91_adc_of_get_resolution(struct iio_dev *idev,
struct platform_device *pdev)
{
struct at91_adc_state *st = iio_priv(idev);
struct device_node *np = pdev->dev.of_node;
int count, i, ret = 0;
char *res_name, *s;
u32 *resolutions;
count = of_property_count_strings(np, "atmel,adc-res-names");
if (count < 2) {
dev_err(&idev->dev, "You must specified at least two resolution names for "
"adc-res-names property in the DT\n");
return count;
}
resolutions = kmalloc_array(count, sizeof(*resolutions), GFP_KERNEL);
if (!resolutions)
return -ENOMEM;
if (of_property_read_u32_array(np, "atmel,adc-res", resolutions, count)) {
dev_err(&idev->dev, "Missing adc-res property in the DT.\n");
ret = -ENODEV;
goto ret;
}
if (of_property_read_string(np, "atmel,adc-use-res", (const char **)&res_name))
res_name = "highres";
for (i = 0; i < count; i++) {
if (of_property_read_string_index(np, "atmel,adc-res-names", i, (const char **)&s))
continue;
if (strcmp(res_name, s))
continue;
st->res = resolutions[i];
if (!strcmp(res_name, "lowres"))
st->low_res = true;
else
st->low_res = false;
dev_info(&idev->dev, "Resolution used: %u bits\n", st->res);
goto ret;
}
dev_err(&idev->dev, "There is no resolution for %s\n", res_name);
ret:
kfree(resolutions);
return ret;
}
static u32 calc_startup_ticks_9260(u32 startup_time, u32 adc_clk_khz)
{
@@ -881,96 +831,6 @@ static int at91_adc_probe_dt_ts(struct device_node *node,
}
}
static int at91_adc_probe_dt(struct iio_dev *idev,
struct platform_device *pdev)
{
struct at91_adc_state *st = iio_priv(idev);
struct device_node *node = pdev->dev.of_node;
struct device_node *trig_node;
int i = 0, ret;
u32 prop;
st->caps = of_device_get_match_data(&pdev->dev);
st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers");
if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) {
dev_err(&idev->dev, "Missing adc-channels-used property in the DT.\n");
ret = -EINVAL;
goto error_ret;
}
st->channels_mask = prop;
st->sleep_mode = of_property_read_bool(node, "atmel,adc-sleep-mode");
if (of_property_read_u32(node, "atmel,adc-startup-time", &prop)) {
dev_err(&idev->dev, "Missing adc-startup-time property in the DT.\n");
ret = -EINVAL;
goto error_ret;
}
st->startup_time = prop;
prop = 0;
of_property_read_u32(node, "atmel,adc-sample-hold-time", &prop);
st->sample_hold_time = prop;
if (of_property_read_u32(node, "atmel,adc-vref", &prop)) {
dev_err(&idev->dev, "Missing adc-vref property in the DT.\n");
ret = -EINVAL;
goto error_ret;
}
st->vref_mv = prop;
ret = at91_adc_of_get_resolution(idev, pdev);
if (ret)
goto error_ret;
st->registers = &st->caps->registers;
st->num_channels = st->caps->num_channels;
st->trigger_number = of_get_child_count(node);
st->trigger_list = devm_kcalloc(&idev->dev,
st->trigger_number,
sizeof(struct at91_adc_trigger),
GFP_KERNEL);
if (!st->trigger_list) {
dev_err(&idev->dev, "Could not allocate trigger list memory.\n");
ret = -ENOMEM;
goto error_ret;
}
for_each_child_of_node(node, trig_node) {
struct at91_adc_trigger *trig = st->trigger_list + i;
const char *name;
if (of_property_read_string(trig_node, "trigger-name", &name)) {
dev_err(&idev->dev, "Missing trigger-name property in the DT.\n");
ret = -EINVAL;
goto error_ret;
}
trig->name = name;
if (of_property_read_u32(trig_node, "trigger-value", &prop)) {
dev_err(&idev->dev, "Missing trigger-value property in the DT.\n");
ret = -EINVAL;
goto error_ret;
}
trig->value = prop;
trig->is_external = of_property_read_bool(trig_node, "trigger-external");
i++;
}
/* Check if touchscreen is supported. */
if (st->caps->has_ts)
return at91_adc_probe_dt_ts(node, st, &idev->dev);
else
dev_info(&idev->dev, "not support touchscreen in the adc compatible string.\n");
return 0;
error_ret:
return ret;
}
static const struct iio_info at91_adc_info = {
.read_raw = &at91_adc_read_raw,
};
@@ -1136,10 +996,12 @@ static void at91_ts_unregister(struct at91_adc_state *st)
static int at91_adc_probe(struct platform_device *pdev)
{
unsigned int prsc, mstrclk, ticks, adc_clk, adc_clk_khz, shtim;
struct device_node *node = pdev->dev.of_node;
int ret;
struct iio_dev *idev;
struct at91_adc_state *st;
u32 reg;
u32 reg, prop;
char *s;
idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct at91_adc_state));
if (!idev)
@@ -1147,9 +1009,51 @@ static int at91_adc_probe(struct platform_device *pdev)
st = iio_priv(idev);
ret = at91_adc_probe_dt(idev, pdev);
if (ret)
return ret;
st->caps = of_device_get_match_data(&pdev->dev);
st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers");
if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) {
dev_err(&idev->dev, "Missing adc-channels-used property in the DT.\n");
return -EINVAL;
}
st->channels_mask = prop;
st->sleep_mode = of_property_read_bool(node, "atmel,adc-sleep-mode");
if (of_property_read_u32(node, "atmel,adc-startup-time", &prop)) {
dev_err(&idev->dev, "Missing adc-startup-time property in the DT.\n");
return -EINVAL;
}
st->startup_time = prop;
prop = 0;
of_property_read_u32(node, "atmel,adc-sample-hold-time", &prop);
st->sample_hold_time = prop;
if (of_property_read_u32(node, "atmel,adc-vref", &prop)) {
dev_err(&idev->dev, "Missing adc-vref property in the DT.\n");
return -EINVAL;
}
st->vref_mv = prop;
st->res = st->caps->high_res_bits;
if (st->caps->low_res_bits &&
!of_property_read_string(node, "atmel,adc-use-res", (const char **)&s)
&& !strcmp(s, "lowres"))
st->res = st->caps->low_res_bits;
dev_info(&idev->dev, "Resolution used: %u bits\n", st->res);
st->registers = &st->caps->registers;
st->num_channels = st->caps->num_channels;
/* Check if touchscreen is supported. */
if (st->caps->has_ts) {
ret = at91_adc_probe_dt_ts(node, st, &idev->dev);
if (ret)
return ret;
}
platform_set_drvdata(pdev, idev);
@@ -1245,7 +1149,7 @@ static int at91_adc_probe(struct platform_device *pdev)
reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask;
reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask;
if (st->low_res)
if (st->res == st->caps->low_res_bits)
reg |= AT91_ADC_LOWRES;
if (st->sleep_mode)
reg |= AT91_ADC_SLEEP;
@@ -1357,9 +1261,18 @@ static int at91_adc_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
static const struct at91_adc_trigger at91sam9260_triggers[] = {
{ .name = "timer-counter-0", .value = 0x1 },
{ .name = "timer-counter-1", .value = 0x3 },
{ .name = "timer-counter-2", .value = 0x5 },
{ .name = "external", .value = 0xd, .is_external = true },
};
static struct at91_adc_caps at91sam9260_caps = {
.calc_startup_ticks = calc_startup_ticks_9260,
.num_channels = 4,
.low_res_bits = 8,
.high_res_bits = 10,
.registers = {
.channel_base = AT91_ADC_CHR(0),
.drdy_mask = AT91_ADC_DRDY,
@@ -1368,12 +1281,23 @@ static struct at91_adc_caps at91sam9260_caps = {
.mr_prescal_mask = AT91_ADC_PRESCAL_9260,
.mr_startup_mask = AT91_ADC_STARTUP_9260,
},
.triggers = at91sam9260_triggers,
.trigger_number = ARRAY_SIZE(at91sam9260_triggers),
};
static const struct at91_adc_trigger at91sam9x5_triggers[] = {
{ .name = "external-rising", .value = 0x1, .is_external = true },
{ .name = "external-falling", .value = 0x2, .is_external = true },
{ .name = "external-any", .value = 0x3, .is_external = true },
{ .name = "continuous", .value = 0x6 },
};
static struct at91_adc_caps at91sam9rl_caps = {
.has_ts = true,
.calc_startup_ticks = calc_startup_ticks_9260, /* same as 9260 */
.num_channels = 6,
.low_res_bits = 8,
.high_res_bits = 10,
.registers = {
.channel_base = AT91_ADC_CHR(0),
.drdy_mask = AT91_ADC_DRDY,
@@ -1382,12 +1306,16 @@ static struct at91_adc_caps at91sam9rl_caps = {
.mr_prescal_mask = AT91_ADC_PRESCAL_9260,
.mr_startup_mask = AT91_ADC_STARTUP_9G45,
},
.triggers = at91sam9x5_triggers,
.trigger_number = ARRAY_SIZE(at91sam9x5_triggers),
};
static struct at91_adc_caps at91sam9g45_caps = {
.has_ts = true,
.calc_startup_ticks = calc_startup_ticks_9260, /* same as 9260 */
.num_channels = 8,
.low_res_bits = 8,
.high_res_bits = 10,
.registers = {
.channel_base = AT91_ADC_CHR(0),
.drdy_mask = AT91_ADC_DRDY,
@@ -1396,6 +1324,8 @@ static struct at91_adc_caps at91sam9g45_caps = {
.mr_prescal_mask = AT91_ADC_PRESCAL_9G45,
.mr_startup_mask = AT91_ADC_STARTUP_9G45,
},
.triggers = at91sam9x5_triggers,
.trigger_number = ARRAY_SIZE(at91sam9x5_triggers),
};
static struct at91_adc_caps at91sam9x5_caps = {
@@ -1405,6 +1335,8 @@ static struct at91_adc_caps at91sam9x5_caps = {
.ts_pen_detect_sensitivity = 2,
.calc_startup_ticks = calc_startup_ticks_9x5,
.num_channels = 12,
.low_res_bits = 8,
.high_res_bits = 10,
.registers = {
.channel_base = AT91_ADC_CDR0_9X5,
.drdy_mask = AT91_ADC_SR_DRDY_9X5,
@@ -1414,6 +1346,29 @@ static struct at91_adc_caps at91sam9x5_caps = {
.mr_prescal_mask = AT91_ADC_PRESCAL_9G45,
.mr_startup_mask = AT91_ADC_STARTUP_9X5,
},
.triggers = at91sam9x5_triggers,
.trigger_number = ARRAY_SIZE(at91sam9x5_triggers),
};
static struct at91_adc_caps sama5d3_caps = {
.has_ts = true,
.has_tsmr = true,
.ts_filter_average = 3,
.ts_pen_detect_sensitivity = 2,
.calc_startup_ticks = calc_startup_ticks_9x5,
.num_channels = 12,
.low_res_bits = 0,
.high_res_bits = 12,
.registers = {
.channel_base = AT91_ADC_CDR0_9X5,
.drdy_mask = AT91_ADC_SR_DRDY_9X5,
.status_register = AT91_ADC_SR_9X5,
.trigger_register = AT91_ADC_TRGR_9X5,
.mr_prescal_mask = AT91_ADC_PRESCAL_9G45,
.mr_startup_mask = AT91_ADC_STARTUP_9X5,
},
.triggers = at91sam9x5_triggers,
.trigger_number = ARRAY_SIZE(at91sam9x5_triggers),
};
static const struct of_device_id at91_adc_dt_ids[] = {
@@ -1421,33 +1376,14 @@ static const struct of_device_id at91_adc_dt_ids[] = {
{ .compatible = "atmel,at91sam9rl-adc", .data = &at91sam9rl_caps },
{ .compatible = "atmel,at91sam9g45-adc", .data = &at91sam9g45_caps },
{ .compatible = "atmel,at91sam9x5-adc", .data = &at91sam9x5_caps },
{ .compatible = "atmel,sama5d3-adc", .data = &sama5d3_caps },
{},
};
MODULE_DEVICE_TABLE(of, at91_adc_dt_ids);
static const struct platform_device_id at91_adc_ids[] = {
{
.name = "at91sam9260-adc",
.driver_data = (unsigned long)&at91sam9260_caps,
}, {
.name = "at91sam9rl-adc",
.driver_data = (unsigned long)&at91sam9rl_caps,
}, {
.name = "at91sam9g45-adc",
.driver_data = (unsigned long)&at91sam9g45_caps,
}, {
.name = "at91sam9x5-adc",
.driver_data = (unsigned long)&at91sam9x5_caps,
}, {
/* terminator */
}
};
MODULE_DEVICE_TABLE(platform, at91_adc_ids);
static struct platform_driver at91_adc_driver = {
.probe = at91_adc_probe,
.remove = at91_adc_remove,
.id_table = at91_adc_ids,
.driver = {
.name = DRIVER_NAME,
.of_match_table = at91_adc_dt_ids,

View File

@@ -462,7 +462,7 @@ static int rockchip_saradc_resume(struct device *dev)
ret = clk_prepare_enable(info->clk);
if (ret)
return ret;
clk_disable_unprepare(info->pclk);
return ret;
}

View File

@@ -70,11 +70,10 @@ static const struct iio_chan_spec adc084s021_channels[] = {
* @adc: The ADC SPI data.
* @data: Buffer for converted data.
*/
static int adc084s021_adc_conversion(struct adc084s021 *adc, void *data)
static int adc084s021_adc_conversion(struct adc084s021 *adc, __be16 *data)
{
int n_words = (adc->spi_trans.len >> 1) - 1; /* Discard first word */
int ret, i = 0;
u16 *p = data;
/* Do the transfer */
ret = spi_sync(adc->spi, &adc->message);
@@ -82,7 +81,7 @@ static int adc084s021_adc_conversion(struct adc084s021 *adc, void *data)
return ret;
for (; i < n_words; i++)
*(p + i) = adc->rx_buf[i + 1];
*(data + i) = adc->rx_buf[i + 1];
return ret;
}
@@ -93,6 +92,7 @@ static int adc084s021_read_raw(struct iio_dev *indio_dev,
{
struct adc084s021 *adc = iio_priv(indio_dev);
int ret;
__be16 be_val;
switch (mask) {
case IIO_CHAN_INFO_RAW:
@@ -107,13 +107,13 @@ static int adc084s021_read_raw(struct iio_dev *indio_dev,
}
adc->tx_buf[0] = channel->channel << 3;
ret = adc084s021_adc_conversion(adc, val);
ret = adc084s021_adc_conversion(adc, &be_val);
iio_device_release_direct_mode(indio_dev);
regulator_disable(adc->reg);
if (ret < 0)
return ret;
*val = be16_to_cpu(*val);
*val = be16_to_cpu(be_val);
*val = (*val >> channel->scan_type.shift) & 0xff;
return IIO_VAL_INT;

View File

@@ -99,6 +99,14 @@ struct ads124s_private {
struct gpio_desc *reset_gpio;
struct spi_device *spi;
struct mutex lock;
/*
* Used to correctly align data.
* Ensure timestamp is naturally aligned.
* Note that the full buffer length may not be needed if not
* all channels are enabled, as long as the alignment of the
* timestamp is maintained.
*/
u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u32)] __aligned(8);
u8 data[5] ____cacheline_aligned;
};
@@ -269,7 +277,6 @@ static irqreturn_t ads124s_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ads124s_private *priv = iio_priv(indio_dev);
u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u16)];
int scan_index, j = 0;
int ret;
@@ -284,7 +291,7 @@ static irqreturn_t ads124s_trigger_handler(int irq, void *p)
if (ret)
dev_err(&priv->spi->dev, "Start ADC conversions failed\n");
buffer[j] = ads124s_read(indio_dev, scan_index);
priv->buffer[j] = ads124s_read(indio_dev, scan_index);
ret = ads124s_write_cmd(indio_dev, ADS124S08_STOP_CONV);
if (ret)
dev_err(&priv->spi->dev, "Stop ADC conversions failed\n");
@@ -292,7 +299,7 @@ static irqreturn_t ads124s_trigger_handler(int irq, void *p)
j++;
}
iio_push_to_buffers_with_timestamp(indio_dev, buffer,
iio_push_to_buffers_with_timestamp(indio_dev, priv->buffer,
pf->timestamp);
iio_trigger_notify_done(indio_dev->trig);

View File

@@ -54,6 +54,11 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
struct iio_cb_buffer *cb_buff;
struct iio_channel *chan;
if (!cb) {
dev_err(dev, "Invalid arguments: A callback must be provided!\n");
return ERR_PTR(-EINVAL);
}
cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL);
if (cb_buff == NULL)
return ERR_PTR(-ENOMEM);

View File

@@ -478,7 +478,7 @@ static int adxrs290_data_rdy_trigger_set_state(struct iio_trigger *trig,
return ret;
}
static int adxrs290_reset_trig(struct iio_trigger *trig)
static void adxrs290_reset_trig(struct iio_trigger *trig)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
int val;
@@ -491,14 +491,12 @@ static int adxrs290_reset_trig(struct iio_trigger *trig)
*/
adxrs290_get_rate_data(indio_dev,
ADXRS290_READ_REG(ADXRS290_REG_DATAY0), &val);
return 0;
}
static const struct iio_trigger_ops adxrs290_trigger_ops = {
.set_trigger_state = &adxrs290_data_rdy_trigger_set_state,
.validate_device = &iio_trigger_validate_own_device,
.try_reenable = &adxrs290_reset_trig,
.reenable = &adxrs290_reset_trig,
};
static irqreturn_t adxrs290_trigger_handler(int irq, void *p)

View File

@@ -893,7 +893,7 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p)
return IRQ_HANDLED;
}
static int bmg160_trig_try_reen(struct iio_trigger *trig)
static void bmg160_trig_reen(struct iio_trigger *trig)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct bmg160_data *data = iio_priv(indio_dev);
@@ -902,18 +902,14 @@ static int bmg160_trig_try_reen(struct iio_trigger *trig)
/* new data interrupts don't need ack */
if (data->dready_trigger_on)
return 0;
return;
/* Set latched mode interrupt and clear any latched interrupt */
ret = regmap_write(data->regmap, BMG160_REG_INT_RST_LATCH,
BMG160_INT_MODE_LATCH_INT |
BMG160_INT_MODE_LATCH_RESET);
if (ret < 0) {
if (ret < 0)
dev_err(dev, "Error writing reg_rst_latch\n");
return ret;
}
return 0;
}
static int bmg160_data_rdy_trigger_set_state(struct iio_trigger *trig,
@@ -961,7 +957,7 @@ static int bmg160_data_rdy_trigger_set_state(struct iio_trigger *trig,
static const struct iio_trigger_ops bmg160_trigger_ops = {
.set_trigger_state = bmg160_data_rdy_trigger_set_state,
.try_reenable = bmg160_trig_try_reen,
.reenable = bmg160_trig_reen,
};
static irqreturn_t bmg160_event_handler(int irq, void *private)

View File

@@ -13,6 +13,7 @@
* TODO: add support for setting up the low pass 3dB frequency.
*/
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/err.h>
@@ -784,7 +785,8 @@ static int mpu3050_read_mem(struct mpu3050 *mpu3050,
static int mpu3050_hw_init(struct mpu3050 *mpu3050)
{
int ret;
u8 otp[8];
__le64 otp_le;
u64 otp;
/* Reset */
ret = regmap_update_bits(mpu3050->map,
@@ -815,29 +817,31 @@ static int mpu3050_hw_init(struct mpu3050 *mpu3050)
MPU3050_MEM_USER_BANK |
MPU3050_MEM_OTP_BANK_0),
0,
sizeof(otp),
otp);
sizeof(otp_le),
(u8 *)&otp_le);
if (ret)
return ret;
/* This is device-unique data so it goes into the entropy pool */
add_device_randomness(otp, sizeof(otp));
add_device_randomness(&otp_le, sizeof(otp_le));
otp = le64_to_cpu(otp_le);
dev_info(mpu3050->dev,
"die ID: %04X, wafer ID: %02X, A lot ID: %04X, "
"W lot ID: %03X, WP ID: %01X, rev ID: %02X\n",
"die ID: %04llX, wafer ID: %02llX, A lot ID: %04llX, "
"W lot ID: %03llX, WP ID: %01llX, rev ID: %02llX\n",
/* Die ID, bits 0-12 */
(otp[1] << 8 | otp[0]) & 0x1fff,
FIELD_GET(GENMASK_ULL(12, 0), otp),
/* Wafer ID, bits 13-17 */
((otp[2] << 8 | otp[1]) & 0x03e0) >> 5,
FIELD_GET(GENMASK_ULL(17, 13), otp),
/* A lot ID, bits 18-33 */
((otp[4] << 16 | otp[3] << 8 | otp[2]) & 0x3fffc) >> 2,
FIELD_GET(GENMASK_ULL(33, 18), otp),
/* W lot ID, bits 34-45 */
((otp[5] << 8 | otp[4]) & 0x3ffc) >> 2,
FIELD_GET(GENMASK_ULL(45, 34), otp),
/* WP ID, bits 47-49 */
((otp[6] << 8 | otp[5]) & 0x0380) >> 7,
FIELD_GET(GENMASK_ULL(49, 47), otp),
/* rev ID, bits 50-55 */
otp[6] >> 2);
FIELD_GET(GENMASK_ULL(55, 50), otp));
return 0;
}

View File

@@ -13,6 +13,7 @@
#define HTS221_DEV_NAME "hts221"
#include <linux/iio/iio.h>
#include <linux/regulator/consumer.h>
enum hts221_sensor_type {
HTS221_SENSOR_H,
@@ -29,6 +30,7 @@ struct hts221_hw {
const char *name;
struct device *dev;
struct regmap *regmap;
struct regulator *vdd;
struct iio_trigger *trig;
int irq;

View File

@@ -547,6 +547,35 @@ static const struct iio_info hts221_info = {
static const unsigned long hts221_scan_masks[] = {0x3, 0x0};
static int hts221_init_regulators(struct device *dev)
{
struct iio_dev *iio_dev = dev_get_drvdata(dev);
struct hts221_hw *hw = iio_priv(iio_dev);
int err;
hw->vdd = devm_regulator_get(dev, "vdd");
if (IS_ERR(hw->vdd))
return dev_err_probe(dev, PTR_ERR(hw->vdd),
"failed to get vdd regulator\n");
err = regulator_enable(hw->vdd);
if (err) {
dev_err(dev, "failed to enable vdd regulator: %d\n", err);
return err;
}
msleep(50);
return 0;
}
static void hts221_chip_uninit(void *data)
{
struct hts221_hw *hw = data;
regulator_disable(hw->vdd);
}
int hts221_probe(struct device *dev, int irq, const char *name,
struct regmap *regmap)
{
@@ -567,6 +596,14 @@ int hts221_probe(struct device *dev, int irq, const char *name,
hw->irq = irq;
hw->regmap = regmap;
err = hts221_init_regulators(dev);
if (err)
return err;
err = devm_add_action_or_reset(dev, hts221_chip_uninit, hw);
if (err)
return err;
err = hts221_check_whoami(hw);
if (err < 0)
return err;

View File

@@ -10,6 +10,13 @@ struct bmi160_data {
struct iio_trigger *trig;
struct regulator_bulk_data supplies[2];
struct iio_mount_matrix orientation;
/*
* Ensure natural alignment for timestamp if present.
* Max length needed: 2 * 3 channels + 4 bytes padding + 8 byte ts.
* If fewer channels are enabled, less space may be needed, as
* long as the timestamp is still aligned to 8 bytes.
*/
__le16 buf[12] __aligned(8);
};
extern const struct regmap_config bmi160_regmap_config;

View File

@@ -427,8 +427,6 @@ static irqreturn_t bmi160_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct bmi160_data *data = iio_priv(indio_dev);
__le16 buf[16];
/* 3 sens x 3 axis x __le16 + 3 x __le16 pad + 4 x __le16 tstamp */
int i, ret, j = 0, base = BMI160_REG_DATA_MAGN_XOUT_L;
__le16 sample;
@@ -438,10 +436,10 @@ static irqreturn_t bmi160_trigger_handler(int irq, void *p)
&sample, sizeof(sample));
if (ret)
goto done;
buf[j++] = sample;
data->buf[j++] = sample;
}
iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp);
iio_push_to_buffers_with_timestamp(indio_dev, data->buf, pf->timestamp);
done:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;

View File

@@ -1063,24 +1063,20 @@ static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig,
return ret;
}
static int kmx61_trig_try_reenable(struct iio_trigger *trig)
static void kmx61_trig_reenable(struct iio_trigger *trig)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct kmx61_data *data = kmx61_get_data(indio_dev);
int ret;
ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INL);
if (ret < 0) {
if (ret < 0)
dev_err(&data->client->dev, "Error reading reg_inl\n");
return ret;
}
return 0;
}
static const struct iio_trigger_ops kmx61_trigger_ops = {
.set_trigger_state = kmx61_data_rdy_trigger_set_state,
.try_reenable = kmx61_trig_try_reenable,
.reenable = kmx61_trig_reenable,
};
static irqreturn_t kmx61_event_handler(int irq, void *private)

View File

@@ -12,7 +12,7 @@ config IIO_ST_LSM6DSX
Say yes here to build support for STMicroelectronics LSM6DSx imu
sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm,
ism330dlc, lsm6dso, lsm6dsox, asm330lhh, lsm6dsr, lsm6ds3tr-c,
ism330dhcx, lsm6dsrx, lsm6ds0, the accelerometer/gyroscope
ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop, the accelerometer/gyroscope
of lsm9ds1 and lsm6dst.
To compile this driver as a module, choose M here: the module

View File

@@ -13,6 +13,7 @@
#include <linux/device.h>
#include <linux/iio/iio.h>
#include <linux/regulator/consumer.h>
#define ST_LSM6DS3_DEV_NAME "lsm6ds3"
#define ST_LSM6DS3H_DEV_NAME "lsm6ds3h"
@@ -29,6 +30,7 @@
#define ST_LSM6DS0_DEV_NAME "lsm6ds0"
#define ST_LSM6DSRX_DEV_NAME "lsm6dsrx"
#define ST_LSM6DST_DEV_NAME "lsm6dst"
#define ST_LSM6DSOP_DEV_NAME "lsm6dsop"
enum st_lsm6dsx_hw_id {
ST_LSM6DS3_ID,
@@ -46,6 +48,7 @@ enum st_lsm6dsx_hw_id {
ST_LSM6DS0_ID,
ST_LSM6DSRX_ID,
ST_LSM6DST_ID,
ST_LSM6DSOP_ID,
ST_LSM6DSX_MAX_ID,
};
@@ -265,7 +268,6 @@ struct st_lsm6dsx_ext_dev_settings {
/**
* struct st_lsm6dsx_settings - ST IMU sensor settings
* @wai: Sensor WhoAmI default value.
* @reset: register address for reset.
* @boot: register address for boot.
* @bdu: register address for Block Data Update.
@@ -283,7 +285,6 @@ struct st_lsm6dsx_ext_dev_settings {
* @shub_settings: i2c controller related settings.
*/
struct st_lsm6dsx_settings {
u8 wai;
struct st_lsm6dsx_reg reset;
struct st_lsm6dsx_reg boot;
struct st_lsm6dsx_reg bdu;
@@ -291,6 +292,7 @@ struct st_lsm6dsx_settings {
struct {
enum st_lsm6dsx_hw_id hw_id;
const char *name;
u8 wai;
} id[ST_LSM6DSX_MAX_ID];
struct {
const struct iio_chan_spec *chan;
@@ -368,6 +370,7 @@ struct st_lsm6dsx_sensor {
* struct st_lsm6dsx_hw - ST IMU MEMS hw instance
* @dev: Pointer to instance of struct device (I2C or SPI).
* @regmap: Register map of the device.
* @regulators: VDD/VDDIO voltage regulators.
* @irq: Device interrupt line (I2C or SPI).
* @fifo_lock: Mutex to prevent concurrent access to the hw FIFO.
* @conf_lock: Mutex to prevent concurrent FIFO configuration update.
@@ -390,6 +393,7 @@ struct st_lsm6dsx_sensor {
struct st_lsm6dsx_hw {
struct device *dev;
struct regmap *regmap;
struct regulator_bulk_data regulators[2];
int irq;
struct mutex fifo_lock;

View File

@@ -14,7 +14,7 @@
* (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated depending on the
* value of the decimation factor and ODR set for each FIFO data set.
*
* LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/LSM6DSRX/ISM330DHCX/LSM6DST:
* LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/LSM6DSRX/ISM330DHCX/LSM6DST/LSM6DSOP:
* The FIFO buffer can be configured to store data from gyroscope and
* accelerometer. Each sample is queued with a tag (1B) indicating data
* source (gyroscope, accelerometer, hw timer).

View File

@@ -26,7 +26,7 @@
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
* - FIFO size: 4KB
*
* - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX/LSM6DST:
* - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP:
* - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416,
* 833
* - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
@@ -90,7 +90,6 @@ static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
{
.wai = 0x68,
.reset = {
.addr = 0x22,
.mask = BIT(0),
@@ -108,9 +107,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
{
.hw_id = ST_LSM9DS1_ID,
.name = ST_LSM9DS1_DEV_NAME,
.wai = 0x68,
}, {
.hw_id = ST_LSM6DS0_ID,
.name = ST_LSM6DS0_DEV_NAME,
.wai = 0x68,
},
},
.channels = {
@@ -195,7 +196,6 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
{
.wai = 0x69,
.reset = {
.addr = 0x12,
.mask = BIT(0),
@@ -213,6 +213,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
{
.hw_id = ST_LSM6DS3_ID,
.name = ST_LSM6DS3_DEV_NAME,
.wai = 0x69,
},
},
.channels = {
@@ -361,7 +362,6 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
{
.wai = 0x69,
.reset = {
.addr = 0x12,
.mask = BIT(0),
@@ -379,6 +379,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
{
.hw_id = ST_LSM6DS3H_ID,
.name = ST_LSM6DS3H_DEV_NAME,
.wai = 0x69,
},
},
.channels = {
@@ -527,7 +528,6 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
{
.wai = 0x6a,
.reset = {
.addr = 0x12,
.mask = BIT(0),
@@ -545,15 +545,19 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
{
.hw_id = ST_LSM6DSL_ID,
.name = ST_LSM6DSL_DEV_NAME,
.wai = 0x6a,
}, {
.hw_id = ST_LSM6DSM_ID,
.name = ST_LSM6DSM_DEV_NAME,
.wai = 0x6a,
}, {
.hw_id = ST_ISM330DLC_ID,
.name = ST_ISM330DLC_DEV_NAME,
.wai = 0x6a,
}, {
.hw_id = ST_LSM6DS3TRC_ID,
.name = ST_LSM6DS3TRC_DEV_NAME,
.wai = 0x6a,
},
},
.channels = {
@@ -743,388 +747,6 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
},
},
{
.wai = 0x6c,
.reset = {
.addr = 0x12,
.mask = BIT(0),
},
.boot = {
.addr = 0x12,
.mask = BIT(7),
},
.bdu = {
.addr = 0x12,
.mask = BIT(6),
},
.max_fifo_size = 512,
.id = {
{
.hw_id = ST_LSM6DSO_ID,
.name = ST_LSM6DSO_DEV_NAME,
}, {
.hw_id = ST_LSM6DSOX_ID,
.name = ST_LSM6DSOX_DEV_NAME,
},
},
.channels = {
[ST_LSM6DSX_ID_ACC] = {
.chan = st_lsm6dsx_acc_channels,
.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
},
[ST_LSM6DSX_ID_GYRO] = {
.chan = st_lsm6dsx_gyro_channels,
.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
},
},
.drdy_mask = {
.addr = 0x13,
.mask = BIT(3),
},
.odr_table = {
[ST_LSM6DSX_ID_ACC] = {
.reg = {
.addr = 0x10,
.mask = GENMASK(7, 4),
},
.odr_avl[0] = { 12500, 0x01 },
.odr_avl[1] = { 26000, 0x02 },
.odr_avl[2] = { 52000, 0x03 },
.odr_avl[3] = { 104000, 0x04 },
.odr_avl[4] = { 208000, 0x05 },
.odr_avl[5] = { 416000, 0x06 },
.odr_avl[6] = { 833000, 0x07 },
.odr_len = 7,
},
[ST_LSM6DSX_ID_GYRO] = {
.reg = {
.addr = 0x11,
.mask = GENMASK(7, 4),
},
.odr_avl[0] = { 12500, 0x01 },
.odr_avl[1] = { 26000, 0x02 },
.odr_avl[2] = { 52000, 0x03 },
.odr_avl[3] = { 104000, 0x04 },
.odr_avl[4] = { 208000, 0x05 },
.odr_avl[5] = { 416000, 0x06 },
.odr_avl[6] = { 833000, 0x07 },
.odr_len = 7,
},
},
.fs_table = {
[ST_LSM6DSX_ID_ACC] = {
.reg = {
.addr = 0x10,
.mask = GENMASK(3, 2),
},
.fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
.fs_len = 4,
},
[ST_LSM6DSX_ID_GYRO] = {
.reg = {
.addr = 0x11,
.mask = GENMASK(3, 2),
},
.fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
.fs_len = 4,
},
},
.irq_config = {
.irq1 = {
.addr = 0x0d,
.mask = BIT(3),
},
.irq2 = {
.addr = 0x0e,
.mask = BIT(3),
},
.lir = {
.addr = 0x56,
.mask = BIT(0),
},
.clear_on_read = {
.addr = 0x56,
.mask = BIT(6),
},
.irq1_func = {
.addr = 0x5e,
.mask = BIT(5),
},
.irq2_func = {
.addr = 0x5f,
.mask = BIT(5),
},
.hla = {
.addr = 0x12,
.mask = BIT(5),
},
.od = {
.addr = 0x12,
.mask = BIT(4),
},
},
.batch = {
[ST_LSM6DSX_ID_ACC] = {
.addr = 0x09,
.mask = GENMASK(3, 0),
},
[ST_LSM6DSX_ID_GYRO] = {
.addr = 0x09,
.mask = GENMASK(7, 4),
},
},
.fifo_ops = {
.update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_tagged_fifo,
.fifo_th = {
.addr = 0x07,
.mask = GENMASK(8, 0),
},
.fifo_diff = {
.addr = 0x3a,
.mask = GENMASK(9, 0),
},
.th_wl = 1,
},
.ts_settings = {
.timer_en = {
.addr = 0x19,
.mask = BIT(5),
},
.decimator = {
.addr = 0x0a,
.mask = GENMASK(7, 6),
},
.freq_fine = 0x63,
},
.shub_settings = {
.page_mux = {
.addr = 0x01,
.mask = BIT(6),
},
.master_en = {
.sec_page = true,
.addr = 0x14,
.mask = BIT(2),
},
.pullup_en = {
.sec_page = true,
.addr = 0x14,
.mask = BIT(3),
},
.aux_sens = {
.addr = 0x14,
.mask = GENMASK(1, 0),
},
.wr_once = {
.addr = 0x14,
.mask = BIT(6),
},
.num_ext_dev = 3,
.shub_out = {
.sec_page = true,
.addr = 0x02,
},
.slv0_addr = 0x15,
.dw_slv0_addr = 0x21,
.batch_en = BIT(3),
},
.event_settings = {
.enable_reg = {
.addr = 0x58,
.mask = BIT(7),
},
.wakeup_reg = {
.addr = 0x5b,
.mask = GENMASK(5, 0),
},
.wakeup_src_reg = 0x1b,
.wakeup_src_status_mask = BIT(3),
.wakeup_src_z_mask = BIT(0),
.wakeup_src_y_mask = BIT(1),
.wakeup_src_x_mask = BIT(2),
},
},
{
.wai = 0x6b,
.reset = {
.addr = 0x12,
.mask = BIT(0),
},
.boot = {
.addr = 0x12,
.mask = BIT(7),
},
.bdu = {
.addr = 0x12,
.mask = BIT(6),
},
.max_fifo_size = 512,
.id = {
{
.hw_id = ST_ASM330LHH_ID,
.name = ST_ASM330LHH_DEV_NAME,
},
},
.channels = {
[ST_LSM6DSX_ID_ACC] = {
.chan = st_lsm6dsx_acc_channels,
.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
},
[ST_LSM6DSX_ID_GYRO] = {
.chan = st_lsm6dsx_gyro_channels,
.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
},
},
.drdy_mask = {
.addr = 0x13,
.mask = BIT(3),
},
.odr_table = {
[ST_LSM6DSX_ID_ACC] = {
.reg = {
.addr = 0x10,
.mask = GENMASK(7, 4),
},
.odr_avl[0] = { 12500, 0x01 },
.odr_avl[1] = { 26000, 0x02 },
.odr_avl[2] = { 52000, 0x03 },
.odr_avl[3] = { 104000, 0x04 },
.odr_avl[4] = { 208000, 0x05 },
.odr_avl[5] = { 416000, 0x06 },
.odr_avl[6] = { 833000, 0x07 },
.odr_len = 7,
},
[ST_LSM6DSX_ID_GYRO] = {
.reg = {
.addr = 0x11,
.mask = GENMASK(7, 4),
},
.odr_avl[0] = { 12500, 0x01 },
.odr_avl[1] = { 26000, 0x02 },
.odr_avl[2] = { 52000, 0x03 },
.odr_avl[3] = { 104000, 0x04 },
.odr_avl[4] = { 208000, 0x05 },
.odr_avl[5] = { 416000, 0x06 },
.odr_avl[6] = { 833000, 0x07 },
.odr_len = 7,
},
},
.fs_table = {
[ST_LSM6DSX_ID_ACC] = {
.reg = {
.addr = 0x10,
.mask = GENMASK(3, 2),
},
.fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
.fs_len = 4,
},
[ST_LSM6DSX_ID_GYRO] = {
.reg = {
.addr = 0x11,
.mask = GENMASK(3, 2),
},
.fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
.fs_len = 4,
},
},
.irq_config = {
.irq1 = {
.addr = 0x0d,
.mask = BIT(3),
},
.irq2 = {
.addr = 0x0e,
.mask = BIT(3),
},
.lir = {
.addr = 0x56,
.mask = BIT(0),
},
.clear_on_read = {
.addr = 0x56,
.mask = BIT(6),
},
.irq1_func = {
.addr = 0x5e,
.mask = BIT(5),
},
.irq2_func = {
.addr = 0x5f,
.mask = BIT(5),
},
.hla = {
.addr = 0x12,
.mask = BIT(5),
},
.od = {
.addr = 0x12,
.mask = BIT(4),
},
},
.batch = {
[ST_LSM6DSX_ID_ACC] = {
.addr = 0x09,
.mask = GENMASK(3, 0),
},
[ST_LSM6DSX_ID_GYRO] = {
.addr = 0x09,
.mask = GENMASK(7, 4),
},
},
.fifo_ops = {
.update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_tagged_fifo,
.fifo_th = {
.addr = 0x07,
.mask = GENMASK(8, 0),
},
.fifo_diff = {
.addr = 0x3a,
.mask = GENMASK(9, 0),
},
.th_wl = 1,
},
.ts_settings = {
.timer_en = {
.addr = 0x19,
.mask = BIT(5),
},
.decimator = {
.addr = 0x0a,
.mask = GENMASK(7, 6),
},
.freq_fine = 0x63,
},
.event_settings = {
.enable_reg = {
.addr = 0x58,
.mask = BIT(7),
},
.wakeup_reg = {
.addr = 0x5B,
.mask = GENMASK(5, 0),
},
.wakeup_src_reg = 0x1b,
.wakeup_src_status_mask = BIT(3),
.wakeup_src_z_mask = BIT(0),
.wakeup_src_y_mask = BIT(1),
.wakeup_src_x_mask = BIT(2),
},
},
{
.wai = 0x6b,
.reset = {
.addr = 0x12,
.mask = BIT(0),
@@ -1142,217 +764,27 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
{
.hw_id = ST_LSM6DSR_ID,
.name = ST_LSM6DSR_DEV_NAME,
.wai = 0x6b,
}, {
.hw_id = ST_ISM330DHCX_ID,
.name = ST_ISM330DHCX_DEV_NAME,
.wai = 0x6b,
}, {
.hw_id = ST_LSM6DSRX_ID,
.name = ST_LSM6DSRX_DEV_NAME,
},
},
.channels = {
[ST_LSM6DSX_ID_ACC] = {
.chan = st_lsm6dsx_acc_channels,
.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
},
[ST_LSM6DSX_ID_GYRO] = {
.chan = st_lsm6dsx_gyro_channels,
.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
},
},
.drdy_mask = {
.addr = 0x13,
.mask = BIT(3),
},
.odr_table = {
[ST_LSM6DSX_ID_ACC] = {
.reg = {
.addr = 0x10,
.mask = GENMASK(7, 4),
},
.odr_avl[0] = { 12500, 0x01 },
.odr_avl[1] = { 26000, 0x02 },
.odr_avl[2] = { 52000, 0x03 },
.odr_avl[3] = { 104000, 0x04 },
.odr_avl[4] = { 208000, 0x05 },
.odr_avl[5] = { 416000, 0x06 },
.odr_avl[6] = { 833000, 0x07 },
.odr_len = 7,
},
[ST_LSM6DSX_ID_GYRO] = {
.reg = {
.addr = 0x11,
.mask = GENMASK(7, 4),
},
.odr_avl[0] = { 12500, 0x01 },
.odr_avl[1] = { 26000, 0x02 },
.odr_avl[2] = { 52000, 0x03 },
.odr_avl[3] = { 104000, 0x04 },
.odr_avl[4] = { 208000, 0x05 },
.odr_avl[5] = { 416000, 0x06 },
.odr_avl[6] = { 833000, 0x07 },
.odr_len = 7,
},
},
.fs_table = {
[ST_LSM6DSX_ID_ACC] = {
.reg = {
.addr = 0x10,
.mask = GENMASK(3, 2),
},
.fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
.fs_len = 4,
},
[ST_LSM6DSX_ID_GYRO] = {
.reg = {
.addr = 0x11,
.mask = GENMASK(3, 2),
},
.fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
.fs_len = 4,
},
},
.irq_config = {
.irq1 = {
.addr = 0x0d,
.mask = BIT(3),
},
.irq2 = {
.addr = 0x0e,
.mask = BIT(3),
},
.lir = {
.addr = 0x56,
.mask = BIT(0),
},
.clear_on_read = {
.addr = 0x56,
.mask = BIT(6),
},
.irq1_func = {
.addr = 0x5e,
.mask = BIT(5),
},
.irq2_func = {
.addr = 0x5f,
.mask = BIT(5),
},
.hla = {
.addr = 0x12,
.mask = BIT(5),
},
.od = {
.addr = 0x12,
.mask = BIT(4),
},
},
.batch = {
[ST_LSM6DSX_ID_ACC] = {
.addr = 0x09,
.mask = GENMASK(3, 0),
},
[ST_LSM6DSX_ID_GYRO] = {
.addr = 0x09,
.mask = GENMASK(7, 4),
},
},
.fifo_ops = {
.update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_tagged_fifo,
.fifo_th = {
.addr = 0x07,
.mask = GENMASK(8, 0),
},
.fifo_diff = {
.addr = 0x3a,
.mask = GENMASK(9, 0),
},
.th_wl = 1,
},
.ts_settings = {
.timer_en = {
.addr = 0x19,
.mask = BIT(5),
},
.decimator = {
.addr = 0x0a,
.mask = GENMASK(7, 6),
},
.freq_fine = 0x63,
},
.shub_settings = {
.page_mux = {
.addr = 0x01,
.mask = BIT(6),
},
.master_en = {
.sec_page = true,
.addr = 0x14,
.mask = BIT(2),
},
.pullup_en = {
.sec_page = true,
.addr = 0x14,
.mask = BIT(3),
},
.aux_sens = {
.addr = 0x14,
.mask = GENMASK(1, 0),
},
.wr_once = {
.addr = 0x14,
.mask = BIT(6),
},
.num_ext_dev = 3,
.shub_out = {
.sec_page = true,
.addr = 0x02,
},
.slv0_addr = 0x15,
.dw_slv0_addr = 0x21,
.batch_en = BIT(3),
},
.event_settings = {
.enable_reg = {
.addr = 0x58,
.mask = BIT(7),
},
.wakeup_reg = {
.addr = 0x5B,
.mask = GENMASK(5, 0),
},
.wakeup_src_reg = 0x1b,
.wakeup_src_status_mask = BIT(3),
.wakeup_src_z_mask = BIT(0),
.wakeup_src_y_mask = BIT(1),
.wakeup_src_x_mask = BIT(2),
}
},
{
.wai = 0x6d,
.reset = {
.addr = 0x12,
.mask = BIT(0),
},
.boot = {
.addr = 0x12,
.mask = BIT(7),
},
.bdu = {
.addr = 0x12,
.mask = BIT(6),
},
.max_fifo_size = 512,
.id = {
{
.wai = 0x6b,
}, {
.hw_id = ST_LSM6DSO_ID,
.name = ST_LSM6DSO_DEV_NAME,
.wai = 0x6c,
}, {
.hw_id = ST_LSM6DSOX_ID,
.name = ST_LSM6DSOX_DEV_NAME,
.wai = 0x6c,
}, {
.hw_id = ST_LSM6DST_ID,
.name = ST_LSM6DST_DEV_NAME,
.wai = 0x6d,
},
},
.channels = {
@@ -1539,6 +971,183 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.wakeup_src_x_mask = BIT(2),
},
},
{
.reset = {
.addr = 0x12,
.mask = BIT(0),
},
.boot = {
.addr = 0x12,
.mask = BIT(7),
},
.bdu = {
.addr = 0x12,
.mask = BIT(6),
},
.max_fifo_size = 512,
.id = {
{
.hw_id = ST_ASM330LHH_ID,
.name = ST_ASM330LHH_DEV_NAME,
.wai = 0x6b,
}, {
.hw_id = ST_LSM6DSOP_ID,
.name = ST_LSM6DSOP_DEV_NAME,
.wai = 0x6c,
},
},
.channels = {
[ST_LSM6DSX_ID_ACC] = {
.chan = st_lsm6dsx_acc_channels,
.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
},
[ST_LSM6DSX_ID_GYRO] = {
.chan = st_lsm6dsx_gyro_channels,
.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
},
},
.drdy_mask = {
.addr = 0x13,
.mask = BIT(3),
},
.odr_table = {
[ST_LSM6DSX_ID_ACC] = {
.reg = {
.addr = 0x10,
.mask = GENMASK(7, 4),
},
.odr_avl[0] = { 12500, 0x01 },
.odr_avl[1] = { 26000, 0x02 },
.odr_avl[2] = { 52000, 0x03 },
.odr_avl[3] = { 104000, 0x04 },
.odr_avl[4] = { 208000, 0x05 },
.odr_avl[5] = { 416000, 0x06 },
.odr_avl[6] = { 833000, 0x07 },
.odr_len = 7,
},
[ST_LSM6DSX_ID_GYRO] = {
.reg = {
.addr = 0x11,
.mask = GENMASK(7, 4),
},
.odr_avl[0] = { 12500, 0x01 },
.odr_avl[1] = { 26000, 0x02 },
.odr_avl[2] = { 52000, 0x03 },
.odr_avl[3] = { 104000, 0x04 },
.odr_avl[4] = { 208000, 0x05 },
.odr_avl[5] = { 416000, 0x06 },
.odr_avl[6] = { 833000, 0x07 },
.odr_len = 7,
},
},
.fs_table = {
[ST_LSM6DSX_ID_ACC] = {
.reg = {
.addr = 0x10,
.mask = GENMASK(3, 2),
},
.fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
.fs_len = 4,
},
[ST_LSM6DSX_ID_GYRO] = {
.reg = {
.addr = 0x11,
.mask = GENMASK(3, 2),
},
.fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
.fs_len = 4,
},
},
.irq_config = {
.irq1 = {
.addr = 0x0d,
.mask = BIT(3),
},
.irq2 = {
.addr = 0x0e,
.mask = BIT(3),
},
.lir = {
.addr = 0x56,
.mask = BIT(0),
},
.clear_on_read = {
.addr = 0x56,
.mask = BIT(6),
},
.irq1_func = {
.addr = 0x5e,
.mask = BIT(5),
},
.irq2_func = {
.addr = 0x5f,
.mask = BIT(5),
},
.hla = {
.addr = 0x12,
.mask = BIT(5),
},
.od = {
.addr = 0x12,
.mask = BIT(4),
},
},
.batch = {
[ST_LSM6DSX_ID_ACC] = {
.addr = 0x09,
.mask = GENMASK(3, 0),
},
[ST_LSM6DSX_ID_GYRO] = {
.addr = 0x09,
.mask = GENMASK(7, 4),
},
},
.fifo_ops = {
.update_fifo = st_lsm6dsx_update_fifo,
.read_fifo = st_lsm6dsx_read_tagged_fifo,
.fifo_th = {
.addr = 0x07,
.mask = GENMASK(8, 0),
},
.fifo_diff = {
.addr = 0x3a,
.mask = GENMASK(9, 0),
},
.th_wl = 1,
},
.ts_settings = {
.timer_en = {
.addr = 0x19,
.mask = BIT(5),
},
.decimator = {
.addr = 0x0a,
.mask = GENMASK(7, 6),
},
.freq_fine = 0x63,
},
.event_settings = {
.enable_reg = {
.addr = 0x58,
.mask = BIT(7),
},
.wakeup_reg = {
.addr = 0x5B,
.mask = GENMASK(5, 0),
},
.wakeup_src_reg = 0x1b,
.wakeup_src_status_mask = BIT(3),
.wakeup_src_z_mask = BIT(0),
.wakeup_src_y_mask = BIT(1),
.wakeup_src_x_mask = BIT(2),
},
},
};
int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
@@ -1582,7 +1191,7 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
return err;
}
if (data != st_lsm6dsx_sensor_settings[i].wai) {
if (data != st_lsm6dsx_sensor_settings[i].id[j].wai) {
dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
return -ENODEV;
}
@@ -2460,19 +2069,35 @@ st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw)
static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
{
struct st_lsm6dsx_hw *hw = private;
int fifo_len = 0, len;
bool event;
int count;
event = st_lsm6dsx_report_motion_event(hw);
if (!hw->settings->fifo_ops.read_fifo)
return event ? IRQ_HANDLED : IRQ_NONE;
mutex_lock(&hw->fifo_lock);
count = hw->settings->fifo_ops.read_fifo(hw);
mutex_unlock(&hw->fifo_lock);
/*
* If we are using edge IRQs, new samples can arrive while
* processing current interrupt since there are no hw
* guarantees the irq line stays "low" long enough to properly
* detect the new interrupt. In this case the new sample will
* be missed.
* Polling FIFO status register allow us to read new
* samples even if the interrupt arrives while processing
* previous data and the timeslot where the line is "low" is
* too short to be properly detected.
*/
do {
mutex_lock(&hw->fifo_lock);
len = hw->settings->fifo_ops.read_fifo(hw);
mutex_unlock(&hw->fifo_lock);
return count || event ? IRQ_HANDLED : IRQ_NONE;
if (len > 0)
fifo_len += len;
} while (len > 0);
return fifo_len || event ? IRQ_HANDLED : IRQ_NONE;
}
static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
@@ -2533,6 +2158,38 @@ static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
return 0;
}
static int st_lsm6dsx_init_regulators(struct device *dev)
{
struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
int err;
/* vdd-vddio power regulators */
hw->regulators[0].supply = "vdd";
hw->regulators[1].supply = "vddio";
err = devm_regulator_bulk_get(dev, ARRAY_SIZE(hw->regulators),
hw->regulators);
if (err)
return dev_err_probe(dev, err, "failed to get regulators\n");
err = regulator_bulk_enable(ARRAY_SIZE(hw->regulators),
hw->regulators);
if (err) {
dev_err(dev, "failed to enable regulators: %d\n", err);
return err;
}
msleep(50);
return 0;
}
static void st_lsm6dsx_chip_uninit(void *data)
{
struct st_lsm6dsx_hw *hw = data;
regulator_bulk_disable(ARRAY_SIZE(hw->regulators), hw->regulators);
}
int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
struct regmap *regmap)
{
@@ -2552,6 +2209,14 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
mutex_init(&hw->conf_lock);
mutex_init(&hw->page_lock);
err = st_lsm6dsx_init_regulators(dev);
if (err)
return err;
err = devm_add_action_or_reset(dev, st_lsm6dsx_chip_uninit, hw);
if (err)
return err;
hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
if (!hw->buff)
return -ENOMEM;

View File

@@ -98,6 +98,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
.compatible = "st,lsm6dst",
.data = (void *)ST_LSM6DST_ID,
},
{
.compatible = "st,lsm6dsop",
.data = (void *)ST_LSM6DSOP_ID,
},
{},
};
MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
@@ -118,6 +122,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
{ ST_LSM6DS0_DEV_NAME, ST_LSM6DS0_ID },
{ ST_LSM6DSRX_DEV_NAME, ST_LSM6DSRX_ID },
{ ST_LSM6DST_DEV_NAME, ST_LSM6DST_ID },
{ ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID },
{},
};
MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);

View File

@@ -98,6 +98,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
.compatible = "st,lsm6dst",
.data = (void *)ST_LSM6DST_ID,
},
{
.compatible = "st,lsm6dsop",
.data = (void *)ST_LSM6DSOP_ID,
},
{},
};
MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
@@ -118,6 +122,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
{ ST_LSM6DS0_DEV_NAME, ST_LSM6DS0_ID },
{ ST_LSM6DSRX_DEV_NAME, ST_LSM6DSRX_ID },
{ ST_LSM6DST_DEV_NAME, ST_LSM6DST_ID },
{ ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID },
{},
};
MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);

View File

@@ -853,12 +853,12 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev,
indio_dev->masklength,
in_ind + 1);
while (in_ind != out_ind) {
in_ind = find_next_bit(indio_dev->active_scan_mask,
indio_dev->masklength,
in_ind + 1);
length = iio_storage_bytes_for_si(indio_dev, in_ind);
/* Make sure we are aligned */
in_loc = roundup(in_loc, length) + length;
in_ind = find_next_bit(indio_dev->active_scan_mask,
indio_dev->masklength,
in_ind + 1);
}
length = iio_storage_bytes_for_si(indio_dev, in_ind);
out_loc = roundup(out_loc, length);

View File

@@ -711,90 +711,52 @@ static ssize_t iio_read_channel_info(struct device *dev,
return iio_format_value(buf, ret, val_len, vals);
}
static ssize_t iio_format_avail_list(char *buf, const int *vals,
int type, int length)
static ssize_t iio_format_list(char *buf, const int *vals, int type, int length,
const char *prefix, const char *suffix)
{
ssize_t len;
int stride;
int i;
ssize_t len = 0;
switch (type) {
case IIO_VAL_INT:
for (i = 0; i < length; i++) {
len += __iio_format_value(buf + len, PAGE_SIZE - len,
type, 1, &vals[i]);
if (len >= PAGE_SIZE)
return -EFBIG;
if (i < length - 1)
len += scnprintf(buf + len, PAGE_SIZE - len,
" ");
else
len += scnprintf(buf + len, PAGE_SIZE - len,
"\n");
if (len >= PAGE_SIZE)
return -EFBIG;
}
stride = 1;
break;
default:
for (i = 0; i < length / 2; i++) {
len += __iio_format_value(buf + len, PAGE_SIZE - len,
type, 2, &vals[i * 2]);
if (len >= PAGE_SIZE)
return -EFBIG;
if (i < length / 2 - 1)
len += scnprintf(buf + len, PAGE_SIZE - len,
" ");
else
len += scnprintf(buf + len, PAGE_SIZE - len,
"\n");
stride = 2;
break;
}
len = scnprintf(buf, PAGE_SIZE, prefix);
for (i = 0; i <= length - stride; i += stride) {
if (i != 0) {
len += scnprintf(buf + len, PAGE_SIZE - len, " ");
if (len >= PAGE_SIZE)
return -EFBIG;
}
len += __iio_format_value(buf + len, PAGE_SIZE - len, type,
stride, &vals[i]);
if (len >= PAGE_SIZE)
return -EFBIG;
}
len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n", suffix);
return len;
}
static ssize_t iio_format_avail_list(char *buf, const int *vals,
int type, int length)
{
return iio_format_list(buf, vals, type, length, "", "");
}
static ssize_t iio_format_avail_range(char *buf, const int *vals, int type)
{
int i;
ssize_t len;
len = snprintf(buf, PAGE_SIZE, "[");
switch (type) {
case IIO_VAL_INT:
for (i = 0; i < 3; i++) {
len += __iio_format_value(buf + len, PAGE_SIZE - len,
type, 1, &vals[i]);
if (len >= PAGE_SIZE)
return -EFBIG;
if (i < 2)
len += scnprintf(buf + len, PAGE_SIZE - len,
" ");
else
len += scnprintf(buf + len, PAGE_SIZE - len,
"]\n");
if (len >= PAGE_SIZE)
return -EFBIG;
}
break;
default:
for (i = 0; i < 3; i++) {
len += __iio_format_value(buf + len, PAGE_SIZE - len,
type, 2, &vals[i * 2]);
if (len >= PAGE_SIZE)
return -EFBIG;
if (i < 2)
len += scnprintf(buf + len, PAGE_SIZE - len,
" ");
else
len += scnprintf(buf + len, PAGE_SIZE - len,
"]\n");
if (len >= PAGE_SIZE)
return -EFBIG;
}
}
return len;
return iio_format_list(buf, vals, type, 3, "[", "]");
}
static ssize_t iio_read_channel_info_avail(struct device *dev,

View File

@@ -203,10 +203,8 @@ EXPORT_SYMBOL(iio_trigger_poll_chained);
void iio_trigger_notify_done(struct iio_trigger *trig)
{
if (atomic_dec_and_test(&trig->use_count) && trig->ops &&
trig->ops->try_reenable)
if (trig->ops->try_reenable(trig))
/* Missed an interrupt so launch new poll now */
iio_trigger_poll(trig);
trig->ops->reenable)
trig->ops->reenable(trig);
}
EXPORT_SYMBOL(iio_trigger_notify_done);

View File

@@ -24,6 +24,21 @@ struct iio_map_internal {
static LIST_HEAD(iio_map_list);
static DEFINE_MUTEX(iio_map_list_lock);
static int iio_map_array_unregister_locked(struct iio_dev *indio_dev)
{
int ret = -ENODEV;
struct iio_map_internal *mapi, *next;
list_for_each_entry_safe(mapi, next, &iio_map_list, l) {
if (indio_dev == mapi->indio_dev) {
list_del(&mapi->l);
kfree(mapi);
ret = 0;
}
}
return ret;
}
int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps)
{
int i = 0, ret = 0;
@@ -45,6 +60,8 @@ int iio_map_array_register(struct iio_dev *indio_dev, struct iio_map *maps)
i++;
}
error_ret:
if (ret)
iio_map_array_unregister_locked(indio_dev);
mutex_unlock(&iio_map_list_lock);
return ret;
@@ -57,18 +74,12 @@ EXPORT_SYMBOL_GPL(iio_map_array_register);
*/
int iio_map_array_unregister(struct iio_dev *indio_dev)
{
int ret = -ENODEV;
struct iio_map_internal *mapi, *next;
int ret;
mutex_lock(&iio_map_list_lock);
list_for_each_entry_safe(mapi, next, &iio_map_list, l) {
if (indio_dev == mapi->indio_dev) {
list_del(&mapi->l);
kfree(mapi);
ret = 0;
}
}
ret = iio_map_array_unregister_locked(indio_dev);
mutex_unlock(&iio_map_list_lock);
return ret;
}
EXPORT_SYMBOL_GPL(iio_map_array_unregister);

View File

@@ -194,6 +194,17 @@ struct rpr0521_data {
bool pxs_need_dis;
struct regmap *regmap;
/*
* Ensure correct naturally aligned timestamp.
* Note that the read will put garbage data into
* the padding but this should not be a problem
*/
struct {
__le16 channels[3];
u8 garbage;
s64 ts __aligned(8);
} scan;
};
static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL);
@@ -449,8 +460,6 @@ static irqreturn_t rpr0521_trigger_consumer_handler(int irq, void *p)
struct rpr0521_data *data = iio_priv(indio_dev);
int err;
u8 buffer[16]; /* 3 16-bit channels + padding + ts */
/* Use irq timestamp when reasonable. */
if (iio_trigger_using_own(indio_dev) && data->irq_timestamp) {
pf->timestamp = data->irq_timestamp;
@@ -461,11 +470,11 @@ static irqreturn_t rpr0521_trigger_consumer_handler(int irq, void *p)
pf->timestamp = iio_get_time_ns(indio_dev);
err = regmap_bulk_read(data->regmap, RPR0521_REG_PXS_DATA,
&buffer,
data->scan.channels,
(3 * 2) + 1); /* 3 * 16-bit + (discarded) int clear reg. */
if (!err)
iio_push_to_buffers_with_timestamp(indio_dev,
buffer, pf->timestamp);
&data->scan, pf->timestamp);
else
dev_err(&data->client->dev,
"Trigger consumer can't read from sensor.\n");

View File

@@ -27,6 +27,11 @@ struct st_uvis25_hw {
struct iio_trigger *trig;
bool enabled;
int irq;
/* Ensure timestamp is naturally aligned */
struct {
u8 chan;
s64 ts __aligned(8);
} scan;
};
extern const struct dev_pm_ops st_uvis25_pm_ops;

View File

@@ -232,17 +232,19 @@ static const struct iio_buffer_setup_ops st_uvis25_buffer_ops = {
static irqreturn_t st_uvis25_buffer_handler_thread(int irq, void *p)
{
u8 buffer[ALIGN(sizeof(u8), sizeof(s64)) + sizeof(s64)];
struct iio_poll_func *pf = p;
struct iio_dev *iio_dev = pf->indio_dev;
struct st_uvis25_hw *hw = iio_priv(iio_dev);
unsigned int val;
int err;
err = regmap_read(hw->regmap, ST_UVIS25_REG_OUT_ADDR, (int *)buffer);
err = regmap_read(hw->regmap, ST_UVIS25_REG_OUT_ADDR, &val);
if (err < 0)
goto out;
iio_push_to_buffers_with_timestamp(iio_dev, buffer,
hw->scan.chan = val;
iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan,
iio_get_time_ns(iio_dev));
out:

View File

@@ -766,20 +766,20 @@ static int bmc150_magn_reset_intr(struct bmc150_magn_data *data)
return regmap_read(data->regmap, BMC150_MAGN_REG_X_L, &tmp);
}
static int bmc150_magn_trig_try_reen(struct iio_trigger *trig)
static void bmc150_magn_trig_reen(struct iio_trigger *trig)
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct bmc150_magn_data *data = iio_priv(indio_dev);
int ret;
if (!data->dready_trigger_on)
return 0;
return;
mutex_lock(&data->mutex);
ret = bmc150_magn_reset_intr(data);
mutex_unlock(&data->mutex);
return ret;
if (ret)
dev_err(data->dev, "Failed to reset interrupt\n");
}
static int bmc150_magn_data_rdy_trigger_set_state(struct iio_trigger *trig,
@@ -817,7 +817,7 @@ static int bmc150_magn_data_rdy_trigger_set_state(struct iio_trigger *trig,
static const struct iio_trigger_ops bmc150_magn_trigger_ops = {
.set_trigger_state = bmc150_magn_data_rdy_trigger_set_state,
.try_reenable = bmc150_magn_trig_try_reen,
.reenable = bmc150_magn_trig_reen,
};
static int bmc150_magn_buffer_preenable(struct iio_dev *indio_dev)

View File

@@ -56,6 +56,12 @@ struct mag3110_data {
int sleep_val;
struct regulator *vdd_reg;
struct regulator *vddio_reg;
/* Ensure natural alignment of timestamp */
struct {
__be16 channels[3];
u8 temperature;
s64 ts __aligned(8);
} scan;
};
static int mag3110_request(struct mag3110_data *data)
@@ -387,10 +393,9 @@ static irqreturn_t mag3110_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct mag3110_data *data = iio_priv(indio_dev);
u8 buffer[16]; /* 3 16-bit channels + 1 byte temp + padding + ts */
int ret;
ret = mag3110_read(data, (__be16 *) buffer);
ret = mag3110_read(data, data->scan.channels);
if (ret < 0)
goto done;
@@ -399,10 +404,10 @@ static irqreturn_t mag3110_trigger_handler(int irq, void *p)
MAG3110_DIE_TEMP);
if (ret < 0)
goto done;
buffer[6] = ret;
data->scan.temperature = ret;
}
iio_push_to_buffers_with_timestamp(indio_dev, buffer,
iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
iio_get_time_ns(indio_dev));
done:

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