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

Merge tag 'iio-for-5.3b' of...

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

Jonathan writes:

Second set of IIO device support, features, cleanups and minor fixes for 5.3.

A few bits for the counters subsystem mixed in here as well.
There are some late breaking fixes as well, which aren't so urgent
they can't wait for the merge window.

New Device Support
* adf4371
  - New driver + bindings.
  - Support the adf4372 PLL. Mostly ID and bindings.
* ad8366 (note includes rework of driver needed to allow support for these).
  - Support the ADL5240 variable gain amplifier (VGA).
  - Support the ADA4961 digital gain amplifier (DGA).
* dps310
  - New driver, in several parts from different authors for this temp
    and pressure sensor.
  - Includes errata workaround for a temperature reading issue.
* stk3310
  - Support the stk3335, mostly ID.

Features and cleanups
* core
  - drop error handling on debugfs registration.
  - harden by making sure we don't overrun iio_chan_info_postfix.
* docs
  - convert remaining docs to rst. At somepoint we'll fit these few
    into the main IIO docs.
  - improve sampling_frequency_available docs but explaining the
    range form.
* ad_sigma_delta
  - Drop a pointless goto.
* ad2s1210
  - Drop pointless platform data null check seeing as we don't actually
    use platform data anymore.
* ad7124
  - Relax limitation on channel numbers to allow pseudo different channels.
  - Support control of whether the input is buffered via DT.
  - Use dynamic allocation for channel configuration to make it easier
    to support new devices.
  - YAML binding conversion.
* ad7150
  - Comment tidy up.
  - Consistent and simple if (ret) handling of i2c errors.
  - FIELD_GET and GENMASK.
  - Ternary rather than !!(condition) for readability.
  - Use macros to avoid repetition of channel definitions.
* ad7606
  - Add software channel config (rather that pin controlled)
  - Refactor to simplify addition of new part in future.
* ad7746
  - of_deivce_id table.
* ad7780
  - MAINTAINERS entry
  - YAML DT bindings.
* ad8366
  - Stop using core mlock in favour of well scoped local lock.
  - SPDX + copyright date update.
* ad9834
  - of_device_id table
* adf4371
  - Add support for output stage muting before lock on has occured.
* adis library
  - MAINTAINERS entry to reflect that this now Alexandru's problem ;)
* adis162xx:
  - Fix a slightly incorrect set of comments and print statements on
    minimum supported voltage.
* adis16203
  - of_device_id table.
* adis16240
  - Add of_device_id table (in two parts as first patch only used it for
    MODULE_DEVICE_TABLE.)
* adt7316-spi
  - of_device_id table
* adxl372
  - YAML DT binding conversion.
  - Cleanup use of buffer callback functions (precursor to core rework).
* bh1710
  - Simplify getting the i2c adapter from the client.
* dht11
  - Mote to newer GPIO consumer interface.
* kxcjk-1013.c
  - Add binding for sensor in display of some ultrabooks after userspace
    tools updated for it not be a problem to report two similar sensors.
* imx7d
  - drop unused variables.
  - white space
  - define instead of variable for clock frequency that is fixed.
  - drop pointless error message.
* messon_saradc
  - SPDX
* sps30
  - MAINTAINERS entry
  - YAML binding conversion.
* st_accel
  - Tidy up ordering in various buffer related callbacks. This is
    part of a long running effort to simplify the core code.
* stm32-dfsdm:
  - Manage the resolution cleanly in triggerd modes.
  - Add fast mode support which allows more flexible filter choices.
  - Add a comment on the reason for a 16 bit record when technically
    not 'required'.
* st_lsm6dsx
  - Embed device name in the sensor_settings struct as i3c doesn't
    have a convenient name field to use for this.
* xilinx-adc
  - Relax constraints on supported platforms to reflect that this
    can used with FPGAs on PCIe cards and hence many architectures.
* counters/ftm-quaddec
  - Fix some formatting io MODULE_AUTHOR
  - MAINTAINERS entry

Fixes
* tools
  - fix incorrect handling of 32 bit channels.
* sca3000
  - Potential endian bug that is unlikely to bite anyone (be64 host
    seems unlikely for this old part).
* stm32-adc
  - Add vdda-supply. On some boards it needs to be turned on to supply
    the ADC.  DT bindings included.
* stm32-dfsdm
  - Fix output resolution to work with filter orders other than 3.
  - Fix output datatype as it's signed and previously claimed not to be.

* tag 'iio-for-5.3b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (68 commits)
  iio: iio-utils: Fix possible incorrect mask calculation
  iio: frequency: adf4371: Add support for output stage mute
  dt-bindings: iio: frequency: Add ADF4372 PLL documentation
  iio: frequency: adf4371: Add support for ADF4372 PLL
  dt-bindings: iio: adc: Add buffered input property
  Convert AD7124 bindings documentation to YAML format.
  iio: adc: ad7124: Shift to dynamic allocation for channel configuration
  iio: adc: ad7124: Add buffered input support
  iio: adc: ad7124: Remove input number limitation
  MAINTAINERS: add ADIS IMU driver library entry
  iio: adis162xx: fix low-power docs & reports
  counter/ftm-quaddec: Add missing '>' in MODULE_AUTHOR
  iio: core: no need to check return value of debugfs_create functions
  docs: iio: convert to ReST
  iio: adc: stm32-adc: add missing vdda-supply
  dt-bindings: iio: adc: stm32: add missing vdda supply
  iio: adc: stm32-dfsdm: add comment for 16 bits record
  iio: adc: stm32-dfsdm: add fast mode support
  iio: adc: stm32-dfsdm: manage data resolution in trigger mode
  iio: adc: stm32-dfsdm: fix data type
  ...
