mirror of https://gitee.com/openkylin/linux.git
Second set of new device support, cleanups and features for IIO in the 5.4 cycle
Revised pull request to fix up a missing Signed-off-by and roll in a fix in the lsm9ds1 support after I broke it when applying. Revised again because the fix changed a hash meaning a fix that previously followed it now had the wrong fixes tag. A few fixes in here that could have gone a faster path but aren't quite worth the rush for 5.3. New device support * ad7606 - Support thead7606b
which adds a software controlled mode alongside the pin controlled only approach of the ad7606. Including dt-bindings. * lsm6dsx - Add support for the gyro and accelerometer part of the lsm9ds1 which is a compound device also including a magnetometer (st_sensors driver). Includes bindings and precursor rework of the driver. Features * ad7192 - Add support for low pass filter control. - DT binding docs. Cleanups and minor fixes * MAINTAINERS - Fix a typo in a path. - Add entry for ad7606 * ad5380 - Fix a failure to dereference a pointer before atempting to assign the value. * ad7192 - Drop platform data as not used in mainline and we now have full DT bindings. * ad7606 - YAML conversion for dt-bindings. * adis16240 - Rework write_raw to make it more readable using GENMASK. * adis16460 - Fix and issue with an unsigned variable holding potential negatives. * cros_ec - Fix missing default of calibration vector so that we get 'something' before calibration is complete on a given axis. * hid-sensors - Use int_pow instead of opencoding. * isl29501 - rename dt-binding docs to include renesas inline with other renesas parts and general current convention. * kxcjk1013 - Improve comments on the 'unusual' ACPI ids used to identify which sensor is which in certain laptops. * lsm6dsx - Add one bit to the fifo status masks for a number of parts. - Drop a reserved entry from the sensitivity values to tidy up interface. - Use core conversion macro from G to m/s^2 for lsm9ds1 to make it easier to relate to the datasheet and consistent with other parts supported. * max1027 - Use device managed APIs to avoid manual error handling and cleanup. * rfd77402 - Typo in Kconfig help. * sc27xx - Switch to polling mode from interrupts as interrupt handling typically to slow for very short sleeps. * st-sensors - Fix some missing selects for regmap. * tools - Add a .gitignore containing the binary outputs. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAl1uyTgRHGppYzIzQGtl cm5lbC5vcmcACgkQVIU0mcT0Foideg//fknN/aM40zRZlClkWx9XqUsByS/3XUAl dZL//5DGh566D8/auBeacQxt6SzOFRpj2XwWI/K8mGJi39y9LFOywOn4dDgOBh3x VWe/1eCNFg9Y1eMCXncYHBtxxobuV3UKEjVtYFtzg210HP/KM6C3fWdPTpmj1zNZ PYSnKGiBGxeJHMCUjN0QweifIRvTy0MLkxPc9CUHcFq0XiMD2enI4TwHYuZ/CNQw oisDPPksbPTW5R547vLEnQe/p16MtoFMX57yehbzKIp6qYBEVR+D5ne5kxct8x80 Ma7YVWLyWTxYF/MwLi3felIniEeyYhgTFVhy2rhZGt6eKDmNFTwTrJG5iTweeHQm 3FJPbZ04lDjE3RhoETGDc2aSqY5/Xy1nnOJcMjZ1twbDxPGmN2/rCP3YxYRmGL/P VCsCZYeQF6cKi7FyFiViqALTPH0k/Ebklol1f/IG8CuFCs8r/m6kKMeSJX3+miHZ gIxA2lX5uj8FIiB1bZxORN76W5PzxLji5IiCPy1KtlBin3E3oWM3nQLXNHpzp2Fw 5A8IyHb/qDoKnO1MlTkprIxdIzKqV4gtWqkY1kTBYyNyreMP/dsiw/lC1rnzWMm/ v7JHuTbO/Ay5gvT58goK7FD77CyvRTvy3bmi7PNkWJyogWpnRTLiPusMDz7FwxK4 Ffrbi7+qijk= =rPVR -----END PGP SIGNATURE----- Merge tag 'iio-for-5.4b-take3' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next Jonathan writes: Second set of new device support, cleanups and features for IIO in the 5.4 cycle Revised pull request to fix up a missing Signed-off-by and roll in a fix in the lsm9ds1 support after I broke it when applying. Revised again because the fix changed a hash meaning a fix that previously followed it now had the wrong fixes tag. A few fixes in here that could have gone a faster path but aren't quite worth the rush for 5.3. New device support * ad7606 - Support thead7606b
which adds a software controlled mode alongside the pin controlled only approach of the ad7606. Including dt-bindings. * lsm6dsx - Add support for the gyro and accelerometer part of the lsm9ds1 which is a compound device also including a magnetometer (st_sensors driver). Includes bindings and precursor rework of the driver. Features * ad7192 - Add support for low pass filter control. - DT binding docs. Cleanups and minor fixes * MAINTAINERS - Fix a typo in a path. - Add entry for ad7606 * ad5380 - Fix a failure to dereference a pointer before atempting to assign the value. * ad7192 - Drop platform data as not used in mainline and we now have full DT bindings. * ad7606 - YAML conversion for dt-bindings. * adis16240 - Rework write_raw to make it more readable using GENMASK. * adis16460 - Fix and issue with an unsigned variable holding potential negatives. * cros_ec - Fix missing default of calibration vector so that we get 'something' before calibration is complete on a given axis. * hid-sensors - Use int_pow instead of opencoding. * isl29501 - rename dt-binding docs to include renesas inline with other renesas parts and general current convention. * kxcjk1013 - Improve comments on the 'unusual' ACPI ids used to identify which sensor is which in certain laptops. * lsm6dsx - Add one bit to the fifo status masks for a number of parts. - Drop a reserved entry from the sensitivity values to tidy up interface. - Use core conversion macro from G to m/s^2 for lsm9ds1 to make it easier to relate to the datasheet and consistent with other parts supported. * max1027 - Use device managed APIs to avoid manual error handling and cleanup. * rfd77402 - Typo in Kconfig help. * sc27xx - Switch to polling mode from interrupts as interrupt handling typically to slow for very short sleeps. * st-sensors - Fix some missing selects for regmap. * tools - Add a .gitignore containing the binary outputs. * tag 'iio-for-5.4b-take3' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (27 commits) iio: imu: st_lsm6dsx: rely on IIO_G_TO_M_S_2 for gain definition for LSM9DS1 iio: imu: st_lsm6dsx: remove invalid gain value for LSM9DS1 iio: cros_ec: set calibscale for 3d MEMS to unit vector iio: dac: ad5380: fix incorrect assignment to val iio: imu: st_lsm6dsx: Fix FIFO diff mask for tagged fifo dt-bindings: iio: imu: st_lsm6dsx: add lsm9ds1 device bindings iio: imu: st_lsm6dsx: add support for accel/gyro unit of lsm9ds1 iio: imu: st_lsm6dsx: move register definitions to sensor_settings struct iio: imu: st_lsm6dsx: introduce update_fifo function pointer dt-bindings: iio: light: isl29501: Rename bindings documentation file Kconfig: Fix the reference to the RFD77402 ToF sensor in the 'help' section iio: st_sensors: Fix build error dt-bindings: iio: adc: Add AD7606B ADC documentation dt-bindings: iio: adc: Migrate AD7606 documentation to yaml MAINTAINERS: Add Beniamin Bia for AD7606 driver iio: adc: ad7606: Add support for AD7606B ADC tools: iio: add .gitignore iio: adc: sc27xx: Change to polling mode to read data iio: hid-sensor-attributes: Convert to use int_pow() iio: adc: max1027: Use device-managed APIs ...
This commit is contained in:
commit
74eb9c06b1
|
@ -0,0 +1,121 @@
|
|||
# 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,ad7192.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices AD7192 ADC device driver
|
||||
|
||||
maintainers:
|
||||
- Michael Hennerich <michael.hennerich@analog.com>
|
||||
|
||||
description: |
|
||||
Bindings for the Analog Devices AD7192 ADC device. Datasheet can be
|
||||
found here:
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/AD7192.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ad7190
|
||||
- adi,ad7192
|
||||
- adi,ad7193
|
||||
- adi,ad7195
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
spi-cpol: true
|
||||
|
||||
spi-cpha: true
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description: phandle to the master clock (mclk)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
dvdd-supply:
|
||||
description: DVdd voltage supply
|
||||
items:
|
||||
- const: dvdd
|
||||
|
||||
avdd-supply:
|
||||
description: AVdd voltage supply
|
||||
items:
|
||||
- const: avdd
|
||||
|
||||
adi,rejection-60-Hz-enable:
|
||||
description: |
|
||||
This bit enables a notch at 60 Hz when the first notch of the sinc
|
||||
filter is at 50 Hz. When REJ60 is set, a filter notch is placed at
|
||||
60 Hz when the sinc filter first notch is at 50 Hz. This allows
|
||||
simultaneous 50 Hz/ 60 Hz rejection.
|
||||
type: boolean
|
||||
|
||||
adi,refin2-pins-enable:
|
||||
description: |
|
||||
External reference applied between the P1/REFIN2(+) and P0/REFIN2(−) pins.
|
||||
type: boolean
|
||||
|
||||
adi,buffer-enable:
|
||||
description: |
|
||||
Enables the buffer on the analog inputs. If cleared, the analog inputs
|
||||
are unbuffered, lowering the power consumption of the device. If this
|
||||
bit is set, the analog inputs are buffered, allowing the user to place
|
||||
source impedances on the front end without contributing gain errors to
|
||||
the system.
|
||||
type: boolean
|
||||
|
||||
adi,burnout-currents-enable:
|
||||
description: |
|
||||
When this bit is set to 1, the 500 nA current sources in the signal
|
||||
path are enabled. When BURN = 0, the burnout currents are disabled.
|
||||
The burnout currents can be enabled only when the buffer is active
|
||||
and when chop is disabled.
|
||||
type: boolean
|
||||
|
||||
bipolar:
|
||||
description: see Documentation/devicetree/bindings/iio/adc/adc.txt
|
||||
type: boolean
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- dvdd-supply
|
||||
- avdd-supply
|
||||
- spi-cpol
|
||||
- spi-cpha
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi0 {
|
||||
adc@0 {
|
||||
compatible = "adi,ad7192";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <1000000>;
|
||||
spi-cpol;
|
||||
spi-cpha;
|
||||
clocks = <&ad7192_mclk>;
|
||||
clock-names = "mclk";
|
||||
#interrupt-cells = <2>;
|
||||
interrupts = <25 0x2>;
|
||||
interrupt-parent = <&gpio>;
|
||||
dvdd-supply = <&dvdd>;
|
||||
avdd-supply = <&avdd>;
|
||||
|
||||
adi,refin2-pins-enable;
|
||||
adi,rejection-60-Hz-enable;
|
||||
adi,buffer-enable;
|
||||
adi,burnout-currents-enable;
|
||||
};
|
||||
};
|
|
@ -1,66 +0,0 @@
|
|||
Analog Devices AD7606 Simultaneous Sampling ADC
|
||||
|
||||
Required properties for the AD7606:
|
||||
|
||||
- compatible: Must be one of
|
||||
* "adi,ad7605-4"
|
||||
* "adi,ad7606-8"
|
||||
* "adi,ad7606-6"
|
||||
* "adi,ad7606-4"
|
||||
* "adi,ad7616"
|
||||
- reg: SPI chip select number for the device
|
||||
- spi-max-frequency: Max SPI frequency to use
|
||||
see: Documentation/devicetree/bindings/spi/spi-bus.txt
|
||||
- spi-cpha: See Documentation/devicetree/bindings/spi/spi-bus.txt
|
||||
- avcc-supply: phandle to the Avcc power supply
|
||||
- interrupts: IRQ line for the ADC
|
||||
see: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
|
||||
- adi,conversion-start-gpios: must be the device tree identifier of the CONVST pin.
|
||||
This logic input is used to initiate conversions on the analog
|
||||
input channels. As the line is active high, it should be marked
|
||||
GPIO_ACTIVE_HIGH.
|
||||
|
||||
Optional properties:
|
||||
|
||||
- reset-gpios: must be the device tree identifier of the RESET pin. If specified,
|
||||
it will be asserted during driver probe. As the line is active high,
|
||||
it should be marked GPIO_ACTIVE_HIGH.
|
||||
- standby-gpios: must be the device tree identifier of the STBY pin. This pin is used
|
||||
to place the AD7606 into one of two power-down modes, Standby mode or
|
||||
Shutdown mode. As the line is active low, it should be marked
|
||||
GPIO_ACTIVE_LOW.
|
||||
- adi,first-data-gpios: must be the device tree identifier of the FRSTDATA pin.
|
||||
The FRSTDATA output indicates when the first channel, V1, is
|
||||
being read back on either the parallel, byte or serial interface.
|
||||
As the line is active high, it should be marked GPIO_ACTIVE_HIGH.
|
||||
- adi,range-gpios: must be the device tree identifier of the RANGE pin. The polarity on
|
||||
this pin determines the input range of the analog input channels. If
|
||||
this pin is tied to a logic high, the analog input range is ±10V for
|
||||
all channels. If this pin is tied to a logic low, the analog input range
|
||||
is ±5V for all channels. As the line is active high, it should be marked
|
||||
GPIO_ACTIVE_HIGH.
|
||||
- adi,oversampling-ratio-gpios: must be the device tree identifier of the over-sampling
|
||||
mode pins. As the line is active high, it should be marked
|
||||
GPIO_ACTIVE_HIGH.
|
||||
|
||||
Example:
|
||||
|
||||
adc@0 {
|
||||
compatible = "adi,ad7606-8";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <1000000>;
|
||||
spi-cpol;
|
||||
|
||||
avcc-supply = <&adc_vref>;
|
||||
|
||||
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-parent = <&gpio>;
|
||||
|
||||
adi,conversion-start-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
|
||||
adi,first-data-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
|
||||
adi,oversampling-ratio-gpios = <&gpio 18 GPIO_ACTIVE_HIGH
|
||||
&gpio 23 GPIO_ACTIVE_HIGH
|
||||
&gpio 26 GPIO_ACTIVE_HIGH>;
|
||||
standby-gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
|
||||
};
|
|
@ -0,0 +1,138 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/adi,ad7606.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices AD7606 Simultaneous Sampling ADC
|
||||
|
||||
maintainers:
|
||||
- Beniamin Bia <beniamin.bia@analog.com>
|
||||
- Stefan Popa <stefan.popa@analog.com>
|
||||
|
||||
description: |
|
||||
Analog Devices AD7606 Simultaneous Sampling ADC
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/ad7606_7606-6_7606-4.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/AD7606B.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/AD7616.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ad7605-4
|
||||
- adi,ad7606-8
|
||||
- adi,ad7606-6
|
||||
- adi,ad7606-4
|
||||
- adi,ad7606b
|
||||
- adi,ad7616
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
spi-cpha: true
|
||||
|
||||
avcc-supply:
|
||||
description:
|
||||
Phandle to the Avcc power supply
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
adi,conversion-start-gpios:
|
||||
description:
|
||||
Must be the device tree identifier of the CONVST pin.
|
||||
This logic input is used to initiate conversions on the analog
|
||||
input channels. As the line is active high, it should be marked
|
||||
GPIO_ACTIVE_HIGH.
|
||||
maxItems: 1
|
||||
|
||||
reset-gpios:
|
||||
description:
|
||||
Must be the device tree identifier of the RESET 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
|
||||
|
||||
standby-gpios:
|
||||
description:
|
||||
Must be the device tree identifier of the STBY pin. This pin is used
|
||||
to place the AD7606 into one of two power-down modes, Standby mode or
|
||||
Shutdown mode. As the line is active low, it should be marked
|
||||
GPIO_ACTIVE_LOW.
|
||||
maxItems: 1
|
||||
|
||||
adi,first-data-gpios:
|
||||
description:
|
||||
Must be the device tree identifier of the FRSTDATA pin.
|
||||
The FRSTDATA output indicates when the first channel, V1, is
|
||||
being read back on either the parallel, byte or serial interface.
|
||||
As the line is active high, it should be marked GPIO_ACTIVE_HIGH.
|
||||
maxItems: 1
|
||||
|
||||
adi,range-gpios:
|
||||
description:
|
||||
Must be the device tree identifier of the RANGE pin. The polarity on
|
||||
this pin determines the input range of the analog input channels. If
|
||||
this pin is tied to a logic high, the analog input range is ±10V for
|
||||
all channels. If this pin is tied to a logic low, the analog input range
|
||||
is ±5V for all channels. As the line is active high, it should be marked
|
||||
GPIO_ACTIVE_HIGH.
|
||||
maxItems: 1
|
||||
|
||||
adi,oversampling-ratio-gpios:
|
||||
description:
|
||||
Must be the device tree identifier of the over-sampling
|
||||
mode pins. As the line is active high, it should be marked
|
||||
GPIO_ACTIVE_HIGH.
|
||||
maxItems: 1
|
||||
|
||||
adi,sw-mode:
|
||||
description:
|
||||
Software mode of operation, so far available only for ad7616 and ad7606b.
|
||||
It is enabled when all three oversampling mode pins are connected to
|
||||
high level. The device is configured by the corresponding registers. If the
|
||||
adi,oversampling-ratio-gpios property is defined, then the driver will set the
|
||||
oversampling gpios to high. Otherwise, it is assumed that the pins are hardwired
|
||||
to VDD.
|
||||
type: boolean
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- spi-cpha
|
||||
- avcc-supply
|
||||
- interrupts
|
||||
- adi,conversion-start-gpios
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
spi0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0 {
|
||||
compatible = "adi,ad7606-8";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <1000000>;
|
||||
spi-cpol;
|
||||
spi-cpha;
|
||||
|
||||
avcc-supply = <&adc_vref>;
|
||||
|
||||
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-parent = <&gpio>;
|
||||
|
||||
adi,conversion-start-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>;
|
||||
adi,first-data-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
|
||||
adi,oversampling-ratio-gpios = <&gpio 18 GPIO_ACTIVE_HIGH
|
||||
&gpio 23 GPIO_ACTIVE_HIGH
|
||||
&gpio 26 GPIO_ACTIVE_HIGH>;
|
||||
standby-gpios = <&gpio 24 GPIO_ACTIVE_LOW>;
|
||||
adi,sw-mode;
|
||||
};
|
||||
};
|
||||
...
|
|
@ -13,6 +13,7 @@ Required properties:
|
|||
"st,lsm6dsr"
|
||||
"st,lsm6ds3tr-c"
|
||||
"st,ism330dhcx"
|
||||
"st,lsm9ds1-imu"
|
||||
- reg: i2c address of the sensor / spi cs line
|
||||
|
||||
Optional properties:
|
||||
|
|
|
@ -903,11 +903,12 @@ F: Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml
|
|||
|
||||
ANALOG DEVICES INC AD7606 DRIVER
|
||||
M: Stefan Popa <stefan.popa@analog.com>
|
||||
M: Beniamin Bia <beniamin.bia@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
W: http://ez.analog.com/community/linux-device-drivers
|
||||
S: Supported
|
||||
F: drivers/iio/adc/ad7606.c
|
||||
F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.txt
|
||||
F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml
|
||||
|
||||
ANALOG DEVICES INC AD7768-1 DRIVER
|
||||
M: Stefan Popa <stefan.popa@analog.com>
|
||||
|
@ -6341,7 +6342,7 @@ 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/ABI/testing/sysfs-bus-counter-ftm-quaddec
|
||||
F: Documentation/devicetree/bindings/counter/ftm-quaddec.txt
|
||||
F: drivers/counter/ftm-quaddec.c
|
||||
|
||||
|
|
|
@ -1486,8 +1486,8 @@ static const struct acpi_device_id kx_acpi_match[] = {
|
|||
{"KIOX0008", KXCJ91008},
|
||||
{"KIOX0009", KXTJ21009},
|
||||
{"KIOX000A", KXCJ91008},
|
||||
{"KIOX010A", KXCJ91008}, /* KXCJ91008 inside the display of a 2-in-1 */
|
||||
{"KIOX020A", KXCJ91008},
|
||||
{"KIOX010A", KXCJ91008}, /* KXCJ91008 in the display of a yoga 2-in-1 */
|
||||
{"KIOX020A", KXCJ91008}, /* KXCJ91008 in the base of a yoga 2-in-1 */
|
||||
{"KXTJ1009", KXTJ21009},
|
||||
{"KXJ2109", KXTJ21009},
|
||||
{"SMO8500", KXCJ91008},
|
||||
|
|
|
@ -410,12 +410,19 @@ static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
|
|||
.oversampling_avail = ad7606_oversampling_avail,
|
||||
.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
|
||||
},
|
||||
[ID_AD7606B] = {
|
||||
.channels = ad7606_channels,
|
||||
.num_channels = 9,
|
||||
.oversampling_avail = ad7606_oversampling_avail,
|
||||
.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
|
||||
},
|
||||
[ID_AD7616] = {
|
||||
.channels = ad7616_channels,
|
||||
.num_channels = 17,
|
||||
.oversampling_avail = ad7616_oversampling_avail,
|
||||
.oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail),
|
||||
.os_req_reset = true,
|
||||
.init_delay_ms = 15,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -631,8 +638,10 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
|
|||
dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n");
|
||||
|
||||
/* AD7616 requires al least 15ms to reconfigure after a reset */
|
||||
if (msleep_interruptible(15))
|
||||
return -ERESTARTSYS;
|
||||
if (st->chip_info->init_delay_ms) {
|
||||
if (msleep_interruptible(st->chip_info->init_delay_ms))
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
|
||||
st->write_scale = ad7606_write_scale_hw;
|
||||
st->write_os = ad7606_write_os_hw;
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
* oversampling ratios.
|
||||
* @oversampling_num number of elements stored in oversampling_avail array
|
||||
* @os_req_reset some devices require a reset to update oversampling
|
||||
* @init_delay_ms required delay in miliseconds for initialization
|
||||
* after a restart
|
||||
*/
|
||||
struct ad7606_chip_info {
|
||||
const struct iio_chan_spec *channels;
|
||||
|
@ -53,6 +55,7 @@ struct ad7606_chip_info {
|
|||
const unsigned int *oversampling_avail;
|
||||
unsigned int oversampling_num;
|
||||
bool os_req_reset;
|
||||
unsigned long init_delay_ms;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -155,6 +158,7 @@ enum ad7606_supported_device_ids {
|
|||
ID_AD7606_8,
|
||||
ID_AD7606_6,
|
||||
ID_AD7606_4,
|
||||
ID_AD7606B,
|
||||
ID_AD7616,
|
||||
};
|
||||
|
||||
|
|
|
@ -28,9 +28,23 @@
|
|||
* an offset of 2 for register address.
|
||||
*/
|
||||
#define AD7616_RANGE_CH_ADDR(ch) ((ch) >> 2)
|
||||
/* The range of the channel is stored on 2 bits*/
|
||||
/* The range of the channel is stored in 2 bits */
|
||||
#define AD7616_RANGE_CH_MSK(ch) (0b11 << (((ch) & 0b11) * 2))
|
||||
#define AD7616_RANGE_CH_MODE(ch, mode) ((mode) << ((((ch) & 0b11)) * 2))
|
||||
|
||||
#define AD7606_CONFIGURATION_REGISTER 0x02
|
||||
#define AD7606_SINGLE_DOUT 0x00
|
||||
|
||||
/*
|
||||
* Range for AD7606B channels are stored in registers starting with address 0x3.
|
||||
* Each register stores range for 2 channels(4 bits per channel).
|
||||
*/
|
||||
#define AD7606_RANGE_CH_MSK(ch) (GENMASK(3, 0) << (4 * ((ch) & 0x1)))
|
||||
#define AD7606_RANGE_CH_MODE(ch, mode) \
|
||||
((GENMASK(3, 0) & mode) << (4 * ((ch) & 0x1)))
|
||||
#define AD7606_RANGE_CH_ADDR(ch) (0x03 + ((ch) >> 1))
|
||||
#define AD7606_OS_MODE 0x08
|
||||
|
||||
static const struct iio_chan_spec ad7616_sw_channels[] = {
|
||||
IIO_CHAN_SOFT_TIMESTAMP(16),
|
||||
AD7616_CHANNEL(0),
|
||||
|
@ -51,6 +65,22 @@ static const struct iio_chan_spec ad7616_sw_channels[] = {
|
|||
AD7616_CHANNEL(15),
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec ad7606b_sw_channels[] = {
|
||||
IIO_CHAN_SOFT_TIMESTAMP(8),
|
||||
AD7616_CHANNEL(0),
|
||||
AD7616_CHANNEL(1),
|
||||
AD7616_CHANNEL(2),
|
||||
AD7616_CHANNEL(3),
|
||||
AD7616_CHANNEL(4),
|
||||
AD7616_CHANNEL(5),
|
||||
AD7616_CHANNEL(6),
|
||||
AD7616_CHANNEL(7),
|
||||
};
|
||||
|
||||
static const unsigned int ad7606B_oversampling_avail[9] = {
|
||||
1, 2, 4, 8, 16, 32, 64, 128, 256
|
||||
};
|
||||
|
||||
static u16 ad7616_spi_rd_wr_cmd(int addr, char isWriteOp)
|
||||
{
|
||||
/*
|
||||
|
@ -60,6 +90,16 @@ static u16 ad7616_spi_rd_wr_cmd(int addr, char isWriteOp)
|
|||
return ((addr & 0x7F) << 1) | ((isWriteOp & 0x1) << 7);
|
||||
}
|
||||
|
||||
static u16 ad7606B_spi_rd_wr_cmd(int addr, char is_write_op)
|
||||
{
|
||||
/*
|
||||
* The address of register consists of one bit which
|
||||
* specifies a read command placed in bit 6, followed by
|
||||
* 6 bits of address.
|
||||
*/
|
||||
return (addr & 0x3F) | (((~is_write_op) & 0x1) << 6);
|
||||
}
|
||||
|
||||
static int ad7606_spi_read_block(struct device *dev,
|
||||
int count, void *buf)
|
||||
{
|
||||
|
@ -169,6 +209,23 @@ static int ad7616_write_os_sw(struct iio_dev *indio_dev, int val)
|
|||
AD7616_OS_MASK, val << 2);
|
||||
}
|
||||
|
||||
static int ad7606_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
|
||||
{
|
||||
struct ad7606_state *st = iio_priv(indio_dev);
|
||||
|
||||
return ad7606_spi_write_mask(st,
|
||||
AD7606_RANGE_CH_ADDR(ch),
|
||||
AD7606_RANGE_CH_MSK(ch),
|
||||
AD7606_RANGE_CH_MODE(ch, val));
|
||||
}
|
||||
|
||||
static int ad7606_write_os_sw(struct iio_dev *indio_dev, int val)
|
||||
{
|
||||
struct ad7606_state *st = iio_priv(indio_dev);
|
||||
|
||||
return ad7606_spi_reg_write(st, AD7606_OS_MODE, val);
|
||||
}
|
||||
|
||||
static int ad7616_sw_mode_config(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct ad7606_state *st = iio_priv(indio_dev);
|
||||
|
@ -189,6 +246,42 @@ static int ad7616_sw_mode_config(struct iio_dev *indio_dev)
|
|||
AD7616_BURST_MODE | AD7616_SEQEN_MODE);
|
||||
}
|
||||
|
||||
static int ad7606B_sw_mode_config(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct ad7606_state *st = iio_priv(indio_dev);
|
||||
unsigned long os[3] = {1};
|
||||
|
||||
/*
|
||||
* Software mode is enabled when all three oversampling
|
||||
* pins are set to high. If oversampling gpios are defined
|
||||
* in the device tree, then they need to be set to high,
|
||||
* otherwise, they must be hardwired to VDD
|
||||
*/
|
||||
if (st->gpio_os) {
|
||||
gpiod_set_array_value(ARRAY_SIZE(os),
|
||||
st->gpio_os->desc, st->gpio_os->info, os);
|
||||
}
|
||||
/* OS of 128 and 256 are available only in software mode */
|
||||
st->oversampling_avail = ad7606B_oversampling_avail;
|
||||
st->num_os_ratios = ARRAY_SIZE(ad7606B_oversampling_avail);
|
||||
|
||||
st->write_scale = ad7606_write_scale_sw;
|
||||
st->write_os = &ad7606_write_os_sw;
|
||||
|
||||
/* Configure device spi to output on a single channel */
|
||||
st->bops->reg_write(st,
|
||||
AD7606_CONFIGURATION_REGISTER,
|
||||
AD7606_SINGLE_DOUT);
|
||||
|
||||
/*
|
||||
* Scale can be configured individually for each channel
|
||||
* in software mode.
|
||||
*/
|
||||
indio_dev->channels = ad7606b_sw_channels;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ad7606_bus_ops ad7606_spi_bops = {
|
||||
.read_block = ad7606_spi_read_block,
|
||||
};
|
||||
|
@ -202,6 +295,15 @@ static const struct ad7606_bus_ops ad7616_spi_bops = {
|
|||
.sw_mode_config = ad7616_sw_mode_config,
|
||||
};
|
||||
|
||||
static const struct ad7606_bus_ops ad7606B_spi_bops = {
|
||||
.read_block = ad7606_spi_read_block,
|
||||
.reg_read = ad7606_spi_reg_read,
|
||||
.reg_write = ad7606_spi_reg_write,
|
||||
.write_mask = ad7606_spi_write_mask,
|
||||
.rd_wr_cmd = ad7606B_spi_rd_wr_cmd,
|
||||
.sw_mode_config = ad7606B_sw_mode_config,
|
||||
};
|
||||
|
||||
static int ad7606_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
|
@ -211,6 +313,9 @@ static int ad7606_spi_probe(struct spi_device *spi)
|
|||
case ID_AD7616:
|
||||
bops = &ad7616_spi_bops;
|
||||
break;
|
||||
case ID_AD7606B:
|
||||
bops = &ad7606B_spi_bops;
|
||||
break;
|
||||
default:
|
||||
bops = &ad7606_spi_bops;
|
||||
break;
|
||||
|
@ -226,6 +331,7 @@ static const struct spi_device_id ad7606_id_table[] = {
|
|||
{ "ad7606-4", ID_AD7606_4 },
|
||||
{ "ad7606-6", ID_AD7606_6 },
|
||||
{ "ad7606-8", ID_AD7606_8 },
|
||||
{ "ad7606b", ID_AD7606B },
|
||||
{ "ad7616", ID_AD7616 },
|
||||
{}
|
||||
};
|
||||
|
@ -236,6 +342,7 @@ static const struct of_device_id ad7606_of_match[] = {
|
|||
{ .compatible = "adi,ad7606-4" },
|
||||
{ .compatible = "adi,ad7606-6" },
|
||||
{ .compatible = "adi,ad7606-8" },
|
||||
{ .compatible = "adi,ad7606b" },
|
||||
{ .compatible = "adi,ad7616" },
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -427,8 +427,9 @@ static int max1027_probe(struct spi_device *spi)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
|
||||
&max1027_trigger_handler, NULL);
|
||||
ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
|
||||
&iio_pollfunc_store_time,
|
||||
&max1027_trigger_handler, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(&indio_dev->dev, "Failed to setup buffer\n");
|
||||
return ret;
|
||||
|
@ -439,7 +440,7 @@ static int max1027_probe(struct spi_device *spi)
|
|||
if (st->trig == NULL) {
|
||||
ret = -ENOMEM;
|
||||
dev_err(&indio_dev->dev, "Failed to allocate iio trigger\n");
|
||||
goto fail_trigger_alloc;
|
||||
return ret;
|
||||
}
|
||||
|
||||
st->trig->ops = &max1027_trigger_ops;
|
||||
|
@ -454,7 +455,7 @@ static int max1027_probe(struct spi_device *spi)
|
|||
spi->dev.driver->name, st->trig);
|
||||
if (ret < 0) {
|
||||
dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n");
|
||||
goto fail_dev_register;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable averaging */
|
||||
|
@ -462,34 +463,10 @@ static int max1027_probe(struct spi_device *spi)
|
|||
ret = spi_write(st->spi, &st->reg, 1);
|
||||
if (ret < 0) {
|
||||
dev_err(&indio_dev->dev, "Failed to configure averaging register\n");
|
||||
goto fail_dev_register;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&indio_dev->dev, "Failed to register iio device\n");
|
||||
goto fail_dev_register;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_dev_register:
|
||||
fail_trigger_alloc:
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max1027_remove(struct spi_device *spi)
|
||||
{
|
||||
struct iio_dev *indio_dev = spi_get_drvdata(spi);
|
||||
|
||||
pr_debug("%s: remove(spi = 0x%p)\n", __func__, spi);
|
||||
|
||||
iio_device_unregister(indio_dev);
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
|
||||
return 0;
|
||||
return devm_iio_device_register(&spi->dev, indio_dev);
|
||||
}
|
||||
|
||||
static struct spi_driver max1027_driver = {
|
||||
|
@ -498,7 +475,6 @@ static struct spi_driver max1027_driver = {
|
|||
.of_match_table = of_match_ptr(max1027_adc_dt_ids),
|
||||
},
|
||||
.probe = max1027_probe,
|
||||
.remove = max1027_remove,
|
||||
.id_table = max1027_id,
|
||||
};
|
||||
module_spi_driver(max1027_driver);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <linux/hwspinlock.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/of.h>
|
||||
|
@ -46,14 +45,18 @@
|
|||
/* Bits definitions for SC27XX_ADC_INT_CLR registers */
|
||||
#define SC27XX_ADC_IRQ_CLR BIT(0)
|
||||
|
||||
/* Bits definitions for SC27XX_ADC_INT_RAW registers */
|
||||
#define SC27XX_ADC_IRQ_RAW BIT(0)
|
||||
|
||||
/* Mask definition for SC27XX_ADC_DATA register */
|
||||
#define SC27XX_ADC_DATA_MASK GENMASK(11, 0)
|
||||
|
||||
/* Timeout (ms) for the trylock of hardware spinlocks */
|
||||
#define SC27XX_ADC_HWLOCK_TIMEOUT 5000
|
||||
|
||||
/* Timeout (ms) for ADC data conversion according to ADC datasheet */
|
||||
#define SC27XX_ADC_RDY_TIMEOUT 100
|
||||
/* Timeout (us) for ADC data conversion according to ADC datasheet */
|
||||
#define SC27XX_ADC_RDY_TIMEOUT 1000000
|
||||
#define SC27XX_ADC_POLL_RAW_STATUS 500
|
||||
|
||||
/* Maximum ADC channel number */
|
||||
#define SC27XX_ADC_CHANNEL_MAX 32
|
||||
|
@ -72,10 +75,8 @@ struct sc27xx_adc_data {
|
|||
* subsystems which will access the unique ADC controller.
|
||||
*/
|
||||
struct hwspinlock *hwlock;
|
||||
struct completion completion;
|
||||
int channel_scale[SC27XX_ADC_CHANNEL_MAX];
|
||||
u32 base;
|
||||
int value;
|
||||
int irq;
|
||||
};
|
||||
|
||||
|
@ -188,9 +189,7 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
|
|||
int scale, int *val)
|
||||
{
|
||||
int ret;
|
||||
u32 tmp;
|
||||
|
||||
reinit_completion(&data->completion);
|
||||
u32 tmp, value, status;
|
||||
|
||||
ret = hwspin_lock_timeout_raw(data->hwlock, SC27XX_ADC_HWLOCK_TIMEOUT);
|
||||
if (ret) {
|
||||
|
@ -203,6 +202,11 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
|
|||
if (ret)
|
||||
goto unlock_adc;
|
||||
|
||||
ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR,
|
||||
SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR);
|
||||
if (ret)
|
||||
goto disable_adc;
|
||||
|
||||
/* Configure the channel id and scale */
|
||||
tmp = (scale << SC27XX_ADC_SCALE_SHIFT) & SC27XX_ADC_SCALE_MASK;
|
||||
tmp |= channel & SC27XX_ADC_CHN_ID_MASK;
|
||||
|
@ -226,15 +230,22 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
|
|||
if (ret)
|
||||
goto disable_adc;
|
||||
|
||||
ret = wait_for_completion_timeout(&data->completion,
|
||||
msecs_to_jiffies(SC27XX_ADC_RDY_TIMEOUT));
|
||||
if (!ret) {
|
||||
dev_err(data->dev, "read ADC data timeout\n");
|
||||
ret = -ETIMEDOUT;
|
||||
} else {
|
||||
ret = 0;
|
||||
ret = regmap_read_poll_timeout(data->regmap,
|
||||
data->base + SC27XX_ADC_INT_RAW,
|
||||
status, (status & SC27XX_ADC_IRQ_RAW),
|
||||
SC27XX_ADC_POLL_RAW_STATUS,
|
||||
SC27XX_ADC_RDY_TIMEOUT);
|
||||
if (ret) {
|
||||
dev_err(data->dev, "read adc timeout, status = 0x%x\n", status);
|
||||
goto disable_adc;
|
||||
}
|
||||
|
||||
ret = regmap_read(data->regmap, data->base + SC27XX_ADC_DATA, &value);
|
||||
if (ret)
|
||||
goto disable_adc;
|
||||
|
||||
value &= SC27XX_ADC_DATA_MASK;
|
||||
|
||||
disable_adc:
|
||||
regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL,
|
||||
SC27XX_ADC_EN, 0);
|
||||
|
@ -242,32 +253,11 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
|
|||
hwspin_unlock_raw(data->hwlock);
|
||||
|
||||
if (!ret)
|
||||
*val = data->value;
|
||||
*val = value;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static irqreturn_t sc27xx_adc_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct sc27xx_adc_data *data = dev_id;
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR,
|
||||
SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR);
|
||||
if (ret)
|
||||
return IRQ_RETVAL(ret);
|
||||
|
||||
ret = regmap_read(data->regmap, data->base + SC27XX_ADC_DATA,
|
||||
&data->value);
|
||||
if (ret)
|
||||
return IRQ_RETVAL(ret);
|
||||
|
||||
data->value &= SC27XX_ADC_DATA_MASK;
|
||||
complete(&data->completion);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data,
|
||||
int channel, int scale,
|
||||
u32 *div_numerator, u32 *div_denominator)
|
||||
|
@ -454,11 +444,6 @@ static int sc27xx_adc_enable(struct sc27xx_adc_data *data)
|
|||
if (ret)
|
||||
goto disable_adc;
|
||||
|
||||
ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_EN,
|
||||
SC27XX_ADC_IRQ_EN, SC27XX_ADC_IRQ_EN);
|
||||
if (ret)
|
||||
goto disable_clk;
|
||||
|
||||
/* ADC channel scales' calibration from nvmem device */
|
||||
ret = sc27xx_adc_scale_calibration(data, true);
|
||||
if (ret)
|
||||
|
@ -484,9 +469,6 @@ static void sc27xx_adc_disable(void *_data)
|
|||
{
|
||||
struct sc27xx_adc_data *data = _data;
|
||||
|
||||
regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_EN,
|
||||
SC27XX_ADC_IRQ_EN, 0);
|
||||
|
||||
/* Disable ADC work clock and controller clock */
|
||||
regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN,
|
||||
SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0);
|
||||
|
@ -551,7 +533,6 @@ static int sc27xx_adc_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
init_completion(&sc27xx_data->completion);
|
||||
sc27xx_data->dev = dev;
|
||||
|
||||
ret = sc27xx_adc_enable(sc27xx_data);
|
||||
|
@ -566,14 +547,6 @@ static int sc27xx_adc_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_request_threaded_irq(dev, sc27xx_data->irq, NULL,
|
||||
sc27xx_adc_isr, IRQF_ONESHOT,
|
||||
pdev->name, sc27xx_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to request ADC irq\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
indio_dev->dev.parent = dev;
|
||||
indio_dev->name = dev_name(dev);
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
|
|
@ -90,7 +90,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
|
|||
struct cros_ec_dev *ec = dev_get_drvdata(pdev->dev.parent);
|
||||
struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev);
|
||||
u32 ver_mask;
|
||||
int ret;
|
||||
int ret, i;
|
||||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
|
@ -136,6 +136,9 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
|
|||
/* Set sign vector, only used for backward compatibility. */
|
||||
memset(state->sign, 1, CROS_EC_SENSOR_MAX_AXIS);
|
||||
|
||||
for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++)
|
||||
state->calib[i].scale = MOTION_SENSE_DEFAULT_SCALE;
|
||||
|
||||
/* 0 is a correct value used to stop the device */
|
||||
state->frequencies[0] = 0;
|
||||
if (state->msg->version < 3) {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/hid-sensor-hub.h>
|
||||
#include <linux/iio/iio.h>
|
||||
|
@ -68,16 +69,6 @@ static struct {
|
|||
{HID_USAGE_SENSOR_HUMIDITY, 0, 1000, 0},
|
||||
};
|
||||
|
||||
static int pow_10(unsigned power)
|
||||
{
|
||||
int i;
|
||||
int ret = 1;
|
||||
for (i = 0; i < power; ++i)
|
||||
ret = ret * 10;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void simple_div(int dividend, int divisor, int *whole,
|
||||
int *micro_frac)
|
||||
{
|
||||
|
@ -96,14 +87,14 @@ static void simple_div(int dividend, int divisor, int *whole,
|
|||
rem *= 10;
|
||||
exp++;
|
||||
}
|
||||
*micro_frac = (rem / divisor) * pow_10(6-exp);
|
||||
*micro_frac = (rem / divisor) * int_pow(10, 6 - exp);
|
||||
}
|
||||
}
|
||||
|
||||
static void split_micro_fraction(unsigned int no, int exp, int *val1, int *val2)
|
||||
{
|
||||
*val1 = no/pow_10(exp);
|
||||
*val2 = no%pow_10(exp) * pow_10(6-exp);
|
||||
*val1 = no / int_pow(10, exp);
|
||||
*val2 = no % int_pow(10, exp) * int_pow(10, 6 - exp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -125,7 +116,7 @@ static void convert_from_vtf_format(u32 value, int size, int exp,
|
|||
}
|
||||
exp = hid_sensor_convert_exponent(exp);
|
||||
if (exp >= 0) {
|
||||
*val1 = sign * value * pow_10(exp);
|
||||
*val1 = sign * value * int_pow(10, exp);
|
||||
*val2 = 0;
|
||||
} else {
|
||||
split_micro_fraction(value, -exp, val1, val2);
|
||||
|
@ -145,10 +136,10 @@ static u32 convert_to_vtf_format(int size, int exp, int val1, int val2)
|
|||
sign = -1;
|
||||
exp = hid_sensor_convert_exponent(exp);
|
||||
if (exp < 0) {
|
||||
value = abs(val1) * pow_10(-exp);
|
||||
value += abs(val2) / pow_10(6+exp);
|
||||
value = abs(val1) * int_pow(10, -exp);
|
||||
value += abs(val2) / int_pow(10, 6 + exp);
|
||||
} else
|
||||
value = abs(val1) / pow_10(exp);
|
||||
value = abs(val1) / int_pow(10, exp);
|
||||
if (sign < 0)
|
||||
value = ((1LL << (size * 8)) - value);
|
||||
|
||||
|
@ -211,12 +202,12 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st,
|
|||
if (val1 < 0 || val2 < 0)
|
||||
return -EINVAL;
|
||||
|
||||
value = val1 * pow_10(6) + val2;
|
||||
value = val1 * int_pow(10, 6) + val2;
|
||||
if (value) {
|
||||
if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND)
|
||||
value = pow_10(9)/value;
|
||||
value = int_pow(10, 9) / value;
|
||||
else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND)
|
||||
value = pow_10(6)/value;
|
||||
value = int_pow(10, 6) / value;
|
||||
else
|
||||
value = 0;
|
||||
}
|
||||
|
@ -311,34 +302,34 @@ static void adjust_exponent_nano(int *val0, int *val1, int scale0,
|
|||
int rem;
|
||||
|
||||
if (exp > 0) {
|
||||
*val0 = scale0 * pow_10(exp);
|
||||
*val0 = scale0 * int_pow(10, exp);
|
||||
res = 0;
|
||||
if (exp > 9) {
|
||||
*val1 = 0;
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < exp; ++i) {
|
||||
x = scale1 / pow_10(8 - i);
|
||||
res += (pow_10(exp - 1 - i) * x);
|
||||
scale1 = scale1 % pow_10(8 - i);
|
||||
x = scale1 / int_pow(10, 8 - i);
|
||||
res += int_pow(10, exp - 1 - i) * x;
|
||||
scale1 = scale1 % int_pow(10, 8 - i);
|
||||
}
|
||||
*val0 += res;
|
||||
*val1 = scale1 * pow_10(exp);
|
||||
*val1 = scale1 * int_pow(10, exp);
|
||||
} else if (exp < 0) {
|
||||
exp = abs(exp);
|
||||
if (exp > 9) {
|
||||
*val0 = *val1 = 0;
|
||||
return;
|
||||
}
|
||||
*val0 = scale0 / pow_10(exp);
|
||||
rem = scale0 % pow_10(exp);
|
||||
*val0 = scale0 / int_pow(10, exp);
|
||||
rem = scale0 % int_pow(10, exp);
|
||||
res = 0;
|
||||
for (i = 0; i < (9 - exp); ++i) {
|
||||
x = scale1 / pow_10(8 - i);
|
||||
res += (pow_10(8 - exp - i) * x);
|
||||
scale1 = scale1 % pow_10(8 - i);
|
||||
x = scale1 / int_pow(10, 8 - i);
|
||||
res += int_pow(10, 8 - exp - i) * x;
|
||||
scale1 = scale1 % int_pow(10, 8 - i);
|
||||
}
|
||||
*val1 = rem * pow_10(9 - exp) + res;
|
||||
*val1 = rem * int_pow(10, 9 - exp) + res;
|
||||
} else {
|
||||
*val0 = scale0;
|
||||
*val1 = scale1;
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
|
||||
config IIO_ST_SENSORS_I2C
|
||||
tristate
|
||||
select REGMAP_I2C
|
||||
|
||||
config IIO_ST_SENSORS_SPI
|
||||
tristate
|
||||
select REGMAP_SPI
|
||||
|
||||
config IIO_ST_SENSORS_CORE
|
||||
tristate
|
||||
|
|
|
@ -220,7 +220,7 @@ static int ad5380_read_raw(struct iio_dev *indio_dev,
|
|||
if (ret)
|
||||
return ret;
|
||||
*val >>= chan->scan_type.shift;
|
||||
val -= (1 << chan->scan_type.realbits) / 2;
|
||||
*val -= (1 << chan->scan_type.realbits) / 2;
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = 2 * st->vref;
|
||||
|
|
|
@ -152,7 +152,7 @@ static int adis16460_debugfs_init(struct iio_dev *indio_dev)
|
|||
static int adis16460_set_freq(struct iio_dev *indio_dev, int val, int val2)
|
||||
{
|
||||
struct adis16460 *st = iio_priv(indio_dev);
|
||||
unsigned int t;
|
||||
int t;
|
||||
|
||||
t = val * 1000 + val2 / 1000;
|
||||
if (t <= 0)
|
||||
|
|
|
@ -12,7 +12,7 @@ config IIO_ST_LSM6DSX
|
|||
Say yes here to build support for STMicroelectronics LSM6DSx imu
|
||||
sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm,
|
||||
ism330dlc, lsm6dso, lsm6dsox, asm330lhh, lsm6dsr, lsm6ds3tr-c,
|
||||
ism330dhcx
|
||||
ism330dhcx and the accelerometer/gyroscope of lsm9ds1.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called st_lsm6dsx.
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define ST_LSM6DSR_DEV_NAME "lsm6dsr"
|
||||
#define ST_LSM6DS3TRC_DEV_NAME "lsm6ds3tr-c"
|
||||
#define ST_ISM330DHCX_DEV_NAME "ism330dhcx"
|
||||
#define ST_LSM9DS1_DEV_NAME "lsm9ds1-imu"
|
||||
|
||||
enum st_lsm6dsx_hw_id {
|
||||
ST_LSM6DS3_ID,
|
||||
|
@ -37,6 +38,7 @@ enum st_lsm6dsx_hw_id {
|
|||
ST_LSM6DSR_ID,
|
||||
ST_LSM6DS3TRC_ID,
|
||||
ST_ISM330DHCX_ID,
|
||||
ST_LSM9DS1_ID,
|
||||
ST_LSM6DSX_MAX_ID,
|
||||
};
|
||||
|
||||
|
@ -75,6 +77,7 @@ struct st_lsm6dsx_reg {
|
|||
u8 mask;
|
||||
};
|
||||
|
||||
struct st_lsm6dsx_sensor;
|
||||
struct st_lsm6dsx_hw;
|
||||
|
||||
struct st_lsm6dsx_odr {
|
||||
|
@ -101,12 +104,14 @@ struct st_lsm6dsx_fs_table_entry {
|
|||
|
||||
/**
|
||||
* struct st_lsm6dsx_fifo_ops - ST IMU FIFO settings
|
||||
* @update_fifo: Update FIFO configuration callback.
|
||||
* @read_fifo: Read FIFO callback.
|
||||
* @fifo_th: FIFO threshold register info (addr + mask).
|
||||
* @fifo_diff: FIFO diff status register info (addr + mask).
|
||||
* @th_wl: FIFO threshold word length.
|
||||
*/
|
||||
struct st_lsm6dsx_fifo_ops {
|
||||
int (*update_fifo)(struct st_lsm6dsx_sensor *sensor, bool enable);
|
||||
int (*read_fifo)(struct st_lsm6dsx_hw *hw);
|
||||
struct {
|
||||
u8 addr;
|
||||
|
@ -200,6 +205,9 @@ struct st_lsm6dsx_ext_dev_settings {
|
|||
/**
|
||||
* struct st_lsm6dsx_settings - ST IMU sensor settings
|
||||
* @wai: Sensor WhoAmI default value.
|
||||
* @int1_addr: Control Register address for INT1
|
||||
* @int2_addr: Control Register address for INT2
|
||||
* @reset_addr: register address for reset/reboot
|
||||
* @max_fifo_size: Sensor max fifo length in FIFO words.
|
||||
* @id: List of hw id/device name supported by the driver configuration.
|
||||
* @channels: IIO channels supported by the device.
|
||||
|
@ -213,6 +221,9 @@ struct st_lsm6dsx_ext_dev_settings {
|
|||
*/
|
||||
struct st_lsm6dsx_settings {
|
||||
u8 wai;
|
||||
u8 int1_addr;
|
||||
u8 int2_addr;
|
||||
u8 reset_addr;
|
||||
u16 max_fifo_size;
|
||||
struct {
|
||||
enum st_lsm6dsx_hw_id hw_id;
|
||||
|
@ -327,6 +338,7 @@ int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw);
|
|||
int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val);
|
||||
int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,
|
||||
u16 watermark);
|
||||
int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable);
|
||||
int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw);
|
||||
int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
|
||||
enum st_lsm6dsx_fifo_mode fifo_mode);
|
||||
|
|
|
@ -602,9 +602,8 @@ int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable)
|
||||
int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable)
|
||||
{
|
||||
struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
|
||||
struct st_lsm6dsx_hw *hw = sensor->hw;
|
||||
int err;
|
||||
|
||||
|
@ -676,12 +675,24 @@ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
|
|||
|
||||
static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev)
|
||||
{
|
||||
return st_lsm6dsx_update_fifo(iio_dev, true);
|
||||
struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
|
||||
struct st_lsm6dsx_hw *hw = sensor->hw;
|
||||
|
||||
if (!hw->settings->fifo_ops.update_fifo)
|
||||
return -ENOTSUPP;
|
||||
|
||||
return hw->settings->fifo_ops.update_fifo(sensor, true);
|
||||
}
|
||||
|
||||
static int st_lsm6dsx_buffer_postdisable(struct iio_dev *iio_dev)
|
||||
{
|
||||
return st_lsm6dsx_update_fifo(iio_dev, false);
|
||||
struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
|
||||
struct st_lsm6dsx_hw *hw = sensor->hw;
|
||||
|
||||
if (!hw->settings->fifo_ops.update_fifo)
|
||||
return -ENOTSUPP;
|
||||
|
||||
return hw->settings->fifo_ops.update_fifo(sensor, false);
|
||||
}
|
||||
|
||||
static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = {
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
* +-125/+-245/+-500/+-1000/+-2000 dps
|
||||
* LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
|
||||
* allowing dynamic batching of sensor data.
|
||||
* LSM9DSx series is similar but includes an additional magnetometer, handled
|
||||
* by a different driver.
|
||||
*
|
||||
* Supported sensors:
|
||||
* - LSM6DS3:
|
||||
|
@ -30,6 +32,13 @@
|
|||
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
|
||||
* - FIFO size: 3KB
|
||||
*
|
||||
* - LSM9DS1:
|
||||
* - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
|
||||
* - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
|
||||
* - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
|
||||
* - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
|
||||
* - FIFO size: 32
|
||||
*
|
||||
* Copyright 2016 STMicroelectronics Inc.
|
||||
*
|
||||
* Lorenzo Bianconi <lorenzo.bianconi@st.com>
|
||||
|
@ -49,17 +58,12 @@
|
|||
|
||||
#include "st_lsm6dsx.h"
|
||||
|
||||
#define ST_LSM6DSX_REG_INT1_ADDR 0x0d
|
||||
#define ST_LSM6DSX_REG_INT2_ADDR 0x0e
|
||||
#define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3)
|
||||
#define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f
|
||||
#define ST_LSM6DSX_REG_RESET_ADDR 0x12
|
||||
#define ST_LSM6DSX_REG_RESET_MASK BIT(0)
|
||||
#define ST_LSM6DSX_REG_BOOT_MASK BIT(7)
|
||||
#define ST_LSM6DSX_REG_BDU_ADDR 0x12
|
||||
#define ST_LSM6DSX_REG_BDU_MASK BIT(6)
|
||||
#define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13
|
||||
#define ST_LSM6DSX_REG_INT2_ON_INT1_MASK BIT(5)
|
||||
|
||||
static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
|
||||
ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
|
||||
|
@ -75,9 +79,89 @@ static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
|
|||
IIO_CHAN_SOFT_TIMESTAMP(3),
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
|
||||
ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
|
||||
ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
|
||||
ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
|
||||
IIO_CHAN_SOFT_TIMESTAMP(3),
|
||||
};
|
||||
|
||||
static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
||||
{
|
||||
.wai = 0x68,
|
||||
.int1_addr = 0x0c,
|
||||
.int2_addr = 0x0d,
|
||||
.reset_addr = 0x22,
|
||||
.max_fifo_size = 32,
|
||||
.id = {
|
||||
{
|
||||
.hw_id = ST_LSM9DS1_ID,
|
||||
.name = ST_LSM9DS1_DEV_NAME,
|
||||
},
|
||||
},
|
||||
.channels = {
|
||||
[ST_LSM6DSX_ID_ACC] = {
|
||||
.chan = st_lsm6dsx_acc_channels,
|
||||
.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
|
||||
},
|
||||
[ST_LSM6DSX_ID_GYRO] = {
|
||||
.chan = st_lsm6ds0_gyro_channels,
|
||||
.len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
|
||||
},
|
||||
},
|
||||
.odr_table = {
|
||||
[ST_LSM6DSX_ID_ACC] = {
|
||||
.reg = {
|
||||
.addr = 0x20,
|
||||
.mask = GENMASK(7, 5),
|
||||
},
|
||||
.odr_avl[0] = { 10, 0x01 },
|
||||
.odr_avl[1] = { 50, 0x02 },
|
||||
.odr_avl[2] = { 119, 0x03 },
|
||||
.odr_avl[3] = { 238, 0x04 },
|
||||
.odr_avl[4] = { 476, 0x05 },
|
||||
.odr_avl[5] = { 952, 0x06 },
|
||||
},
|
||||
[ST_LSM6DSX_ID_GYRO] = {
|
||||
.reg = {
|
||||
.addr = 0x10,
|
||||
.mask = GENMASK(7, 5),
|
||||
},
|
||||
.odr_avl[0] = { 15, 0x01 },
|
||||
.odr_avl[1] = { 60, 0x02 },
|
||||
.odr_avl[2] = { 119, 0x03 },
|
||||
.odr_avl[3] = { 238, 0x04 },
|
||||
.odr_avl[4] = { 476, 0x05 },
|
||||
.odr_avl[5] = { 952, 0x06 },
|
||||
},
|
||||
},
|
||||
.fs_table = {
|
||||
[ST_LSM6DSX_ID_ACC] = {
|
||||
.reg = {
|
||||
.addr = 0x20,
|
||||
.mask = GENMASK(4, 3),
|
||||
},
|
||||
.fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
|
||||
.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
|
||||
.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
|
||||
.fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 },
|
||||
},
|
||||
[ST_LSM6DSX_ID_GYRO] = {
|
||||
.reg = {
|
||||
.addr = 0x10,
|
||||
.mask = GENMASK(4, 3),
|
||||
},
|
||||
.fs_avl[0] = { IIO_DEGREE_TO_RAD(245), 0x0 },
|
||||
.fs_avl[1] = { IIO_DEGREE_TO_RAD(500), 0x1 },
|
||||
.fs_avl[2] = { IIO_DEGREE_TO_RAD(2000), 0x3 },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
.wai = 0x69,
|
||||
.int1_addr = 0x0d,
|
||||
.int2_addr = 0x0e,
|
||||
.reset_addr = 0x12,
|
||||
.max_fifo_size = 1365,
|
||||
.id = {
|
||||
{
|
||||
|
@ -154,6 +238,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
},
|
||||
.fifo_ops = {
|
||||
.update_fifo = st_lsm6dsx_update_fifo,
|
||||
.read_fifo = st_lsm6dsx_read_fifo,
|
||||
.fifo_th = {
|
||||
.addr = 0x06,
|
||||
|
@ -186,6 +271,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
{
|
||||
.wai = 0x69,
|
||||
.int1_addr = 0x0d,
|
||||
.int2_addr = 0x0e,
|
||||
.reset_addr = 0x12,
|
||||
.max_fifo_size = 682,
|
||||
.id = {
|
||||
{
|
||||
|
@ -262,6 +350,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
},
|
||||
.fifo_ops = {
|
||||
.update_fifo = st_lsm6dsx_update_fifo,
|
||||
.read_fifo = st_lsm6dsx_read_fifo,
|
||||
.fifo_th = {
|
||||
.addr = 0x06,
|
||||
|
@ -294,6 +383,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
{
|
||||
.wai = 0x6a,
|
||||
.int1_addr = 0x0d,
|
||||
.int2_addr = 0x0e,
|
||||
.reset_addr = 0x12,
|
||||
.max_fifo_size = 682,
|
||||
.id = {
|
||||
{
|
||||
|
@ -379,6 +471,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
},
|
||||
.fifo_ops = {
|
||||
.update_fifo = st_lsm6dsx_update_fifo,
|
||||
.read_fifo = st_lsm6dsx_read_fifo,
|
||||
.fifo_th = {
|
||||
.addr = 0x06,
|
||||
|
@ -411,6 +504,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
{
|
||||
.wai = 0x6c,
|
||||
.int1_addr = 0x0d,
|
||||
.int2_addr = 0x0e,
|
||||
.reset_addr = 0x12,
|
||||
.max_fifo_size = 512,
|
||||
.id = {
|
||||
{
|
||||
|
@ -490,6 +586,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
},
|
||||
.fifo_ops = {
|
||||
.update_fifo = st_lsm6dsx_update_fifo,
|
||||
.read_fifo = st_lsm6dsx_read_tagged_fifo,
|
||||
.fifo_th = {
|
||||
.addr = 0x07,
|
||||
|
@ -497,7 +594,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
.fifo_diff = {
|
||||
.addr = 0x3a,
|
||||
.mask = GENMASK(8, 0),
|
||||
.mask = GENMASK(9, 0),
|
||||
},
|
||||
.th_wl = 1,
|
||||
},
|
||||
|
@ -540,6 +637,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
{
|
||||
.wai = 0x6b,
|
||||
.int1_addr = 0x0d,
|
||||
.int2_addr = 0x0e,
|
||||
.reset_addr = 0x12,
|
||||
.max_fifo_size = 512,
|
||||
.id = {
|
||||
{
|
||||
|
@ -616,6 +716,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
},
|
||||
.fifo_ops = {
|
||||
.update_fifo = st_lsm6dsx_update_fifo,
|
||||
.read_fifo = st_lsm6dsx_read_tagged_fifo,
|
||||
.fifo_th = {
|
||||
.addr = 0x07,
|
||||
|
@ -623,7 +724,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
.fifo_diff = {
|
||||
.addr = 0x3a,
|
||||
.mask = GENMASK(8, 0),
|
||||
.mask = GENMASK(9, 0),
|
||||
},
|
||||
.th_wl = 1,
|
||||
},
|
||||
|
@ -640,6 +741,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
{
|
||||
.wai = 0x6b,
|
||||
.int1_addr = 0x0d,
|
||||
.int2_addr = 0x0e,
|
||||
.reset_addr = 0x12,
|
||||
.max_fifo_size = 512,
|
||||
.id = {
|
||||
{
|
||||
|
@ -719,6 +823,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
},
|
||||
.fifo_ops = {
|
||||
.update_fifo = st_lsm6dsx_update_fifo,
|
||||
.read_fifo = st_lsm6dsx_read_tagged_fifo,
|
||||
.fifo_th = {
|
||||
.addr = 0x07,
|
||||
|
@ -726,7 +831,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
.fifo_diff = {
|
||||
.addr = 0x3a,
|
||||
.mask = GENMASK(8, 0),
|
||||
.mask = GENMASK(9, 0),
|
||||
},
|
||||
.th_wl = 1,
|
||||
},
|
||||
|
@ -1090,13 +1195,19 @@ static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
|
|||
char *buf)
|
||||
{
|
||||
struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
|
||||
const struct st_lsm6dsx_fs_table_entry *fs_table;
|
||||
enum st_lsm6dsx_sensor_id id = sensor->id;
|
||||
struct st_lsm6dsx_hw *hw = sensor->hw;
|
||||
int i, len = 0;
|
||||
|
||||
for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
|
||||
fs_table = &hw->settings->fs_table[id];
|
||||
for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) {
|
||||
if (!fs_table->fs_avl[i].gain)
|
||||
break;
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
|
||||
hw->settings->fs_table[id].fs_avl[i].gain);
|
||||
fs_table->fs_avl[i].gain);
|
||||
}
|
||||
buf[len - 1] = '\n';
|
||||
|
||||
return len;
|
||||
|
@ -1166,10 +1277,10 @@ static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg)
|
|||
|
||||
switch (drdy_pin) {
|
||||
case 1:
|
||||
*drdy_reg = ST_LSM6DSX_REG_INT1_ADDR;
|
||||
*drdy_reg = hw->settings->int1_addr;
|
||||
break;
|
||||
case 2:
|
||||
*drdy_reg = ST_LSM6DSX_REG_INT2_ADDR;
|
||||
*drdy_reg = hw->settings->int2_addr;
|
||||
break;
|
||||
default:
|
||||
dev_err(hw->dev, "unsupported data ready pin\n");
|
||||
|
@ -1269,7 +1380,7 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
|
|||
int err;
|
||||
|
||||
/* device sw reset */
|
||||
err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR,
|
||||
err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
|
||||
ST_LSM6DSX_REG_RESET_MASK,
|
||||
FIELD_PREP(ST_LSM6DSX_REG_RESET_MASK, 1));
|
||||
if (err < 0)
|
||||
|
@ -1278,7 +1389,7 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
|
|||
msleep(50);
|
||||
|
||||
/* reload trimming parameter */
|
||||
err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR,
|
||||
err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
|
||||
ST_LSM6DSX_REG_BOOT_MASK,
|
||||
FIELD_PREP(ST_LSM6DSX_REG_BOOT_MASK, 1));
|
||||
if (err < 0)
|
||||
|
|
|
@ -83,6 +83,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
|
|||
.compatible = "st,ism330dhcx",
|
||||
.data = (void *)ST_ISM330DHCX_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lsm9ds1-imu",
|
||||
.data = (void *)ST_LSM9DS1_ID,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
|
||||
|
@ -99,6 +103,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
|
|||
{ ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID },
|
||||
{ ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID },
|
||||
{ ST_ISM330DHCX_DEV_NAME, ST_ISM330DHCX_ID },
|
||||
{ ST_LSM9DS1_DEV_NAME, ST_LSM9DS1_ID },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
|
||||
|
|
|
@ -83,6 +83,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
|
|||
.compatible = "st,ism330dhcx",
|
||||
.data = (void *)ST_ISM330DHCX_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lsm9ds1-imu",
|
||||
.data = (void *)ST_LSM9DS1_ID,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
|
||||
|
@ -99,6 +103,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
|
|||
{ ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID },
|
||||
{ ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID },
|
||||
{ ST_ISM330DHCX_DEV_NAME, ST_ISM330DHCX_ID },
|
||||
{ ST_LSM9DS1_DEV_NAME, ST_LSM9DS1_ID },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
|
||||
|
|
|
@ -62,7 +62,7 @@ config RFD77402
|
|||
tristate "RFD77402 ToF sensor"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y to build a driver for the RFD77420 Time-of-Flight (distance)
|
||||
Say Y to build a driver for the RFD77402 Time-of-Flight (distance)
|
||||
sensor module with I2C interface.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
|
|
|
@ -309,15 +309,12 @@ static int adis16240_write_raw(struct iio_dev *indio_dev,
|
|||
long mask)
|
||||
{
|
||||
struct adis *st = iio_priv(indio_dev);
|
||||
int bits = 10;
|
||||
s16 val16;
|
||||
u8 addr;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_CALIBBIAS:
|
||||
val16 = val & ((1 << bits) - 1);
|
||||
addr = adis16240_addresses[chan->scan_index][0];
|
||||
return adis_write_reg_16(st, addr, val16);
|
||||
return adis_write_reg_16(st, addr, val & GENMASK(9, 0));
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
#include <linux/iio/triggered_buffer.h>
|
||||
#include <linux/iio/adc/ad_sigma_delta.h>
|
||||
|
||||
#include "ad7192.h"
|
||||
|
||||
/* Registers */
|
||||
#define AD7192_REG_COMM 0 /* Communications Register (WO, 8-bit) */
|
||||
#define AD7192_REG_STAT 0 /* Status Register (RO, 8-bit) */
|
||||
|
@ -145,6 +143,10 @@
|
|||
#define AD7192_EXT_FREQ_MHZ_MAX 5120000
|
||||
#define AD7192_INT_FREQ_MHZ 4915200
|
||||
|
||||
#define AD7192_NO_SYNC_FILTER 1
|
||||
#define AD7192_SYNC3_FILTER 3
|
||||
#define AD7192_SYNC4_FILTER 4
|
||||
|
||||
/* NOTE:
|
||||
* The AD7190/2/5 features a dual use data out ready DOUT/RDY output.
|
||||
* In order to avoid contentions on the SPI bus, it's therefore necessary
|
||||
|
@ -252,7 +254,7 @@ static int ad7192_of_clock_select(struct ad7192_state *st)
|
|||
static int ad7192_setup(struct ad7192_state *st, struct device_node *np)
|
||||
{
|
||||
struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi);
|
||||
bool rej60_en, sinc3_en, refin2_en, chop_en;
|
||||
bool rej60_en, refin2_en;
|
||||
bool buf_en, bipolar, burnout_curr_en;
|
||||
unsigned long long scale_uv;
|
||||
int i, ret, id;
|
||||
|
@ -284,24 +286,12 @@ static int ad7192_setup(struct ad7192_state *st, struct device_node *np)
|
|||
if (rej60_en)
|
||||
st->mode |= AD7192_MODE_REJ60;
|
||||
|
||||
sinc3_en = of_property_read_bool(np, "adi,sinc3-filter-enable");
|
||||
if (sinc3_en)
|
||||
st->mode |= AD7192_MODE_SINC3;
|
||||
|
||||
refin2_en = of_property_read_bool(np, "adi,refin2-pins-enable");
|
||||
if (refin2_en && st->devid != ID_AD7195)
|
||||
st->conf |= AD7192_CONF_REFSEL;
|
||||
|
||||
chop_en = of_property_read_bool(np, "adi,chop-enable");
|
||||
if (chop_en) {
|
||||
st->conf |= AD7192_CONF_CHOP;
|
||||
if (sinc3_en)
|
||||
st->f_order = 3; /* SINC 3rd order */
|
||||
else
|
||||
st->f_order = 4; /* SINC 4th order */
|
||||
} else {
|
||||
st->f_order = 1;
|
||||
}
|
||||
st->conf &= ~AD7192_CONF_CHOP;
|
||||
st->f_order = AD7192_NO_SYNC_FILTER;
|
||||
|
||||
buf_en = of_property_read_bool(np, "adi,buffer-enable");
|
||||
if (buf_en)
|
||||
|
@ -313,7 +303,7 @@ static int ad7192_setup(struct ad7192_state *st, struct device_node *np)
|
|||
|
||||
burnout_curr_en = of_property_read_bool(np,
|
||||
"adi,burnout-currents-enable");
|
||||
if (burnout_curr_en && buf_en && !chop_en) {
|
||||
if (burnout_curr_en && buf_en) {
|
||||
st->conf |= AD7192_CONF_BURN;
|
||||
} else if (burnout_curr_en) {
|
||||
dev_warn(&st->sd.spi->dev,
|
||||
|
@ -411,6 +401,49 @@ static ssize_t ad7192_set(struct device *dev,
|
|||
return ret ? ret : len;
|
||||
}
|
||||
|
||||
static void ad7192_get_available_filter_freq(struct ad7192_state *st,
|
||||
int *freq)
|
||||
{
|
||||
unsigned int fadc;
|
||||
|
||||
/* Formulas for filter at page 25 of the datasheet */
|
||||
fadc = DIV_ROUND_CLOSEST(st->fclk,
|
||||
AD7192_SYNC4_FILTER * AD7192_MODE_RATE(st->mode));
|
||||
freq[0] = DIV_ROUND_CLOSEST(fadc * 240, 1024);
|
||||
|
||||
fadc = DIV_ROUND_CLOSEST(st->fclk,
|
||||
AD7192_SYNC3_FILTER * AD7192_MODE_RATE(st->mode));
|
||||
freq[1] = DIV_ROUND_CLOSEST(fadc * 240, 1024);
|
||||
|
||||
fadc = DIV_ROUND_CLOSEST(st->fclk, AD7192_MODE_RATE(st->mode));
|
||||
freq[2] = DIV_ROUND_CLOSEST(fadc * 230, 1024);
|
||||
freq[3] = DIV_ROUND_CLOSEST(fadc * 272, 1024);
|
||||
}
|
||||
|
||||
static ssize_t ad7192_show_filter_avail(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct ad7192_state *st = iio_priv(indio_dev);
|
||||
unsigned int freq_avail[4], i;
|
||||
size_t len = 0;
|
||||
|
||||
ad7192_get_available_filter_freq(st, freq_avail);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(freq_avail); i++)
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"%d.%d ", freq_avail[i] / 1000,
|
||||
freq_avail[i] % 1000);
|
||||
|
||||
buf[len - 1] = '\n';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR(filter_low_pass_3db_frequency_available,
|
||||
0444, ad7192_show_filter_avail, NULL, 0);
|
||||
|
||||
static IIO_DEVICE_ATTR(bridge_switch_en, 0644,
|
||||
ad7192_show_bridge_switch, ad7192_set,
|
||||
AD7192_REG_GPOCON);
|
||||
|
@ -420,6 +453,7 @@ static IIO_DEVICE_ATTR(ac_excitation_en, 0644,
|
|||
AD7192_REG_MODE);
|
||||
|
||||
static struct attribute *ad7192_attributes[] = {
|
||||
&iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr,
|
||||
&iio_dev_attr_bridge_switch_en.dev_attr.attr,
|
||||
&iio_dev_attr_ac_excitation_en.dev_attr.attr,
|
||||
NULL
|
||||
|
@ -430,6 +464,7 @@ static const struct attribute_group ad7192_attribute_group = {
|
|||
};
|
||||
|
||||
static struct attribute *ad7195_attributes[] = {
|
||||
&iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr,
|
||||
&iio_dev_attr_bridge_switch_en.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
@ -443,6 +478,75 @@ static unsigned int ad7192_get_temp_scale(bool unipolar)
|
|||
return unipolar ? 2815 * 2 : 2815;
|
||||
}
|
||||
|
||||
static int ad7192_set_3db_filter_freq(struct ad7192_state *st,
|
||||
int val, int val2)
|
||||
{
|
||||
int freq_avail[4], i, ret, freq;
|
||||
unsigned int diff_new, diff_old;
|
||||
int idx = 0;
|
||||
|
||||
diff_old = U32_MAX;
|
||||
freq = val * 1000 + val2;
|
||||
|
||||
ad7192_get_available_filter_freq(st, freq_avail);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(freq_avail); i++) {
|
||||
diff_new = abs(freq - freq_avail[i]);
|
||||
if (diff_new < diff_old) {
|
||||
diff_old = diff_new;
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
switch (idx) {
|
||||
case 0:
|
||||
st->f_order = AD7192_SYNC4_FILTER;
|
||||
st->mode &= ~AD7192_MODE_SINC3;
|
||||
|
||||
st->conf |= AD7192_CONF_CHOP;
|
||||
break;
|
||||
case 1:
|
||||
st->f_order = AD7192_SYNC3_FILTER;
|
||||
st->mode |= AD7192_MODE_SINC3;
|
||||
|
||||
st->conf |= AD7192_CONF_CHOP;
|
||||
break;
|
||||
case 2:
|
||||
st->f_order = AD7192_NO_SYNC_FILTER;
|
||||
st->mode &= ~AD7192_MODE_SINC3;
|
||||
|
||||
st->conf &= ~AD7192_CONF_CHOP;
|
||||
break;
|
||||
case 3:
|
||||
st->f_order = AD7192_NO_SYNC_FILTER;
|
||||
st->mode |= AD7192_MODE_SINC3;
|
||||
|
||||
st->conf &= ~AD7192_CONF_CHOP;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf);
|
||||
}
|
||||
|
||||
static int ad7192_get_3db_filter_freq(struct ad7192_state *st)
|
||||
{
|
||||
unsigned int fadc;
|
||||
|
||||
fadc = DIV_ROUND_CLOSEST(st->fclk,
|
||||
st->f_order * AD7192_MODE_RATE(st->mode));
|
||||
|
||||
if (st->conf & AD7192_CONF_CHOP)
|
||||
return DIV_ROUND_CLOSEST(fadc * 240, 1024);
|
||||
if (st->mode & AD7192_MODE_SINC3)
|
||||
return DIV_ROUND_CLOSEST(fadc * 272, 1024);
|
||||
else
|
||||
return DIV_ROUND_CLOSEST(fadc * 230, 1024);
|
||||
}
|
||||
|
||||
static int ad7192_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int *val,
|
||||
|
@ -483,6 +587,10 @@ static int ad7192_read_raw(struct iio_dev *indio_dev,
|
|||
*val = st->fclk /
|
||||
(st->f_order * 1024 * AD7192_MODE_RATE(st->mode));
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
|
||||
*val = ad7192_get_3db_filter_freq(st);
|
||||
*val2 = 1000;
|
||||
return IIO_VAL_FRACTIONAL;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
@ -537,6 +645,9 @@ static int ad7192_write_raw(struct iio_dev *indio_dev,
|
|||
st->mode |= AD7192_MODE_RATE(div);
|
||||
ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
|
||||
break;
|
||||
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
|
||||
ret = ad7192_set_3db_filter_freq(st, val, val2 / 1000);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
@ -555,6 +666,8 @@ static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev,
|
|||
return IIO_VAL_INT_PLUS_NANO;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -655,6 +768,8 @@ static int ad7192_channels_config(struct iio_dev *indio_dev)
|
|||
|
||||
for (i = 0; i < indio_dev->num_channels; i++) {
|
||||
*chan = channels[i];
|
||||
chan->info_mask_shared_by_all |=
|
||||
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY);
|
||||
if (chan->type != IIO_TEMP)
|
||||
chan->info_mask_shared_by_type_available |=
|
||||
BIT(IIO_CHAN_INFO_SCALE);
|
||||
|
@ -666,16 +781,10 @@ static int ad7192_channels_config(struct iio_dev *indio_dev)
|
|||
|
||||
static int ad7192_probe(struct spi_device *spi)
|
||||
{
|
||||
const struct ad7192_platform_data *pdata = dev_get_platdata(&spi->dev);
|
||||
struct ad7192_state *st;
|
||||
struct iio_dev *indio_dev;
|
||||
int ret, voltage_uv = 0;
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&spi->dev, "no platform data?\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!spi->irq) {
|
||||
dev_err(&spi->dev, "no IRQ?\n");
|
||||
return -ENODEV;
|
||||
|
@ -713,12 +822,10 @@ static int ad7192_probe(struct spi_device *spi)
|
|||
|
||||
voltage_uv = regulator_get_voltage(st->avdd);
|
||||
|
||||
if (pdata->vref_mv)
|
||||
st->int_vref_mv = pdata->vref_mv;
|
||||
else if (voltage_uv)
|
||||
if (voltage_uv)
|
||||
st->int_vref_mv = voltage_uv / 1000;
|
||||
else
|
||||
dev_warn(&spi->dev, "reference voltage undefined\n");
|
||||
dev_err(&spi->dev, "Device tree error, reference voltage undefined\n");
|
||||
|
||||
spi_set_drvdata(spi, indio_dev);
|
||||
st->devid = spi_get_device_id(spi)->driver_data;
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* AD7190 AD7192 AD7195 SPI ADC driver
|
||||
*
|
||||
* Copyright 2011 Analog Devices Inc.
|
||||
*/
|
||||
#ifndef IIO_ADC_AD7192_H_
|
||||
#define IIO_ADC_AD7192_H_
|
||||
|
||||
/*
|
||||
* TODO: struct ad7192_platform_data needs to go into include/linux/iio
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct ad7192_platform_data - platform/board specific information
|
||||
* @vref_mv: the external reference voltage in millivolt
|
||||
* @clock_source_sel: [0..3]
|
||||
* 0 External 4.92 MHz clock connected from MCLK1 to MCLK2
|
||||
* 1 External Clock applied to MCLK2
|
||||
* 2 Internal 4.92 MHz Clock not available at the MCLK2 pin
|
||||
* 3 Internal 4.92 MHz Clock available at the MCLK2 pin
|
||||
* @ext_clk_Hz: the external clock frequency in Hz, if not set
|
||||
* the driver uses the internal clock (16.776 MHz)
|
||||
* @refin2_en: REFIN1/REFIN2 Reference Select (AD7190/2 only)
|
||||
* @rej60_en: 50/60Hz notch filter enable
|
||||
* @sinc3_en: SINC3 filter enable (default SINC4)
|
||||
* @chop_en: CHOP mode enable
|
||||
* @buf_en: buffered input mode enable
|
||||
* @unipolar_en: unipolar mode enable
|
||||
* @burnout_curr_en: constant current generators on AIN(+|-) enable
|
||||
*/
|
||||
|
||||
struct ad7192_platform_data {
|
||||
u16 vref_mv;
|
||||
};
|
||||
|
||||
#endif /* IIO_ADC_AD7192_H_ */
|
|
@ -0,0 +1,4 @@
|
|||
iio_event_monitor
|
||||
iio_generic_buffer
|
||||
lsiio
|
||||
include/
|
Loading…
Reference in New Issue