diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-09-03 16:27:46 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-09-03 16:27:46 -0400 |
commit | 74eb9c06b1d722468db397595ac6834b9e4ac235 (patch) | |
tree | a201cde5eb2ce3f1785f4f4c2a650782e5c967b8 | |
parent | dfa5b30b12aa8c324d6b90c369e71c90061a8a33 (diff) | |
parent | 6fa029486b74c266c39b718b8643ed42d24f977a (diff) |
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 the ad7606b 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
...
28 files changed, 756 insertions, 281 deletions
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml new file mode 100644 index 000000000000..676ec42e1438 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml | |||
@@ -0,0 +1,121 @@ | |||
1 | # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | ||
2 | # Copyright 2019 Analog Devices Inc. | ||
3 | %YAML 1.2 | ||
4 | --- | ||
5 | $id: http://devicetree.org/schemas/bindings/iio/adc/adi,ad7192.yaml# | ||
6 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
7 | |||
8 | title: Analog Devices AD7192 ADC device driver | ||
9 | |||
10 | maintainers: | ||
11 | - Michael Hennerich <michael.hennerich@analog.com> | ||
12 | |||
13 | description: | | ||
14 | Bindings for the Analog Devices AD7192 ADC device. Datasheet can be | ||
15 | found here: | ||
16 | https://www.analog.com/media/en/technical-documentation/data-sheets/AD7192.pdf | ||
17 | |||
18 | properties: | ||
19 | compatible: | ||
20 | enum: | ||
21 | - adi,ad7190 | ||
22 | - adi,ad7192 | ||
23 | - adi,ad7193 | ||
24 | - adi,ad7195 | ||
25 | |||
26 | reg: | ||
27 | maxItems: 1 | ||
28 | |||
29 | spi-cpol: true | ||
30 | |||
31 | spi-cpha: true | ||
32 | |||
33 | clocks: | ||
34 | maxItems: 1 | ||
35 | description: phandle to the master clock (mclk) | ||
36 | |||
37 | clock-names: | ||
38 | items: | ||
39 | - const: mclk | ||
40 | |||
41 | interrupts: | ||
42 | maxItems: 1 | ||
43 | |||
44 | dvdd-supply: | ||
45 | description: DVdd voltage supply | ||
46 | items: | ||
47 | - const: dvdd | ||
48 | |||
49 | avdd-supply: | ||
50 | description: AVdd voltage supply | ||
51 | items: | ||
52 | - const: avdd | ||
53 | |||
54 | adi,rejection-60-Hz-enable: | ||
55 | description: | | ||
56 | This bit enables a notch at 60 Hz when the first notch of the sinc | ||
57 | filter is at 50 Hz. When REJ60 is set, a filter notch is placed at | ||
58 | 60 Hz when the sinc filter first notch is at 50 Hz. This allows | ||
59 | simultaneous 50 Hz/ 60 Hz rejection. | ||
60 | type: boolean | ||
61 | |||
62 | adi,refin2-pins-enable: | ||
63 | description: | | ||
64 | External reference applied between the P1/REFIN2(+) and P0/REFIN2(−) pins. | ||
65 | type: boolean | ||
66 | |||
67 | adi,buffer-enable: | ||
68 | description: | | ||
69 | Enables the buffer on the analog inputs. If cleared, the analog inputs | ||
70 | are unbuffered, lowering the power consumption of the device. If this | ||
71 | bit is set, the analog inputs are buffered, allowing the user to place | ||
72 | source impedances on the front end without contributing gain errors to | ||
73 | the system. | ||
74 | type: boolean | ||
75 | |||
76 | adi,burnout-currents-enable: | ||
77 | description: | | ||
78 | When this bit is set to 1, the 500 nA current sources in the signal | ||
79 | path are enabled. When BURN = 0, the burnout currents are disabled. | ||
80 | The burnout currents can be enabled only when the buffer is active | ||
81 | and when chop is disabled. | ||
82 | type: boolean | ||
83 | |||
84 | bipolar: | ||
85 | description: see Documentation/devicetree/bindings/iio/adc/adc.txt | ||
86 | type: boolean | ||
87 | |||
88 | required: | ||
89 | - compatible | ||
90 | - reg | ||
91 | - clocks | ||
92 | - clock-names | ||
93 | - interrupts | ||
94 | - dvdd-supply | ||
95 | - avdd-supply | ||
96 | - spi-cpol | ||
97 | - spi-cpha | ||
98 | |||
99 | examples: | ||
100 | - | | ||
101 | spi0 { | ||
102 | adc@0 { | ||
103 | compatible = "adi,ad7192"; | ||
104 | reg = <0>; | ||
105 | spi-max-frequency = <1000000>; | ||
106 | spi-cpol; | ||
107 | spi-cpha; | ||
108 | clocks = <&ad7192_mclk>; | ||
109 | clock-names = "mclk"; | ||
110 | #interrupt-cells = <2>; | ||
111 | interrupts = <25 0x2>; | ||
112 | interrupt-parent = <&gpio>; | ||
113 | dvdd-supply = <&dvdd>; | ||
114 | avdd-supply = <&avdd>; | ||
115 | |||
116 | adi,refin2-pins-enable; | ||
117 | adi,rejection-60-Hz-enable; | ||
118 | adi,buffer-enable; | ||
119 | adi,burnout-currents-enable; | ||
120 | }; | ||
121 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7606.txt b/Documentation/devicetree/bindings/iio/adc/adi,ad7606.txt deleted file mode 100644 index d8652460198e..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7606.txt +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | Analog Devices AD7606 Simultaneous Sampling ADC | ||
2 | |||
3 | Required properties for the AD7606: | ||
4 | |||
5 | - compatible: Must be one of | ||
6 | * "adi,ad7605-4" | ||
7 | * "adi,ad7606-8" | ||
8 | * "adi,ad7606-6" | ||
9 | * "adi,ad7606-4" | ||
10 | * "adi,ad7616" | ||
11 | - reg: SPI chip select number for the device | ||
12 | - spi-max-frequency: Max SPI frequency to use | ||
13 | see: Documentation/devicetree/bindings/spi/spi-bus.txt | ||
14 | - spi-cpha: See Documentation/devicetree/bindings/spi/spi-bus.txt | ||
15 | - avcc-supply: phandle to the Avcc power supply | ||
16 | - interrupts: IRQ line for the ADC | ||
17 | see: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | ||
18 | - adi,conversion-start-gpios: must be the device tree identifier of the CONVST pin. | ||
19 | This logic input is used to initiate conversions on the analog | ||
20 | input channels. As the line is active high, it should be marked | ||
21 | GPIO_ACTIVE_HIGH. | ||
22 | |||
23 | Optional properties: | ||
24 | |||
25 | - reset-gpios: must be the device tree identifier of the RESET pin. If specified, | ||
26 | it will be asserted during driver probe. As the line is active high, | ||
27 | it should be marked GPIO_ACTIVE_HIGH. | ||
28 | - standby-gpios: must be the device tree identifier of the STBY pin. This pin is used | ||
29 | to place the AD7606 into one of two power-down modes, Standby mode or | ||
30 | Shutdown mode. As the line is active low, it should be marked | ||
31 | GPIO_ACTIVE_LOW. | ||
32 | - adi,first-data-gpios: must be the device tree identifier of the FRSTDATA pin. | ||
33 | The FRSTDATA output indicates when the first channel, V1, is | ||
34 | being read back on either the parallel, byte or serial interface. | ||
35 | As the line is active high, it should be marked GPIO_ACTIVE_HIGH. | ||
36 | - adi,range-gpios: must be the device tree identifier of the RANGE pin. The polarity on | ||
37 | this pin determines the input range of the analog input channels. If | ||
38 | this pin is tied to a logic high, the analog input range is ±10V for | ||
39 | all channels. If this pin is tied to a logic low, the analog input range | ||
40 | is ±5V for all channels. As the line is active high, it should be marked | ||
41 | GPIO_ACTIVE_HIGH. | ||
42 | - adi,oversampling-ratio-gpios: must be the device tree identifier of the over-sampling | ||
43 | mode pins. As the line is active high, it should be marked | ||
44 | GPIO_ACTIVE_HIGH. | ||
45 | |||
46 | Example: | ||
47 | |||
48 | adc@0 { | ||
49 | compatible = "adi,ad7606-8"; | ||
50 | reg = <0>; | ||
51 | spi-max-frequency = <1000000>; | ||
52 | spi-cpol; | ||
53 | |||
54 | avcc-supply = <&adc_vref>; | ||
55 | |||
56 | interrupts = <25 IRQ_TYPE_EDGE_FALLING>; | ||
57 | interrupt-parent = <&gpio>; | ||
58 | |||
59 | adi,conversion-start-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; | ||
60 | reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; | ||
61 | adi,first-data-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; | ||
62 | adi,oversampling-ratio-gpios = <&gpio 18 GPIO_ACTIVE_HIGH | ||
63 | &gpio 23 GPIO_ACTIVE_HIGH | ||
64 | &gpio 26 GPIO_ACTIVE_HIGH>; | ||
65 | standby-gpios = <&gpio 24 GPIO_ACTIVE_LOW>; | ||
66 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml new file mode 100644 index 000000000000..cc544fdc38be --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml | |||
@@ -0,0 +1,138 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | %YAML 1.2 | ||
3 | --- | ||
4 | $id: http://devicetree.org/schemas/iio/adc/adi,ad7606.yaml# | ||
5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
6 | |||
7 | title: Analog Devices AD7606 Simultaneous Sampling ADC | ||
8 | |||
9 | maintainers: | ||
10 | - Beniamin Bia <beniamin.bia@analog.com> | ||
11 | - Stefan Popa <stefan.popa@analog.com> | ||
12 | |||
13 | description: | | ||
14 | Analog Devices AD7606 Simultaneous Sampling ADC | ||
15 | https://www.analog.com/media/en/technical-documentation/data-sheets/ad7606_7606-6_7606-4.pdf | ||
16 | https://www.analog.com/media/en/technical-documentation/data-sheets/AD7606B.pdf | ||
17 | https://www.analog.com/media/en/technical-documentation/data-sheets/AD7616.pdf | ||
18 | |||
19 | properties: | ||
20 | compatible: | ||
21 | enum: | ||
22 | - adi,ad7605-4 | ||
23 | - adi,ad7606-8 | ||
24 | - adi,ad7606-6 | ||
25 | - adi,ad7606-4 | ||
26 | - adi,ad7606b | ||
27 | - adi,ad7616 | ||
28 | |||
29 | reg: | ||
30 | maxItems: 1 | ||
31 | |||
32 | spi-cpha: true | ||
33 | |||
34 | avcc-supply: | ||
35 | description: | ||
36 | Phandle to the Avcc power supply | ||
37 | maxItems: 1 | ||
38 | |||
39 | interrupts: | ||
40 | maxItems: 1 | ||
41 | |||
42 | adi,conversion-start-gpios: | ||
43 | description: | ||
44 | Must be the device tree identifier of the CONVST pin. | ||
45 | This logic input is used to initiate conversions on the analog | ||
46 | input channels. As the line is active high, it should be marked | ||
47 | GPIO_ACTIVE_HIGH. | ||
48 | maxItems: 1 | ||
49 | |||
50 | reset-gpios: | ||
51 | description: | ||
52 | Must be the device tree identifier of the RESET pin. If specified, | ||
53 | it will be asserted during driver probe. As the line is active high, | ||
54 | it should be marked GPIO_ACTIVE_HIGH. | ||
55 | maxItems: 1 | ||
56 | |||
57 | standby-gpios: | ||
58 | description: | ||
59 | Must be the device tree identifier of the STBY pin. This pin is used | ||
60 | to place the AD7606 into one of two power-down modes, Standby mode or | ||
61 | Shutdown mode. As the line is active low, it should be marked | ||
62 | GPIO_ACTIVE_LOW. | ||
63 | maxItems: 1 | ||
64 | |||
65 | adi,first-data-gpios: | ||
66 | description: | ||
67 | Must be the device tree identifier of the FRSTDATA pin. | ||
68 | The FRSTDATA output indicates when the first channel, V1, is | ||
69 | being read back on either the parallel, byte or serial interface. | ||
70 | As the line is active high, it should be marked GPIO_ACTIVE_HIGH. | ||
71 | maxItems: 1 | ||
72 | |||
73 | adi,range-gpios: | ||
74 | description: | ||
75 | Must be the device tree identifier of the RANGE pin. The polarity on | ||
76 | this pin determines the input range of the analog input channels. If | ||
77 | this pin is tied to a logic high, the analog input range is ±10V for | ||
78 | all channels. If this pin is tied to a logic low, the analog input range | ||
79 | is ±5V for all channels. As the line is active high, it should be marked | ||
80 | GPIO_ACTIVE_HIGH. | ||
81 | maxItems: 1 | ||
82 | |||
83 | adi,oversampling-ratio-gpios: | ||
84 | description: | ||
85 | Must be the device tree identifier of the over-sampling | ||
86 | mode pins. As the line is active high, it should be marked | ||
87 | GPIO_ACTIVE_HIGH. | ||
88 | maxItems: 1 | ||
89 | |||
90 | adi,sw-mode: | ||
91 | description: | ||
92 | Software mode of operation, so far available only for ad7616 and ad7606b. | ||
93 | It is enabled when all three oversampling mode pins are connected to | ||
94 | high level. The device is configured by the corresponding registers. If the | ||
95 | adi,oversampling-ratio-gpios property is defined, then the driver will set the | ||
96 | oversampling gpios to high. Otherwise, it is assumed that the pins are hardwired | ||
97 | to VDD. | ||
98 | type: boolean | ||
99 | |||
100 | required: | ||
101 | - compatible | ||
102 | - reg | ||
103 | - spi-cpha | ||
104 | - avcc-supply | ||
105 | - interrupts | ||
106 | - adi,conversion-start-gpios | ||
107 | |||
108 | examples: | ||
109 | - | | ||
110 | #include <dt-bindings/gpio/gpio.h> | ||
111 | #include <dt-bindings/interrupt-controller/irq.h> | ||
112 | spi0 { | ||
113 | #address-cells = <1>; | ||
114 | #size-cells = <0>; | ||
115 | |||
116 | adc@0 { | ||
117 | compatible = "adi,ad7606-8"; | ||
118 | reg = <0>; | ||
119 | spi-max-frequency = <1000000>; | ||
120 | spi-cpol; | ||
121 | spi-cpha; | ||
122 | |||
123 | avcc-supply = <&adc_vref>; | ||
124 | |||
125 | interrupts = <25 IRQ_TYPE_EDGE_FALLING>; | ||
126 | interrupt-parent = <&gpio>; | ||
127 | |||
128 | adi,conversion-start-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; | ||
129 | reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; | ||
130 | adi,first-data-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; | ||
131 | adi,oversampling-ratio-gpios = <&gpio 18 GPIO_ACTIVE_HIGH | ||
132 | &gpio 23 GPIO_ACTIVE_HIGH | ||
133 | &gpio 26 GPIO_ACTIVE_HIGH>; | ||
134 | standby-gpios = <&gpio 24 GPIO_ACTIVE_LOW>; | ||
135 | adi,sw-mode; | ||
136 | }; | ||
137 | }; | ||
138 | ... | ||
diff --git a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt index 87407d110bb7..6d0c050d89fe 100644 --- a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +++ b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt | |||
@@ -13,6 +13,7 @@ Required properties: | |||
13 | "st,lsm6dsr" | 13 | "st,lsm6dsr" |
14 | "st,lsm6ds3tr-c" | 14 | "st,lsm6ds3tr-c" |
15 | "st,ism330dhcx" | 15 | "st,ism330dhcx" |
16 | "st,lsm9ds1-imu" | ||
16 | - reg: i2c address of the sensor / spi cs line | 17 | - reg: i2c address of the sensor / spi cs line |
17 | 18 | ||
18 | Optional properties: | 19 | Optional properties: |
diff --git a/Documentation/devicetree/bindings/iio/light/isl29501.txt b/Documentation/devicetree/bindings/iio/light/renesas,isl29501.txt index 46957997fee3..46957997fee3 100644 --- a/Documentation/devicetree/bindings/iio/light/isl29501.txt +++ b/Documentation/devicetree/bindings/iio/light/renesas,isl29501.txt | |||
diff --git a/MAINTAINERS b/MAINTAINERS index d39c510037a7..8c71957ca9d8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -903,11 +903,12 @@ F: Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml | |||
903 | 903 | ||
904 | ANALOG DEVICES INC AD7606 DRIVER | 904 | ANALOG DEVICES INC AD7606 DRIVER |
905 | M: Stefan Popa <stefan.popa@analog.com> | 905 | M: Stefan Popa <stefan.popa@analog.com> |
906 | M: Beniamin Bia <beniamin.bia@analog.com> | ||
906 | L: linux-iio@vger.kernel.org | 907 | L: linux-iio@vger.kernel.org |
907 | W: http://ez.analog.com/community/linux-device-drivers | 908 | W: http://ez.analog.com/community/linux-device-drivers |
908 | S: Supported | 909 | S: Supported |
909 | F: drivers/iio/adc/ad7606.c | 910 | F: drivers/iio/adc/ad7606.c |
910 | F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.txt | 911 | F: Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml |
911 | 912 | ||
912 | ANALOG DEVICES INC AD7768-1 DRIVER | 913 | ANALOG DEVICES INC AD7768-1 DRIVER |
913 | M: Stefan Popa <stefan.popa@analog.com> | 914 | M: Stefan Popa <stefan.popa@analog.com> |
@@ -6341,7 +6342,7 @@ FLEXTIMER FTM-QUADDEC DRIVER | |||
6341 | M: Patrick Havelange <patrick.havelange@essensium.com> | 6342 | M: Patrick Havelange <patrick.havelange@essensium.com> |
6342 | L: linux-iio@vger.kernel.org | 6343 | L: linux-iio@vger.kernel.org |
6343 | S: Maintained | 6344 | S: Maintained |
6344 | F: Documentation/ABI/testing/sysfs-bus-counter-ftm-quadddec | 6345 | F: Documentation/ABI/testing/sysfs-bus-counter-ftm-quaddec |
6345 | F: Documentation/devicetree/bindings/counter/ftm-quaddec.txt | 6346 | F: Documentation/devicetree/bindings/counter/ftm-quaddec.txt |
6346 | F: drivers/counter/ftm-quaddec.c | 6347 | F: drivers/counter/ftm-quaddec.c |
6347 | 6348 | ||
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 6645771aa349..fee535d6e45b 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c | |||
@@ -1486,8 +1486,8 @@ static const struct acpi_device_id kx_acpi_match[] = { | |||
1486 | {"KIOX0008", KXCJ91008}, | 1486 | {"KIOX0008", KXCJ91008}, |
1487 | {"KIOX0009", KXTJ21009}, | 1487 | {"KIOX0009", KXTJ21009}, |
1488 | {"KIOX000A", KXCJ91008}, | 1488 | {"KIOX000A", KXCJ91008}, |
1489 | {"KIOX010A", KXCJ91008}, /* KXCJ91008 inside the display of a 2-in-1 */ | 1489 | {"KIOX010A", KXCJ91008}, /* KXCJ91008 in the display of a yoga 2-in-1 */ |
1490 | {"KIOX020A", KXCJ91008}, | 1490 | {"KIOX020A", KXCJ91008}, /* KXCJ91008 in the base of a yoga 2-in-1 */ |
1491 | {"KXTJ1009", KXTJ21009}, | 1491 | {"KXTJ1009", KXTJ21009}, |
1492 | {"KXJ2109", KXTJ21009}, | 1492 | {"KXJ2109", KXTJ21009}, |
1493 | {"SMO8500", KXCJ91008}, | 1493 | {"SMO8500", KXCJ91008}, |
diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index ed2d08437e5d..f5ba94c03a8d 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c | |||
@@ -410,12 +410,19 @@ static const struct ad7606_chip_info ad7606_chip_info_tbl[] = { | |||
410 | .oversampling_avail = ad7606_oversampling_avail, | 410 | .oversampling_avail = ad7606_oversampling_avail, |
411 | .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), | 411 | .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), |
412 | }, | 412 | }, |
413 | [ID_AD7606B] = { | ||
414 | .channels = ad7606_channels, | ||
415 | .num_channels = 9, | ||
416 | .oversampling_avail = ad7606_oversampling_avail, | ||
417 | .oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail), | ||
418 | }, | ||
413 | [ID_AD7616] = { | 419 | [ID_AD7616] = { |
414 | .channels = ad7616_channels, | 420 | .channels = ad7616_channels, |
415 | .num_channels = 17, | 421 | .num_channels = 17, |
416 | .oversampling_avail = ad7616_oversampling_avail, | 422 | .oversampling_avail = ad7616_oversampling_avail, |
417 | .oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail), | 423 | .oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail), |
418 | .os_req_reset = true, | 424 | .os_req_reset = true, |
425 | .init_delay_ms = 15, | ||
419 | }, | 426 | }, |
420 | }; | 427 | }; |
421 | 428 | ||
@@ -631,8 +638,10 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, | |||
631 | dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n"); | 638 | dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n"); |
632 | 639 | ||
633 | /* AD7616 requires al least 15ms to reconfigure after a reset */ | 640 | /* AD7616 requires al least 15ms to reconfigure after a reset */ |
634 | if (msleep_interruptible(15)) | 641 | if (st->chip_info->init_delay_ms) { |
635 | return -ERESTARTSYS; | 642 | if (msleep_interruptible(st->chip_info->init_delay_ms)) |
643 | return -ERESTARTSYS; | ||
644 | } | ||
636 | 645 | ||
637 | st->write_scale = ad7606_write_scale_hw; | 646 | st->write_scale = ad7606_write_scale_hw; |
638 | st->write_os = ad7606_write_os_hw; | 647 | st->write_os = ad7606_write_os_hw; |
diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h index eeaaa8b905db..9350ef1f63b5 100644 --- a/drivers/iio/adc/ad7606.h +++ b/drivers/iio/adc/ad7606.h | |||
@@ -46,6 +46,8 @@ | |||
46 | * oversampling ratios. | 46 | * oversampling ratios. |
47 | * @oversampling_num number of elements stored in oversampling_avail array | 47 | * @oversampling_num number of elements stored in oversampling_avail array |
48 | * @os_req_reset some devices require a reset to update oversampling | 48 | * @os_req_reset some devices require a reset to update oversampling |
49 | * @init_delay_ms required delay in miliseconds for initialization | ||
50 | * after a restart | ||
49 | */ | 51 | */ |
50 | struct ad7606_chip_info { | 52 | struct ad7606_chip_info { |
51 | const struct iio_chan_spec *channels; | 53 | const struct iio_chan_spec *channels; |
@@ -53,6 +55,7 @@ struct ad7606_chip_info { | |||
53 | const unsigned int *oversampling_avail; | 55 | const unsigned int *oversampling_avail; |
54 | unsigned int oversampling_num; | 56 | unsigned int oversampling_num; |
55 | bool os_req_reset; | 57 | bool os_req_reset; |
58 | unsigned long init_delay_ms; | ||
56 | }; | 59 | }; |
57 | 60 | ||
58 | /** | 61 | /** |
@@ -155,6 +158,7 @@ enum ad7606_supported_device_ids { | |||
155 | ID_AD7606_8, | 158 | ID_AD7606_8, |
156 | ID_AD7606_6, | 159 | ID_AD7606_6, |
157 | ID_AD7606_4, | 160 | ID_AD7606_4, |
161 | ID_AD7606B, | ||
158 | ID_AD7616, | 162 | ID_AD7616, |
159 | }; | 163 | }; |
160 | 164 | ||
diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c index 98ed52b74507..29945ad07dca 100644 --- a/drivers/iio/adc/ad7606_spi.c +++ b/drivers/iio/adc/ad7606_spi.c | |||
@@ -28,9 +28,23 @@ | |||
28 | * an offset of 2 for register address. | 28 | * an offset of 2 for register address. |
29 | */ | 29 | */ |
30 | #define AD7616_RANGE_CH_ADDR(ch) ((ch) >> 2) | 30 | #define AD7616_RANGE_CH_ADDR(ch) ((ch) >> 2) |
31 | /* The range of the channel is stored on 2 bits*/ | 31 | /* The range of the channel is stored in 2 bits */ |
32 | #define AD7616_RANGE_CH_MSK(ch) (0b11 << (((ch) & 0b11) * 2)) | 32 | #define AD7616_RANGE_CH_MSK(ch) (0b11 << (((ch) & 0b11) * 2)) |
33 | #define AD7616_RANGE_CH_MODE(ch, mode) ((mode) << ((((ch) & 0b11)) * 2)) | 33 | #define AD7616_RANGE_CH_MODE(ch, mode) ((mode) << ((((ch) & 0b11)) * 2)) |
34 | |||
35 | #define AD7606_CONFIGURATION_REGISTER 0x02 | ||
36 | #define AD7606_SINGLE_DOUT 0x00 | ||
37 | |||
38 | /* | ||
39 | * Range for AD7606B channels are stored in registers starting with address 0x3. | ||
40 | * Each register stores range for 2 channels(4 bits per channel). | ||
41 | */ | ||
42 | #define AD7606_RANGE_CH_MSK(ch) (GENMASK(3, 0) << (4 * ((ch) & 0x1))) | ||
43 | #define AD7606_RANGE_CH_MODE(ch, mode) \ | ||
44 | ((GENMASK(3, 0) & mode) << (4 * ((ch) & 0x1))) | ||
45 | #define AD7606_RANGE_CH_ADDR(ch) (0x03 + ((ch) >> 1)) | ||
46 | #define AD7606_OS_MODE 0x08 | ||
47 | |||
34 | static const struct iio_chan_spec ad7616_sw_channels[] = { | 48 | static const struct iio_chan_spec ad7616_sw_channels[] = { |
35 | IIO_CHAN_SOFT_TIMESTAMP(16), | 49 | IIO_CHAN_SOFT_TIMESTAMP(16), |
36 | AD7616_CHANNEL(0), | 50 | AD7616_CHANNEL(0), |
@@ -51,6 +65,22 @@ static const struct iio_chan_spec ad7616_sw_channels[] = { | |||
51 | AD7616_CHANNEL(15), | 65 | AD7616_CHANNEL(15), |
52 | }; | 66 | }; |
53 | 67 | ||
68 | static const struct iio_chan_spec ad7606b_sw_channels[] = { | ||
69 | IIO_CHAN_SOFT_TIMESTAMP(8), | ||
70 | AD7616_CHANNEL(0), | ||
71 | AD7616_CHANNEL(1), | ||
72 | AD7616_CHANNEL(2), | ||
73 | AD7616_CHANNEL(3), | ||
74 | AD7616_CHANNEL(4), | ||
75 | AD7616_CHANNEL(5), | ||
76 | AD7616_CHANNEL(6), | ||
77 | AD7616_CHANNEL(7), | ||
78 | }; | ||
79 | |||
80 | static const unsigned int ad7606B_oversampling_avail[9] = { | ||
81 | 1, 2, 4, 8, 16, 32, 64, 128, 256 | ||
82 | }; | ||
83 | |||
54 | static u16 ad7616_spi_rd_wr_cmd(int addr, char isWriteOp) | 84 | static u16 ad7616_spi_rd_wr_cmd(int addr, char isWriteOp) |
55 | { | 85 | { |
56 | /* | 86 | /* |
@@ -60,6 +90,16 @@ static u16 ad7616_spi_rd_wr_cmd(int addr, char isWriteOp) | |||
60 | return ((addr & 0x7F) << 1) | ((isWriteOp & 0x1) << 7); | 90 | return ((addr & 0x7F) << 1) | ((isWriteOp & 0x1) << 7); |
61 | } | 91 | } |
62 | 92 | ||
93 | static u16 ad7606B_spi_rd_wr_cmd(int addr, char is_write_op) | ||
94 | { | ||
95 | /* | ||
96 | * The address of register consists of one bit which | ||
97 | * specifies a read command placed in bit 6, followed by | ||
98 | * 6 bits of address. | ||
99 | */ | ||
100 | return (addr & 0x3F) | (((~is_write_op) & 0x1) << 6); | ||
101 | } | ||
102 | |||
63 | static int ad7606_spi_read_block(struct device *dev, | 103 | static int ad7606_spi_read_block(struct device *dev, |
64 | int count, void *buf) | 104 | int count, void *buf) |
65 | { | 105 | { |
@@ -169,6 +209,23 @@ static int ad7616_write_os_sw(struct iio_dev *indio_dev, int val) | |||
169 | AD7616_OS_MASK, val << 2); | 209 | AD7616_OS_MASK, val << 2); |
170 | } | 210 | } |
171 | 211 | ||
212 | static int ad7606_write_scale_sw(struct iio_dev *indio_dev, int ch, int val) | ||
213 | { | ||
214 | struct ad7606_state *st = iio_priv(indio_dev); | ||
215 | |||
216 | return ad7606_spi_write_mask(st, | ||
217 | AD7606_RANGE_CH_ADDR(ch), | ||
218 | AD7606_RANGE_CH_MSK(ch), | ||
219 | AD7606_RANGE_CH_MODE(ch, val)); | ||
220 | } | ||
221 | |||
222 | static int ad7606_write_os_sw(struct iio_dev *indio_dev, int val) | ||
223 | { | ||
224 | struct ad7606_state *st = iio_priv(indio_dev); | ||
225 | |||
226 | return ad7606_spi_reg_write(st, AD7606_OS_MODE, val); | ||
227 | } | ||
228 | |||
172 | static int ad7616_sw_mode_config(struct iio_dev *indio_dev) | 229 | static int ad7616_sw_mode_config(struct iio_dev *indio_dev) |
173 | { | 230 | { |
174 | struct ad7606_state *st = iio_priv(indio_dev); | 231 | struct ad7606_state *st = iio_priv(indio_dev); |
@@ -189,6 +246,42 @@ static int ad7616_sw_mode_config(struct iio_dev *indio_dev) | |||
189 | AD7616_BURST_MODE | AD7616_SEQEN_MODE); | 246 | AD7616_BURST_MODE | AD7616_SEQEN_MODE); |
190 | } | 247 | } |
191 | 248 | ||
249 | static int ad7606B_sw_mode_config(struct iio_dev *indio_dev) | ||
250 | { | ||
251 | struct ad7606_state *st = iio_priv(indio_dev); | ||
252 | unsigned long os[3] = {1}; | ||
253 | |||
254 | /* | ||
255 | * Software mode is enabled when all three oversampling | ||
256 | * pins are set to high. If oversampling gpios are defined | ||
257 | * in the device tree, then they need to be set to high, | ||
258 | * otherwise, they must be hardwired to VDD | ||
259 | */ | ||
260 | if (st->gpio_os) { | ||
261 | gpiod_set_array_value(ARRAY_SIZE(os), | ||
262 | st->gpio_os->desc, st->gpio_os->info, os); | ||
263 | } | ||
264 | /* OS of 128 and 256 are available only in software mode */ | ||
265 | st->oversampling_avail = ad7606B_oversampling_avail; | ||
266 | st->num_os_ratios = ARRAY_SIZE(ad7606B_oversampling_avail); | ||
267 | |||
268 | st->write_scale = ad7606_write_scale_sw; | ||
269 | st->write_os = &ad7606_write_os_sw; | ||
270 | |||
271 | /* Configure device spi to output on a single channel */ | ||
272 | st->bops->reg_write(st, | ||
273 | AD7606_CONFIGURATION_REGISTER, | ||
274 | AD7606_SINGLE_DOUT); | ||
275 | |||
276 | /* | ||
277 | * Scale can be configured individually for each channel | ||
278 | * in software mode. | ||
279 | */ | ||
280 | indio_dev->channels = ad7606b_sw_channels; | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
192 | static const struct ad7606_bus_ops ad7606_spi_bops = { | 285 | static const struct ad7606_bus_ops ad7606_spi_bops = { |
193 | .read_block = ad7606_spi_read_block, | 286 | .read_block = ad7606_spi_read_block, |
194 | }; | 287 | }; |
@@ -202,6 +295,15 @@ static const struct ad7606_bus_ops ad7616_spi_bops = { | |||
202 | .sw_mode_config = ad7616_sw_mode_config, | 295 | .sw_mode_config = ad7616_sw_mode_config, |
203 | }; | 296 | }; |
204 | 297 | ||
298 | static const struct ad7606_bus_ops ad7606B_spi_bops = { | ||
299 | .read_block = ad7606_spi_read_block, | ||
300 | .reg_read = ad7606_spi_reg_read, | ||
301 | .reg_write = ad7606_spi_reg_write, | ||
302 | .write_mask = ad7606_spi_write_mask, | ||
303 | .rd_wr_cmd = ad7606B_spi_rd_wr_cmd, | ||
304 | .sw_mode_config = ad7606B_sw_mode_config, | ||
305 | }; | ||
306 | |||
205 | static int ad7606_spi_probe(struct spi_device *spi) | 307 | static int ad7606_spi_probe(struct spi_device *spi) |
206 | { | 308 | { |
207 | const struct spi_device_id *id = spi_get_device_id(spi); | 309 | const struct spi_device_id *id = spi_get_device_id(spi); |
@@ -211,6 +313,9 @@ static int ad7606_spi_probe(struct spi_device *spi) | |||
211 | case ID_AD7616: | 313 | case ID_AD7616: |
212 | bops = &ad7616_spi_bops; | 314 | bops = &ad7616_spi_bops; |
213 | break; | 315 | break; |
316 | case ID_AD7606B: | ||
317 | bops = &ad7606B_spi_bops; | ||
318 | break; | ||
214 | default: | 319 | default: |
215 | bops = &ad7606_spi_bops; | 320 | bops = &ad7606_spi_bops; |
216 | break; | 321 | break; |
@@ -226,6 +331,7 @@ static const struct spi_device_id ad7606_id_table[] = { | |||
226 | { "ad7606-4", ID_AD7606_4 }, | 331 | { "ad7606-4", ID_AD7606_4 }, |
227 | { "ad7606-6", ID_AD7606_6 }, | 332 | { "ad7606-6", ID_AD7606_6 }, |
228 | { "ad7606-8", ID_AD7606_8 }, | 333 | { "ad7606-8", ID_AD7606_8 }, |
334 | { "ad7606b", ID_AD7606B }, | ||
229 | { "ad7616", ID_AD7616 }, | 335 | { "ad7616", ID_AD7616 }, |
230 | {} | 336 | {} |
231 | }; | 337 | }; |
@@ -236,6 +342,7 @@ static const struct of_device_id ad7606_of_match[] = { | |||
236 | { .compatible = "adi,ad7606-4" }, | 342 | { .compatible = "adi,ad7606-4" }, |
237 | { .compatible = "adi,ad7606-6" }, | 343 | { .compatible = "adi,ad7606-6" }, |
238 | { .compatible = "adi,ad7606-8" }, | 344 | { .compatible = "adi,ad7606-8" }, |
345 | { .compatible = "adi,ad7606b" }, | ||
239 | { .compatible = "adi,ad7616" }, | 346 | { .compatible = "adi,ad7616" }, |
240 | { }, | 347 | { }, |
241 | }; | 348 | }; |
diff --git a/drivers/iio/adc/max1027.c b/drivers/iio/adc/max1027.c index da84adfdb819..214883458582 100644 --- a/drivers/iio/adc/max1027.c +++ b/drivers/iio/adc/max1027.c | |||
@@ -427,8 +427,9 @@ static int max1027_probe(struct spi_device *spi) | |||
427 | return -ENOMEM; | 427 | return -ENOMEM; |
428 | } | 428 | } |
429 | 429 | ||
430 | ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, | 430 | ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, |
431 | &max1027_trigger_handler, NULL); | 431 | &iio_pollfunc_store_time, |
432 | &max1027_trigger_handler, NULL); | ||
432 | if (ret < 0) { | 433 | if (ret < 0) { |
433 | dev_err(&indio_dev->dev, "Failed to setup buffer\n"); | 434 | dev_err(&indio_dev->dev, "Failed to setup buffer\n"); |
434 | return ret; | 435 | return ret; |
@@ -439,7 +440,7 @@ static int max1027_probe(struct spi_device *spi) | |||
439 | if (st->trig == NULL) { | 440 | if (st->trig == NULL) { |
440 | ret = -ENOMEM; | 441 | ret = -ENOMEM; |
441 | dev_err(&indio_dev->dev, "Failed to allocate iio trigger\n"); | 442 | dev_err(&indio_dev->dev, "Failed to allocate iio trigger\n"); |
442 | goto fail_trigger_alloc; | 443 | return ret; |
443 | } | 444 | } |
444 | 445 | ||
445 | st->trig->ops = &max1027_trigger_ops; | 446 | st->trig->ops = &max1027_trigger_ops; |
@@ -454,7 +455,7 @@ static int max1027_probe(struct spi_device *spi) | |||
454 | spi->dev.driver->name, st->trig); | 455 | spi->dev.driver->name, st->trig); |
455 | if (ret < 0) { | 456 | if (ret < 0) { |
456 | dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n"); | 457 | dev_err(&indio_dev->dev, "Failed to allocate IRQ.\n"); |
457 | goto fail_dev_register; | 458 | return ret; |
458 | } | 459 | } |
459 | 460 | ||
460 | /* Disable averaging */ | 461 | /* Disable averaging */ |
@@ -462,34 +463,10 @@ static int max1027_probe(struct spi_device *spi) | |||
462 | ret = spi_write(st->spi, &st->reg, 1); | 463 | ret = spi_write(st->spi, &st->reg, 1); |
463 | if (ret < 0) { | 464 | if (ret < 0) { |
464 | dev_err(&indio_dev->dev, "Failed to configure averaging register\n"); | 465 | dev_err(&indio_dev->dev, "Failed to configure averaging register\n"); |
465 | goto fail_dev_register; | 466 | return ret; |
466 | } | ||
467 | |||
468 | ret = iio_device_register(indio_dev); | ||
469 | if (ret < 0) { | ||
470 | dev_err(&indio_dev->dev, "Failed to register iio device\n"); | ||
471 | goto fail_dev_register; | ||
472 | } | 467 | } |
473 | 468 | ||
474 | return 0; | 469 | return devm_iio_device_register(&spi->dev, indio_dev); |
475 | |||
476 | fail_dev_register: | ||
477 | fail_trigger_alloc: | ||
478 | iio_triggered_buffer_cleanup(indio_dev); | ||
479 | |||
480 | return ret; | ||
481 | } | ||
482 | |||
483 | static int max1027_remove(struct spi_device *spi) | ||
484 | { | ||
485 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
486 | |||
487 | pr_debug("%s: remove(spi = 0x%p)\n", __func__, spi); | ||
488 | |||
489 | iio_device_unregister(indio_dev); | ||
490 | iio_triggered_buffer_cleanup(indio_dev); | ||
491 | |||
492 | return 0; | ||
493 | } | 470 | } |
494 | 471 | ||
495 | static struct spi_driver max1027_driver = { | 472 | static struct spi_driver max1027_driver = { |
@@ -498,7 +475,6 @@ static struct spi_driver max1027_driver = { | |||
498 | .of_match_table = of_match_ptr(max1027_adc_dt_ids), | 475 | .of_match_table = of_match_ptr(max1027_adc_dt_ids), |
499 | }, | 476 | }, |
500 | .probe = max1027_probe, | 477 | .probe = max1027_probe, |
501 | .remove = max1027_remove, | ||
502 | .id_table = max1027_id, | 478 | .id_table = max1027_id, |
503 | }; | 479 | }; |
504 | module_spi_driver(max1027_driver); | 480 | module_spi_driver(max1027_driver); |
diff --git a/drivers/iio/adc/sc27xx_adc.c b/drivers/iio/adc/sc27xx_adc.c index c2203a46f0d8..a6c046575ec3 100644 --- a/drivers/iio/adc/sc27xx_adc.c +++ b/drivers/iio/adc/sc27xx_adc.c | |||
@@ -3,7 +3,6 @@ | |||
3 | 3 | ||
4 | #include <linux/hwspinlock.h> | 4 | #include <linux/hwspinlock.h> |
5 | #include <linux/iio/iio.h> | 5 | #include <linux/iio/iio.h> |
6 | #include <linux/interrupt.h> | ||
7 | #include <linux/module.h> | 6 | #include <linux/module.h> |
8 | #include <linux/nvmem-consumer.h> | 7 | #include <linux/nvmem-consumer.h> |
9 | #include <linux/of.h> | 8 | #include <linux/of.h> |
@@ -46,14 +45,18 @@ | |||
46 | /* Bits definitions for SC27XX_ADC_INT_CLR registers */ | 45 | /* Bits definitions for SC27XX_ADC_INT_CLR registers */ |
47 | #define SC27XX_ADC_IRQ_CLR BIT(0) | 46 | #define SC27XX_ADC_IRQ_CLR BIT(0) |
48 | 47 | ||
48 | /* Bits definitions for SC27XX_ADC_INT_RAW registers */ | ||
49 | #define SC27XX_ADC_IRQ_RAW BIT(0) | ||
50 | |||
49 | /* Mask definition for SC27XX_ADC_DATA register */ | 51 | /* Mask definition for SC27XX_ADC_DATA register */ |
50 | #define SC27XX_ADC_DATA_MASK GENMASK(11, 0) | 52 | #define SC27XX_ADC_DATA_MASK GENMASK(11, 0) |
51 | 53 | ||
52 | /* Timeout (ms) for the trylock of hardware spinlocks */ | 54 | /* Timeout (ms) for the trylock of hardware spinlocks */ |
53 | #define SC27XX_ADC_HWLOCK_TIMEOUT 5000 | 55 | #define SC27XX_ADC_HWLOCK_TIMEOUT 5000 |
54 | 56 | ||
55 | /* Timeout (ms) for ADC data conversion according to ADC datasheet */ | 57 | /* Timeout (us) for ADC data conversion according to ADC datasheet */ |
56 | #define SC27XX_ADC_RDY_TIMEOUT 100 | 58 | #define SC27XX_ADC_RDY_TIMEOUT 1000000 |
59 | #define SC27XX_ADC_POLL_RAW_STATUS 500 | ||
57 | 60 | ||
58 | /* Maximum ADC channel number */ | 61 | /* Maximum ADC channel number */ |
59 | #define SC27XX_ADC_CHANNEL_MAX 32 | 62 | #define SC27XX_ADC_CHANNEL_MAX 32 |
@@ -72,10 +75,8 @@ struct sc27xx_adc_data { | |||
72 | * subsystems which will access the unique ADC controller. | 75 | * subsystems which will access the unique ADC controller. |
73 | */ | 76 | */ |
74 | struct hwspinlock *hwlock; | 77 | struct hwspinlock *hwlock; |
75 | struct completion completion; | ||
76 | int channel_scale[SC27XX_ADC_CHANNEL_MAX]; | 78 | int channel_scale[SC27XX_ADC_CHANNEL_MAX]; |
77 | u32 base; | 79 | u32 base; |
78 | int value; | ||
79 | int irq; | 80 | int irq; |
80 | }; | 81 | }; |
81 | 82 | ||
@@ -188,9 +189,7 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, | |||
188 | int scale, int *val) | 189 | int scale, int *val) |
189 | { | 190 | { |
190 | int ret; | 191 | int ret; |
191 | u32 tmp; | 192 | u32 tmp, value, status; |
192 | |||
193 | reinit_completion(&data->completion); | ||
194 | 193 | ||
195 | ret = hwspin_lock_timeout_raw(data->hwlock, SC27XX_ADC_HWLOCK_TIMEOUT); | 194 | ret = hwspin_lock_timeout_raw(data->hwlock, SC27XX_ADC_HWLOCK_TIMEOUT); |
196 | if (ret) { | 195 | if (ret) { |
@@ -203,6 +202,11 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, | |||
203 | if (ret) | 202 | if (ret) |
204 | goto unlock_adc; | 203 | goto unlock_adc; |
205 | 204 | ||
205 | ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR, | ||
206 | SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR); | ||
207 | if (ret) | ||
208 | goto disable_adc; | ||
209 | |||
206 | /* Configure the channel id and scale */ | 210 | /* Configure the channel id and scale */ |
207 | tmp = (scale << SC27XX_ADC_SCALE_SHIFT) & SC27XX_ADC_SCALE_MASK; | 211 | tmp = (scale << SC27XX_ADC_SCALE_SHIFT) & SC27XX_ADC_SCALE_MASK; |
208 | tmp |= channel & SC27XX_ADC_CHN_ID_MASK; | 212 | tmp |= channel & SC27XX_ADC_CHN_ID_MASK; |
@@ -226,15 +230,22 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, | |||
226 | if (ret) | 230 | if (ret) |
227 | goto disable_adc; | 231 | goto disable_adc; |
228 | 232 | ||
229 | ret = wait_for_completion_timeout(&data->completion, | 233 | ret = regmap_read_poll_timeout(data->regmap, |
230 | msecs_to_jiffies(SC27XX_ADC_RDY_TIMEOUT)); | 234 | data->base + SC27XX_ADC_INT_RAW, |
231 | if (!ret) { | 235 | status, (status & SC27XX_ADC_IRQ_RAW), |
232 | dev_err(data->dev, "read ADC data timeout\n"); | 236 | SC27XX_ADC_POLL_RAW_STATUS, |
233 | ret = -ETIMEDOUT; | 237 | SC27XX_ADC_RDY_TIMEOUT); |
234 | } else { | 238 | if (ret) { |
235 | ret = 0; | 239 | dev_err(data->dev, "read adc timeout, status = 0x%x\n", status); |
240 | goto disable_adc; | ||
236 | } | 241 | } |
237 | 242 | ||
243 | ret = regmap_read(data->regmap, data->base + SC27XX_ADC_DATA, &value); | ||
244 | if (ret) | ||
245 | goto disable_adc; | ||
246 | |||
247 | value &= SC27XX_ADC_DATA_MASK; | ||
248 | |||
238 | disable_adc: | 249 | disable_adc: |
239 | regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL, | 250 | regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL, |
240 | SC27XX_ADC_EN, 0); | 251 | SC27XX_ADC_EN, 0); |
@@ -242,32 +253,11 @@ unlock_adc: | |||
242 | hwspin_unlock_raw(data->hwlock); | 253 | hwspin_unlock_raw(data->hwlock); |
243 | 254 | ||
244 | if (!ret) | 255 | if (!ret) |
245 | *val = data->value; | 256 | *val = value; |
246 | 257 | ||
247 | return ret; | 258 | return ret; |
248 | } | 259 | } |
249 | 260 | ||
250 | static irqreturn_t sc27xx_adc_isr(int irq, void *dev_id) | ||
251 | { | ||
252 | struct sc27xx_adc_data *data = dev_id; | ||
253 | int ret; | ||
254 | |||
255 | ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR, | ||
256 | SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR); | ||
257 | if (ret) | ||
258 | return IRQ_RETVAL(ret); | ||
259 | |||
260 | ret = regmap_read(data->regmap, data->base + SC27XX_ADC_DATA, | ||
261 | &data->value); | ||
262 | if (ret) | ||
263 | return IRQ_RETVAL(ret); | ||
264 | |||
265 | data->value &= SC27XX_ADC_DATA_MASK; | ||
266 | complete(&data->completion); | ||
267 | |||
268 | return IRQ_HANDLED; | ||
269 | } | ||
270 | |||
271 | static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data, | 261 | static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data, |
272 | int channel, int scale, | 262 | int channel, int scale, |
273 | u32 *div_numerator, u32 *div_denominator) | 263 | u32 *div_numerator, u32 *div_denominator) |
@@ -454,11 +444,6 @@ static int sc27xx_adc_enable(struct sc27xx_adc_data *data) | |||
454 | if (ret) | 444 | if (ret) |
455 | goto disable_adc; | 445 | goto disable_adc; |
456 | 446 | ||
457 | ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_EN, | ||
458 | SC27XX_ADC_IRQ_EN, SC27XX_ADC_IRQ_EN); | ||
459 | if (ret) | ||
460 | goto disable_clk; | ||
461 | |||
462 | /* ADC channel scales' calibration from nvmem device */ | 447 | /* ADC channel scales' calibration from nvmem device */ |
463 | ret = sc27xx_adc_scale_calibration(data, true); | 448 | ret = sc27xx_adc_scale_calibration(data, true); |
464 | if (ret) | 449 | if (ret) |
@@ -484,9 +469,6 @@ static void sc27xx_adc_disable(void *_data) | |||
484 | { | 469 | { |
485 | struct sc27xx_adc_data *data = _data; | 470 | struct sc27xx_adc_data *data = _data; |
486 | 471 | ||
487 | regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_EN, | ||
488 | SC27XX_ADC_IRQ_EN, 0); | ||
489 | |||
490 | /* Disable ADC work clock and controller clock */ | 472 | /* Disable ADC work clock and controller clock */ |
491 | regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN, | 473 | regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN, |
492 | SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0); | 474 | SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0); |
@@ -551,7 +533,6 @@ static int sc27xx_adc_probe(struct platform_device *pdev) | |||
551 | return ret; | 533 | return ret; |
552 | } | 534 | } |
553 | 535 | ||
554 | init_completion(&sc27xx_data->completion); | ||
555 | sc27xx_data->dev = dev; | 536 | sc27xx_data->dev = dev; |
556 | 537 | ||
557 | ret = sc27xx_adc_enable(sc27xx_data); | 538 | ret = sc27xx_adc_enable(sc27xx_data); |
@@ -566,14 +547,6 @@ static int sc27xx_adc_probe(struct platform_device *pdev) | |||
566 | return ret; | 547 | return ret; |
567 | } | 548 | } |
568 | 549 | ||
569 | ret = devm_request_threaded_irq(dev, sc27xx_data->irq, NULL, | ||
570 | sc27xx_adc_isr, IRQF_ONESHOT, | ||
571 | pdev->name, sc27xx_data); | ||
572 | if (ret) { | ||
573 | dev_err(dev, "failed to request ADC irq\n"); | ||
574 | return ret; | ||
575 | } | ||
576 | |||
577 | indio_dev->dev.parent = dev; | 550 | indio_dev->dev.parent = dev; |
578 | indio_dev->name = dev_name(dev); | 551 | indio_dev->name = dev_name(dev); |
579 | indio_dev->modes = INDIO_DIRECT_MODE; | 552 | indio_dev->modes = INDIO_DIRECT_MODE; |
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c index fd833295bb17..d44ae126f457 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c | |||
@@ -90,7 +90,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, | |||
90 | struct cros_ec_dev *ec = dev_get_drvdata(pdev->dev.parent); | 90 | struct cros_ec_dev *ec = dev_get_drvdata(pdev->dev.parent); |
91 | struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev); | 91 | struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev); |
92 | u32 ver_mask; | 92 | u32 ver_mask; |
93 | int ret; | 93 | int ret, i; |
94 | 94 | ||
95 | platform_set_drvdata(pdev, indio_dev); | 95 | platform_set_drvdata(pdev, indio_dev); |
96 | 96 | ||
@@ -136,6 +136,9 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, | |||
136 | /* Set sign vector, only used for backward compatibility. */ | 136 | /* Set sign vector, only used for backward compatibility. */ |
137 | memset(state->sign, 1, CROS_EC_SENSOR_MAX_AXIS); | 137 | memset(state->sign, 1, CROS_EC_SENSOR_MAX_AXIS); |
138 | 138 | ||
139 | for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++) | ||
140 | state->calib[i].scale = MOTION_SENSE_DEFAULT_SCALE; | ||
141 | |||
139 | /* 0 is a correct value used to stop the device */ | 142 | /* 0 is a correct value used to stop the device */ |
140 | state->frequencies[0] = 0; | 143 | state->frequencies[0] = 0; |
141 | if (state->msg->version < 3) { | 144 | if (state->msg->version < 3) { |
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c index a8a3fe428d8d..b9dd19b34267 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
10 | #include <linux/irq.h> | 10 | #include <linux/irq.h> |
11 | #include <linux/kernel.h> | ||
11 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
12 | #include <linux/hid-sensor-hub.h> | 13 | #include <linux/hid-sensor-hub.h> |
13 | #include <linux/iio/iio.h> | 14 | #include <linux/iio/iio.h> |
@@ -68,16 +69,6 @@ static struct { | |||
68 | {HID_USAGE_SENSOR_HUMIDITY, 0, 1000, 0}, | 69 | {HID_USAGE_SENSOR_HUMIDITY, 0, 1000, 0}, |
69 | }; | 70 | }; |
70 | 71 | ||
71 | static int pow_10(unsigned power) | ||
72 | { | ||
73 | int i; | ||
74 | int ret = 1; | ||
75 | for (i = 0; i < power; ++i) | ||
76 | ret = ret * 10; | ||
77 | |||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | static void simple_div(int dividend, int divisor, int *whole, | 72 | static void simple_div(int dividend, int divisor, int *whole, |
82 | int *micro_frac) | 73 | int *micro_frac) |
83 | { | 74 | { |
@@ -96,14 +87,14 @@ static void simple_div(int dividend, int divisor, int *whole, | |||
96 | rem *= 10; | 87 | rem *= 10; |
97 | exp++; | 88 | exp++; |
98 | } | 89 | } |
99 | *micro_frac = (rem / divisor) * pow_10(6-exp); | 90 | *micro_frac = (rem / divisor) * int_pow(10, 6 - exp); |
100 | } | 91 | } |
101 | } | 92 | } |
102 | 93 | ||
103 | static void split_micro_fraction(unsigned int no, int exp, int *val1, int *val2) | 94 | static void split_micro_fraction(unsigned int no, int exp, int *val1, int *val2) |
104 | { | 95 | { |
105 | *val1 = no/pow_10(exp); | 96 | *val1 = no / int_pow(10, exp); |
106 | *val2 = no%pow_10(exp) * pow_10(6-exp); | 97 | *val2 = no % int_pow(10, exp) * int_pow(10, 6 - exp); |
107 | } | 98 | } |
108 | 99 | ||
109 | /* | 100 | /* |
@@ -125,7 +116,7 @@ static void convert_from_vtf_format(u32 value, int size, int exp, | |||
125 | } | 116 | } |
126 | exp = hid_sensor_convert_exponent(exp); | 117 | exp = hid_sensor_convert_exponent(exp); |
127 | if (exp >= 0) { | 118 | if (exp >= 0) { |
128 | *val1 = sign * value * pow_10(exp); | 119 | *val1 = sign * value * int_pow(10, exp); |
129 | *val2 = 0; | 120 | *val2 = 0; |
130 | } else { | 121 | } else { |
131 | split_micro_fraction(value, -exp, val1, val2); | 122 | 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) | |||
145 | sign = -1; | 136 | sign = -1; |
146 | exp = hid_sensor_convert_exponent(exp); | 137 | exp = hid_sensor_convert_exponent(exp); |
147 | if (exp < 0) { | 138 | if (exp < 0) { |
148 | value = abs(val1) * pow_10(-exp); | 139 | value = abs(val1) * int_pow(10, -exp); |
149 | value += abs(val2) / pow_10(6+exp); | 140 | value += abs(val2) / int_pow(10, 6 + exp); |
150 | } else | 141 | } else |
151 | value = abs(val1) / pow_10(exp); | 142 | value = abs(val1) / int_pow(10, exp); |
152 | if (sign < 0) | 143 | if (sign < 0) |
153 | value = ((1LL << (size * 8)) - value); | 144 | value = ((1LL << (size * 8)) - value); |
154 | 145 | ||
@@ -211,12 +202,12 @@ int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st, | |||
211 | if (val1 < 0 || val2 < 0) | 202 | if (val1 < 0 || val2 < 0) |
212 | return -EINVAL; | 203 | return -EINVAL; |
213 | 204 | ||
214 | value = val1 * pow_10(6) + val2; | 205 | value = val1 * int_pow(10, 6) + val2; |
215 | if (value) { | 206 | if (value) { |
216 | if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND) | 207 | if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND) |
217 | value = pow_10(9)/value; | 208 | value = int_pow(10, 9) / value; |
218 | else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND) | 209 | else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND) |
219 | value = pow_10(6)/value; | 210 | value = int_pow(10, 6) / value; |
220 | else | 211 | else |
221 | value = 0; | 212 | value = 0; |
222 | } | 213 | } |
@@ -311,34 +302,34 @@ static void adjust_exponent_nano(int *val0, int *val1, int scale0, | |||
311 | int rem; | 302 | int rem; |
312 | 303 | ||
313 | if (exp > 0) { | 304 | if (exp > 0) { |
314 | *val0 = scale0 * pow_10(exp); | 305 | *val0 = scale0 * int_pow(10, exp); |
315 | res = 0; | 306 | res = 0; |
316 | if (exp > 9) { | 307 | if (exp > 9) { |
317 | *val1 = 0; | 308 | *val1 = 0; |
318 | return; | 309 | return; |
319 | } | 310 | } |
320 | for (i = 0; i < exp; ++i) { | 311 | for (i = 0; i < exp; ++i) { |
321 | x = scale1 / pow_10(8 - i); | 312 | x = scale1 / int_pow(10, 8 - i); |
322 | res += (pow_10(exp - 1 - i) * x); | 313 | res += int_pow(10, exp - 1 - i) * x; |
323 | scale1 = scale1 % pow_10(8 - i); | 314 | scale1 = scale1 % int_pow(10, 8 - i); |
324 | } | 315 | } |
325 | *val0 += res; | 316 | *val0 += res; |
326 | *val1 = scale1 * pow_10(exp); | 317 | *val1 = scale1 * int_pow(10, exp); |
327 | } else if (exp < 0) { | 318 | } else if (exp < 0) { |
328 | exp = abs(exp); | 319 | exp = abs(exp); |
329 | if (exp > 9) { | 320 | if (exp > 9) { |
330 | *val0 = *val1 = 0; | 321 | *val0 = *val1 = 0; |
331 | return; | 322 | return; |
332 | } | 323 | } |
333 | *val0 = scale0 / pow_10(exp); | 324 | *val0 = scale0 / int_pow(10, exp); |
334 | rem = scale0 % pow_10(exp); | 325 | rem = scale0 % int_pow(10, exp); |
335 | res = 0; | 326 | res = 0; |
336 | for (i = 0; i < (9 - exp); ++i) { | 327 | for (i = 0; i < (9 - exp); ++i) { |
337 | x = scale1 / pow_10(8 - i); | 328 | x = scale1 / int_pow(10, 8 - i); |
338 | res += (pow_10(8 - exp - i) * x); | 329 | res += int_pow(10, 8 - exp - i) * x; |
339 | scale1 = scale1 % pow_10(8 - i); | 330 | scale1 = scale1 % int_pow(10, 8 - i); |
340 | } | 331 | } |
341 | *val1 = rem * pow_10(9 - exp) + res; | 332 | *val1 = rem * int_pow(10, 9 - exp) + res; |
342 | } else { | 333 | } else { |
343 | *val0 = scale0; | 334 | *val0 = scale0; |
344 | *val1 = scale1; | 335 | *val1 = scale1; |
diff --git a/drivers/iio/common/st_sensors/Kconfig b/drivers/iio/common/st_sensors/Kconfig index 91b98e152d75..9364ec7a811f 100644 --- a/drivers/iio/common/st_sensors/Kconfig +++ b/drivers/iio/common/st_sensors/Kconfig | |||
@@ -5,9 +5,11 @@ | |||
5 | 5 | ||
6 | config IIO_ST_SENSORS_I2C | 6 | config IIO_ST_SENSORS_I2C |
7 | tristate | 7 | tristate |
8 | select REGMAP_I2C | ||
8 | 9 | ||
9 | config IIO_ST_SENSORS_SPI | 10 | config IIO_ST_SENSORS_SPI |
10 | tristate | 11 | tristate |
12 | select REGMAP_SPI | ||
11 | 13 | ||
12 | config IIO_ST_SENSORS_CORE | 14 | config IIO_ST_SENSORS_CORE |
13 | tristate | 15 | tristate |
diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c index 4335214800d2..2ebe08326048 100644 --- a/drivers/iio/dac/ad5380.c +++ b/drivers/iio/dac/ad5380.c | |||
@@ -220,7 +220,7 @@ static int ad5380_read_raw(struct iio_dev *indio_dev, | |||
220 | if (ret) | 220 | if (ret) |
221 | return ret; | 221 | return ret; |
222 | *val >>= chan->scan_type.shift; | 222 | *val >>= chan->scan_type.shift; |
223 | val -= (1 << chan->scan_type.realbits) / 2; | 223 | *val -= (1 << chan->scan_type.realbits) / 2; |
224 | return IIO_VAL_INT; | 224 | return IIO_VAL_INT; |
225 | case IIO_CHAN_INFO_SCALE: | 225 | case IIO_CHAN_INFO_SCALE: |
226 | *val = 2 * st->vref; | 226 | *val = 2 * st->vref; |
diff --git a/drivers/iio/imu/adis16460.c b/drivers/iio/imu/adis16460.c index 1ef11640ee20..6aed9e84abbf 100644 --- a/drivers/iio/imu/adis16460.c +++ b/drivers/iio/imu/adis16460.c | |||
@@ -152,7 +152,7 @@ static int adis16460_debugfs_init(struct iio_dev *indio_dev) | |||
152 | static int adis16460_set_freq(struct iio_dev *indio_dev, int val, int val2) | 152 | static int adis16460_set_freq(struct iio_dev *indio_dev, int val, int val2) |
153 | { | 153 | { |
154 | struct adis16460 *st = iio_priv(indio_dev); | 154 | struct adis16460 *st = iio_priv(indio_dev); |
155 | unsigned int t; | 155 | int t; |
156 | 156 | ||
157 | t = val * 1000 + val2 / 1000; | 157 | t = val * 1000 + val2 / 1000; |
158 | if (t <= 0) | 158 | if (t <= 0) |
diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig index 939058b27746..77aa0e77212d 100644 --- a/drivers/iio/imu/st_lsm6dsx/Kconfig +++ b/drivers/iio/imu/st_lsm6dsx/Kconfig | |||
@@ -12,7 +12,7 @@ config IIO_ST_LSM6DSX | |||
12 | Say yes here to build support for STMicroelectronics LSM6DSx imu | 12 | Say yes here to build support for STMicroelectronics LSM6DSx imu |
13 | sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm, | 13 | sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm, |
14 | ism330dlc, lsm6dso, lsm6dsox, asm330lhh, lsm6dsr, lsm6ds3tr-c, | 14 | ism330dlc, lsm6dso, lsm6dsox, asm330lhh, lsm6dsr, lsm6ds3tr-c, |
15 | ism330dhcx | 15 | ism330dhcx and the accelerometer/gyroscope of lsm9ds1. |
16 | 16 | ||
17 | To compile this driver as a module, choose M here: the module | 17 | To compile this driver as a module, choose M here: the module |
18 | will be called st_lsm6dsx. | 18 | will be called st_lsm6dsx. |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 4e8e67ae1632..80e42c7dbcbe 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #define ST_LSM6DSR_DEV_NAME "lsm6dsr" | 24 | #define ST_LSM6DSR_DEV_NAME "lsm6dsr" |
25 | #define ST_LSM6DS3TRC_DEV_NAME "lsm6ds3tr-c" | 25 | #define ST_LSM6DS3TRC_DEV_NAME "lsm6ds3tr-c" |
26 | #define ST_ISM330DHCX_DEV_NAME "ism330dhcx" | 26 | #define ST_ISM330DHCX_DEV_NAME "ism330dhcx" |
27 | #define ST_LSM9DS1_DEV_NAME "lsm9ds1-imu" | ||
27 | 28 | ||
28 | enum st_lsm6dsx_hw_id { | 29 | enum st_lsm6dsx_hw_id { |
29 | ST_LSM6DS3_ID, | 30 | ST_LSM6DS3_ID, |
@@ -37,6 +38,7 @@ enum st_lsm6dsx_hw_id { | |||
37 | ST_LSM6DSR_ID, | 38 | ST_LSM6DSR_ID, |
38 | ST_LSM6DS3TRC_ID, | 39 | ST_LSM6DS3TRC_ID, |
39 | ST_ISM330DHCX_ID, | 40 | ST_ISM330DHCX_ID, |
41 | ST_LSM9DS1_ID, | ||
40 | ST_LSM6DSX_MAX_ID, | 42 | ST_LSM6DSX_MAX_ID, |
41 | }; | 43 | }; |
42 | 44 | ||
@@ -75,6 +77,7 @@ struct st_lsm6dsx_reg { | |||
75 | u8 mask; | 77 | u8 mask; |
76 | }; | 78 | }; |
77 | 79 | ||
80 | struct st_lsm6dsx_sensor; | ||
78 | struct st_lsm6dsx_hw; | 81 | struct st_lsm6dsx_hw; |
79 | 82 | ||
80 | struct st_lsm6dsx_odr { | 83 | struct st_lsm6dsx_odr { |
@@ -101,12 +104,14 @@ struct st_lsm6dsx_fs_table_entry { | |||
101 | 104 | ||
102 | /** | 105 | /** |
103 | * struct st_lsm6dsx_fifo_ops - ST IMU FIFO settings | 106 | * struct st_lsm6dsx_fifo_ops - ST IMU FIFO settings |
107 | * @update_fifo: Update FIFO configuration callback. | ||
104 | * @read_fifo: Read FIFO callback. | 108 | * @read_fifo: Read FIFO callback. |
105 | * @fifo_th: FIFO threshold register info (addr + mask). | 109 | * @fifo_th: FIFO threshold register info (addr + mask). |
106 | * @fifo_diff: FIFO diff status register info (addr + mask). | 110 | * @fifo_diff: FIFO diff status register info (addr + mask). |
107 | * @th_wl: FIFO threshold word length. | 111 | * @th_wl: FIFO threshold word length. |
108 | */ | 112 | */ |
109 | struct st_lsm6dsx_fifo_ops { | 113 | struct st_lsm6dsx_fifo_ops { |
114 | int (*update_fifo)(struct st_lsm6dsx_sensor *sensor, bool enable); | ||
110 | int (*read_fifo)(struct st_lsm6dsx_hw *hw); | 115 | int (*read_fifo)(struct st_lsm6dsx_hw *hw); |
111 | struct { | 116 | struct { |
112 | u8 addr; | 117 | u8 addr; |
@@ -200,6 +205,9 @@ struct st_lsm6dsx_ext_dev_settings { | |||
200 | /** | 205 | /** |
201 | * struct st_lsm6dsx_settings - ST IMU sensor settings | 206 | * struct st_lsm6dsx_settings - ST IMU sensor settings |
202 | * @wai: Sensor WhoAmI default value. | 207 | * @wai: Sensor WhoAmI default value. |
208 | * @int1_addr: Control Register address for INT1 | ||
209 | * @int2_addr: Control Register address for INT2 | ||
210 | * @reset_addr: register address for reset/reboot | ||
203 | * @max_fifo_size: Sensor max fifo length in FIFO words. | 211 | * @max_fifo_size: Sensor max fifo length in FIFO words. |
204 | * @id: List of hw id/device name supported by the driver configuration. | 212 | * @id: List of hw id/device name supported by the driver configuration. |
205 | * @channels: IIO channels supported by the device. | 213 | * @channels: IIO channels supported by the device. |
@@ -213,6 +221,9 @@ struct st_lsm6dsx_ext_dev_settings { | |||
213 | */ | 221 | */ |
214 | struct st_lsm6dsx_settings { | 222 | struct st_lsm6dsx_settings { |
215 | u8 wai; | 223 | u8 wai; |
224 | u8 int1_addr; | ||
225 | u8 int2_addr; | ||
226 | u8 reset_addr; | ||
216 | u16 max_fifo_size; | 227 | u16 max_fifo_size; |
217 | struct { | 228 | struct { |
218 | enum st_lsm6dsx_hw_id hw_id; | 229 | enum st_lsm6dsx_hw_id hw_id; |
@@ -327,6 +338,7 @@ int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw); | |||
327 | int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val); | 338 | int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val); |
328 | int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, | 339 | int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, |
329 | u16 watermark); | 340 | u16 watermark); |
341 | int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable); | ||
330 | int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw); | 342 | int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw); |
331 | int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, | 343 | int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, |
332 | enum st_lsm6dsx_fifo_mode fifo_mode); | 344 | enum st_lsm6dsx_fifo_mode fifo_mode); |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index 2c03a5b80f80..b0f3da1976e4 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | |||
@@ -602,9 +602,8 @@ int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw) | |||
602 | return err; | 602 | return err; |
603 | } | 603 | } |
604 | 604 | ||
605 | static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable) | 605 | int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable) |
606 | { | 606 | { |
607 | struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); | ||
608 | struct st_lsm6dsx_hw *hw = sensor->hw; | 607 | struct st_lsm6dsx_hw *hw = sensor->hw; |
609 | int err; | 608 | int err; |
610 | 609 | ||
@@ -676,12 +675,24 @@ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) | |||
676 | 675 | ||
677 | static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev) | 676 | static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev) |
678 | { | 677 | { |
679 | return st_lsm6dsx_update_fifo(iio_dev, true); | 678 | struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); |
679 | struct st_lsm6dsx_hw *hw = sensor->hw; | ||
680 | |||
681 | if (!hw->settings->fifo_ops.update_fifo) | ||
682 | return -ENOTSUPP; | ||
683 | |||
684 | return hw->settings->fifo_ops.update_fifo(sensor, true); | ||
680 | } | 685 | } |
681 | 686 | ||
682 | static int st_lsm6dsx_buffer_postdisable(struct iio_dev *iio_dev) | 687 | static int st_lsm6dsx_buffer_postdisable(struct iio_dev *iio_dev) |
683 | { | 688 | { |
684 | return st_lsm6dsx_update_fifo(iio_dev, false); | 689 | struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); |
690 | struct st_lsm6dsx_hw *hw = sensor->hw; | ||
691 | |||
692 | if (!hw->settings->fifo_ops.update_fifo) | ||
693 | return -ENOTSUPP; | ||
694 | |||
695 | return hw->settings->fifo_ops.update_fifo(sensor, false); | ||
685 | } | 696 | } |
686 | 697 | ||
687 | static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = { | 698 | static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = { |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 85824d6739ee..2d3495560136 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | |||
@@ -10,6 +10,8 @@ | |||
10 | * +-125/+-245/+-500/+-1000/+-2000 dps | 10 | * +-125/+-245/+-500/+-1000/+-2000 dps |
11 | * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer | 11 | * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer |
12 | * allowing dynamic batching of sensor data. | 12 | * allowing dynamic batching of sensor data. |
13 | * LSM9DSx series is similar but includes an additional magnetometer, handled | ||
14 | * by a different driver. | ||
13 | * | 15 | * |
14 | * Supported sensors: | 16 | * Supported sensors: |
15 | * - LSM6DS3: | 17 | * - LSM6DS3: |
@@ -30,6 +32,13 @@ | |||
30 | * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 | 32 | * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 |
31 | * - FIFO size: 3KB | 33 | * - FIFO size: 3KB |
32 | * | 34 | * |
35 | * - LSM9DS1: | ||
36 | * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952 | ||
37 | * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 | ||
38 | * - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952 | ||
39 | * - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000 | ||
40 | * - FIFO size: 32 | ||
41 | * | ||
33 | * Copyright 2016 STMicroelectronics Inc. | 42 | * Copyright 2016 STMicroelectronics Inc. |
34 | * | 43 | * |
35 | * Lorenzo Bianconi <lorenzo.bianconi@st.com> | 44 | * Lorenzo Bianconi <lorenzo.bianconi@st.com> |
@@ -49,17 +58,12 @@ | |||
49 | 58 | ||
50 | #include "st_lsm6dsx.h" | 59 | #include "st_lsm6dsx.h" |
51 | 60 | ||
52 | #define ST_LSM6DSX_REG_INT1_ADDR 0x0d | ||
53 | #define ST_LSM6DSX_REG_INT2_ADDR 0x0e | ||
54 | #define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3) | 61 | #define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3) |
55 | #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f | 62 | #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f |
56 | #define ST_LSM6DSX_REG_RESET_ADDR 0x12 | ||
57 | #define ST_LSM6DSX_REG_RESET_MASK BIT(0) | 63 | #define ST_LSM6DSX_REG_RESET_MASK BIT(0) |
58 | #define ST_LSM6DSX_REG_BOOT_MASK BIT(7) | 64 | #define ST_LSM6DSX_REG_BOOT_MASK BIT(7) |
59 | #define ST_LSM6DSX_REG_BDU_ADDR 0x12 | 65 | #define ST_LSM6DSX_REG_BDU_ADDR 0x12 |
60 | #define ST_LSM6DSX_REG_BDU_MASK BIT(6) | 66 | #define ST_LSM6DSX_REG_BDU_MASK BIT(6) |
61 | #define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13 | ||
62 | #define ST_LSM6DSX_REG_INT2_ON_INT1_MASK BIT(5) | ||
63 | 67 | ||
64 | static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { | 68 | static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { |
65 | ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0), | 69 | ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0), |
@@ -75,9 +79,89 @@ static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = { | |||
75 | IIO_CHAN_SOFT_TIMESTAMP(3), | 79 | IIO_CHAN_SOFT_TIMESTAMP(3), |
76 | }; | 80 | }; |
77 | 81 | ||
82 | static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = { | ||
83 | ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0), | ||
84 | ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1), | ||
85 | ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2), | ||
86 | IIO_CHAN_SOFT_TIMESTAMP(3), | ||
87 | }; | ||
88 | |||
78 | static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | 89 | static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { |
79 | { | 90 | { |
91 | .wai = 0x68, | ||
92 | .int1_addr = 0x0c, | ||
93 | .int2_addr = 0x0d, | ||
94 | .reset_addr = 0x22, | ||
95 | .max_fifo_size = 32, | ||
96 | .id = { | ||
97 | { | ||
98 | .hw_id = ST_LSM9DS1_ID, | ||
99 | .name = ST_LSM9DS1_DEV_NAME, | ||
100 | }, | ||
101 | }, | ||
102 | .channels = { | ||
103 | [ST_LSM6DSX_ID_ACC] = { | ||
104 | .chan = st_lsm6dsx_acc_channels, | ||
105 | .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), | ||
106 | }, | ||
107 | [ST_LSM6DSX_ID_GYRO] = { | ||
108 | .chan = st_lsm6ds0_gyro_channels, | ||
109 | .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels), | ||
110 | }, | ||
111 | }, | ||
112 | .odr_table = { | ||
113 | [ST_LSM6DSX_ID_ACC] = { | ||
114 | .reg = { | ||
115 | .addr = 0x20, | ||
116 | .mask = GENMASK(7, 5), | ||
117 | }, | ||
118 | .odr_avl[0] = { 10, 0x01 }, | ||
119 | .odr_avl[1] = { 50, 0x02 }, | ||
120 | .odr_avl[2] = { 119, 0x03 }, | ||
121 | .odr_avl[3] = { 238, 0x04 }, | ||
122 | .odr_avl[4] = { 476, 0x05 }, | ||
123 | .odr_avl[5] = { 952, 0x06 }, | ||
124 | }, | ||
125 | [ST_LSM6DSX_ID_GYRO] = { | ||
126 | .reg = { | ||
127 | .addr = 0x10, | ||
128 | .mask = GENMASK(7, 5), | ||
129 | }, | ||
130 | .odr_avl[0] = { 15, 0x01 }, | ||
131 | .odr_avl[1] = { 60, 0x02 }, | ||
132 | .odr_avl[2] = { 119, 0x03 }, | ||
133 | .odr_avl[3] = { 238, 0x04 }, | ||
134 | .odr_avl[4] = { 476, 0x05 }, | ||
135 | .odr_avl[5] = { 952, 0x06 }, | ||
136 | }, | ||
137 | }, | ||
138 | .fs_table = { | ||
139 | [ST_LSM6DSX_ID_ACC] = { | ||
140 | .reg = { | ||
141 | .addr = 0x20, | ||
142 | .mask = GENMASK(4, 3), | ||
143 | }, | ||
144 | .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, | ||
145 | .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, | ||
146 | .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, | ||
147 | .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 }, | ||
148 | }, | ||
149 | [ST_LSM6DSX_ID_GYRO] = { | ||
150 | .reg = { | ||
151 | .addr = 0x10, | ||
152 | .mask = GENMASK(4, 3), | ||
153 | }, | ||
154 | .fs_avl[0] = { IIO_DEGREE_TO_RAD(245), 0x0 }, | ||
155 | .fs_avl[1] = { IIO_DEGREE_TO_RAD(500), 0x1 }, | ||
156 | .fs_avl[2] = { IIO_DEGREE_TO_RAD(2000), 0x3 }, | ||
157 | }, | ||
158 | }, | ||
159 | }, | ||
160 | { | ||
80 | .wai = 0x69, | 161 | .wai = 0x69, |
162 | .int1_addr = 0x0d, | ||
163 | .int2_addr = 0x0e, | ||
164 | .reset_addr = 0x12, | ||
81 | .max_fifo_size = 1365, | 165 | .max_fifo_size = 1365, |
82 | .id = { | 166 | .id = { |
83 | { | 167 | { |
@@ -154,6 +238,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
154 | }, | 238 | }, |
155 | }, | 239 | }, |
156 | .fifo_ops = { | 240 | .fifo_ops = { |
241 | .update_fifo = st_lsm6dsx_update_fifo, | ||
157 | .read_fifo = st_lsm6dsx_read_fifo, | 242 | .read_fifo = st_lsm6dsx_read_fifo, |
158 | .fifo_th = { | 243 | .fifo_th = { |
159 | .addr = 0x06, | 244 | .addr = 0x06, |
@@ -186,6 +271,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
186 | }, | 271 | }, |
187 | { | 272 | { |
188 | .wai = 0x69, | 273 | .wai = 0x69, |
274 | .int1_addr = 0x0d, | ||
275 | .int2_addr = 0x0e, | ||
276 | .reset_addr = 0x12, | ||
189 | .max_fifo_size = 682, | 277 | .max_fifo_size = 682, |
190 | .id = { | 278 | .id = { |
191 | { | 279 | { |
@@ -262,6 +350,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
262 | }, | 350 | }, |
263 | }, | 351 | }, |
264 | .fifo_ops = { | 352 | .fifo_ops = { |
353 | .update_fifo = st_lsm6dsx_update_fifo, | ||
265 | .read_fifo = st_lsm6dsx_read_fifo, | 354 | .read_fifo = st_lsm6dsx_read_fifo, |
266 | .fifo_th = { | 355 | .fifo_th = { |
267 | .addr = 0x06, | 356 | .addr = 0x06, |
@@ -294,6 +383,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
294 | }, | 383 | }, |
295 | { | 384 | { |
296 | .wai = 0x6a, | 385 | .wai = 0x6a, |
386 | .int1_addr = 0x0d, | ||
387 | .int2_addr = 0x0e, | ||
388 | .reset_addr = 0x12, | ||
297 | .max_fifo_size = 682, | 389 | .max_fifo_size = 682, |
298 | .id = { | 390 | .id = { |
299 | { | 391 | { |
@@ -379,6 +471,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
379 | }, | 471 | }, |
380 | }, | 472 | }, |
381 | .fifo_ops = { | 473 | .fifo_ops = { |
474 | .update_fifo = st_lsm6dsx_update_fifo, | ||
382 | .read_fifo = st_lsm6dsx_read_fifo, | 475 | .read_fifo = st_lsm6dsx_read_fifo, |
383 | .fifo_th = { | 476 | .fifo_th = { |
384 | .addr = 0x06, | 477 | .addr = 0x06, |
@@ -411,6 +504,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
411 | }, | 504 | }, |
412 | { | 505 | { |
413 | .wai = 0x6c, | 506 | .wai = 0x6c, |
507 | .int1_addr = 0x0d, | ||
508 | .int2_addr = 0x0e, | ||
509 | .reset_addr = 0x12, | ||
414 | .max_fifo_size = 512, | 510 | .max_fifo_size = 512, |
415 | .id = { | 511 | .id = { |
416 | { | 512 | { |
@@ -490,6 +586,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
490 | }, | 586 | }, |
491 | }, | 587 | }, |
492 | .fifo_ops = { | 588 | .fifo_ops = { |
589 | .update_fifo = st_lsm6dsx_update_fifo, | ||
493 | .read_fifo = st_lsm6dsx_read_tagged_fifo, | 590 | .read_fifo = st_lsm6dsx_read_tagged_fifo, |
494 | .fifo_th = { | 591 | .fifo_th = { |
495 | .addr = 0x07, | 592 | .addr = 0x07, |
@@ -497,7 +594,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
497 | }, | 594 | }, |
498 | .fifo_diff = { | 595 | .fifo_diff = { |
499 | .addr = 0x3a, | 596 | .addr = 0x3a, |
500 | .mask = GENMASK(8, 0), | 597 | .mask = GENMASK(9, 0), |
501 | }, | 598 | }, |
502 | .th_wl = 1, | 599 | .th_wl = 1, |
503 | }, | 600 | }, |
@@ -540,6 +637,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
540 | }, | 637 | }, |
541 | { | 638 | { |
542 | .wai = 0x6b, | 639 | .wai = 0x6b, |
640 | .int1_addr = 0x0d, | ||
641 | .int2_addr = 0x0e, | ||
642 | .reset_addr = 0x12, | ||
543 | .max_fifo_size = 512, | 643 | .max_fifo_size = 512, |
544 | .id = { | 644 | .id = { |
545 | { | 645 | { |
@@ -616,6 +716,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
616 | }, | 716 | }, |
617 | }, | 717 | }, |
618 | .fifo_ops = { | 718 | .fifo_ops = { |
719 | .update_fifo = st_lsm6dsx_update_fifo, | ||
619 | .read_fifo = st_lsm6dsx_read_tagged_fifo, | 720 | .read_fifo = st_lsm6dsx_read_tagged_fifo, |
620 | .fifo_th = { | 721 | .fifo_th = { |
621 | .addr = 0x07, | 722 | .addr = 0x07, |
@@ -623,7 +724,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
623 | }, | 724 | }, |
624 | .fifo_diff = { | 725 | .fifo_diff = { |
625 | .addr = 0x3a, | 726 | .addr = 0x3a, |
626 | .mask = GENMASK(8, 0), | 727 | .mask = GENMASK(9, 0), |
627 | }, | 728 | }, |
628 | .th_wl = 1, | 729 | .th_wl = 1, |
629 | }, | 730 | }, |
@@ -640,6 +741,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
640 | }, | 741 | }, |
641 | { | 742 | { |
642 | .wai = 0x6b, | 743 | .wai = 0x6b, |
744 | .int1_addr = 0x0d, | ||
745 | .int2_addr = 0x0e, | ||
746 | .reset_addr = 0x12, | ||
643 | .max_fifo_size = 512, | 747 | .max_fifo_size = 512, |
644 | .id = { | 748 | .id = { |
645 | { | 749 | { |
@@ -719,6 +823,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
719 | }, | 823 | }, |
720 | }, | 824 | }, |
721 | .fifo_ops = { | 825 | .fifo_ops = { |
826 | .update_fifo = st_lsm6dsx_update_fifo, | ||
722 | .read_fifo = st_lsm6dsx_read_tagged_fifo, | 827 | .read_fifo = st_lsm6dsx_read_tagged_fifo, |
723 | .fifo_th = { | 828 | .fifo_th = { |
724 | .addr = 0x07, | 829 | .addr = 0x07, |
@@ -726,7 +831,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
726 | }, | 831 | }, |
727 | .fifo_diff = { | 832 | .fifo_diff = { |
728 | .addr = 0x3a, | 833 | .addr = 0x3a, |
729 | .mask = GENMASK(8, 0), | 834 | .mask = GENMASK(9, 0), |
730 | }, | 835 | }, |
731 | .th_wl = 1, | 836 | .th_wl = 1, |
732 | }, | 837 | }, |
@@ -1090,13 +1195,19 @@ static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, | |||
1090 | char *buf) | 1195 | char *buf) |
1091 | { | 1196 | { |
1092 | struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); | 1197 | struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); |
1198 | const struct st_lsm6dsx_fs_table_entry *fs_table; | ||
1093 | enum st_lsm6dsx_sensor_id id = sensor->id; | 1199 | enum st_lsm6dsx_sensor_id id = sensor->id; |
1094 | struct st_lsm6dsx_hw *hw = sensor->hw; | 1200 | struct st_lsm6dsx_hw *hw = sensor->hw; |
1095 | int i, len = 0; | 1201 | int i, len = 0; |
1096 | 1202 | ||
1097 | for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) | 1203 | fs_table = &hw->settings->fs_table[id]; |
1204 | for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) { | ||
1205 | if (!fs_table->fs_avl[i].gain) | ||
1206 | break; | ||
1207 | |||
1098 | len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", | 1208 | len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", |
1099 | hw->settings->fs_table[id].fs_avl[i].gain); | 1209 | fs_table->fs_avl[i].gain); |
1210 | } | ||
1100 | buf[len - 1] = '\n'; | 1211 | buf[len - 1] = '\n'; |
1101 | 1212 | ||
1102 | return len; | 1213 | return len; |
@@ -1166,10 +1277,10 @@ static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg) | |||
1166 | 1277 | ||
1167 | switch (drdy_pin) { | 1278 | switch (drdy_pin) { |
1168 | case 1: | 1279 | case 1: |
1169 | *drdy_reg = ST_LSM6DSX_REG_INT1_ADDR; | 1280 | *drdy_reg = hw->settings->int1_addr; |
1170 | break; | 1281 | break; |
1171 | case 2: | 1282 | case 2: |
1172 | *drdy_reg = ST_LSM6DSX_REG_INT2_ADDR; | 1283 | *drdy_reg = hw->settings->int2_addr; |
1173 | break; | 1284 | break; |
1174 | default: | 1285 | default: |
1175 | dev_err(hw->dev, "unsupported data ready pin\n"); | 1286 | dev_err(hw->dev, "unsupported data ready pin\n"); |
@@ -1269,7 +1380,7 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) | |||
1269 | int err; | 1380 | int err; |
1270 | 1381 | ||
1271 | /* device sw reset */ | 1382 | /* device sw reset */ |
1272 | err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR, | 1383 | err = regmap_update_bits(hw->regmap, hw->settings->reset_addr, |
1273 | ST_LSM6DSX_REG_RESET_MASK, | 1384 | ST_LSM6DSX_REG_RESET_MASK, |
1274 | FIELD_PREP(ST_LSM6DSX_REG_RESET_MASK, 1)); | 1385 | FIELD_PREP(ST_LSM6DSX_REG_RESET_MASK, 1)); |
1275 | if (err < 0) | 1386 | if (err < 0) |
@@ -1278,7 +1389,7 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) | |||
1278 | msleep(50); | 1389 | msleep(50); |
1279 | 1390 | ||
1280 | /* reload trimming parameter */ | 1391 | /* reload trimming parameter */ |
1281 | err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR, | 1392 | err = regmap_update_bits(hw->regmap, hw->settings->reset_addr, |
1282 | ST_LSM6DSX_REG_BOOT_MASK, | 1393 | ST_LSM6DSX_REG_BOOT_MASK, |
1283 | FIELD_PREP(ST_LSM6DSX_REG_BOOT_MASK, 1)); | 1394 | FIELD_PREP(ST_LSM6DSX_REG_BOOT_MASK, 1)); |
1284 | if (err < 0) | 1395 | if (err < 0) |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 15c6aa5b6caa..f52511059545 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | |||
@@ -83,6 +83,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { | |||
83 | .compatible = "st,ism330dhcx", | 83 | .compatible = "st,ism330dhcx", |
84 | .data = (void *)ST_ISM330DHCX_ID, | 84 | .data = (void *)ST_ISM330DHCX_ID, |
85 | }, | 85 | }, |
86 | { | ||
87 | .compatible = "st,lsm9ds1-imu", | ||
88 | .data = (void *)ST_LSM9DS1_ID, | ||
89 | }, | ||
86 | {}, | 90 | {}, |
87 | }; | 91 | }; |
88 | MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); | 92 | MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match); |
@@ -99,6 +103,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = { | |||
99 | { ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID }, | 103 | { ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID }, |
100 | { ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID }, | 104 | { ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID }, |
101 | { ST_ISM330DHCX_DEV_NAME, ST_ISM330DHCX_ID }, | 105 | { ST_ISM330DHCX_DEV_NAME, ST_ISM330DHCX_ID }, |
106 | { ST_LSM9DS1_DEV_NAME, ST_LSM9DS1_ID }, | ||
102 | {}, | 107 | {}, |
103 | }; | 108 | }; |
104 | MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); | 109 | MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table); |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index a8430ee11310..344b28dddebb 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | |||
@@ -83,6 +83,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = { | |||
83 | .compatible = "st,ism330dhcx", | 83 | .compatible = "st,ism330dhcx", |
84 | .data = (void *)ST_ISM330DHCX_ID, | 84 | .data = (void *)ST_ISM330DHCX_ID, |
85 | }, | 85 | }, |
86 | { | ||
87 | .compatible = "st,lsm9ds1-imu", | ||
88 | .data = (void *)ST_LSM9DS1_ID, | ||
89 | }, | ||
86 | {}, | 90 | {}, |
87 | }; | 91 | }; |
88 | MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); | 92 | MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match); |
@@ -99,6 +103,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = { | |||
99 | { ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID }, | 103 | { ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID }, |
100 | { ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID }, | 104 | { ST_LSM6DS3TRC_DEV_NAME, ST_LSM6DS3TRC_ID }, |
101 | { ST_ISM330DHCX_DEV_NAME, ST_ISM330DHCX_ID }, | 105 | { ST_ISM330DHCX_DEV_NAME, ST_ISM330DHCX_ID }, |
106 | { ST_LSM9DS1_DEV_NAME, ST_LSM9DS1_ID }, | ||
102 | {}, | 107 | {}, |
103 | }; | 108 | }; |
104 | MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); | 109 | MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table); |
diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig index 6b5cce6f1a7b..d53601447da4 100644 --- a/drivers/iio/proximity/Kconfig +++ b/drivers/iio/proximity/Kconfig | |||
@@ -62,7 +62,7 @@ config RFD77402 | |||
62 | tristate "RFD77402 ToF sensor" | 62 | tristate "RFD77402 ToF sensor" |
63 | depends on I2C | 63 | depends on I2C |
64 | help | 64 | help |
65 | Say Y to build a driver for the RFD77420 Time-of-Flight (distance) | 65 | Say Y to build a driver for the RFD77402 Time-of-Flight (distance) |
66 | sensor module with I2C interface. | 66 | sensor module with I2C interface. |
67 | 67 | ||
68 | To compile this driver as a module, choose M here: the | 68 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/staging/iio/accel/adis16240.c b/drivers/staging/iio/accel/adis16240.c index 62f4b3b1b457..82099db4bf0c 100644 --- a/drivers/staging/iio/accel/adis16240.c +++ b/drivers/staging/iio/accel/adis16240.c | |||
@@ -309,15 +309,12 @@ static int adis16240_write_raw(struct iio_dev *indio_dev, | |||
309 | long mask) | 309 | long mask) |
310 | { | 310 | { |
311 | struct adis *st = iio_priv(indio_dev); | 311 | struct adis *st = iio_priv(indio_dev); |
312 | int bits = 10; | ||
313 | s16 val16; | ||
314 | u8 addr; | 312 | u8 addr; |
315 | 313 | ||
316 | switch (mask) { | 314 | switch (mask) { |
317 | case IIO_CHAN_INFO_CALIBBIAS: | 315 | case IIO_CHAN_INFO_CALIBBIAS: |
318 | val16 = val & ((1 << bits) - 1); | ||
319 | addr = adis16240_addresses[chan->scan_index][0]; | 316 | addr = adis16240_addresses[chan->scan_index][0]; |
320 | return adis_write_reg_16(st, addr, val16); | 317 | return adis_write_reg_16(st, addr, val & GENMASK(9, 0)); |
321 | } | 318 | } |
322 | return -EINVAL; | 319 | return -EINVAL; |
323 | } | 320 | } |
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index df06e0570f9b..e6b660489165 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c | |||
@@ -25,8 +25,6 @@ | |||
25 | #include <linux/iio/triggered_buffer.h> | 25 | #include <linux/iio/triggered_buffer.h> |
26 | #include <linux/iio/adc/ad_sigma_delta.h> | 26 | #include <linux/iio/adc/ad_sigma_delta.h> |
27 | 27 | ||
28 | #include "ad7192.h" | ||
29 | |||
30 | /* Registers */ | 28 | /* Registers */ |
31 | #define AD7192_REG_COMM 0 /* Communications Register (WO, 8-bit) */ | 29 | #define AD7192_REG_COMM 0 /* Communications Register (WO, 8-bit) */ |
32 | #define AD7192_REG_STAT 0 /* Status Register (RO, 8-bit) */ | 30 | #define AD7192_REG_STAT 0 /* Status Register (RO, 8-bit) */ |
@@ -145,6 +143,10 @@ | |||
145 | #define AD7192_EXT_FREQ_MHZ_MAX 5120000 | 143 | #define AD7192_EXT_FREQ_MHZ_MAX 5120000 |
146 | #define AD7192_INT_FREQ_MHZ 4915200 | 144 | #define AD7192_INT_FREQ_MHZ 4915200 |
147 | 145 | ||
146 | #define AD7192_NO_SYNC_FILTER 1 | ||
147 | #define AD7192_SYNC3_FILTER 3 | ||
148 | #define AD7192_SYNC4_FILTER 4 | ||
149 | |||
148 | /* NOTE: | 150 | /* NOTE: |
149 | * The AD7190/2/5 features a dual use data out ready DOUT/RDY output. | 151 | * The AD7190/2/5 features a dual use data out ready DOUT/RDY output. |
150 | * In order to avoid contentions on the SPI bus, it's therefore necessary | 152 | * 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) | |||
252 | static int ad7192_setup(struct ad7192_state *st, struct device_node *np) | 254 | static int ad7192_setup(struct ad7192_state *st, struct device_node *np) |
253 | { | 255 | { |
254 | struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi); | 256 | struct iio_dev *indio_dev = spi_get_drvdata(st->sd.spi); |
255 | bool rej60_en, sinc3_en, refin2_en, chop_en; | 257 | bool rej60_en, refin2_en; |
256 | bool buf_en, bipolar, burnout_curr_en; | 258 | bool buf_en, bipolar, burnout_curr_en; |
257 | unsigned long long scale_uv; | 259 | unsigned long long scale_uv; |
258 | int i, ret, id; | 260 | int i, ret, id; |
@@ -284,24 +286,12 @@ static int ad7192_setup(struct ad7192_state *st, struct device_node *np) | |||
284 | if (rej60_en) | 286 | if (rej60_en) |
285 | st->mode |= AD7192_MODE_REJ60; | 287 | st->mode |= AD7192_MODE_REJ60; |
286 | 288 | ||
287 | sinc3_en = of_property_read_bool(np, "adi,sinc3-filter-enable"); | ||
288 | if (sinc3_en) | ||
289 | st->mode |= AD7192_MODE_SINC3; | ||
290 | |||
291 | refin2_en = of_property_read_bool(np, "adi,refin2-pins-enable"); | 289 | refin2_en = of_property_read_bool(np, "adi,refin2-pins-enable"); |
292 | if (refin2_en && st->devid != ID_AD7195) | 290 | if (refin2_en && st->devid != ID_AD7195) |
293 | st->conf |= AD7192_CONF_REFSEL; | 291 | st->conf |= AD7192_CONF_REFSEL; |
294 | 292 | ||
295 | chop_en = of_property_read_bool(np, "adi,chop-enable"); | 293 | st->conf &= ~AD7192_CONF_CHOP; |
296 | if (chop_en) { | 294 | st->f_order = AD7192_NO_SYNC_FILTER; |
297 | st->conf |= AD7192_CONF_CHOP; | ||
298 | if (sinc3_en) | ||
299 | st->f_order = 3; /* SINC 3rd order */ | ||
300 | else | ||
301 | st->f_order = 4; /* SINC 4th order */ | ||
302 | } else { | ||
303 | st->f_order = 1; | ||
304 | } | ||
305 | 295 | ||
306 | buf_en = of_property_read_bool(np, "adi,buffer-enable"); | 296 | buf_en = of_property_read_bool(np, "adi,buffer-enable"); |
307 | if (buf_en) | 297 | if (buf_en) |
@@ -313,7 +303,7 @@ static int ad7192_setup(struct ad7192_state *st, struct device_node *np) | |||
313 | 303 | ||
314 | burnout_curr_en = of_property_read_bool(np, | 304 | burnout_curr_en = of_property_read_bool(np, |
315 | "adi,burnout-currents-enable"); | 305 | "adi,burnout-currents-enable"); |
316 | if (burnout_curr_en && buf_en && !chop_en) { | 306 | if (burnout_curr_en && buf_en) { |
317 | st->conf |= AD7192_CONF_BURN; | 307 | st->conf |= AD7192_CONF_BURN; |
318 | } else if (burnout_curr_en) { | 308 | } else if (burnout_curr_en) { |
319 | dev_warn(&st->sd.spi->dev, | 309 | dev_warn(&st->sd.spi->dev, |
@@ -411,6 +401,49 @@ static ssize_t ad7192_set(struct device *dev, | |||
411 | return ret ? ret : len; | 401 | return ret ? ret : len; |
412 | } | 402 | } |
413 | 403 | ||
404 | static void ad7192_get_available_filter_freq(struct ad7192_state *st, | ||
405 | int *freq) | ||
406 | { | ||
407 | unsigned int fadc; | ||
408 | |||
409 | /* Formulas for filter at page 25 of the datasheet */ | ||
410 | fadc = DIV_ROUND_CLOSEST(st->fclk, | ||
411 | AD7192_SYNC4_FILTER * AD7192_MODE_RATE(st->mode)); | ||
412 | freq[0] = DIV_ROUND_CLOSEST(fadc * 240, 1024); | ||
413 | |||
414 | fadc = DIV_ROUND_CLOSEST(st->fclk, | ||
415 | AD7192_SYNC3_FILTER * AD7192_MODE_RATE(st->mode)); | ||
416 | freq[1] = DIV_ROUND_CLOSEST(fadc * 240, 1024); | ||
417 | |||
418 | fadc = DIV_ROUND_CLOSEST(st->fclk, AD7192_MODE_RATE(st->mode)); | ||
419 | freq[2] = DIV_ROUND_CLOSEST(fadc * 230, 1024); | ||
420 | freq[3] = DIV_ROUND_CLOSEST(fadc * 272, 1024); | ||
421 | } | ||
422 | |||
423 | static ssize_t ad7192_show_filter_avail(struct device *dev, | ||
424 | struct device_attribute *attr, | ||
425 | char *buf) | ||
426 | { | ||
427 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | ||
428 | struct ad7192_state *st = iio_priv(indio_dev); | ||
429 | unsigned int freq_avail[4], i; | ||
430 | size_t len = 0; | ||
431 | |||
432 | ad7192_get_available_filter_freq(st, freq_avail); | ||
433 | |||
434 | for (i = 0; i < ARRAY_SIZE(freq_avail); i++) | ||
435 | len += scnprintf(buf + len, PAGE_SIZE - len, | ||
436 | "%d.%d ", freq_avail[i] / 1000, | ||
437 | freq_avail[i] % 1000); | ||
438 | |||
439 | buf[len - 1] = '\n'; | ||
440 | |||
441 | return len; | ||
442 | } | ||
443 | |||
444 | static IIO_DEVICE_ATTR(filter_low_pass_3db_frequency_available, | ||
445 | 0444, ad7192_show_filter_avail, NULL, 0); | ||
446 | |||
414 | static IIO_DEVICE_ATTR(bridge_switch_en, 0644, | 447 | static IIO_DEVICE_ATTR(bridge_switch_en, 0644, |
415 | ad7192_show_bridge_switch, ad7192_set, | 448 | ad7192_show_bridge_switch, ad7192_set, |
416 | AD7192_REG_GPOCON); | 449 | AD7192_REG_GPOCON); |
@@ -420,6 +453,7 @@ static IIO_DEVICE_ATTR(ac_excitation_en, 0644, | |||
420 | AD7192_REG_MODE); | 453 | AD7192_REG_MODE); |
421 | 454 | ||
422 | static struct attribute *ad7192_attributes[] = { | 455 | static struct attribute *ad7192_attributes[] = { |
456 | &iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr, | ||
423 | &iio_dev_attr_bridge_switch_en.dev_attr.attr, | 457 | &iio_dev_attr_bridge_switch_en.dev_attr.attr, |
424 | &iio_dev_attr_ac_excitation_en.dev_attr.attr, | 458 | &iio_dev_attr_ac_excitation_en.dev_attr.attr, |
425 | NULL | 459 | NULL |
@@ -430,6 +464,7 @@ static const struct attribute_group ad7192_attribute_group = { | |||
430 | }; | 464 | }; |
431 | 465 | ||
432 | static struct attribute *ad7195_attributes[] = { | 466 | static struct attribute *ad7195_attributes[] = { |
467 | &iio_dev_attr_filter_low_pass_3db_frequency_available.dev_attr.attr, | ||
433 | &iio_dev_attr_bridge_switch_en.dev_attr.attr, | 468 | &iio_dev_attr_bridge_switch_en.dev_attr.attr, |
434 | NULL | 469 | NULL |
435 | }; | 470 | }; |
@@ -443,6 +478,75 @@ static unsigned int ad7192_get_temp_scale(bool unipolar) | |||
443 | return unipolar ? 2815 * 2 : 2815; | 478 | return unipolar ? 2815 * 2 : 2815; |
444 | } | 479 | } |
445 | 480 | ||
481 | static int ad7192_set_3db_filter_freq(struct ad7192_state *st, | ||
482 | int val, int val2) | ||
483 | { | ||
484 | int freq_avail[4], i, ret, freq; | ||
485 | unsigned int diff_new, diff_old; | ||
486 | int idx = 0; | ||
487 | |||
488 | diff_old = U32_MAX; | ||
489 | freq = val * 1000 + val2; | ||
490 | |||
491 | ad7192_get_available_filter_freq(st, freq_avail); | ||
492 | |||
493 | for (i = 0; i < ARRAY_SIZE(freq_avail); i++) { | ||
494 | diff_new = abs(freq - freq_avail[i]); | ||
495 | if (diff_new < diff_old) { | ||
496 | diff_old = diff_new; | ||
497 | idx = i; | ||
498 | } | ||
499 | } | ||
500 | |||
501 | switch (idx) { | ||
502 | case 0: | ||
503 | st->f_order = AD7192_SYNC4_FILTER; | ||
504 | st->mode &= ~AD7192_MODE_SINC3; | ||
505 | |||
506 | st->conf |= AD7192_CONF_CHOP; | ||
507 | break; | ||
508 | case 1: | ||
509 | st->f_order = AD7192_SYNC3_FILTER; | ||
510 | st->mode |= AD7192_MODE_SINC3; | ||
511 | |||
512 | st->conf |= AD7192_CONF_CHOP; | ||
513 | break; | ||
514 | case 2: | ||
515 | st->f_order = AD7192_NO_SYNC_FILTER; | ||
516 | st->mode &= ~AD7192_MODE_SINC3; | ||
517 | |||
518 | st->conf &= ~AD7192_CONF_CHOP; | ||
519 | break; | ||
520 | case 3: | ||
521 | st->f_order = AD7192_NO_SYNC_FILTER; | ||
522 | st->mode |= AD7192_MODE_SINC3; | ||
523 | |||
524 | st->conf &= ~AD7192_CONF_CHOP; | ||
525 | break; | ||
526 | } | ||
527 | |||
528 | ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); | ||
529 | if (ret < 0) | ||
530 | return ret; | ||
531 | |||
532 | return ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, st->conf); | ||
533 | } | ||
534 | |||
535 | static int ad7192_get_3db_filter_freq(struct ad7192_state *st) | ||
536 | { | ||
537 | unsigned int fadc; | ||
538 | |||
539 | fadc = DIV_ROUND_CLOSEST(st->fclk, | ||
540 | st->f_order * AD7192_MODE_RATE(st->mode)); | ||
541 | |||
542 | if (st->conf & AD7192_CONF_CHOP) | ||
543 | return DIV_ROUND_CLOSEST(fadc * 240, 1024); | ||
544 | if (st->mode & AD7192_MODE_SINC3) | ||
545 | return DIV_ROUND_CLOSEST(fadc * 272, 1024); | ||
546 | else | ||
547 | return DIV_ROUND_CLOSEST(fadc * 230, 1024); | ||
548 | } | ||
549 | |||
446 | static int ad7192_read_raw(struct iio_dev *indio_dev, | 550 | static int ad7192_read_raw(struct iio_dev *indio_dev, |
447 | struct iio_chan_spec const *chan, | 551 | struct iio_chan_spec const *chan, |
448 | int *val, | 552 | int *val, |
@@ -483,6 +587,10 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, | |||
483 | *val = st->fclk / | 587 | *val = st->fclk / |
484 | (st->f_order * 1024 * AD7192_MODE_RATE(st->mode)); | 588 | (st->f_order * 1024 * AD7192_MODE_RATE(st->mode)); |
485 | return IIO_VAL_INT; | 589 | return IIO_VAL_INT; |
590 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | ||
591 | *val = ad7192_get_3db_filter_freq(st); | ||
592 | *val2 = 1000; | ||
593 | return IIO_VAL_FRACTIONAL; | ||
486 | } | 594 | } |
487 | 595 | ||
488 | return -EINVAL; | 596 | return -EINVAL; |
@@ -537,6 +645,9 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, | |||
537 | st->mode |= AD7192_MODE_RATE(div); | 645 | st->mode |= AD7192_MODE_RATE(div); |
538 | ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); | 646 | ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode); |
539 | break; | 647 | break; |
648 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | ||
649 | ret = ad7192_set_3db_filter_freq(st, val, val2 / 1000); | ||
650 | break; | ||
540 | default: | 651 | default: |
541 | ret = -EINVAL; | 652 | ret = -EINVAL; |
542 | } | 653 | } |
@@ -555,6 +666,8 @@ static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev, | |||
555 | return IIO_VAL_INT_PLUS_NANO; | 666 | return IIO_VAL_INT_PLUS_NANO; |
556 | case IIO_CHAN_INFO_SAMP_FREQ: | 667 | case IIO_CHAN_INFO_SAMP_FREQ: |
557 | return IIO_VAL_INT; | 668 | return IIO_VAL_INT; |
669 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | ||
670 | return IIO_VAL_INT_PLUS_MICRO; | ||
558 | default: | 671 | default: |
559 | return -EINVAL; | 672 | return -EINVAL; |
560 | } | 673 | } |
@@ -655,6 +768,8 @@ static int ad7192_channels_config(struct iio_dev *indio_dev) | |||
655 | 768 | ||
656 | for (i = 0; i < indio_dev->num_channels; i++) { | 769 | for (i = 0; i < indio_dev->num_channels; i++) { |
657 | *chan = channels[i]; | 770 | *chan = channels[i]; |
771 | chan->info_mask_shared_by_all |= | ||
772 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY); | ||
658 | if (chan->type != IIO_TEMP) | 773 | if (chan->type != IIO_TEMP) |
659 | chan->info_mask_shared_by_type_available |= | 774 | chan->info_mask_shared_by_type_available |= |
660 | BIT(IIO_CHAN_INFO_SCALE); | 775 | BIT(IIO_CHAN_INFO_SCALE); |
@@ -666,16 +781,10 @@ static int ad7192_channels_config(struct iio_dev *indio_dev) | |||
666 | 781 | ||
667 | static int ad7192_probe(struct spi_device *spi) | 782 | static int ad7192_probe(struct spi_device *spi) |
668 | { | 783 | { |
669 | const struct ad7192_platform_data *pdata = dev_get_platdata(&spi->dev); | ||
670 | struct ad7192_state *st; | 784 | struct ad7192_state *st; |
671 | struct iio_dev *indio_dev; | 785 | struct iio_dev *indio_dev; |
672 | int ret, voltage_uv = 0; | 786 | int ret, voltage_uv = 0; |
673 | 787 | ||
674 | if (!pdata) { | ||
675 | dev_err(&spi->dev, "no platform data?\n"); | ||
676 | return -ENODEV; | ||
677 | } | ||
678 | |||
679 | if (!spi->irq) { | 788 | if (!spi->irq) { |
680 | dev_err(&spi->dev, "no IRQ?\n"); | 789 | dev_err(&spi->dev, "no IRQ?\n"); |
681 | return -ENODEV; | 790 | return -ENODEV; |
@@ -713,12 +822,10 @@ static int ad7192_probe(struct spi_device *spi) | |||
713 | 822 | ||
714 | voltage_uv = regulator_get_voltage(st->avdd); | 823 | voltage_uv = regulator_get_voltage(st->avdd); |
715 | 824 | ||
716 | if (pdata->vref_mv) | 825 | if (voltage_uv) |
717 | st->int_vref_mv = pdata->vref_mv; | ||
718 | else if (voltage_uv) | ||
719 | st->int_vref_mv = voltage_uv / 1000; | 826 | st->int_vref_mv = voltage_uv / 1000; |
720 | else | 827 | else |
721 | dev_warn(&spi->dev, "reference voltage undefined\n"); | 828 | dev_err(&spi->dev, "Device tree error, reference voltage undefined\n"); |
722 | 829 | ||
723 | spi_set_drvdata(spi, indio_dev); | 830 | spi_set_drvdata(spi, indio_dev); |
724 | st->devid = spi_get_device_id(spi)->driver_data; | 831 | st->devid = spi_get_device_id(spi)->driver_data; |
diff --git a/drivers/staging/iio/adc/ad7192.h b/drivers/staging/iio/adc/ad7192.h deleted file mode 100644 index f3669e1df084..000000000000 --- a/drivers/staging/iio/adc/ad7192.h +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * AD7190 AD7192 AD7195 SPI ADC driver | ||
4 | * | ||
5 | * Copyright 2011 Analog Devices Inc. | ||
6 | */ | ||
7 | #ifndef IIO_ADC_AD7192_H_ | ||
8 | #define IIO_ADC_AD7192_H_ | ||
9 | |||
10 | /* | ||
11 | * TODO: struct ad7192_platform_data needs to go into include/linux/iio | ||
12 | */ | ||
13 | |||
14 | /** | ||
15 | * struct ad7192_platform_data - platform/board specific information | ||
16 | * @vref_mv: the external reference voltage in millivolt | ||
17 | * @clock_source_sel: [0..3] | ||
18 | * 0 External 4.92 MHz clock connected from MCLK1 to MCLK2 | ||
19 | * 1 External Clock applied to MCLK2 | ||
20 | * 2 Internal 4.92 MHz Clock not available at the MCLK2 pin | ||
21 | * 3 Internal 4.92 MHz Clock available at the MCLK2 pin | ||
22 | * @ext_clk_Hz: the external clock frequency in Hz, if not set | ||
23 | * the driver uses the internal clock (16.776 MHz) | ||
24 | * @refin2_en: REFIN1/REFIN2 Reference Select (AD7190/2 only) | ||
25 | * @rej60_en: 50/60Hz notch filter enable | ||
26 | * @sinc3_en: SINC3 filter enable (default SINC4) | ||
27 | * @chop_en: CHOP mode enable | ||
28 | * @buf_en: buffered input mode enable | ||
29 | * @unipolar_en: unipolar mode enable | ||
30 | * @burnout_curr_en: constant current generators on AIN(+|-) enable | ||
31 | */ | ||
32 | |||
33 | struct ad7192_platform_data { | ||
34 | u16 vref_mv; | ||
35 | }; | ||
36 | |||
37 | #endif /* IIO_ADC_AD7192_H_ */ | ||
diff --git a/tools/iio/.gitignore b/tools/iio/.gitignore new file mode 100644 index 000000000000..3758202618bd --- /dev/null +++ b/tools/iio/.gitignore | |||
@@ -0,0 +1,4 @@ | |||
1 | iio_event_monitor | ||
2 | iio_generic_buffer | ||
3 | lsiio | ||
4 | include/ | ||