parents 003e6cc3 208a68c8
...@@ -61,8 +61,11 @@ What: /sys/bus/iio/devices/triggerX/sampling_frequency_available ...@@ -61,8 +61,11 @@ What: /sys/bus/iio/devices/triggerX/sampling_frequency_available
KernelVersion: 2.6.35 KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org Contact: linux-iio@vger.kernel.org
Description: Description:
When the internal sampling clock can only take a small When the internal sampling clock can only take a specific set of
discrete set of values, this file lists those available. frequencies, we can specify the available values with:
- a small discrete set of values like "0 2 4 6 8"
- a range with minimum, step and maximum frequencies like
"[min step max]"
What: /sys/bus/iio/devices/iio:deviceX/oversampling_ratio What: /sys/bus/iio/devices/iio:deviceX/oversampling_ratio
KernelVersion: 2.6.38 KernelVersion: 2.6.38
......
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency
KernelVersion:
Contact: linux-iio@vger.kernel.org
Description:
Stores the PLL frequency in Hz for channel Y.
Reading returns the actual frequency in Hz.
The ADF4371 has an integrated VCO with fundamendal output
frequency ranging from 4000000000 Hz 8000000000 Hz.
out_altvoltage0_frequency:
A divide by 1, 2, 4, 8, 16, 32 or circuit generates
frequencies from 62500000 Hz to 8000000000 Hz.
out_altvoltage1_frequency:
This channel duplicates the channel 0 frequency
out_altvoltage2_frequency:
A frequency doubler generates frequencies from
8000000000 Hz to 16000000000 Hz.
out_altvoltage3_frequency:
A frequency quadrupler generates frequencies from
16000000000 Hz to 32000000000 Hz.
Note: writes to one of the channels will affect the frequency of
all the other channels, since it involves changing the VCO
fundamental output frequency.
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_name
KernelVersion:
Contact: linux-iio@vger.kernel.org
Description:
Reading returns the datasheet name for channel Y:
out_altvoltage0_name: RF8x
out_altvoltage1_name: RFAUX8x
out_altvoltage2_name: RF16x
out_altvoltage3_name: RF32x
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown
KernelVersion:
Contact: linux-iio@vger.kernel.org
Description:
This attribute allows the user to power down the PLL and it's
RFOut buffers.
Writing 1 causes the specified channel to power down.
Clearing returns to normal operation.
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/accelerometers/adi,adxl372.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer
maintainers:
- Stefan Popa <stefan.popa@analog.com>
description: |
Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer that supports
both I2C & SPI interfaces
https://www.analog.com/en/products/adxl372.html
properties:
compatible:
enum:
- adi,adxl372
reg:
maxItems: 1
interrupts:
maxItems: 1
required:
- compatible
- reg
- interrupts
examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
#address-cells = <1>;
#size-cells = <0>;
/* Example for a I2C device node */
accelerometer@53 {
compatible = "adi,adxl372";
reg = <0x53>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
};
};
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
spi0 {
#address-cells = <1>;
#size-cells = <0>;
accelerometer@0 {
compatible = "adi,adxl372";
reg = <0>;
spi-max-frequency = <1000000>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
};
};
Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer
http://www.analog.com/media/en/technical-documentation/data-sheets/adxl372.pdf
Required properties:
- compatible : should be "adi,adxl372"
- reg: the I2C address or SPI chip select number for the device
Required properties for SPI bus usage:
- spi-max-frequency: Max SPI frequency to use
Optional properties:
- interrupts: interrupt mapping for IRQ as documented in
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Example for a I2C device node:
accelerometer@53 {
compatible = "adi,adxl372";
reg = <0x53>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
};
Example for a SPI device node:
accelerometer@0 {
compatible = "adi,adxl372";
reg = <0>;
spi-max-frequency = <1000000>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
};
Analog Devices AD7124 ADC device driver
Required properties for the AD7124:
- compatible: Must be one of "adi,ad7124-4" or "adi,ad7124-8"
- reg: SPI chip select number for the device
- spi-max-frequency: Max SPI frequency to use
see: Documentation/devicetree/bindings/spi/spi-bus.txt
- clocks: phandle to the master clock (mclk)
see: Documentation/devicetree/bindings/clock/clock-bindings.txt
- clock-names: Must be "mclk".
- interrupts: IRQ line for the ADC
see: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Required properties:
* #address-cells: Must be 1.
* #size-cells: Must be 0.
Subnode(s) represent the external channels which are connected to the ADC.
Each subnode represents one channel and has the following properties:
Required properties:
* reg: The channel number. It can have up to 4 channels on ad7124-4
and 8 channels on ad7124-8, numbered from 0 to 15.
* diff-channels: see: Documentation/devicetree/bindings/iio/adc/adc.txt
Optional properties:
* bipolar: see: Documentation/devicetree/bindings/iio/adc/adc.txt
* adi,reference-select: Select the reference source to use when
converting on the the specific channel. Valid values are:
0: REFIN1(+)/REFIN1(−).
1: REFIN2(+)/REFIN2(−).
3: AVDD
If this field is left empty, internal reference is selected.
Optional properties:
- refin1-supply: refin1 supply can be used as reference for conversion.
- refin2-supply: refin2 supply can be used as reference for conversion.
- avdd-supply: avdd supply can be used as reference for conversion.
Example:
adc@0 {
compatible = "adi,ad7124-4";
reg = <0>;
spi-max-frequency = <5000000>;
interrupts = <25 2>;
interrupt-parent = <&gpio>;
refin1-supply = <&adc_vref>;
clocks = <&ad7124_mclk>;
clock-names = "mclk";
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
diff-channels = <0 1>;
adi,reference-select = <0>;
};
channel@1 {
reg = <1>;
bipolar;
diff-channels = <2 3>;
adi,reference-select = <0>;
};
channel@2 {
reg = <2>;
diff-channels = <4 5>;
};
channel@3 {
reg = <3>;
diff-channels = <6 7>;
};
};
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# Copyright 2019 Analog Devices Inc.
%YAML 1.2
---
$id: http://devicetree.org/schemas/bindings/iio/adc/adi,ad7124.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD7124 ADC device driver
maintainers:
- Stefan Popa <stefan.popa@analog.com>
description: |
Bindings for the Analog Devices AD7124 ADC device. Datasheet can be
found here:
https://www.analog.com/media/en/technical-documentation/data-sheets/AD7124-8.pdf
properties:
compatible:
enum:
- adi,ad7124-4
- adi,ad7124-8
reg:
description: SPI chip select number for the device
maxItems: 1
clocks:
maxItems: 1
description: phandle to the master clock (mclk)
clock-names:
items:
- const: mclk
interrupts:
description: IRQ line for the ADC
maxItems: 1
'#address-cells':
const: 1
'#size-cells':
const: 0
refin1-supply:
description: refin1 supply can be used as reference for conversion.
maxItems: 1
refin2-supply:
description: refin2 supply can be used as reference for conversion.
maxItems: 1
avdd-supply:
description: avdd supply can be used as reference for conversion.
maxItems: 1
required:
- compatible
- reg
- clocks
- clock-names
- interrupts
patternProperties:
"^channel@([0-9]|1[0-5])$":
type: object
description: |
Represents the external channels which are connected to the ADC.
See Documentation/devicetree/bindings/iio/adc/adc.txt.
properties:
reg:
description: |
The channel number. It can have up to 8 channels on ad7124-4
and 16 channels on ad7124-8, numbered from 0 to 15.
items:
minimum: 0
maximum: 15
adi,reference-select:
description: |
Select the reference source to use when converting on
the specific channel. Valid values are:
0: REFIN1(+)/REFIN1(−).
1: REFIN2(+)/REFIN2(−).
3: AVDD
If this field is left empty, internal reference is selected.
allOf:
- $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
bipolar:
description: see Documentation/devicetree/bindings/iio/adc/adc.txt
type: boolean
adi,buffered-positive:
description: Enable buffered mode for positive input.
type: boolean
adi,buffered-negative:
description: Enable buffered mode for negative input.
type: boolean
required:
- reg
- diff-channels
examples:
- |
adc@0 {
compatible = "adi,ad7124-4";
reg = <0>;
spi-max-frequency = <5000000>;
interrupts = <25 2>;
interrupt-parent = <&gpio>;
refin1-supply = <&adc_vref>;
clocks = <&ad7124_mclk>;
clock-names = "mclk";
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
diff-channels = <0 1>;
adi,reference-select = <0>;
adi,buffered-positive;
};
channel@1 {
reg = <1>;
bipolar;
diff-channels = <2 3>;
adi,reference-select = <0>;
adi,buffered-positive;
adi,buffered-negative;
};
channel@2 {
reg = <2>;
diff-channels = <4 5>;
};
channel@3 {
reg = <3>;
diff-channels = <6 7>;
};
};
* Analog Devices AD7170/AD7171/AD7780/AD7781
Data sheets:
- AD7170:
* https://www.analog.com/media/en/technical-documentation/data-sheets/AD7170.pdf
- AD7171:
* https://www.analog.com/media/en/technical-documentation/data-sheets/AD7171.pdf
- AD7780:
* https://www.analog.com/media/en/technical-documentation/data-sheets/ad7780.pdf
- AD7781:
* https://www.analog.com/media/en/technical-documentation/data-sheets/AD7781.pdf
Required properties:
- compatible: should be one of
* "adi,ad7170"
* "adi,ad7171"
* "adi,ad7780"
* "adi,ad7781"
- reg: spi chip select number for the device
- vref-supply: the regulator supply for the ADC reference voltage
Optional properties:
- powerdown-gpios: must be the device tree identifier of the PDRST pin. If
specified, it will be asserted during driver probe. As the
line is active high, it should be marked GPIO_ACTIVE_HIGH.
- adi,gain-gpios: must be the device tree identifier of the GAIN pin. Only for
the ad778x chips. If specified, it will be asserted during
driver probe. As the line is active low, it should be marked
GPIO_ACTIVE_LOW.
- adi,filter-gpios: must be the device tree identifier of the FILTER pin. Only
for the ad778x chips. If specified, it will be asserted
during driver probe. As the line is active low, it should be
marked GPIO_ACTIVE_LOW.
Example:
adc@0 {
compatible = "adi,ad7780";
reg = <0>;
vref-supply = <&vdd_supply>
powerdown-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>;
adi,gain-gpios = <&gpio 5 GPIO_ACTIVE_LOW>;
adi,filter-gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adi,ad7780.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD7170/AD7171/AD7780/AD7781 analog to digital converters
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>
description: |
The ad7780 is a sigma-delta analog to digital converter. This driver provides
reading voltage values and status bits from both the ad778x and ad717x series.
Its interface also allows writing on the FILTER and GAIN GPIO pins on the
ad778x.
Specifications on the converters can be found at:
AD7170:
https://www.analog.com/media/en/technical-documentation/data-sheets/AD7170.pdf
AD7171:
https://www.analog.com/media/en/technical-documentation/data-sheets/AD7171.pdf
AD7780:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad7780.pdf
AD7781:
https://www.analog.com/media/en/technical-documentation/data-sheets/AD7781.pdf
properties:
compatible:
enum:
- adi,ad7170
- adi,ad7171
- adi,ad7780
- adi,ad7781
reg:
maxItems: 1
avdd-supply:
description:
The regulator supply for the ADC reference voltage.
maxItems: 1
powerdown-gpios:
description:
Must be the device tree identifier of the PDRST pin. If
specified, it will be asserted during driver probe. As the
line is active high, it should be marked GPIO_ACTIVE_HIGH.
maxItems: 1
adi,gain-gpios:
description:
Must be the device tree identifier of the GAIN pin. Only for
the ad778x chips. If specified, it will be asserted during
driver probe. As the line is active low, it should be marked
GPIO_ACTIVE_LOW.
maxItems: 1
adi,filter-gpios:
description:
Must be the device tree identifier of the FILTER pin. Only
for the ad778x chips. If specified, it will be asserted
during driver probe. As the line is active low, it should be
marked GPIO_ACTIVE_LOW.
maxItems: 1
required:
- compatible
- reg
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi0 {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7780";
reg = <0>;
avdd-supply = <&vdd_supply>;
powerdown-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
adi,gain-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>;
adi,filter-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
};
};
...@@ -38,6 +38,7 @@ Required properties: ...@@ -38,6 +38,7 @@ Required properties:
It's required on stm32h7. It's required on stm32h7.
- clock-names: Must be "adc" and/or "bus" depending on part used. - clock-names: Must be "adc" and/or "bus" depending on part used.
- interrupt-controller: Identifies the controller node as interrupt-parent - interrupt-controller: Identifies the controller node as interrupt-parent
- vdda-supply: Phandle to the vdda input analog voltage.
- vref-supply: Phandle to the vref input analog reference voltage. - vref-supply: Phandle to the vref input analog reference voltage.
- #interrupt-cells = <1>; - #interrupt-cells = <1>;
- #address-cells = <1>; - #address-cells = <1>;
......
* Sensirion SPS30 particulate matter sensor
Required properties:
- compatible: must be "sensirion,sps30"
- reg: the I2C address of the sensor
Example:
sps30@69 {
compatible = "sensirion,sps30";
reg = <0x69>;
};
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/chemical/sensirion,sps30.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sensirion SPS30 particulate matter sensor
maintainers:
- Tomasz Duszynski <tduszyns@gmail.com>
description: |
Air pollution sensor capable of measuring mass concentration of dust
particles.
properties:
compatible:
enum:
- sensirion,sps30
reg:
maxItems: 1
required:
- compatible
- reg
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
air-pollution-sensor@69 {
compatible = "sensirion,sps30";
reg = <0x69>;
};
};
...
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/frequency/adf4371.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices ADF4371/ADF4372 Wideband Synthesizers
maintainers:
- Popa Stefan <stefan.popa@analog.com>
description: |
Analog Devices ADF4371/ADF4372 SPI Wideband Synthesizers
https://www.analog.com/media/en/technical-documentation/data-sheets/adf4371.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/adf4372.pdf
properties:
compatible:
enum:
- adi,adf4371
- adi,adf4372
reg:
maxItems: 1
clocks:
description:
Definition of the external clock (see clock/clock-bindings.txt)
maxItems: 1
clock-names:
description:
Must be "clkin"
maxItems: 1
adi,mute-till-lock-en:
type: boolean
description:
If this property is present, then the supply current to RF8P and RF8N
output stage will shut down until the ADF4371/ADF4372 achieves lock as
measured by the digital lock detect circuitry.
required:
- compatible
- reg
- clocks
- clock-names
examples:
- |
spi0 {
#address-cells = <1>;
#size-cells = <0>;
frequency@0 {
compatible = "adi,adf4371";
reg = <0>;
spi-max-frequency = <1000000>;
clocks = <&adf4371_clkin>;
clock-names = "clkin";
};
};
...
Cirrus Logic EP93xx ADC driver. ==============================
Cirrus Logic EP93xx ADC driver
==============================
1. Overview 1. Overview
===========
The driver is intended to work on both low-end (EP9301, EP9302) devices with The driver is intended to work on both low-end (EP9301, EP9302) devices with
5-channel ADC and high-end (EP9307, EP9312, EP9315) devices with 10-channel 5-channel ADC and high-end (EP9307, EP9312, EP9315) devices with 10-channel
touchscreen/ADC module. touchscreen/ADC module.
2. Channel numbering 2. Channel numbering
====================
Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets. Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets.
EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is
...@@ -17,13 +21,20 @@ Assuming ep93xx_adc is IIO device0, you'd find the following entries under ...@@ -17,13 +21,20 @@ Assuming ep93xx_adc is IIO device0, you'd find the following entries under
+-----------------+---------------+ +-----------------+---------------+
| sysfs entry | ball/pin name | | sysfs entry | ball/pin name |
+-----------------+---------------+ +=================+===============+
| in_voltage0_raw | YM | | in_voltage0_raw | YM |
+-----------------+---------------+
| in_voltage1_raw | SXP | | in_voltage1_raw | SXP |
+-----------------+---------------+
| in_voltage2_raw | SXM | | in_voltage2_raw | SXM |
+-----------------+---------------+
| in_voltage3_raw | SYP | | in_voltage3_raw | SYP |
+-----------------+---------------+
| in_voltage4_raw | SYM | | in_voltage4_raw | SYM |
+-----------------+---------------+
| in_voltage5_raw | XP | | in_voltage5_raw | XP |
+-----------------+---------------+
| in_voltage6_raw | XM | | in_voltage6_raw | XM |
+-----------------+---------------+
| in_voltage7_raw | YP | | in_voltage7_raw | YP |
+-----------------+---------------+ +-----------------+---------------+
===============================
Industrial IIO configfs support Industrial IIO configfs support
===============================
1. Overview 1. Overview
===========
Configfs is a filesystem-based manager of kernel objects. IIO uses some Configfs is a filesystem-based manager of kernel objects. IIO uses some
objects that could be easily configured using configfs (e.g.: devices, objects that could be easily configured using configfs (e.g.: devices,
...@@ -10,20 +13,22 @@ See Documentation/filesystems/configfs/configfs.txt for more information ...@@ -10,20 +13,22 @@ See Documentation/filesystems/configfs/configfs.txt for more information
about how configfs works. about how configfs works.
2. Usage 2. Usage
========
In order to use configfs support in IIO we need to select it at compile In order to use configfs support in IIO we need to select it at compile
time via CONFIG_IIO_CONFIGFS config option. time via CONFIG_IIO_CONFIGFS config option.
Then, mount the configfs filesystem (usually under /config directory): Then, mount the configfs filesystem (usually under /config directory)::
$ mkdir /config $ mkdir /config
$ mount -t configfs none /config $ mount -t configfs none /config
At this point, all default IIO groups will be created and can be accessed At this point, all default IIO groups will be created and can be accessed
under /config/iio. Next chapters will describe available IIO configuration under /config/iio. Next chapters will describe available IIO configuration
objects. objects.
3. Software triggers 3. Software triggers
====================
One of the IIO default configfs groups is the "triggers" group. It is One of the IIO default configfs groups is the "triggers" group. It is
automagically accessible when the configfs is mounted and can be found automagically accessible when the configfs is mounted and can be found
...@@ -31,40 +36,40 @@ under /config/iio/triggers. ...@@ -31,40 +36,40 @@ under /config/iio/triggers.
IIO software triggers implementation offers support for creating multiple IIO software triggers implementation offers support for creating multiple
trigger types. A new trigger type is usually implemented as a separate trigger types. A new trigger type is usually implemented as a separate
kernel module following the interface in include/linux/iio/sw_trigger.h: kernel module following the interface in include/linux/iio/sw_trigger.h::
/* /*
* drivers/iio/trigger/iio-trig-sample.c * drivers/iio/trigger/iio-trig-sample.c
* sample kernel module implementing a new trigger type * sample kernel module implementing a new trigger type
*/ */
#include <linux/iio/sw_trigger.h> #include <linux/iio/sw_trigger.h>
static struct iio_sw_trigger *iio_trig_sample_probe(const char *name) static struct iio_sw_trigger *iio_trig_sample_probe(const char *name)
{ {
/* /*
* This allocates and registers an IIO trigger plus other * This allocates and registers an IIO trigger plus other
* trigger type specific initialization. * trigger type specific initialization.
*/ */
} }
static int iio_trig_hrtimer_remove(struct iio_sw_trigger *swt) static int iio_trig_hrtimer_remove(struct iio_sw_trigger *swt)
{ {
/* /*
* This undoes the actions in iio_trig_sample_probe * This undoes the actions in iio_trig_sample_probe
*/ */
} }
static const struct iio_sw_trigger_ops iio_trig_sample_ops = { static const struct iio_sw_trigger_ops iio_trig_sample_ops = {
.probe = iio_trig_sample_probe, .probe = iio_trig_sample_probe,
.remove = iio_trig_sample_remove, .remove = iio_trig_sample_remove,
}; };
static struct iio_sw_trigger_type iio_trig_sample = { static struct iio_sw_trigger_type iio_trig_sample = {
.name = "trig-sample", .name = "trig-sample",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.ops = &iio_trig_sample_ops, .ops = &iio_trig_sample_ops,
}; };
module_iio_sw_trigger_driver(iio_trig_sample); module_iio_sw_trigger_driver(iio_trig_sample);
...@@ -73,21 +78,24 @@ iio-trig-sample module will create 'trig-sample' trigger type directory ...@@ -73,21 +78,24 @@ iio-trig-sample module will create 'trig-sample' trigger type directory
/config/iio/triggers/trig-sample. /config/iio/triggers/trig-sample.
We support the following interrupt sources (trigger types): We support the following interrupt sources (trigger types):
* hrtimer, uses high resolution timers as interrupt source * hrtimer, uses high resolution timers as interrupt source
3.1 Hrtimer triggers creation and destruction 3.1 Hrtimer triggers creation and destruction
---------------------------------------------
Loading iio-trig-hrtimer module will register hrtimer trigger types allowing Loading iio-trig-hrtimer module will register hrtimer trigger types allowing
users to create hrtimer triggers under /config/iio/triggers/hrtimer. users to create hrtimer triggers under /config/iio/triggers/hrtimer.
e.g: e.g::
$ mkdir /config/iio/triggers/hrtimer/instance1 $ mkdir /config/iio/triggers/hrtimer/instance1
$ rmdir /config/iio/triggers/hrtimer/instance1 $ rmdir /config/iio/triggers/hrtimer/instance1
Each trigger can have one or more attributes specific to the trigger type. Each trigger can have one or more attributes specific to the trigger type.
3.2 "hrtimer" trigger types attributes 3.2 "hrtimer" trigger types attributes
--------------------------------------
"hrtimer" trigger type doesn't have any configurable attribute from /config dir. "hrtimer" trigger type doesn't have any configurable attribute from /config dir.
It does introduce the sampling_frequency attribute to trigger directory. It does introduce the sampling_frequency attribute to trigger directory.
:orphan:
==============
Industrial I/O
==============
.. toctree::
:maxdepth: 1
iio_configfs
ep93xx_adc
...@@ -560,7 +560,7 @@ S: Supported ...@@ -560,7 +560,7 @@ S: Supported
F: drivers/iio/accel/adxl372.c F: drivers/iio/accel/adxl372.c
F: drivers/iio/accel/adxl372_spi.c F: drivers/iio/accel/adxl372_spi.c
F: drivers/iio/accel/adxl372_i2c.c F: drivers/iio/accel/adxl372_i2c.c
F: Documentation/devicetree/bindings/iio/accel/adxl372.txt F: Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml
AF9013 MEDIA DRIVER AF9013 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi> M: Antti Palosaari <crope@iki.fi>
...@@ -910,6 +910,15 @@ S: Supported ...@@ -910,6 +910,15 @@ S: Supported
F: drivers/iio/adc/ad7768-1.c F: drivers/iio/adc/ad7768-1.c
F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt
ANALOG DEVICES INC AD7780 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com>
M: Renato Lui Geh <renatogeh@gmail.com>
L: linux-iio@vger.kernel.org
W: http://ez.analog.com/community/linux-device-drivers
S: Supported
F: drivers/iio/adc/ad7780.c
F: Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml
ANALOG DEVICES INC AD9389B DRIVER ANALOG DEVICES INC AD9389B DRIVER
M: Hans Verkuil <hans.verkuil@cisco.com> M: Hans Verkuil <hans.verkuil@cisco.com>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
...@@ -922,6 +931,13 @@ S: Supported ...@@ -922,6 +931,13 @@ S: Supported
F: drivers/mux/adgs1408.c F: drivers/mux/adgs1408.c
F: Documentation/devicetree/bindings/mux/adi,adgs1408.txt F: Documentation/devicetree/bindings/mux/adi,adgs1408.txt
ANALOG DEVICES INC ADIS DRIVER LIBRARY
M: Alexandru Ardelean <alexandru.ardelean@analog.com>
S: Supported
L: linux-iio@vger.kernel.org
F: include/linux/iio/imu/adis.h
F: drivers/iio/imu/adis.c
ANALOG DEVICES INC ADP5061 DRIVER ANALOG DEVICES INC ADP5061 DRIVER
M: Stefan Popa <stefan.popa@analog.com> M: Stefan Popa <stefan.popa@analog.com>
L: linux-pm@vger.kernel.org L: linux-pm@vger.kernel.org
...@@ -6219,6 +6235,14 @@ M: Philip Kelleher <pjk1939@linux.ibm.com> ...@@ -6219,6 +6235,14 @@ M: Philip Kelleher <pjk1939@linux.ibm.com>
S: Maintained S: Maintained
F: drivers/block/rsxx/ F: drivers/block/rsxx/
FLEXTIMER FTM-QUADDEC DRIVER
M: Patrick Havelange <patrick.havelange@essensium.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/sysfs-bus-counter-ftm-quadddec
F: Documentation/devicetree/bindings/counter/ftm-quaddec.txt
F: drivers/counter/ftm-quaddec.c
FLOPPY DRIVER FLOPPY DRIVER
M: Jiri Kosina <jikos@kernel.org> M: Jiri Kosina <jikos@kernel.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git
...@@ -7773,6 +7797,12 @@ W: http://industrypack.sourceforge.net ...@@ -7773,6 +7797,12 @@ W: http://industrypack.sourceforge.net
S: Maintained S: Maintained
F: drivers/ipack/ F: drivers/ipack/
INFINEON DPS310 Driver
M: Eddie James <eajames@linux.ibm.com>
L: linux-iio@vger.kernel.org
F: drivers/iio/pressure/dps310.c
S: Maintained
INFINIBAND SUBSYSTEM INFINIBAND SUBSYSTEM
M: Doug Ledford <dledford@redhat.com> M: Doug Ledford <dledford@redhat.com>
M: Jason Gunthorpe <jgg@mellanox.com> M: Jason Gunthorpe <jgg@mellanox.com>
...@@ -14161,6 +14191,12 @@ S: Maintained ...@@ -14161,6 +14191,12 @@ S: Maintained
F: drivers/misc/phantom.c F: drivers/misc/phantom.c
F: include/uapi/linux/phantom.h F: include/uapi/linux/phantom.h
SENSIRION SPS30 AIR POLLUTION SENSOR DRIVER
M: Tomasz Duszynski <tduszyns@gmail.com>
S: Maintained
F: drivers/iio/chemical/sps30.c
F: Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.yaml
SERIAL DEVICE BUS SERIAL DEVICE BUS
M: Rob Herring <robh@kernel.org> M: Rob Herring <robh@kernel.org>
L: linux-serial@vger.kernel.org L: linux-serial@vger.kernel.org
......
...@@ -352,5 +352,5 @@ static struct platform_driver ftm_quaddec_driver = { ...@@ -352,5 +352,5 @@ static struct platform_driver ftm_quaddec_driver = {
module_platform_driver(ftm_quaddec_driver); module_platform_driver(ftm_quaddec_driver);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kjeld Flarup <kfa@deif.com"); MODULE_AUTHOR("Kjeld Flarup <kfa@deif.com>");
MODULE_AUTHOR("Patrick Havelange <patrick.havelange@essensium.com"); MODULE_AUTHOR("Patrick Havelange <patrick.havelange@essensium.com>");
...@@ -28,7 +28,7 @@ config IIO_CONFIGFS ...@@ -28,7 +28,7 @@ config IIO_CONFIGFS
help help
This allows configuring various IIO bits through configfs This allows configuring various IIO bits through configfs
(e.g. software triggers). For more info see (e.g. software triggers). For more info see
Documentation/iio/iio_configfs.txt. Documentation/iio/iio_configfs.rst.
config IIO_TRIGGER config IIO_TRIGGER
bool "Enable triggered sampling support" bool "Enable triggered sampling support"
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
#define ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT 2 #define ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT 2
/* Power supply above 3.625 V */ /* Power supply above 3.625 V */
#define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1 #define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1
/* Power supply below 3.15 V */ /* Power supply below 2.975 V */
#define ADIS16201_DIAG_STAT_POWER_LOW_BIT 0 #define ADIS16201_DIAG_STAT_POWER_LOW_BIT 0
/* System Command Register Definition */ /* System Command Register Definition */
...@@ -230,7 +230,7 @@ static const char * const adis16201_status_error_msgs[] = { ...@@ -230,7 +230,7 @@ static const char * const adis16201_status_error_msgs[] = {
[ADIS16201_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", [ADIS16201_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
[ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed", [ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed",
[ADIS16201_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", [ADIS16201_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
[ADIS16201_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", [ADIS16201_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V",
}; };
static const struct adis_data adis16201_data = { static const struct adis_data adis16201_data = {
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
#define ADIS16209_STAT_FLASH_UPT_FAIL_BIT 2 #define ADIS16209_STAT_FLASH_UPT_FAIL_BIT 2
/* Power supply above 3.625 V */ /* Power supply above 3.625 V */
#define ADIS16209_STAT_POWER_HIGH_BIT 1 #define ADIS16209_STAT_POWER_HIGH_BIT 1
/* Power supply below 3.15 V */ /* Power supply below 2.975 V */
#define ADIS16209_STAT_POWER_LOW_BIT 0 #define ADIS16209_STAT_POWER_LOW_BIT 0
#define ADIS16209_CMD_REG 0x3E #define ADIS16209_CMD_REG 0x3E
...@@ -240,7 +240,7 @@ static const char * const adis16209_status_error_msgs[] = { ...@@ -240,7 +240,7 @@ static const char * const adis16209_status_error_msgs[] = {
[ADIS16209_STAT_SPI_FAIL_BIT] = "SPI failure", [ADIS16209_STAT_SPI_FAIL_BIT] = "SPI failure",
[ADIS16209_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed", [ADIS16209_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed",
[ADIS16209_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", [ADIS16209_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
[ADIS16209_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", [ADIS16209_STAT_POWER_LOW_BIT] = "Power supply below 2.975V",
}; };
static const struct adis_data adis16209_data = { static const struct adis_data adis16209_data = {
......
...@@ -782,10 +782,14 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) ...@@ -782,10 +782,14 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev)
unsigned int mask; unsigned int mask;
int i, ret; int i, ret;
ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0); ret = iio_triggered_buffer_postenable(indio_dev);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0);
if (ret < 0)
goto err;
mask = *indio_dev->active_scan_mask; mask = *indio_dev->active_scan_mask;
for (i = 0; i < ARRAY_SIZE(adxl372_axis_lookup_table); i++) { for (i = 0; i < ARRAY_SIZE(adxl372_axis_lookup_table); i++) {
...@@ -793,8 +797,10 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) ...@@ -793,8 +797,10 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev)
break; break;
} }
if (i == ARRAY_SIZE(adxl372_axis_lookup_table)) if (i == ARRAY_SIZE(adxl372_axis_lookup_table)) {
return -EINVAL; ret = -EINVAL;
goto err;
}
st->fifo_format = adxl372_axis_lookup_table[i].fifo_format; st->fifo_format = adxl372_axis_lookup_table[i].fifo_format;
st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask, st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask,
...@@ -814,26 +820,25 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) ...@@ -814,26 +820,25 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev)
if (ret < 0) { if (ret < 0) {
st->fifo_mode = ADXL372_FIFO_BYPASSED; st->fifo_mode = ADXL372_FIFO_BYPASSED;
adxl372_set_interrupts(st, 0, 0); adxl372_set_interrupts(st, 0, 0);
return ret; goto err;
} }
return iio_triggered_buffer_postenable(indio_dev); return 0;
err:
iio_triggered_buffer_predisable(indio_dev);
return ret;
} }
static int adxl372_buffer_predisable(struct iio_dev *indio_dev) static int adxl372_buffer_predisable(struct iio_dev *indio_dev)
{ {
struct adxl372_state *st = iio_priv(indio_dev); struct adxl372_state *st = iio_priv(indio_dev);
int ret;
ret = iio_triggered_buffer_predisable(indio_dev);
if (ret < 0)
return ret;
adxl372_set_interrupts(st, 0, 0); adxl372_set_interrupts(st, 0, 0);
st->fifo_mode = ADXL372_FIFO_BYPASSED; st->fifo_mode = ADXL372_FIFO_BYPASSED;
adxl372_configure_fifo(st); adxl372_configure_fifo(st);
return 0; return iio_triggered_buffer_predisable(indio_dev);
} }
static const struct iio_buffer_setup_ops adxl372_buffer_ops = { static const struct iio_buffer_setup_ops adxl372_buffer_ops = {
......
...@@ -1487,6 +1487,7 @@ static const struct acpi_device_id kx_acpi_match[] = { ...@@ -1487,6 +1487,7 @@ static const struct acpi_device_id kx_acpi_match[] = {
{"KIOX0009", KXTJ21009}, {"KIOX0009", KXTJ21009},
{"KIOX000A", KXCJ91008}, {"KIOX000A", KXCJ91008},
{"KIOX010A", KXCJ91008}, /* KXCJ91008 inside the display of a 2-in-1 */ {"KIOX010A", KXCJ91008}, /* KXCJ91008 inside the display of a 2-in-1 */
{"KIOX020A", KXCJ91008},
{"KXTJ1009", KXTJ21009}, {"KXTJ1009", KXTJ21009},
{"KXJ2109", KXTJ21009}, {"KXJ2109", KXTJ21009},
{"SMO8500", KXCJ91008}, {"SMO8500", KXCJ91008},
......
...@@ -869,8 +869,9 @@ static int sca3000_read_event_value(struct iio_dev *indio_dev, ...@@ -869,8 +869,9 @@ static int sca3000_read_event_value(struct iio_dev *indio_dev,
enum iio_event_info info, enum iio_event_info info,
int *val, int *val2) int *val, int *val2)
{ {
int ret, i;
struct sca3000_state *st = iio_priv(indio_dev); struct sca3000_state *st = iio_priv(indio_dev);
long ret;
int i;
switch (info) { switch (info) {
case IIO_EV_INFO_VALUE: case IIO_EV_INFO_VALUE:
...@@ -882,11 +883,11 @@ static int sca3000_read_event_value(struct iio_dev *indio_dev, ...@@ -882,11 +883,11 @@ static int sca3000_read_event_value(struct iio_dev *indio_dev,
return ret; return ret;
*val = 0; *val = 0;
if (chan->channel2 == IIO_MOD_Y) if (chan->channel2 == IIO_MOD_Y)
for_each_set_bit(i, (unsigned long *)&ret, for_each_set_bit(i, &ret,
ARRAY_SIZE(st->info->mot_det_mult_y)) ARRAY_SIZE(st->info->mot_det_mult_y))
*val += st->info->mot_det_mult_y[i]; *val += st->info->mot_det_mult_y[i];
else else
for_each_set_bit(i, (unsigned long *)&ret, for_each_set_bit(i, &ret,
ARRAY_SIZE(st->info->mot_det_mult_xz)) ARRAY_SIZE(st->info->mot_det_mult_xz))
*val += st->info->mot_det_mult_xz[i]; *val += st->info->mot_det_mult_xz[i];
......
...@@ -45,17 +45,19 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev) ...@@ -45,17 +45,19 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
goto allocate_memory_error; goto allocate_memory_error;
} }
err = st_sensors_set_axis_enable(indio_dev, err = iio_triggered_buffer_postenable(indio_dev);
(u8)indio_dev->active_scan_mask[0]);
if (err < 0) if (err < 0)
goto st_accel_buffer_postenable_error; goto st_accel_buffer_postenable_error;
err = iio_triggered_buffer_postenable(indio_dev); err = st_sensors_set_axis_enable(indio_dev,
(u8)indio_dev->active_scan_mask[0]);
if (err < 0) if (err < 0)
goto st_accel_buffer_postenable_error; goto st_sensors_set_axis_enable_error;
return err; return err;
st_sensors_set_axis_enable_error:
iio_triggered_buffer_predisable(indio_dev);
st_accel_buffer_postenable_error: st_accel_buffer_postenable_error:
kfree(adata->buffer_data); kfree(adata->buffer_data);
allocate_memory_error: allocate_memory_error:
...@@ -64,20 +66,22 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev) ...@@ -64,20 +66,22 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
static int st_accel_buffer_predisable(struct iio_dev *indio_dev) static int st_accel_buffer_predisable(struct iio_dev *indio_dev)
{ {
int err; int err, err2;
struct st_sensor_data *adata = iio_priv(indio_dev); struct st_sensor_data *adata = iio_priv(indio_dev);
err = iio_triggered_buffer_predisable(indio_dev);
if (err < 0)
goto st_accel_buffer_predisable_error;
err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS); err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
if (err < 0) if (err < 0)
goto st_accel_buffer_predisable_error; goto st_accel_buffer_predisable_error;
err = st_sensors_set_enable(indio_dev, false); err = st_sensors_set_enable(indio_dev, false);
if (err < 0)
goto st_accel_buffer_predisable_error;
st_accel_buffer_predisable_error: st_accel_buffer_predisable_error:
err2 = iio_triggered_buffer_predisable(indio_dev);
if (!err)
err = err2;
kfree(adata->buffer_data); kfree(adata->buffer_data);
return err; return err;
} }
......
...@@ -1085,7 +1085,6 @@ config VIPERBOARD_ADC ...@@ -1085,7 +1085,6 @@ config VIPERBOARD_ADC
config XILINX_XADC config XILINX_XADC
tristate "Xilinx XADC driver" tristate "Xilinx XADC driver"
depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
select IIO_BUFFER select IIO_BUFFER
select IIO_TRIGGERED_BUFFER select IIO_TRIGGERED_BUFFER
......
...@@ -61,6 +61,8 @@ ...@@ -61,6 +61,8 @@
#define AD7124_CONFIG_REF_SEL(x) FIELD_PREP(AD7124_CONFIG_REF_SEL_MSK, x) #define AD7124_CONFIG_REF_SEL(x) FIELD_PREP(AD7124_CONFIG_REF_SEL_MSK, x)
#define AD7124_CONFIG_PGA_MSK GENMASK(2, 0) #define AD7124_CONFIG_PGA_MSK GENMASK(2, 0)
#define AD7124_CONFIG_PGA(x) FIELD_PREP(AD7124_CONFIG_PGA_MSK, x) #define AD7124_CONFIG_PGA(x) FIELD_PREP(AD7124_CONFIG_PGA_MSK, x)
#define AD7124_CONFIG_IN_BUFF_MSK GENMASK(7, 6)
#define AD7124_CONFIG_IN_BUFF(x) FIELD_PREP(AD7124_CONFIG_IN_BUFF_MSK, x)
/* AD7124_FILTER_X */ /* AD7124_FILTER_X */
#define AD7124_FILTER_FS_MSK GENMASK(10, 0) #define AD7124_FILTER_FS_MSK GENMASK(10, 0)
...@@ -108,6 +110,8 @@ struct ad7124_chip_info { ...@@ -108,6 +110,8 @@ struct ad7124_chip_info {
struct ad7124_channel_config { struct ad7124_channel_config {
enum ad7124_ref_sel refsel; enum ad7124_ref_sel refsel;
bool bipolar; bool bipolar;
bool buf_positive;
bool buf_negative;
unsigned int ain; unsigned int ain;
unsigned int vref_mv; unsigned int vref_mv;
unsigned int pga_bits; unsigned int pga_bits;
...@@ -117,7 +121,7 @@ struct ad7124_channel_config { ...@@ -117,7 +121,7 @@ struct ad7124_channel_config {
struct ad7124_state { struct ad7124_state {
const struct ad7124_chip_info *chip_info; const struct ad7124_chip_info *chip_info;
struct ad_sigma_delta sd; struct ad_sigma_delta sd;
struct ad7124_channel_config channel_config[4]; struct ad7124_channel_config *channel_config;
struct regulator *vref[4]; struct regulator *vref[4];
struct clk *mclk; struct clk *mclk;
unsigned int adc_control; unsigned int adc_control;
...@@ -435,6 +439,7 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, ...@@ -435,6 +439,7 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
struct ad7124_state *st = iio_priv(indio_dev); struct ad7124_state *st = iio_priv(indio_dev);
struct device_node *child; struct device_node *child;
struct iio_chan_spec *chan; struct iio_chan_spec *chan;
struct ad7124_channel_config *chan_config;
unsigned int ain[2], channel = 0, tmp; unsigned int ain[2], channel = 0, tmp;
int ret; int ret;
...@@ -449,8 +454,14 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, ...@@ -449,8 +454,14 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
if (!chan) if (!chan)
return -ENOMEM; return -ENOMEM;
chan_config = devm_kcalloc(indio_dev->dev.parent, st->num_channels,
sizeof(*chan_config), GFP_KERNEL);
if (!chan_config)
return -ENOMEM;
indio_dev->channels = chan; indio_dev->channels = chan;
indio_dev->num_channels = st->num_channels; indio_dev->num_channels = st->num_channels;
st->channel_config = chan_config;
for_each_available_child_of_node(np, child) { for_each_available_child_of_node(np, child) {
ret = of_property_read_u32(child, "reg", &channel); ret = of_property_read_u32(child, "reg", &channel);
...@@ -462,13 +473,6 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, ...@@ -462,13 +473,6 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
if (ret) if (ret)
goto err; goto err;
if (ain[0] >= st->chip_info->num_inputs ||
ain[1] >= st->chip_info->num_inputs) {
dev_err(indio_dev->dev.parent,
"Input pin number out of range.\n");
ret = -EINVAL;
goto err;
}
st->channel_config[channel].ain = AD7124_CHANNEL_AINP(ain[0]) | st->channel_config[channel].ain = AD7124_CHANNEL_AINP(ain[0]) |
AD7124_CHANNEL_AINM(ain[1]); AD7124_CHANNEL_AINM(ain[1]);
st->channel_config[channel].bipolar = st->channel_config[channel].bipolar =
...@@ -480,6 +484,11 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, ...@@ -480,6 +484,11 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
else else
st->channel_config[channel].refsel = tmp; st->channel_config[channel].refsel = tmp;
st->channel_config[channel].buf_positive =
of_property_read_bool(child, "adi,buffered-positive");
st->channel_config[channel].buf_negative =
of_property_read_bool(child, "adi,buffered-negative");
*chan = ad7124_channel_template; *chan = ad7124_channel_template;
chan->address = channel; chan->address = channel;
chan->scan_index = channel; chan->scan_index = channel;
...@@ -499,7 +508,7 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, ...@@ -499,7 +508,7 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
static int ad7124_setup(struct ad7124_state *st) static int ad7124_setup(struct ad7124_state *st)
{ {
unsigned int val, fclk, power_mode; unsigned int val, fclk, power_mode;
int i, ret; int i, ret, tmp;
fclk = clk_get_rate(st->mclk); fclk = clk_get_rate(st->mclk);
if (!fclk) if (!fclk)
...@@ -532,8 +541,12 @@ static int ad7124_setup(struct ad7124_state *st) ...@@ -532,8 +541,12 @@ static int ad7124_setup(struct ad7124_state *st)
if (ret < 0) if (ret < 0)
return ret; return ret;
tmp = (st->channel_config[i].buf_positive << 1) +
st->channel_config[i].buf_negative;
val = AD7124_CONFIG_BIPOLAR(st->channel_config[i].bipolar) | val = AD7124_CONFIG_BIPOLAR(st->channel_config[i].bipolar) |
AD7124_CONFIG_REF_SEL(st->channel_config[i].refsel); AD7124_CONFIG_REF_SEL(st->channel_config[i].refsel) |
AD7124_CONFIG_IN_BUFF(tmp);
ret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(i), 2, val); ret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(i), 2, val);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -140,7 +140,7 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, ...@@ -140,7 +140,7 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
int *val2, int *val2,
long m) long m)
{ {
int ret; int ret, ch = 0;
struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_state *st = iio_priv(indio_dev);
switch (m) { switch (m) {
...@@ -157,8 +157,10 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, ...@@ -157,8 +157,10 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
*val = (short)ret; *val = (short)ret;
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
if (st->sw_mode_en)
ch = chan->address;
*val = 0; *val = 0;
*val2 = st->scale_avail[st->range]; *val2 = st->scale_avail[st->range[ch]];
return IIO_VAL_INT_PLUS_MICRO; return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_OVERSAMPLING_RATIO: case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
*val = st->oversampling; *val = st->oversampling;
...@@ -194,6 +196,32 @@ static ssize_t in_voltage_scale_available_show(struct device *dev, ...@@ -194,6 +196,32 @@ static ssize_t in_voltage_scale_available_show(struct device *dev,
static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0);
static int ad7606_write_scale_hw(struct iio_dev *indio_dev, int ch, int val)
{
struct ad7606_state *st = iio_priv(indio_dev);
gpiod_set_value(st->gpio_range, val);
return 0;
}
static int ad7606_write_os_hw(struct iio_dev *indio_dev, int val)
{
struct ad7606_state *st = iio_priv(indio_dev);
DECLARE_BITMAP(values, 3);
values[0] = val;
gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc,
st->gpio_os->info, values);
/* AD7616 requires a reset to update value */
if (st->chip_info->os_req_reset)
ad7606_reset(st);
return 0;
}
static int ad7606_write_raw(struct iio_dev *indio_dev, static int ad7606_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, struct iio_chan_spec const *chan,
int val, int val,
...@@ -201,15 +229,20 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, ...@@ -201,15 +229,20 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
long mask) long mask)
{ {
struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_state *st = iio_priv(indio_dev);
DECLARE_BITMAP(values, 3); int i, ret, ch = 0;
int i;
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
mutex_lock(&st->lock); mutex_lock(&st->lock);
i = find_closest(val2, st->scale_avail, st->num_scales); i = find_closest(val2, st->scale_avail, st->num_scales);
gpiod_set_value(st->gpio_range, i); if (st->sw_mode_en)
st->range = i; ch = chan->address;
ret = st->write_scale(indio_dev, ch, i);
if (ret < 0) {
mutex_unlock(&st->lock);
return ret;
}
st->range[ch] = i;
mutex_unlock(&st->lock); mutex_unlock(&st->lock);
return 0; return 0;
...@@ -218,17 +251,12 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, ...@@ -218,17 +251,12 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
return -EINVAL; return -EINVAL;
i = find_closest(val, st->oversampling_avail, i = find_closest(val, st->oversampling_avail,
st->num_os_ratios); st->num_os_ratios);
values[0] = i;
mutex_lock(&st->lock); mutex_lock(&st->lock);
gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc, ret = st->write_os(indio_dev, i);
st->gpio_os->info, values); if (ret < 0) {
mutex_unlock(&st->lock);
/* AD7616 requires a reset to update value */ return ret;
if (st->chip_info->os_req_reset) }
ad7606_reset(st);
st->oversampling = st->oversampling_avail[i]; st->oversampling = st->oversampling_avail[i];
mutex_unlock(&st->lock); mutex_unlock(&st->lock);
...@@ -536,7 +564,7 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, ...@@ -536,7 +564,7 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
st->bops = bops; st->bops = bops;
st->base_address = base_address; st->base_address = base_address;
/* tied to logic low, analog input range is +/- 5V */ /* tied to logic low, analog input range is +/- 5V */
st->range = 0; st->range[0] = 0;
st->oversampling = 1; st->oversampling = 1;
st->scale_avail = ad7606_scale_avail; st->scale_avail = ad7606_scale_avail;
st->num_scales = ARRAY_SIZE(ad7606_scale_avail); st->num_scales = ARRAY_SIZE(ad7606_scale_avail);
...@@ -589,6 +617,39 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, ...@@ -589,6 +617,39 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
if (ret) if (ret)
dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n"); dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n");
st->write_scale = ad7606_write_scale_hw;
st->write_os = ad7606_write_os_hw;
if (st->chip_info->sw_mode_config)
st->sw_mode_en = device_property_present(st->dev,
"adi,sw-mode");
if (st->sw_mode_en) {
/* After reset, in software mode, ±10 V is set by default */
memset32(st->range, 2, ARRAY_SIZE(st->range));
indio_dev->info = &ad7606_info_os_and_range;
/*
* In software mode, the range gpio has no longer its function.
* Instead, the scale can be configured individually for each
* channel from the range registers.
*/
if (st->chip_info->write_scale_sw)
st->write_scale = st->chip_info->write_scale_sw;
/*
* In software mode, the oversampling is no longer configured
* with GPIO pins. Instead, the oversampling can be configured
* in configuratiion register.
*/
if (st->chip_info->write_os_sw)
st->write_os = st->chip_info->write_os_sw;
ret = st->chip_info->sw_mode_config(indio_dev);
if (ret < 0)
return ret;
}
st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
indio_dev->name, indio_dev->id); indio_dev->name, indio_dev->id);
if (!st->trig) if (!st->trig)
...@@ -643,7 +704,7 @@ static int ad7606_resume(struct device *dev) ...@@ -643,7 +704,7 @@ static int ad7606_resume(struct device *dev)
struct ad7606_state *st = iio_priv(indio_dev); struct ad7606_state *st = iio_priv(indio_dev);
if (st->gpio_standby) { if (st->gpio_standby) {
gpiod_set_value(st->gpio_range, st->range); gpiod_set_value(st->gpio_range, st->range[0]);
gpiod_set_value(st->gpio_standby, 1); gpiod_set_value(st->gpio_standby, 1);
ad7606_reset(st); ad7606_reset(st);
} }
......
...@@ -16,6 +16,12 @@ ...@@ -16,6 +16,12 @@
* oversampling ratios. * oversampling ratios.
* @oversampling_num number of elements stored in oversampling_avail array * @oversampling_num number of elements stored in oversampling_avail array
* @os_req_reset some devices require a reset to update oversampling * @os_req_reset some devices require a reset to update oversampling
* @write_scale_sw pointer to the function which writes the scale via spi
in software mode
* @write_os_sw pointer to the function which writes the os via spi
in software mode
* @sw_mode_config: pointer to a function which configured the device
* for software mode
*/ */
struct ad7606_chip_info { struct ad7606_chip_info {
const struct iio_chan_spec *channels; const struct iio_chan_spec *channels;
...@@ -23,6 +29,9 @@ struct ad7606_chip_info { ...@@ -23,6 +29,9 @@ struct ad7606_chip_info {
const unsigned int *oversampling_avail; const unsigned int *oversampling_avail;
unsigned int oversampling_num; unsigned int oversampling_num;
bool os_req_reset; bool os_req_reset;
int (*write_scale_sw)(struct iio_dev *indio_dev, int ch, int val);
int (*write_os_sw)(struct iio_dev *indio_dev, int val);
int (*sw_mode_config)(struct iio_dev *indio_dev);
}; };
/** /**
...@@ -34,11 +43,14 @@ struct ad7606_chip_info { ...@@ -34,11 +43,14 @@ struct ad7606_chip_info {
* @range voltage range selection, selects which scale to apply * @range voltage range selection, selects which scale to apply
* @oversampling oversampling selection * @oversampling oversampling selection
* @base_address address from where to read data in parallel operation * @base_address address from where to read data in parallel operation
* @sw_mode_en software mode enabled
* @scale_avail pointer to the array which stores the available scales * @scale_avail pointer to the array which stores the available scales
* @num_scales number of elements stored in the scale_avail array * @num_scales number of elements stored in the scale_avail array
* @oversampling_avail pointer to the array which stores the available * @oversampling_avail pointer to the array which stores the available
* oversampling ratios. * oversampling ratios.
* @num_os_ratios number of elements stored in oversampling_avail array * @num_os_ratios number of elements stored in oversampling_avail array
* @write_scale pointer to the function which writes the scale
* @write_os pointer to the function which writes the os
* @lock protect sensor state from concurrent accesses to GPIOs * @lock protect sensor state from concurrent accesses to GPIOs
* @gpio_convst GPIO descriptor for conversion start signal (CONVST) * @gpio_convst GPIO descriptor for conversion start signal (CONVST)
* @gpio_reset GPIO descriptor for device hard-reset * @gpio_reset GPIO descriptor for device hard-reset
...@@ -57,13 +69,16 @@ struct ad7606_state { ...@@ -57,13 +69,16 @@ struct ad7606_state {
const struct ad7606_chip_info *chip_info; const struct ad7606_chip_info *chip_info;
struct regulator *reg; struct regulator *reg;
const struct ad7606_bus_ops *bops; const struct ad7606_bus_ops *bops;
unsigned int range; unsigned int range[16];
unsigned int oversampling; unsigned int oversampling;
void __iomem *base_address; void __iomem *base_address;
bool sw_mode_en;
const unsigned int *scale_avail; const unsigned int *scale_avail;
unsigned int num_scales; unsigned int num_scales;
const unsigned int *oversampling_avail; const unsigned int *oversampling_avail;
unsigned int num_os_ratios; unsigned int num_os_ratios;
int (*write_scale)(struct iio_dev *indio_dev, int ch, int val);
int (*write_os)(struct iio_dev *indio_dev, int val);
struct mutex lock; /* protect sensor state */ struct mutex lock; /* protect sensor state */
struct gpio_desc *gpio_convst; struct gpio_desc *gpio_convst;
......
...@@ -357,7 +357,7 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev) ...@@ -357,7 +357,7 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
ret = ad_sigma_delta_set_channel(sigma_delta, ret = ad_sigma_delta_set_channel(sigma_delta,
indio_dev->channels[channel].address); indio_dev->channels[channel].address);
if (ret) if (ret)
goto err_predisable; return ret;
spi_bus_lock(sigma_delta->spi->master); spi_bus_lock(sigma_delta->spi->master);
sigma_delta->bus_locked = true; sigma_delta->bus_locked = true;
...@@ -374,7 +374,6 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev) ...@@ -374,7 +374,6 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
err_unlock: err_unlock:
spi_bus_unlock(sigma_delta->spi->master); spi_bus_unlock(sigma_delta->spi->master);
err_predisable:
return ret; return ret;
} }
......
...@@ -78,6 +78,7 @@ ...@@ -78,6 +78,7 @@
#define IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT 0xf0000 #define IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT 0xf0000
#define IMX7D_ADC_TIMEOUT msecs_to_jiffies(100) #define IMX7D_ADC_TIMEOUT msecs_to_jiffies(100)
#define IMX7D_ADC_INPUT_CLK 24000000
enum imx7d_adc_clk_pre_div { enum imx7d_adc_clk_pre_div {
IMX7D_ADC_ANALOG_CLK_PRE_DIV_4, IMX7D_ADC_ANALOG_CLK_PRE_DIV_4,
...@@ -100,8 +101,6 @@ struct imx7d_adc_feature { ...@@ -100,8 +101,6 @@ struct imx7d_adc_feature {
enum imx7d_adc_average_num avg_num; enum imx7d_adc_average_num avg_num;
u32 core_time_unit; /* impact the sample rate */ u32 core_time_unit; /* impact the sample rate */
bool average_en;
}; };
struct imx7d_adc { struct imx7d_adc {
...@@ -179,7 +178,6 @@ static void imx7d_adc_feature_config(struct imx7d_adc *info) ...@@ -179,7 +178,6 @@ static void imx7d_adc_feature_config(struct imx7d_adc *info)
info->adc_feature.clk_pre_div = IMX7D_ADC_ANALOG_CLK_PRE_DIV_4; info->adc_feature.clk_pre_div = IMX7D_ADC_ANALOG_CLK_PRE_DIV_4;
info->adc_feature.avg_num = IMX7D_ADC_AVERAGE_NUM_32; info->adc_feature.avg_num = IMX7D_ADC_AVERAGE_NUM_32;
info->adc_feature.core_time_unit = 1; info->adc_feature.core_time_unit = 1;
info->adc_feature.average_en = true;
} }
static void imx7d_adc_sample_rate_set(struct imx7d_adc *info) static void imx7d_adc_sample_rate_set(struct imx7d_adc *info)
...@@ -240,9 +238,8 @@ static void imx7d_adc_channel_set(struct imx7d_adc *info) ...@@ -240,9 +238,8 @@ static void imx7d_adc_channel_set(struct imx7d_adc *info)
/* the channel choose single conversion, and enable average mode */ /* the channel choose single conversion, and enable average mode */
cfg1 |= (IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN | cfg1 |= (IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN |
IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE); IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE |
if (info->adc_feature.average_en) IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN);
cfg1 |= IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN;
/* /*
* physical channel 0 chose logical channel A * physical channel 0 chose logical channel A
...@@ -272,13 +269,11 @@ static void imx7d_adc_channel_set(struct imx7d_adc *info) ...@@ -272,13 +269,11 @@ static void imx7d_adc_channel_set(struct imx7d_adc *info)
static u32 imx7d_adc_get_sample_rate(struct imx7d_adc *info) static u32 imx7d_adc_get_sample_rate(struct imx7d_adc *info)
{ {
/* input clock is always 24MHz */
u32 input_clk = 24000000;
u32 analogue_core_clk; u32 analogue_core_clk;
u32 core_time_unit = info->adc_feature.core_time_unit; u32 core_time_unit = info->adc_feature.core_time_unit;
u32 tmp; u32 tmp;
analogue_core_clk = input_clk / info->pre_div_num; analogue_core_clk = IMX7D_ADC_INPUT_CLK / info->pre_div_num;
tmp = (core_time_unit + 1) * 6; tmp = (core_time_unit + 1) * 6;
return analogue_core_clk / tmp; return analogue_core_clk / tmp;
...@@ -493,11 +488,8 @@ static int imx7d_adc_probe(struct platform_device *pdev) ...@@ -493,11 +488,8 @@ static int imx7d_adc_probe(struct platform_device *pdev)
info->dev = dev; info->dev = dev;
info->regs = devm_platform_ioremap_resource(pdev, 0); info->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(info->regs)) { if (IS_ERR(info->regs))
ret = PTR_ERR(info->regs); return PTR_ERR(info->regs);
dev_err(dev, "Failed to remap adc memory, err = %d\n", ret);
return ret;
}
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
...@@ -531,9 +523,7 @@ static int imx7d_adc_probe(struct platform_device *pdev) ...@@ -531,9 +523,7 @@ static int imx7d_adc_probe(struct platform_device *pdev)
indio_dev->channels = imx7d_adc_iio_channels; indio_dev->channels = imx7d_adc_iio_channels;
indio_dev->num_channels = ARRAY_SIZE(imx7d_adc_iio_channels); indio_dev->num_channels = ARRAY_SIZE(imx7d_adc_iio_channels);
ret = devm_request_irq(dev, irq, ret = devm_request_irq(dev, irq, imx7d_adc_isr, 0, dev_name(dev), info);
imx7d_adc_isr, 0,
dev_name(dev), info);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "Failed requesting irq, irq = %d\n", irq); dev_err(dev, "Failed requesting irq, irq = %d\n", irq);
return ret; return ret;
......
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0
/* /*
* Amlogic Meson Successive Approximation Register (SAR) A/D Converter * Amlogic Meson Successive Approximation Register (SAR) A/D Converter
* *
......
...@@ -87,6 +87,7 @@ struct stm32_adc_priv_cfg { ...@@ -87,6 +87,7 @@ struct stm32_adc_priv_cfg {
* @domain: irq domain reference * @domain: irq domain reference
* @aclk: clock reference for the analog circuitry * @aclk: clock reference for the analog circuitry
* @bclk: bus clock common for all ADCs, depends on part used * @bclk: bus clock common for all ADCs, depends on part used
* @vdda: vdda analog supply reference
* @vref: regulator reference * @vref: regulator reference
* @cfg: compatible configuration data * @cfg: compatible configuration data
* @common: common data for all ADC instances * @common: common data for all ADC instances
...@@ -97,6 +98,7 @@ struct stm32_adc_priv { ...@@ -97,6 +98,7 @@ struct stm32_adc_priv {
struct irq_domain *domain; struct irq_domain *domain;
struct clk *aclk; struct clk *aclk;
struct clk *bclk; struct clk *bclk;
struct regulator *vdda;
struct regulator *vref; struct regulator *vref;
const struct stm32_adc_priv_cfg *cfg; const struct stm32_adc_priv_cfg *cfg;
struct stm32_adc_common common; struct stm32_adc_common common;
...@@ -394,10 +396,16 @@ static int stm32_adc_core_hw_start(struct device *dev) ...@@ -394,10 +396,16 @@ static int stm32_adc_core_hw_start(struct device *dev)
struct stm32_adc_priv *priv = to_stm32_adc_priv(common); struct stm32_adc_priv *priv = to_stm32_adc_priv(common);
int ret; int ret;
ret = regulator_enable(priv->vdda);
if (ret < 0) {
dev_err(dev, "vdda enable failed %d\n", ret);
return ret;
}
ret = regulator_enable(priv->vref); ret = regulator_enable(priv->vref);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "vref enable failed\n"); dev_err(dev, "vref enable failed\n");
return ret; goto err_vdda_disable;
} }
if (priv->bclk) { if (priv->bclk) {
...@@ -425,6 +433,8 @@ static int stm32_adc_core_hw_start(struct device *dev) ...@@ -425,6 +433,8 @@ static int stm32_adc_core_hw_start(struct device *dev)
clk_disable_unprepare(priv->bclk); clk_disable_unprepare(priv->bclk);
err_regulator_disable: err_regulator_disable:
regulator_disable(priv->vref); regulator_disable(priv->vref);
err_vdda_disable:
regulator_disable(priv->vdda);
return ret; return ret;
} }
...@@ -441,6 +451,7 @@ static void stm32_adc_core_hw_stop(struct device *dev) ...@@ -441,6 +451,7 @@ static void stm32_adc_core_hw_stop(struct device *dev)
if (priv->bclk) if (priv->bclk)
clk_disable_unprepare(priv->bclk); clk_disable_unprepare(priv->bclk);
regulator_disable(priv->vref); regulator_disable(priv->vref);
regulator_disable(priv->vdda);
} }
static int stm32_adc_probe(struct platform_device *pdev) static int stm32_adc_probe(struct platform_device *pdev)
...@@ -468,6 +479,14 @@ static int stm32_adc_probe(struct platform_device *pdev) ...@@ -468,6 +479,14 @@ static int stm32_adc_probe(struct platform_device *pdev)
return PTR_ERR(priv->common.base); return PTR_ERR(priv->common.base);
priv->common.phys_base = res->start; priv->common.phys_base = res->start;
priv->vdda = devm_regulator_get(&pdev->dev, "vdda");
if (IS_ERR(priv->vdda)) {
ret = PTR_ERR(priv->vdda);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev, "vdda get failed, %d\n", ret);
return ret;
}
priv->vref = devm_regulator_get(&pdev->dev, "vref"); priv->vref = devm_regulator_get(&pdev->dev, "vref");
if (IS_ERR(priv->vref)) { if (IS_ERR(priv->vref)) {
ret = PTR_ERR(priv->vref); ret = PTR_ERR(priv->vref);
......
This diff is collapsed.
...@@ -243,19 +243,33 @@ enum stm32_dfsdm_sinc_order { ...@@ -243,19 +243,33 @@ enum stm32_dfsdm_sinc_order {
}; };
/** /**
* struct stm32_dfsdm_filter - structure relative to stm32 FDSDM filter * struct stm32_dfsdm_filter_osr - DFSDM filter settings linked to oversampling
* @iosr: integrator oversampling * @iosr: integrator oversampling
* @fosr: filter oversampling * @fosr: filter oversampling
* @ford: filter order * @rshift: output sample right shift (hardware shift)
* @lshift: output sample left shift (software shift)
* @res: output sample resolution * @res: output sample resolution
* @max: output sample maximum positive value
*/
struct stm32_dfsdm_filter_osr {
unsigned int iosr;
unsigned int fosr;
unsigned int rshift;
unsigned int lshift;
u64 res;
s32 max;
};
/**
* struct stm32_dfsdm_filter - structure relative to stm32 FDSDM filter
* @ford: filter order
* @flo: filter oversampling data table indexed by fast mode flag
* @sync_mode: filter synchronized with filter 0 * @sync_mode: filter synchronized with filter 0
* @fast: filter fast mode * @fast: filter fast mode
*/ */
struct stm32_dfsdm_filter { struct stm32_dfsdm_filter {
unsigned int iosr;
unsigned int fosr;
enum stm32_dfsdm_sinc_order ford; enum stm32_dfsdm_sinc_order ford;
u64 res; struct stm32_dfsdm_filter_osr flo[2];
unsigned int sync_mode; unsigned int sync_mode;
unsigned int fast; unsigned int fast;
}; };
......
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0
# #
# Gain Amplifiers, etc. # Gain Amplifiers, etc.
# #
...@@ -7,12 +7,17 @@ ...@@ -7,12 +7,17 @@
menu "Amplifiers" menu "Amplifiers"
config AD8366 config AD8366
tristate "Analog Devices AD8366 VGA" tristate "Analog Devices AD8366 and similar Gain Amplifiers"
depends on SPI depends on SPI
depends on GPIOLIB
select BITREVERSE select BITREVERSE
help help
Say yes here to build support for Analog Devices AD8366 Say yes here to build support for Analog Devices AD8366 and similar
SPI Dual-Digital Variable Gain Amplifier (VGA). gain amplifiers. This driver supports the following gain amplifiers
from Analog Devices:
AD8366 Dual-Digital Variable Gain Amplifier (VGA)
ADA4961 BiCMOS RF Digital Gain Amplifier (DGA)
ADL5240 Digitally controlled variable gain amplifier (VGA)
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called ad8366. module will be called ad8366.
......
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0
/* /*
* AD8366 SPI Dual-Digital Variable Gain Amplifier (VGA) * AD8366 and similar Gain Amplifiers
* This driver supports the following gain amplifiers:
* AD8366 Dual-Digital Variable Gain Amplifier (VGA)
* ADA4961 BiCMOS RF Digital Gain Amplifier (DGA)
* ADL5240 Digitally controlled variable gain amplifier (VGA)
* *
* Copyright 2012 Analog Devices Inc. * Copyright 2012-2019 Analog Devices Inc.
*/ */
#include <linux/device.h> #include <linux/device.h>
...@@ -11,6 +15,7 @@ ...@@ -11,6 +15,7 @@
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/gpio/consumer.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/bitrev.h> #include <linux/bitrev.h>
...@@ -18,10 +23,25 @@ ...@@ -18,10 +23,25 @@
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
enum ad8366_type {
ID_AD8366,
ID_ADA4961,
ID_ADL5240,
};
struct ad8366_info {
int gain_min;
int gain_max;
};
struct ad8366_state { struct ad8366_state {
struct spi_device *spi; struct spi_device *spi;
struct regulator *reg; struct regulator *reg;
struct mutex lock; /* protect sensor state */
struct gpio_desc *reset_gpio;
unsigned char ch[2]; unsigned char ch[2];
enum ad8366_type type;
struct ad8366_info *info;
/* /*
* DMA (thus cache coherency maintenance) requires the * DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines. * transfer buffers to live in their own cache lines.
...@@ -29,19 +49,44 @@ struct ad8366_state { ...@@ -29,19 +49,44 @@ struct ad8366_state {
unsigned char data[2] ____cacheline_aligned; unsigned char data[2] ____cacheline_aligned;
}; };
static struct ad8366_info ad8366_infos[] = {
[ID_AD8366] = {
.gain_min = 4500,
.gain_max = 20500,
},
[ID_ADA4961] = {
.gain_min = -6000,
.gain_max = 15000,
},
[ID_ADL5240] = {
.gain_min = -11500,
.gain_max = 20000,
},
};
static int ad8366_write(struct iio_dev *indio_dev, static int ad8366_write(struct iio_dev *indio_dev,
unsigned char ch_a, unsigned char ch_b) unsigned char ch_a, unsigned char ch_b)
{ {
struct ad8366_state *st = iio_priv(indio_dev); struct ad8366_state *st = iio_priv(indio_dev);
int ret; int ret;
switch (st->type) {
case ID_AD8366:
ch_a = bitrev8(ch_a & 0x3F); ch_a = bitrev8(ch_a & 0x3F);
ch_b = bitrev8(ch_b & 0x3F); ch_b = bitrev8(ch_b & 0x3F);
st->data[0] = ch_b >> 4; st->data[0] = ch_b >> 4;
st->data[1] = (ch_b << 4) | (ch_a >> 2); st->data[1] = (ch_b << 4) | (ch_a >> 2);
break;
case ID_ADA4961:
st->data[0] = ch_a & 0x1F;
break;
case ID_ADL5240:
st->data[0] = (ch_a & 0x3F);
break;
}
ret = spi_write(st->spi, st->data, ARRAY_SIZE(st->data)); ret = spi_write(st->spi, st->data, indio_dev->num_channels);
if (ret < 0) if (ret < 0)
dev_err(&indio_dev->dev, "write failed (%d)", ret); dev_err(&indio_dev->dev, "write failed (%d)", ret);
...@@ -56,24 +101,35 @@ static int ad8366_read_raw(struct iio_dev *indio_dev, ...@@ -56,24 +101,35 @@ static int ad8366_read_raw(struct iio_dev *indio_dev,
{ {
struct ad8366_state *st = iio_priv(indio_dev); struct ad8366_state *st = iio_priv(indio_dev);
int ret; int ret;
unsigned code; int code, gain = 0;
mutex_lock(&indio_dev->mlock); mutex_lock(&st->lock);
switch (m) { switch (m) {
case IIO_CHAN_INFO_HARDWAREGAIN: case IIO_CHAN_INFO_HARDWAREGAIN:
code = st->ch[chan->channel]; code = st->ch[chan->channel];
switch (st->type) {
case ID_AD8366:
gain = code * 253 + 4500;
break;
case ID_ADA4961:
gain = 15000 - code * 1000;
break;
case ID_ADL5240:
gain = 20000 - 31500 + code * 500;
break;
}
/* Values in dB */ /* Values in dB */
code = code * 253 + 4500; *val = gain / 1000;
*val = code / 1000; *val2 = (gain % 1000) * 1000;
*val2 = (code % 1000) * 1000;
ret = IIO_VAL_INT_PLUS_MICRO_DB; ret = IIO_VAL_INT_PLUS_MICRO_DB;
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
mutex_unlock(&indio_dev->mlock); mutex_unlock(&st->lock);
return ret; return ret;
}; };
...@@ -85,21 +141,32 @@ static int ad8366_write_raw(struct iio_dev *indio_dev, ...@@ -85,21 +141,32 @@ static int ad8366_write_raw(struct iio_dev *indio_dev,
long mask) long mask)
{ {
struct ad8366_state *st = iio_priv(indio_dev); struct ad8366_state *st = iio_priv(indio_dev);
unsigned code; struct ad8366_info *inf = st->info;
int code = 0, gain;
int ret; int ret;
if (val < 0 || val2 < 0)
return -EINVAL;
/* Values in dB */ /* Values in dB */
code = (((u8)val * 1000) + ((u32)val2 / 1000)); if (val < 0)
gain = (val * 1000) - (val2 / 1000);
else
gain = (val * 1000) + (val2 / 1000);
if (code > 20500 || code < 4500) if (gain > inf->gain_max || gain < inf->gain_min)
return -EINVAL; return -EINVAL;
code = (code - 4500) / 253; switch (st->type) {
case ID_AD8366:
code = (gain - 4500) / 253;
break;
case ID_ADA4961:
code = (15000 - gain) / 1000;
break;
case ID_ADL5240:
code = ((gain - 500 - 20000) / 500) & 0x3F;
break;
}
mutex_lock(&indio_dev->mlock); mutex_lock(&st->lock);
switch (mask) { switch (mask) {
case IIO_CHAN_INFO_HARDWAREGAIN: case IIO_CHAN_INFO_HARDWAREGAIN:
st->ch[chan->channel] = code; st->ch[chan->channel] = code;
...@@ -108,7 +175,7 @@ static int ad8366_write_raw(struct iio_dev *indio_dev, ...@@ -108,7 +175,7 @@ static int ad8366_write_raw(struct iio_dev *indio_dev,
default: default:
ret = -EINVAL; ret = -EINVAL;
} }
mutex_unlock(&indio_dev->mlock); mutex_unlock(&st->lock);
return ret; return ret;
} }
...@@ -131,6 +198,10 @@ static const struct iio_chan_spec ad8366_channels[] = { ...@@ -131,6 +198,10 @@ static const struct iio_chan_spec ad8366_channels[] = {
AD8366_CHAN(1), AD8366_CHAN(1),
}; };
static const struct iio_chan_spec ada4961_channels[] = {
AD8366_CHAN(0),
};
static int ad8366_probe(struct spi_device *spi) static int ad8366_probe(struct spi_device *spi)
{ {
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
...@@ -151,14 +222,33 @@ static int ad8366_probe(struct spi_device *spi) ...@@ -151,14 +222,33 @@ static int ad8366_probe(struct spi_device *spi)
} }
spi_set_drvdata(spi, indio_dev); spi_set_drvdata(spi, indio_dev);
mutex_init(&st->lock);
st->spi = spi; st->spi = spi;
st->type = spi_get_device_id(spi)->driver_data;
switch (st->type) {
case ID_AD8366:
indio_dev->channels = ad8366_channels;
indio_dev->num_channels = ARRAY_SIZE(ad8366_channels);
break;
case ID_ADA4961:
case ID_ADL5240:
st->reset_gpio = devm_gpiod_get(&spi->dev, "reset",
GPIOD_OUT_HIGH);
indio_dev->channels = ada4961_channels;
indio_dev->num_channels = ARRAY_SIZE(ada4961_channels);
break;
default:
dev_err(&spi->dev, "Invalid device ID\n");
ret = -EINVAL;
goto error_disable_reg;
}
st->info = &ad8366_infos[st->type];
indio_dev->dev.parent = &spi->dev; indio_dev->dev.parent = &spi->dev;
indio_dev->name = spi_get_device_id(spi)->name; indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->info = &ad8366_info; indio_dev->info = &ad8366_info;
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = ad8366_channels;
indio_dev->num_channels = ARRAY_SIZE(ad8366_channels);
ret = ad8366_write(indio_dev, 0 , 0); ret = ad8366_write(indio_dev, 0 , 0);
if (ret < 0) if (ret < 0)
...@@ -192,7 +282,9 @@ static int ad8366_remove(struct spi_device *spi) ...@@ -192,7 +282,9 @@ static int ad8366_remove(struct spi_device *spi)
} }
static const struct spi_device_id ad8366_id[] = { static const struct spi_device_id ad8366_id[] = {
{"ad8366", 0}, {"ad8366", ID_AD8366},
{"ada4961", ID_ADA4961},
{"adl5240", ID_ADL5240},
{} {}
}; };
MODULE_DEVICE_TABLE(spi, ad8366_id); MODULE_DEVICE_TABLE(spi, ad8366_id);
...@@ -209,5 +301,5 @@ static struct spi_driver ad8366_driver = { ...@@ -209,5 +301,5 @@ static struct spi_driver ad8366_driver = {
module_spi_driver(ad8366_driver); module_spi_driver(ad8366_driver);
MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
MODULE_DESCRIPTION("Analog Devices AD8366 VGA"); MODULE_DESCRIPTION("Analog Devices AD8366 and similar Gain Amplifiers");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -39,5 +39,15 @@ config ADF4350 ...@@ -39,5 +39,15 @@ config ADF4350
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called adf4350. module will be called adf4350.
config ADF4371
tristate "Analog Devices ADF4371/ADF4372 Wideband Synthesizers"
depends on SPI
select REGMAP_SPI
help
Say yes here to build support for Analog Devices ADF4371 and ADF4372
Wideband Synthesizers. The driver provides direct access via sysfs.
To compile this driver as a module, choose M here: the
module will be called adf4371.
endmenu endmenu
endmenu endmenu
...@@ -6,3 +6,4 @@ ...@@ -6,3 +6,4 @@
# When adding new entries keep the list in alphabetical order # When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AD9523) += ad9523.o obj-$(CONFIG_AD9523) += ad9523.o
obj-$(CONFIG_ADF4350) += adf4350.o obj-$(CONFIG_ADF4350) += adf4350.o
obj-$(CONFIG_ADF4371) += adf4371.o
This diff is collapsed.
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/of_gpio.h>
#include <linux/timekeeping.h> #include <linux/timekeeping.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
...@@ -72,7 +71,7 @@ ...@@ -72,7 +71,7 @@
struct dht11 { struct dht11 {
struct device *dev; struct device *dev;
int gpio; struct gpio_desc *gpiod;
int irq; int irq;
struct completion completion; struct completion completion;
...@@ -179,7 +178,7 @@ static irqreturn_t dht11_handle_irq(int irq, void *data) ...@@ -179,7 +178,7 @@ static irqreturn_t dht11_handle_irq(int irq, void *data)
if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) { if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) {
dht11->edges[dht11->num_edges].ts = ktime_get_boot_ns(); dht11->edges[dht11->num_edges].ts = ktime_get_boot_ns();
dht11->edges[dht11->num_edges++].value = dht11->edges[dht11->num_edges++].value =
gpio_get_value(dht11->gpio); gpiod_get_value(dht11->gpiod);
if (dht11->num_edges >= DHT11_EDGES_PER_READ) if (dht11->num_edges >= DHT11_EDGES_PER_READ)
complete(&dht11->completion); complete(&dht11->completion);
...@@ -217,12 +216,12 @@ static int dht11_read_raw(struct iio_dev *iio_dev, ...@@ -217,12 +216,12 @@ static int dht11_read_raw(struct iio_dev *iio_dev,
reinit_completion(&dht11->completion); reinit_completion(&dht11->completion);
dht11->num_edges = 0; dht11->num_edges = 0;
ret = gpio_direction_output(dht11->gpio, 0); ret = gpiod_direction_output(dht11->gpiod, 0);
if (ret) if (ret)
goto err; goto err;
usleep_range(DHT11_START_TRANSMISSION_MIN, usleep_range(DHT11_START_TRANSMISSION_MIN,
DHT11_START_TRANSMISSION_MAX); DHT11_START_TRANSMISSION_MAX);
ret = gpio_direction_input(dht11->gpio); ret = gpiod_direction_input(dht11->gpiod);
if (ret) if (ret)
goto err; goto err;
...@@ -294,10 +293,8 @@ MODULE_DEVICE_TABLE(of, dht11_dt_ids); ...@@ -294,10 +293,8 @@ MODULE_DEVICE_TABLE(of, dht11_dt_ids);
static int dht11_probe(struct platform_device *pdev) static int dht11_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct dht11 *dht11; struct dht11 *dht11;
struct iio_dev *iio; struct iio_dev *iio;
int ret;
iio = devm_iio_device_alloc(dev, sizeof(*dht11)); iio = devm_iio_device_alloc(dev, sizeof(*dht11));
if (!iio) { if (!iio) {
...@@ -307,18 +304,13 @@ static int dht11_probe(struct platform_device *pdev) ...@@ -307,18 +304,13 @@ static int dht11_probe(struct platform_device *pdev)
dht11 = iio_priv(iio); dht11 = iio_priv(iio);
dht11->dev = dev; dht11->dev = dev;
dht11->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN);
if (IS_ERR(dht11->gpiod))
return PTR_ERR(dht11->gpiod);
ret = of_get_gpio(node, 0); dht11->irq = gpiod_to_irq(dht11->gpiod);
if (ret < 0)
return ret;
dht11->gpio = ret;
ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name);
if (ret)
return ret;
dht11->irq = gpio_to_irq(dht11->gpio);
if (dht11->irq < 0) { if (dht11->irq < 0) {
dev_err(dev, "GPIO %d has no interrupt\n", dht11->gpio); dev_err(dev, "GPIO %d has no interrupt\n", desc_to_gpio(dht11->gpiod));
return -EINVAL; return -EINVAL;
} }
......
...@@ -197,7 +197,7 @@ struct st_lsm6dsx_ext_dev_settings { ...@@ -197,7 +197,7 @@ struct st_lsm6dsx_ext_dev_settings {
* struct st_lsm6dsx_settings - ST IMU sensor settings * struct st_lsm6dsx_settings - ST IMU sensor settings
* @wai: Sensor WhoAmI default value. * @wai: Sensor WhoAmI default value.
* @max_fifo_size: Sensor max fifo length in FIFO words. * @max_fifo_size: Sensor max fifo length in FIFO words.
* @id: List of hw id supported by the driver configuration. * @id: List of hw id/device name supported by the driver configuration.
* @decimator: List of decimator register info (addr + mask). * @decimator: List of decimator register info (addr + mask).
* @batch: List of FIFO batching register info (addr + mask). * @batch: List of FIFO batching register info (addr + mask).
* @fifo_ops: Sensor hw FIFO parameters. * @fifo_ops: Sensor hw FIFO parameters.
...@@ -207,7 +207,10 @@ struct st_lsm6dsx_ext_dev_settings { ...@@ -207,7 +207,10 @@ struct st_lsm6dsx_ext_dev_settings {
struct st_lsm6dsx_settings { struct st_lsm6dsx_settings {
u8 wai; u8 wai;
u16 max_fifo_size; u16 max_fifo_size;
enum st_lsm6dsx_hw_id id[ST_LSM6DSX_MAX_ID]; struct {
enum st_lsm6dsx_hw_id hw_id;
const char *name;
} id[ST_LSM6DSX_MAX_ID];
struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID]; struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID];
struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID]; struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID];
struct st_lsm6dsx_fifo_ops fifo_ops; struct st_lsm6dsx_fifo_ops fifo_ops;
...@@ -303,7 +306,7 @@ struct st_lsm6dsx_hw { ...@@ -303,7 +306,7 @@ struct st_lsm6dsx_hw {
static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0}; static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0};
extern const struct dev_pm_ops st_lsm6dsx_pm_ops; extern const struct dev_pm_ops st_lsm6dsx_pm_ops;
int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
struct regmap *regmap); struct regmap *regmap);
int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
bool enable); bool enable);
......
...@@ -124,7 +124,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { ...@@ -124,7 +124,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.wai = 0x69, .wai = 0x69,
.max_fifo_size = 1365, .max_fifo_size = 1365,
.id = { .id = {
[0] = ST_LSM6DS3_ID, {
.hw_id = ST_LSM6DS3_ID,
.name = ST_LSM6DS3_DEV_NAME,
},
}, },
.decimator = { .decimator = {
[ST_LSM6DSX_ID_ACC] = { [ST_LSM6DSX_ID_ACC] = {
...@@ -171,7 +174,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { ...@@ -171,7 +174,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.wai = 0x69, .wai = 0x69,
.max_fifo_size = 682, .max_fifo_size = 682,
.id = { .id = {
[0] = ST_LSM6DS3H_ID, {
.hw_id = ST_LSM6DS3H_ID,
.name = ST_LSM6DS3H_DEV_NAME,
},
}, },
.decimator = { .decimator = {
[ST_LSM6DSX_ID_ACC] = { [ST_LSM6DSX_ID_ACC] = {
...@@ -218,9 +224,16 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { ...@@ -218,9 +224,16 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.wai = 0x6a, .wai = 0x6a,
.max_fifo_size = 682, .max_fifo_size = 682,
.id = { .id = {
[0] = ST_LSM6DSL_ID, {
[1] = ST_LSM6DSM_ID, .hw_id = ST_LSM6DSL_ID,
[2] = ST_ISM330DLC_ID, .name = ST_LSM6DSL_DEV_NAME,
}, {
.hw_id = ST_LSM6DSM_ID,
.name = ST_LSM6DSM_DEV_NAME,
}, {
.hw_id = ST_ISM330DLC_ID,
.name = ST_ISM330DLC_DEV_NAME,
},
}, },
.decimator = { .decimator = {
[ST_LSM6DSX_ID_ACC] = { [ST_LSM6DSX_ID_ACC] = {
...@@ -267,8 +280,13 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { ...@@ -267,8 +280,13 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.wai = 0x6c, .wai = 0x6c,
.max_fifo_size = 512, .max_fifo_size = 512,
.id = { .id = {
[0] = ST_LSM6DSO_ID, {
[1] = ST_LSM6DSOX_ID, .hw_id = ST_LSM6DSO_ID,
.name = ST_LSM6DSO_DEV_NAME,
}, {
.hw_id = ST_LSM6DSOX_ID,
.name = ST_LSM6DSOX_DEV_NAME,
},
}, },
.batch = { .batch = {
[ST_LSM6DSX_ID_ACC] = { [ST_LSM6DSX_ID_ACC] = {
...@@ -333,7 +351,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { ...@@ -333,7 +351,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.wai = 0x6b, .wai = 0x6b,
.max_fifo_size = 512, .max_fifo_size = 512,
.id = { .id = {
[0] = ST_ASM330LHH_ID, {
.hw_id = ST_ASM330LHH_ID,
.name = ST_ASM330LHH_DEV_NAME,
},
}, },
.batch = { .batch = {
[ST_LSM6DSX_ID_ACC] = { [ST_LSM6DSX_ID_ACC] = {
...@@ -372,7 +393,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { ...@@ -372,7 +393,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
.wai = 0x6b, .wai = 0x6b,
.max_fifo_size = 512, .max_fifo_size = 512,
.id = { .id = {
[0] = ST_LSM6DSR_ID, {
.hw_id = ST_LSM6DSR_ID,
.name = ST_LSM6DSR_DEV_NAME,
},
}, },
.batch = { .batch = {
[ST_LSM6DSX_ID_ACC] = { [ST_LSM6DSX_ID_ACC] = {
...@@ -470,13 +494,14 @@ int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) ...@@ -470,13 +494,14 @@ int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
return err; return err;
} }
static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id) static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
const char **name)
{ {
int err, i, j, data; int err, i, j, data;
for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) { for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
if (id == st_lsm6dsx_sensor_settings[i].id[j]) if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
break; break;
} }
if (j < ST_LSM6DSX_MAX_ID) if (j < ST_LSM6DSX_MAX_ID)
...@@ -499,6 +524,7 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id) ...@@ -499,6 +524,7 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id)
return -ENODEV; return -ENODEV;
} }
*name = st_lsm6dsx_sensor_settings[i].id[j].name;
hw->settings = &st_lsm6dsx_sensor_settings[i]; hw->settings = &st_lsm6dsx_sensor_settings[i];
return 0; return 0;
...@@ -1040,11 +1066,12 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, ...@@ -1040,11 +1066,12 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
return iio_dev; return iio_dev;
} }
int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
struct regmap *regmap) struct regmap *regmap)
{ {
const struct st_lsm6dsx_shub_settings *hub_settings; const struct st_lsm6dsx_shub_settings *hub_settings;
struct st_lsm6dsx_hw *hw; struct st_lsm6dsx_hw *hw;
const char *name = NULL;
int i, err; int i, err;
hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
...@@ -1065,7 +1092,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, ...@@ -1065,7 +1092,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
hw->irq = irq; hw->irq = irq;
hw->regmap = regmap; hw->regmap = regmap;
err = st_lsm6dsx_check_whoami(hw, hw_id); err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
if (err < 0) if (err < 0)
return err; return err;
......
...@@ -35,8 +35,7 @@ static int st_lsm6dsx_i2c_probe(struct i2c_client *client, ...@@ -35,8 +35,7 @@ static int st_lsm6dsx_i2c_probe(struct i2c_client *client,
return PTR_ERR(regmap); return PTR_ERR(regmap);
} }
return st_lsm6dsx_probe(&client->dev, client->irq, return st_lsm6dsx_probe(&client->dev, client->irq, hw_id, regmap);
hw_id, id->name, regmap);
} }
static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
......
...@@ -35,8 +35,7 @@ static int st_lsm6dsx_spi_probe(struct spi_device *spi) ...@@ -35,8 +35,7 @@ static int st_lsm6dsx_spi_probe(struct spi_device *spi)
return PTR_ERR(regmap); return PTR_ERR(regmap);
} }
return st_lsm6dsx_probe(&spi->dev, spi->irq, return st_lsm6dsx_probe(&spi->dev, spi->irq, hw_id, regmap);
hw_id, id->name, regmap);
} }
static const struct of_device_id st_lsm6dsx_spi_of_match[] = { static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
......
...@@ -366,39 +366,25 @@ static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) ...@@ -366,39 +366,25 @@ static void iio_device_unregister_debugfs(struct iio_dev *indio_dev)
debugfs_remove_recursive(indio_dev->debugfs_dentry); debugfs_remove_recursive(indio_dev->debugfs_dentry);
} }
static int iio_device_register_debugfs(struct iio_dev *indio_dev) static void iio_device_register_debugfs(struct iio_dev *indio_dev)
{ {
struct dentry *d;
if (indio_dev->info->debugfs_reg_access == NULL) if (indio_dev->info->debugfs_reg_access == NULL)
return 0; return;
if (!iio_debugfs_dentry) if (!iio_debugfs_dentry)
return 0; return;
indio_dev->debugfs_dentry = indio_dev->debugfs_dentry =
debugfs_create_dir(dev_name(&indio_dev->dev), debugfs_create_dir(dev_name(&indio_dev->dev),
iio_debugfs_dentry); iio_debugfs_dentry);
if (indio_dev->debugfs_dentry == NULL) {
dev_warn(indio_dev->dev.parent,
"Failed to create debugfs directory\n");
return -EFAULT;
}
d = debugfs_create_file("direct_reg_access", 0644,
indio_dev->debugfs_dentry,
indio_dev, &iio_debugfs_reg_fops);
if (!d) {
iio_device_unregister_debugfs(indio_dev);
return -ENOMEM;
}
return 0; debugfs_create_file("direct_reg_access", 0644,
indio_dev->debugfs_dentry, indio_dev,
&iio_debugfs_reg_fops);
} }
#else #else
static int iio_device_register_debugfs(struct iio_dev *indio_dev) static void iio_device_register_debugfs(struct iio_dev *indio_dev)
{ {
return 0;
} }
static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) static void iio_device_unregister_debugfs(struct iio_dev *indio_dev)
...@@ -1104,6 +1090,8 @@ static int iio_device_add_info_mask_type_avail(struct iio_dev *indio_dev, ...@@ -1104,6 +1090,8 @@ static int iio_device_add_info_mask_type_avail(struct iio_dev *indio_dev,
char *avail_postfix; char *avail_postfix;
for_each_set_bit(i, infomask, sizeof(*infomask) * 8) { for_each_set_bit(i, infomask, sizeof(*infomask) * 8) {
if (i >= ARRAY_SIZE(iio_chan_info_postfix))
return -EINVAL;
avail_postfix = kasprintf(GFP_KERNEL, avail_postfix = kasprintf(GFP_KERNEL,
"%s_available", "%s_available",
iio_chan_info_postfix[i]); iio_chan_info_postfix[i]);
...@@ -1669,12 +1657,7 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) ...@@ -1669,12 +1657,7 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod)
/* configure elements for the chrdev */ /* configure elements for the chrdev */
indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id);
ret = iio_device_register_debugfs(indio_dev); iio_device_register_debugfs(indio_dev);
if (ret) {
dev_err(indio_dev->dev.parent,
"Failed to register debugfs interfaces\n");
return ret;
}
ret = iio_buffer_alloc_sysfs_and_mask(indio_dev); ret = iio_buffer_alloc_sysfs_and_mask(indio_dev);
if (ret) { if (ret) {
......
...@@ -146,7 +146,7 @@ static int bh1780_probe(struct i2c_client *client, ...@@ -146,7 +146,7 @@ static int bh1780_probe(struct i2c_client *client,
{ {
int ret; int ret;
struct bh1780_data *bh1780; struct bh1780_data *bh1780;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct i2c_adapter *adapter = client->adapter;
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#define STK3310_CHIP_ID_VAL 0x13 #define STK3310_CHIP_ID_VAL 0x13
#define STK3311_CHIP_ID_VAL 0x1D #define STK3311_CHIP_ID_VAL 0x1D
#define STK3335_CHIP_ID_VAL 0x51
#define STK3310_PSINT_EN 0x01 #define STK3310_PSINT_EN 0x01
#define STK3310_PS_MAX_VAL 0xFFFF #define STK3310_PS_MAX_VAL 0xFFFF
...@@ -451,7 +452,8 @@ static int stk3310_init(struct iio_dev *indio_dev) ...@@ -451,7 +452,8 @@ static int stk3310_init(struct iio_dev *indio_dev)
return ret; return ret;
if (chipid != STK3310_CHIP_ID_VAL && if (chipid != STK3310_CHIP_ID_VAL &&
chipid != STK3311_CHIP_ID_VAL) { chipid != STK3311_CHIP_ID_VAL &&
chipid != STK3335_CHIP_ID_VAL) {
dev_err(&client->dev, "invalid chip id: 0x%x\n", chipid); dev_err(&client->dev, "invalid chip id: 0x%x\n", chipid);
return -ENODEV; return -ENODEV;
} }
...@@ -663,6 +665,7 @@ static SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend, stk3310_resume); ...@@ -663,6 +665,7 @@ static SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend, stk3310_resume);
static const struct i2c_device_id stk3310_i2c_id[] = { static const struct i2c_device_id stk3310_i2c_id[] = {
{"STK3310", 0}, {"STK3310", 0},
{"STK3311", 0}, {"STK3311", 0},
{"STK3335", 0},
{} {}
}; };
MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id); MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id);
...@@ -670,6 +673,7 @@ MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id); ...@@ -670,6 +673,7 @@ MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id);
static const struct acpi_device_id stk3310_acpi_id[] = { static const struct acpi_device_id stk3310_acpi_id[] = {
{"STK3310", 0}, {"STK3310", 0},
{"STK3311", 0}, {"STK3311", 0},
{"STK3335", 0},
{} {}
}; };
......
...@@ -53,6 +53,17 @@ config IIO_CROS_EC_BARO ...@@ -53,6 +53,17 @@ config IIO_CROS_EC_BARO
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called cros_ec_baro. will be called cros_ec_baro.
config DPS310
tristate "Infineon DPS310 pressure and temperature sensor"
depends on I2C
select REGMAP_I2C
help
Support for the Infineon DPS310 digital barometric pressure sensor.
It can be accessed over I2C bus.
This driver can also be built as a module. If so, the module will be
called dps310.
config HID_SENSOR_PRESS config HID_SENSOR_PRESS
depends on HID_SENSOR_HUB depends on HID_SENSOR_HUB
select IIO_BUFFER select IIO_BUFFER
......
...@@ -9,6 +9,7 @@ obj-$(CONFIG_BMP280) += bmp280.o ...@@ -9,6 +9,7 @@ obj-$(CONFIG_BMP280) += bmp280.o
bmp280-objs := bmp280-core.o bmp280-regmap.o bmp280-objs := bmp280-core.o bmp280-regmap.o
obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o
obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o
obj-$(CONFIG_DPS310) += dps310.o
obj-$(CONFIG_IIO_CROS_EC_BARO) += cros_ec_baro.o obj-$(CONFIG_IIO_CROS_EC_BARO) += cros_ec_baro.o
obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o
obj-$(CONFIG_HP03) += hp03.o obj-$(CONFIG_HP03) += hp03.o
......
This diff is collapsed.
...@@ -122,7 +122,7 @@ ...@@ -122,7 +122,7 @@
/* Power supply above 3.625 V */ /* Power supply above 3.625 V */
#define ADIS16203_DIAG_STAT_POWER_HIGH_BIT 1 #define ADIS16203_DIAG_STAT_POWER_HIGH_BIT 1
/* Power supply below 3.15 V */ /* Power supply below 2.975 V */
#define ADIS16203_DIAG_STAT_POWER_LOW_BIT 0 #define ADIS16203_DIAG_STAT_POWER_LOW_BIT 0
/* GLOB_CMD */ /* GLOB_CMD */
...@@ -234,7 +234,7 @@ static const char * const adis16203_status_error_msgs[] = { ...@@ -234,7 +234,7 @@ static const char * const adis16203_status_error_msgs[] = {
[ADIS16203_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", [ADIS16203_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
[ADIS16203_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", [ADIS16203_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed",
[ADIS16203_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", [ADIS16203_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
[ADIS16203_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", [ADIS16203_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V",
}; };
static const struct adis_data adis16203_data = { static const struct adis_data adis16203_data = {
...@@ -311,9 +311,17 @@ static int adis16203_remove(struct spi_device *spi) ...@@ -311,9 +311,17 @@ static int adis16203_remove(struct spi_device *spi)
return 0; return 0;
} }
static const struct of_device_id adis16203_of_match[] = {
{ .compatible = "adi,adis16203" },
{ },
};
MODULE_DEVICE_TABLE(of, adis16203_of_match);
static struct spi_driver adis16203_driver = { static struct spi_driver adis16203_driver = {
.driver = { .driver = {
.name = "adis16203", .name = "adis16203",
.of_match_table = adis16203_of_match,
}, },
.probe = adis16203_probe, .probe = adis16203_probe,
.remove = adis16203_remove, .remove = adis16203_remove,
......
...@@ -175,7 +175,7 @@ ...@@ -175,7 +175,7 @@
/* Power supply above 3.625 V */ /* Power supply above 3.625 V */
#define ADIS16240_DIAG_STAT_POWER_HIGH_BIT 1 #define ADIS16240_DIAG_STAT_POWER_HIGH_BIT 1
/* Power supply below 3.15 V */ /* Power supply below 2.225 V */
#define ADIS16240_DIAG_STAT_POWER_LOW_BIT 0 #define ADIS16240_DIAG_STAT_POWER_LOW_BIT 0
/* GLOB_CMD */ /* GLOB_CMD */
...@@ -435,9 +435,16 @@ static int adis16240_remove(struct spi_device *spi) ...@@ -435,9 +435,16 @@ static int adis16240_remove(struct spi_device *spi)
return 0; return 0;
} }
static const struct of_device_id adis16240_of_match[] = {
{ .compatible = "adi,adis16240" },
{ },
};
MODULE_DEVICE_TABLE(of, adis16240_of_match);
static struct spi_driver adis16240_driver = { static struct spi_driver adis16240_driver = {
.driver = { .driver = {
.name = "adis16240", .name = "adis16240",
.of_match_table = adis16240_of_match,
}, },
.probe = adis16240_probe, .probe = adis16240_probe,
.remove = adis16240_remove, .remove = adis16240_remove,
......
...@@ -126,9 +126,22 @@ static const struct spi_device_id adt7316_spi_id[] = { ...@@ -126,9 +126,22 @@ static const struct spi_device_id adt7316_spi_id[] = {
MODULE_DEVICE_TABLE(spi, adt7316_spi_id); MODULE_DEVICE_TABLE(spi, adt7316_spi_id);
static const struct of_device_id adt7316_of_spi_match[] = {
{ .compatible = "adi,adt7316" },
{ .compatible = "adi,adt7317" },
{ .compatible = "adi,adt7318" },
{ .compatible = "adi,adt7516" },
{ .compatible = "adi,adt7517" },
{ .compatible = "adi,adt7519" },
{ }
};
MODULE_DEVICE_TABLE(of, adt7316_of_spi_match);
static struct spi_driver adt7316_driver = { static struct spi_driver adt7316_driver = {
.driver = { .driver = {
.name = "adt7316", .name = "adt7316",
.of_match_table = adt7316_of_spi_match,
.pm = ADT7316_PM_OPS, .pm = ADT7316_PM_OPS,
}, },
.probe = adt7316_spi_probe, .probe = adt7316_spi_probe,
......
...@@ -46,6 +46,9 @@ ...@@ -46,6 +46,9 @@
#define AD7150_SN0 22 #define AD7150_SN0 22
#define AD7150_ID 23 #define AD7150_ID 23
/* AD7150 masks */
#define AD7150_THRESHTYPE_MSK GENMASK(6, 5)
/** /**
* struct ad7150_chip_info - instance specific chip data * struct ad7150_chip_info - instance specific chip data
* @client: i2c client for this device * @client: i2c client for this device
...@@ -138,7 +141,7 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, ...@@ -138,7 +141,7 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev,
if (ret < 0) if (ret < 0)
return ret; return ret;
threshtype = (ret >> 5) & 0x03; threshtype = FIELD_GET(AD7150_THRESHTYPE_MSK, ret);
/*check if threshold mode is fixed or adaptive*/ /*check if threshold mode is fixed or adaptive*/
thrfixed = FIELD_GET(AD7150_CFG_FIX, ret); thrfixed = FIELD_GET(AD7150_CFG_FIX, ret);
...@@ -162,7 +165,8 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, ...@@ -162,7 +165,8 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev,
return -EINVAL; return -EINVAL;
} }
/* lock should be held */ /* state_lock should be held to ensure consistent state*/
static int ad7150_write_event_params(struct iio_dev *indio_dev, static int ad7150_write_event_params(struct iio_dev *indio_dev,
unsigned int chan, unsigned int chan,
enum iio_event_type type, enum iio_event_type type,
...@@ -201,16 +205,11 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev, ...@@ -201,16 +205,11 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev,
ret = i2c_smbus_write_byte_data(chip->client, ret = i2c_smbus_write_byte_data(chip->client,
ad7150_addresses[chan][4], ad7150_addresses[chan][4],
sens); sens);
if (ret < 0) if (ret)
return ret; return ret;
return i2c_smbus_write_byte_data(chip->client,
ret = i2c_smbus_write_byte_data(chip->client,
ad7150_addresses[chan][5], ad7150_addresses[chan][5],
timeout); timeout);
if (ret < 0)
return ret;
return 0;
} }
static int ad7150_write_event_config(struct iio_dev *indio_dev, static int ad7150_write_event_config(struct iio_dev *indio_dev,
...@@ -353,8 +352,8 @@ static ssize_t ad7150_show_timeout(struct device *dev, ...@@ -353,8 +352,8 @@ static ssize_t ad7150_show_timeout(struct device *dev,
/* use the event code for consistency reasons */ /* use the event code for consistency reasons */
int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address); int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address);
int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address) int rising = (IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address)
== IIO_EV_DIR_RISING); == IIO_EV_DIR_RISING) ? 1 : 0;
switch (IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address)) { switch (IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address)) {
case IIO_EV_TYPE_MAG_ADAPTIVE: case IIO_EV_TYPE_MAG_ADAPTIVE:
...@@ -468,30 +467,21 @@ static const struct iio_event_spec ad7150_events[] = { ...@@ -468,30 +467,21 @@ static const struct iio_event_spec ad7150_events[] = {
}, },
}; };
#define AD7150_CAPACITANCE_CHAN(_chan) { \
.type = IIO_CAPACITANCE, \
.indexed = 1, \
.channel = _chan, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_AVERAGE_RAW), \
.event_spec = ad7150_events, \
.num_event_specs = ARRAY_SIZE(ad7150_events), \
}
static const struct iio_chan_spec ad7150_channels[] = { static const struct iio_chan_spec ad7150_channels[] = {
{ AD7150_CAPACITANCE_CHAN(0),
.type = IIO_CAPACITANCE, AD7150_CAPACITANCE_CHAN(1)
.indexed = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_AVERAGE_RAW),
.event_spec = ad7150_events,
.num_event_specs = ARRAY_SIZE(ad7150_events),
}, {
.type = IIO_CAPACITANCE,
.indexed = 1,
.channel = 1,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_AVERAGE_RAW),
.event_spec = ad7150_events,
.num_event_specs = ARRAY_SIZE(ad7150_events),
},
}; };
/*
* threshold events
*/
static irqreturn_t ad7150_event_handler(int irq, void *private) static irqreturn_t ad7150_event_handler(int irq, void *private)
{ {
struct iio_dev *indio_dev = private; struct iio_dev *indio_dev = private;
...@@ -580,10 +570,6 @@ static const struct iio_info ad7150_info = { ...@@ -580,10 +570,6 @@ static const struct iio_info ad7150_info = {
.write_event_value = &ad7150_write_event_value, .write_event_value = &ad7150_write_event_value,
}; };
/*
* device probe and remove
*/
static int ad7150_probe(struct i2c_client *client, static int ad7150_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
......
...@@ -748,9 +748,19 @@ static const struct i2c_device_id ad7746_id[] = { ...@@ -748,9 +748,19 @@ static const struct i2c_device_id ad7746_id[] = {
MODULE_DEVICE_TABLE(i2c, ad7746_id); MODULE_DEVICE_TABLE(i2c, ad7746_id);
static const struct of_device_id ad7746_of_match[] = {
{ .compatible = "adi,ad7745" },
{ .compatible = "adi,ad7746" },
{ .compatible = "adi,ad7747" },
{ },
};
MODULE_DEVICE_TABLE(of, ad7746_of_match);
static struct i2c_driver ad7746_driver = { static struct i2c_driver ad7746_driver = {
.driver = { .driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.of_match_table = ad7746_of_match,
}, },
.probe = ad7746_probe, .probe = ad7746_probe,
.id_table = ad7746_id, .id_table = ad7746_id,
......
...@@ -521,9 +521,20 @@ static const struct spi_device_id ad9834_id[] = { ...@@ -521,9 +521,20 @@ static const struct spi_device_id ad9834_id[] = {
}; };
MODULE_DEVICE_TABLE(spi, ad9834_id); MODULE_DEVICE_TABLE(spi, ad9834_id);
static const struct of_device_id ad9834_of_match[] = {
{.compatible = "adi,ad9833"},
{.compatible = "adi,ad9834"},
{.compatible = "adi,ad9837"},
{.compatible = "adi,ad9838"},
{}
};
MODULE_DEVICE_TABLE(of, ad9834_of_match);
static struct spi_driver ad9834_driver = { static struct spi_driver ad9834_driver = {
.driver = { .driver = {
.name = "ad9834", .name = "ad9834",
.of_match_table = ad9834_of_match
}, },
.probe = ad9834_probe, .probe = ad9834_probe,
.remove = ad9834_remove, .remove = ad9834_remove,
......
...@@ -647,9 +647,6 @@ static int ad2s1210_probe(struct spi_device *spi) ...@@ -647,9 +647,6 @@ static int ad2s1210_probe(struct spi_device *spi)
struct ad2s1210_state *st; struct ad2s1210_state *st;
int ret; int ret;
if (!spi->dev.platform_data)
return -EINVAL;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev) if (!indio_dev)
return -ENOMEM; return -ENOMEM;
......
...@@ -156,9 +156,9 @@ int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used, ...@@ -156,9 +156,9 @@ int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used,
*be = (endianchar == 'b'); *be = (endianchar == 'b');
*bytes = padint / 8; *bytes = padint / 8;
if (*bits_used == 64) if (*bits_used == 64)
*mask = ~0; *mask = ~(0ULL);
else else
*mask = (1ULL << *bits_used) - 1; *mask = (1ULL << *bits_used) - 1ULL;
*is_signed = (signchar == 's'); *is_signed = (signchar == 's');
if (fclose(sysfsfp)) { if (fclose(sysfsfp)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment