diff options
58 files changed, 2705 insertions, 467 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 6aef7dbbde44..680451695422 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio | |||
@@ -61,8 +61,11 @@ What: /sys/bus/iio/devices/triggerX/sampling_frequency_available | |||
61 | KernelVersion: 2.6.35 | 61 | KernelVersion: 2.6.35 |
62 | Contact: linux-iio@vger.kernel.org | 62 | Contact: linux-iio@vger.kernel.org |
63 | Description: | 63 | Description: |
64 | When the internal sampling clock can only take a small | 64 | When the internal sampling clock can only take a specific set of |
65 | discrete set of values, this file lists those available. | 65 | frequencies, we can specify the available values with: |
66 | - a small discrete set of values like "0 2 4 6 8" | ||
67 | - a range with minimum, step and maximum frequencies like | ||
68 | "[min step max]" | ||
66 | 69 | ||
67 | What: /sys/bus/iio/devices/iio:deviceX/oversampling_ratio | 70 | What: /sys/bus/iio/devices/iio:deviceX/oversampling_ratio |
68 | KernelVersion: 2.6.38 | 71 | KernelVersion: 2.6.38 |
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4371 b/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4371 new file mode 100644 index 000000000000..302de64cb424 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-frequency-adf4371 | |||
@@ -0,0 +1,44 @@ | |||
1 | What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency | ||
2 | KernelVersion: | ||
3 | Contact: linux-iio@vger.kernel.org | ||
4 | Description: | ||
5 | Stores the PLL frequency in Hz for channel Y. | ||
6 | Reading returns the actual frequency in Hz. | ||
7 | The ADF4371 has an integrated VCO with fundamendal output | ||
8 | frequency ranging from 4000000000 Hz 8000000000 Hz. | ||
9 | |||
10 | out_altvoltage0_frequency: | ||
11 | A divide by 1, 2, 4, 8, 16, 32 or circuit generates | ||
12 | frequencies from 62500000 Hz to 8000000000 Hz. | ||
13 | out_altvoltage1_frequency: | ||
14 | This channel duplicates the channel 0 frequency | ||
15 | out_altvoltage2_frequency: | ||
16 | A frequency doubler generates frequencies from | ||
17 | 8000000000 Hz to 16000000000 Hz. | ||
18 | out_altvoltage3_frequency: | ||
19 | A frequency quadrupler generates frequencies from | ||
20 | 16000000000 Hz to 32000000000 Hz. | ||
21 | |||
22 | Note: writes to one of the channels will affect the frequency of | ||
23 | all the other channels, since it involves changing the VCO | ||
24 | fundamental output frequency. | ||
25 | |||
26 | What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_name | ||
27 | KernelVersion: | ||
28 | Contact: linux-iio@vger.kernel.org | ||
29 | Description: | ||
30 | Reading returns the datasheet name for channel Y: | ||
31 | |||
32 | out_altvoltage0_name: RF8x | ||
33 | out_altvoltage1_name: RFAUX8x | ||
34 | out_altvoltage2_name: RF16x | ||
35 | out_altvoltage3_name: RF32x | ||
36 | |||
37 | What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown | ||
38 | KernelVersion: | ||
39 | Contact: linux-iio@vger.kernel.org | ||
40 | Description: | ||
41 | This attribute allows the user to power down the PLL and it's | ||
42 | RFOut buffers. | ||
43 | Writing 1 causes the specified channel to power down. | ||
44 | Clearing returns to normal operation. | ||
diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml new file mode 100644 index 000000000000..a7fafb9bf5c6 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml | |||
@@ -0,0 +1,63 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | %YAML 1.2 | ||
3 | --- | ||
4 | $id: http://devicetree.org/schemas/iio/accelerometers/adi,adxl372.yaml# | ||
5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
6 | |||
7 | title: Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer | ||
8 | |||
9 | maintainers: | ||
10 | - Stefan Popa <stefan.popa@analog.com> | ||
11 | |||
12 | description: | | ||
13 | Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer that supports | ||
14 | both I2C & SPI interfaces | ||
15 | https://www.analog.com/en/products/adxl372.html | ||
16 | |||
17 | properties: | ||
18 | compatible: | ||
19 | enum: | ||
20 | - adi,adxl372 | ||
21 | |||
22 | reg: | ||
23 | maxItems: 1 | ||
24 | |||
25 | interrupts: | ||
26 | maxItems: 1 | ||
27 | |||
28 | required: | ||
29 | - compatible | ||
30 | - reg | ||
31 | - interrupts | ||
32 | |||
33 | examples: | ||
34 | - | | ||
35 | #include <dt-bindings/gpio/gpio.h> | ||
36 | #include <dt-bindings/interrupt-controller/irq.h> | ||
37 | i2c0 { | ||
38 | #address-cells = <1>; | ||
39 | #size-cells = <0>; | ||
40 | |||
41 | /* Example for a I2C device node */ | ||
42 | accelerometer@53 { | ||
43 | compatible = "adi,adxl372"; | ||
44 | reg = <0x53>; | ||
45 | interrupt-parent = <&gpio>; | ||
46 | interrupts = <25 IRQ_TYPE_EDGE_FALLING>; | ||
47 | }; | ||
48 | }; | ||
49 | - | | ||
50 | #include <dt-bindings/gpio/gpio.h> | ||
51 | #include <dt-bindings/interrupt-controller/irq.h> | ||
52 | spi0 { | ||
53 | #address-cells = <1>; | ||
54 | #size-cells = <0>; | ||
55 | |||
56 | accelerometer@0 { | ||
57 | compatible = "adi,adxl372"; | ||
58 | reg = <0>; | ||
59 | spi-max-frequency = <1000000>; | ||
60 | interrupt-parent = <&gpio>; | ||
61 | interrupts = <25 IRQ_TYPE_EDGE_FALLING>; | ||
62 | }; | ||
63 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/accel/adxl372.txt b/Documentation/devicetree/bindings/iio/accel/adxl372.txt deleted file mode 100644 index a289964756a7..000000000000 --- a/Documentation/devicetree/bindings/iio/accel/adxl372.txt +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer | ||
2 | |||
3 | http://www.analog.com/media/en/technical-documentation/data-sheets/adxl372.pdf | ||
4 | |||
5 | Required properties: | ||
6 | - compatible : should be "adi,adxl372" | ||
7 | - reg: the I2C address or SPI chip select number for the device | ||
8 | |||
9 | Required properties for SPI bus usage: | ||
10 | - spi-max-frequency: Max SPI frequency to use | ||
11 | |||
12 | Optional properties: | ||
13 | - interrupts: interrupt mapping for IRQ as documented in | ||
14 | Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | ||
15 | |||
16 | Example for a I2C device node: | ||
17 | |||
18 | accelerometer@53 { | ||
19 | compatible = "adi,adxl372"; | ||
20 | reg = <0x53>; | ||
21 | interrupt-parent = <&gpio>; | ||
22 | interrupts = <25 IRQ_TYPE_EDGE_FALLING>; | ||
23 | }; | ||
24 | |||
25 | Example for a SPI device node: | ||
26 | |||
27 | accelerometer@0 { | ||
28 | compatible = "adi,adxl372"; | ||
29 | reg = <0>; | ||
30 | spi-max-frequency = <1000000>; | ||
31 | interrupt-parent = <&gpio>; | ||
32 | interrupts = <25 IRQ_TYPE_EDGE_FALLING>; | ||
33 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7124.txt b/Documentation/devicetree/bindings/iio/adc/adi,ad7124.txt deleted file mode 100644 index 416273dce569..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7124.txt +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | Analog Devices AD7124 ADC device driver | ||
2 | |||
3 | Required properties for the AD7124: | ||
4 | - compatible: Must be one of "adi,ad7124-4" or "adi,ad7124-8" | ||
5 | - reg: SPI chip select number for the device | ||
6 | - spi-max-frequency: Max SPI frequency to use | ||
7 | see: Documentation/devicetree/bindings/spi/spi-bus.txt | ||
8 | - clocks: phandle to the master clock (mclk) | ||
9 | see: Documentation/devicetree/bindings/clock/clock-bindings.txt | ||
10 | - clock-names: Must be "mclk". | ||
11 | - interrupts: IRQ line for the ADC | ||
12 | see: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | ||
13 | |||
14 | Required properties: | ||
15 | * #address-cells: Must be 1. | ||
16 | * #size-cells: Must be 0. | ||
17 | |||
18 | Subnode(s) represent the external channels which are connected to the ADC. | ||
19 | Each subnode represents one channel and has the following properties: | ||
20 | Required properties: | ||
21 | * reg: The channel number. It can have up to 4 channels on ad7124-4 | ||
22 | and 8 channels on ad7124-8, numbered from 0 to 15. | ||
23 | * diff-channels: see: Documentation/devicetree/bindings/iio/adc/adc.txt | ||
24 | |||
25 | Optional properties: | ||
26 | * bipolar: see: Documentation/devicetree/bindings/iio/adc/adc.txt | ||
27 | * adi,reference-select: Select the reference source to use when | ||
28 | converting on the the specific channel. Valid values are: | ||
29 | 0: REFIN1(+)/REFIN1(−). | ||
30 | 1: REFIN2(+)/REFIN2(−). | ||
31 | 3: AVDD | ||
32 | If this field is left empty, internal reference is selected. | ||
33 | |||
34 | Optional properties: | ||
35 | - refin1-supply: refin1 supply can be used as reference for conversion. | ||
36 | - refin2-supply: refin2 supply can be used as reference for conversion. | ||
37 | - avdd-supply: avdd supply can be used as reference for conversion. | ||
38 | |||
39 | Example: | ||
40 | adc@0 { | ||
41 | compatible = "adi,ad7124-4"; | ||
42 | reg = <0>; | ||
43 | spi-max-frequency = <5000000>; | ||
44 | interrupts = <25 2>; | ||
45 | interrupt-parent = <&gpio>; | ||
46 | refin1-supply = <&adc_vref>; | ||
47 | clocks = <&ad7124_mclk>; | ||
48 | clock-names = "mclk"; | ||
49 | |||
50 | #address-cells = <1>; | ||
51 | #size-cells = <0>; | ||
52 | |||
53 | channel@0 { | ||
54 | reg = <0>; | ||
55 | diff-channels = <0 1>; | ||
56 | adi,reference-select = <0>; | ||
57 | }; | ||
58 | |||
59 | channel@1 { | ||
60 | reg = <1>; | ||
61 | bipolar; | ||
62 | diff-channels = <2 3>; | ||
63 | adi,reference-select = <0>; | ||
64 | }; | ||
65 | |||
66 | channel@2 { | ||
67 | reg = <2>; | ||
68 | diff-channels = <4 5>; | ||
69 | }; | ||
70 | |||
71 | channel@3 { | ||
72 | reg = <3>; | ||
73 | diff-channels = <6 7>; | ||
74 | }; | ||
75 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml new file mode 100644 index 000000000000..cf494a08b837 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml | |||
@@ -0,0 +1,155 @@ | |||
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,ad7124.yaml# | ||
6 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
7 | |||
8 | title: Analog Devices AD7124 ADC device driver | ||
9 | |||
10 | maintainers: | ||
11 | - Stefan Popa <stefan.popa@analog.com> | ||
12 | |||
13 | description: | | ||
14 | Bindings for the Analog Devices AD7124 ADC device. Datasheet can be | ||
15 | found here: | ||
16 | https://www.analog.com/media/en/technical-documentation/data-sheets/AD7124-8.pdf | ||
17 | |||
18 | properties: | ||
19 | compatible: | ||
20 | enum: | ||
21 | - adi,ad7124-4 | ||
22 | - adi,ad7124-8 | ||
23 | |||
24 | reg: | ||
25 | description: SPI chip select number for the device | ||
26 | maxItems: 1 | ||
27 | |||
28 | clocks: | ||
29 | maxItems: 1 | ||
30 | description: phandle to the master clock (mclk) | ||
31 | |||
32 | clock-names: | ||
33 | items: | ||
34 | - const: mclk | ||
35 | |||
36 | interrupts: | ||
37 | description: IRQ line for the ADC | ||
38 | maxItems: 1 | ||
39 | |||
40 | '#address-cells': | ||
41 | const: 1 | ||
42 | |||
43 | '#size-cells': | ||
44 | const: 0 | ||
45 | |||
46 | refin1-supply: | ||
47 | description: refin1 supply can be used as reference for conversion. | ||
48 | maxItems: 1 | ||
49 | |||
50 | refin2-supply: | ||
51 | description: refin2 supply can be used as reference for conversion. | ||
52 | maxItems: 1 | ||
53 | |||
54 | avdd-supply: | ||
55 | description: avdd supply can be used as reference for conversion. | ||
56 | maxItems: 1 | ||
57 | |||
58 | required: | ||
59 | - compatible | ||
60 | - reg | ||
61 | - clocks | ||
62 | - clock-names | ||
63 | - interrupts | ||
64 | |||
65 | patternProperties: | ||
66 | "^channel@([0-9]|1[0-5])$": | ||
67 | type: object | ||
68 | description: | | ||
69 | Represents the external channels which are connected to the ADC. | ||
70 | See Documentation/devicetree/bindings/iio/adc/adc.txt. | ||
71 | |||
72 | properties: | ||
73 | reg: | ||
74 | description: | | ||
75 | The channel number. It can have up to 8 channels on ad7124-4 | ||
76 | and 16 channels on ad7124-8, numbered from 0 to 15. | ||
77 | items: | ||
78 | minimum: 0 | ||
79 | maximum: 15 | ||
80 | |||
81 | adi,reference-select: | ||
82 | description: | | ||
83 | Select the reference source to use when converting on | ||
84 | the specific channel. Valid values are: | ||
85 | 0: REFIN1(+)/REFIN1(−). | ||
86 | 1: REFIN2(+)/REFIN2(−). | ||
87 | 3: AVDD | ||
88 | If this field is left empty, internal reference is selected. | ||
89 | allOf: | ||
90 | - $ref: /schemas/types.yaml#/definitions/uint32 | ||
91 | - enum: [0, 1, 3] | ||
92 | |||
93 | diff-channels: | ||
94 | description: see Documentation/devicetree/bindings/iio/adc/adc.txt | ||
95 | items: | ||
96 | minimum: 0 | ||
97 | maximum: 15 | ||
98 | |||
99 | bipolar: | ||
100 | description: see Documentation/devicetree/bindings/iio/adc/adc.txt | ||
101 | type: boolean | ||
102 | |||
103 | adi,buffered-positive: | ||
104 | description: Enable buffered mode for positive input. | ||
105 | type: boolean | ||
106 | |||
107 | adi,buffered-negative: | ||
108 | description: Enable buffered mode for negative input. | ||
109 | type: boolean | ||
110 | |||
111 | required: | ||
112 | - reg | ||
113 | - diff-channels | ||
114 | |||
115 | examples: | ||
116 | - | | ||
117 | adc@0 { | ||
118 | compatible = "adi,ad7124-4"; | ||
119 | reg = <0>; | ||
120 | spi-max-frequency = <5000000>; | ||
121 | interrupts = <25 2>; | ||
122 | interrupt-parent = <&gpio>; | ||
123 | refin1-supply = <&adc_vref>; | ||
124 | clocks = <&ad7124_mclk>; | ||
125 | clock-names = "mclk"; | ||
126 | |||
127 | #address-cells = <1>; | ||
128 | #size-cells = <0>; | ||
129 | |||
130 | channel@0 { | ||
131 | reg = <0>; | ||
132 | diff-channels = <0 1>; | ||
133 | adi,reference-select = <0>; | ||
134 | adi,buffered-positive; | ||
135 | }; | ||
136 | |||
137 | channel@1 { | ||
138 | reg = <1>; | ||
139 | bipolar; | ||
140 | diff-channels = <2 3>; | ||
141 | adi,reference-select = <0>; | ||
142 | adi,buffered-positive; | ||
143 | adi,buffered-negative; | ||
144 | }; | ||
145 | |||
146 | channel@2 { | ||
147 | reg = <2>; | ||
148 | diff-channels = <4 5>; | ||
149 | }; | ||
150 | |||
151 | channel@3 { | ||
152 | reg = <3>; | ||
153 | diff-channels = <6 7>; | ||
154 | }; | ||
155 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7780.txt b/Documentation/devicetree/bindings/iio/adc/adi,ad7780.txt deleted file mode 100644 index 440e52555349..000000000000 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7780.txt +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | * Analog Devices AD7170/AD7171/AD7780/AD7781 | ||
2 | |||
3 | Data sheets: | ||
4 | |||
5 | - AD7170: | ||
6 | * https://www.analog.com/media/en/technical-documentation/data-sheets/AD7170.pdf | ||
7 | - AD7171: | ||
8 | * https://www.analog.com/media/en/technical-documentation/data-sheets/AD7171.pdf | ||
9 | - AD7780: | ||
10 | * https://www.analog.com/media/en/technical-documentation/data-sheets/ad7780.pdf | ||
11 | - AD7781: | ||
12 | * https://www.analog.com/media/en/technical-documentation/data-sheets/AD7781.pdf | ||
13 | |||
14 | Required properties: | ||
15 | |||
16 | - compatible: should be one of | ||
17 | * "adi,ad7170" | ||
18 | * "adi,ad7171" | ||
19 | * "adi,ad7780" | ||
20 | * "adi,ad7781" | ||
21 | - reg: spi chip select number for the device | ||
22 | - vref-supply: the regulator supply for the ADC reference voltage | ||
23 | |||
24 | Optional properties: | ||
25 | |||
26 | - powerdown-gpios: must be the device tree identifier of the PDRST pin. If | ||
27 | specified, it will be asserted during driver probe. As the | ||
28 | line is active high, it should be marked GPIO_ACTIVE_HIGH. | ||
29 | - adi,gain-gpios: must be the device tree identifier of the GAIN pin. Only for | ||
30 | the ad778x chips. If specified, it will be asserted during | ||
31 | driver probe. As the line is active low, it should be marked | ||
32 | GPIO_ACTIVE_LOW. | ||
33 | - adi,filter-gpios: must be the device tree identifier of the FILTER pin. Only | ||
34 | for the ad778x chips. If specified, it will be asserted | ||
35 | during driver probe. As the line is active low, it should be | ||
36 | marked GPIO_ACTIVE_LOW. | ||
37 | |||
38 | Example: | ||
39 | |||
40 | adc@0 { | ||
41 | compatible = "adi,ad7780"; | ||
42 | reg = <0>; | ||
43 | vref-supply = <&vdd_supply> | ||
44 | |||
45 | powerdown-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>; | ||
46 | adi,gain-gpios = <&gpio 5 GPIO_ACTIVE_LOW>; | ||
47 | adi,filter-gpios = <&gpio 15 GPIO_ACTIVE_LOW>; | ||
48 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml new file mode 100644 index 000000000000..d1109416963c --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml | |||
@@ -0,0 +1,87 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | %YAML 1.2 | ||
3 | --- | ||
4 | $id: http://devicetree.org/schemas/iio/adc/adi,ad7780.yaml# | ||
5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
6 | |||
7 | title: Analog Devices AD7170/AD7171/AD7780/AD7781 analog to digital converters | ||
8 | |||
9 | maintainers: | ||
10 | - Michael Hennerich <michael.hennerich@analog.com> | ||
11 | |||
12 | description: | | ||
13 | The ad7780 is a sigma-delta analog to digital converter. This driver provides | ||
14 | reading voltage values and status bits from both the ad778x and ad717x series. | ||
15 | Its interface also allows writing on the FILTER and GAIN GPIO pins on the | ||
16 | ad778x. | ||
17 | |||
18 | Specifications on the converters can be found at: | ||
19 | AD7170: | ||
20 | https://www.analog.com/media/en/technical-documentation/data-sheets/AD7170.pdf | ||
21 | AD7171: | ||
22 | https://www.analog.com/media/en/technical-documentation/data-sheets/AD7171.pdf | ||
23 | AD7780: | ||
24 | https://www.analog.com/media/en/technical-documentation/data-sheets/ad7780.pdf | ||
25 | AD7781: | ||
26 | https://www.analog.com/media/en/technical-documentation/data-sheets/AD7781.pdf | ||
27 | |||
28 | properties: | ||
29 | compatible: | ||
30 | enum: | ||
31 | - adi,ad7170 | ||
32 | - adi,ad7171 | ||
33 | - adi,ad7780 | ||
34 | - adi,ad7781 | ||
35 | |||
36 | reg: | ||
37 | maxItems: 1 | ||
38 | |||
39 | avdd-supply: | ||
40 | description: | ||
41 | The regulator supply for the ADC reference voltage. | ||
42 | maxItems: 1 | ||
43 | |||
44 | powerdown-gpios: | ||
45 | description: | ||
46 | Must be the device tree identifier of the PDRST pin. If | ||
47 | specified, it will be asserted during driver probe. As the | ||
48 | line is active high, it should be marked GPIO_ACTIVE_HIGH. | ||
49 | maxItems: 1 | ||
50 | |||
51 | adi,gain-gpios: | ||
52 | description: | ||
53 | Must be the device tree identifier of the GAIN pin. Only for | ||
54 | the ad778x chips. If specified, it will be asserted during | ||
55 | driver probe. As the line is active low, it should be marked | ||
56 | GPIO_ACTIVE_LOW. | ||
57 | maxItems: 1 | ||
58 | |||
59 | adi,filter-gpios: | ||
60 | description: | ||
61 | Must be the device tree identifier of the FILTER pin. Only | ||
62 | for the ad778x chips. If specified, it will be asserted | ||
63 | during driver probe. As the line is active low, it should be | ||
64 | marked GPIO_ACTIVE_LOW. | ||
65 | maxItems: 1 | ||
66 | |||
67 | required: | ||
68 | - compatible | ||
69 | - reg | ||
70 | |||
71 | examples: | ||
72 | - | | ||
73 | #include <dt-bindings/gpio/gpio.h> | ||
74 | spi0 { | ||
75 | #address-cells = <1>; | ||
76 | #size-cells = <0>; | ||
77 | |||
78 | adc@0 { | ||
79 | compatible = "adi,ad7780"; | ||
80 | reg = <0>; | ||
81 | |||
82 | avdd-supply = <&vdd_supply>; | ||
83 | powerdown-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; | ||
84 | adi,gain-gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; | ||
85 | adi,filter-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>; | ||
86 | }; | ||
87 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt index 8346bcb04ad7..93a0bd2efc05 100644 --- a/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-adc.txt | |||
@@ -38,6 +38,7 @@ Required properties: | |||
38 | It's required on stm32h7. | 38 | It's required on stm32h7. |
39 | - clock-names: Must be "adc" and/or "bus" depending on part used. | 39 | - clock-names: Must be "adc" and/or "bus" depending on part used. |
40 | - interrupt-controller: Identifies the controller node as interrupt-parent | 40 | - interrupt-controller: Identifies the controller node as interrupt-parent |
41 | - vdda-supply: Phandle to the vdda input analog voltage. | ||
41 | - vref-supply: Phandle to the vref input analog reference voltage. | 42 | - vref-supply: Phandle to the vref input analog reference voltage. |
42 | - #interrupt-cells = <1>; | 43 | - #interrupt-cells = <1>; |
43 | - #address-cells = <1>; | 44 | - #address-cells = <1>; |
diff --git a/Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.txt b/Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.txt deleted file mode 100644 index 6eee2709b5b6..000000000000 --- a/Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.txt +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | * Sensirion SPS30 particulate matter sensor | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: must be "sensirion,sps30" | ||
5 | - reg: the I2C address of the sensor | ||
6 | |||
7 | Example: | ||
8 | |||
9 | sps30@69 { | ||
10 | compatible = "sensirion,sps30"; | ||
11 | reg = <0x69>; | ||
12 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.yaml b/Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.yaml new file mode 100644 index 000000000000..50a50a0d7070 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.yaml | |||
@@ -0,0 +1,39 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | %YAML 1.2 | ||
3 | --- | ||
4 | $id: http://devicetree.org/schemas/iio/chemical/sensirion,sps30.yaml# | ||
5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
6 | |||
7 | title: Sensirion SPS30 particulate matter sensor | ||
8 | |||
9 | maintainers: | ||
10 | - Tomasz Duszynski <tduszyns@gmail.com> | ||
11 | |||
12 | description: | | ||
13 | Air pollution sensor capable of measuring mass concentration of dust | ||
14 | particles. | ||
15 | |||
16 | properties: | ||
17 | compatible: | ||
18 | enum: | ||
19 | - sensirion,sps30 | ||
20 | reg: | ||
21 | maxItems: 1 | ||
22 | |||
23 | required: | ||
24 | - compatible | ||
25 | - reg | ||
26 | |||
27 | examples: | ||
28 | - | | ||
29 | i2c { | ||
30 | #address-cells = <1>; | ||
31 | #size-cells = <0>; | ||
32 | |||
33 | air-pollution-sensor@69 { | ||
34 | compatible = "sensirion,sps30"; | ||
35 | reg = <0x69>; | ||
36 | }; | ||
37 | }; | ||
38 | |||
39 | ... | ||
diff --git a/Documentation/devicetree/bindings/iio/frequency/adf4371.yaml b/Documentation/devicetree/bindings/iio/frequency/adf4371.yaml new file mode 100644 index 000000000000..7ec3ec94356b --- /dev/null +++ b/Documentation/devicetree/bindings/iio/frequency/adf4371.yaml | |||
@@ -0,0 +1,63 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | %YAML 1.2 | ||
3 | --- | ||
4 | $id: http://devicetree.org/schemas/iio/frequency/adf4371.yaml# | ||
5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
6 | |||
7 | title: Analog Devices ADF4371/ADF4372 Wideband Synthesizers | ||
8 | |||
9 | maintainers: | ||
10 | - Popa Stefan <stefan.popa@analog.com> | ||
11 | |||
12 | description: | | ||
13 | Analog Devices ADF4371/ADF4372 SPI Wideband Synthesizers | ||
14 | https://www.analog.com/media/en/technical-documentation/data-sheets/adf4371.pdf | ||
15 | https://www.analog.com/media/en/technical-documentation/data-sheets/adf4372.pdf | ||
16 | |||
17 | properties: | ||
18 | compatible: | ||
19 | enum: | ||
20 | - adi,adf4371 | ||
21 | - adi,adf4372 | ||
22 | |||
23 | reg: | ||
24 | maxItems: 1 | ||
25 | |||
26 | clocks: | ||
27 | description: | ||
28 | Definition of the external clock (see clock/clock-bindings.txt) | ||
29 | maxItems: 1 | ||
30 | |||
31 | clock-names: | ||
32 | description: | ||
33 | Must be "clkin" | ||
34 | maxItems: 1 | ||
35 | |||
36 | adi,mute-till-lock-en: | ||
37 | type: boolean | ||
38 | description: | ||
39 | If this property is present, then the supply current to RF8P and RF8N | ||
40 | output stage will shut down until the ADF4371/ADF4372 achieves lock as | ||
41 | measured by the digital lock detect circuitry. | ||
42 | |||
43 | required: | ||
44 | - compatible | ||
45 | - reg | ||
46 | - clocks | ||
47 | - clock-names | ||
48 | |||
49 | examples: | ||
50 | - | | ||
51 | spi0 { | ||
52 | #address-cells = <1>; | ||
53 | #size-cells = <0>; | ||
54 | |||
55 | frequency@0 { | ||
56 | compatible = "adi,adf4371"; | ||
57 | reg = <0>; | ||
58 | spi-max-frequency = <1000000>; | ||
59 | clocks = <&adf4371_clkin>; | ||
60 | clock-names = "clkin"; | ||
61 | }; | ||
62 | }; | ||
63 | ... | ||
diff --git a/Documentation/iio/ep93xx_adc.txt b/Documentation/iio/ep93xx_adc.rst index 23053e7817bd..4fd8dea3f6b8 100644 --- a/Documentation/iio/ep93xx_adc.txt +++ b/Documentation/iio/ep93xx_adc.rst | |||
@@ -1,12 +1,16 @@ | |||
1 | Cirrus Logic EP93xx ADC driver. | 1 | ============================== |
2 | Cirrus Logic EP93xx ADC driver | ||
3 | ============================== | ||
2 | 4 | ||
3 | 1. Overview | 5 | 1. Overview |
6 | =========== | ||
4 | 7 | ||
5 | The driver is intended to work on both low-end (EP9301, EP9302) devices with | 8 | The driver is intended to work on both low-end (EP9301, EP9302) devices with |
6 | 5-channel ADC and high-end (EP9307, EP9312, EP9315) devices with 10-channel | 9 | 5-channel ADC and high-end (EP9307, EP9312, EP9315) devices with 10-channel |
7 | touchscreen/ADC module. | 10 | touchscreen/ADC module. |
8 | 11 | ||
9 | 2. Channel numbering | 12 | 2. Channel numbering |
13 | ==================== | ||
10 | 14 | ||
11 | Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets. | 15 | Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets. |
12 | EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is | 16 | EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is |
@@ -17,13 +21,20 @@ Assuming ep93xx_adc is IIO device0, you'd find the following entries under | |||
17 | 21 | ||
18 | +-----------------+---------------+ | 22 | +-----------------+---------------+ |
19 | | sysfs entry | ball/pin name | | 23 | | sysfs entry | ball/pin name | |
20 | +-----------------+---------------+ | 24 | +=================+===============+ |
21 | | in_voltage0_raw | YM | | 25 | | in_voltage0_raw | YM | |
26 | +-----------------+---------------+ | ||
22 | | in_voltage1_raw | SXP | | 27 | | in_voltage1_raw | SXP | |
28 | +-----------------+---------------+ | ||
23 | | in_voltage2_raw | SXM | | 29 | | in_voltage2_raw | SXM | |
30 | +-----------------+---------------+ | ||
24 | | in_voltage3_raw | SYP | | 31 | | in_voltage3_raw | SYP | |
32 | +-----------------+---------------+ | ||
25 | | in_voltage4_raw | SYM | | 33 | | in_voltage4_raw | SYM | |
34 | +-----------------+---------------+ | ||
26 | | in_voltage5_raw | XP | | 35 | | in_voltage5_raw | XP | |
36 | +-----------------+---------------+ | ||
27 | | in_voltage6_raw | XM | | 37 | | in_voltage6_raw | XM | |
38 | +-----------------+---------------+ | ||
28 | | in_voltage7_raw | YP | | 39 | | in_voltage7_raw | YP | |
29 | +-----------------+---------------+ | 40 | +-----------------+---------------+ |
diff --git a/Documentation/iio/iio_configfs.txt b/Documentation/iio/iio_configfs.rst index 4e5f101837a8..ecbfdb3afef7 100644 --- a/Documentation/iio/iio_configfs.txt +++ b/Documentation/iio/iio_configfs.rst | |||
@@ -1,6 +1,9 @@ | |||
1 | =============================== | ||
1 | Industrial IIO configfs support | 2 | Industrial IIO configfs support |
3 | =============================== | ||
2 | 4 | ||
3 | 1. Overview | 5 | 1. Overview |
6 | =========== | ||
4 | 7 | ||
5 | Configfs is a filesystem-based manager of kernel objects. IIO uses some | 8 | Configfs is a filesystem-based manager of kernel objects. IIO uses some |
6 | objects that could be easily configured using configfs (e.g.: devices, | 9 | objects that could be easily configured using configfs (e.g.: devices, |
@@ -10,20 +13,22 @@ See Documentation/filesystems/configfs/configfs.txt for more information | |||
10 | about how configfs works. | 13 | about how configfs works. |
11 | 14 | ||
12 | 2. Usage | 15 | 2. Usage |
16 | ======== | ||
13 | 17 | ||
14 | In order to use configfs support in IIO we need to select it at compile | 18 | In order to use configfs support in IIO we need to select it at compile |
15 | time via CONFIG_IIO_CONFIGFS config option. | 19 | time via CONFIG_IIO_CONFIGFS config option. |
16 | 20 | ||
17 | Then, mount the configfs filesystem (usually under /config directory): | 21 | Then, mount the configfs filesystem (usually under /config directory):: |
18 | 22 | ||
19 | $ mkdir /config | 23 | $ mkdir /config |
20 | $ mount -t configfs none /config | 24 | $ mount -t configfs none /config |
21 | 25 | ||
22 | At this point, all default IIO groups will be created and can be accessed | 26 | At this point, all default IIO groups will be created and can be accessed |
23 | under /config/iio. Next chapters will describe available IIO configuration | 27 | under /config/iio. Next chapters will describe available IIO configuration |
24 | objects. | 28 | objects. |
25 | 29 | ||
26 | 3. Software triggers | 30 | 3. Software triggers |
31 | ==================== | ||
27 | 32 | ||
28 | One of the IIO default configfs groups is the "triggers" group. It is | 33 | One of the IIO default configfs groups is the "triggers" group. It is |
29 | automagically accessible when the configfs is mounted and can be found | 34 | automagically accessible when the configfs is mounted and can be found |
@@ -31,40 +36,40 @@ under /config/iio/triggers. | |||
31 | 36 | ||
32 | IIO software triggers implementation offers support for creating multiple | 37 | IIO software triggers implementation offers support for creating multiple |
33 | trigger types. A new trigger type is usually implemented as a separate | 38 | trigger types. A new trigger type is usually implemented as a separate |
34 | kernel module following the interface in include/linux/iio/sw_trigger.h: | 39 | kernel module following the interface in include/linux/iio/sw_trigger.h:: |
35 | 40 | ||
36 | /* | 41 | /* |
37 | * drivers/iio/trigger/iio-trig-sample.c | 42 | * drivers/iio/trigger/iio-trig-sample.c |
38 | * sample kernel module implementing a new trigger type | 43 | * sample kernel module implementing a new trigger type |
39 | */ | 44 | */ |
40 | #include <linux/iio/sw_trigger.h> | 45 | #include <linux/iio/sw_trigger.h> |
41 | 46 | ||
42 | 47 | ||
43 | static struct iio_sw_trigger *iio_trig_sample_probe(const char *name) | 48 | static struct iio_sw_trigger *iio_trig_sample_probe(const char *name) |
44 | { | 49 | { |
45 | /* | 50 | /* |
46 | * This allocates and registers an IIO trigger plus other | 51 | * This allocates and registers an IIO trigger plus other |
47 | * trigger type specific initialization. | 52 | * trigger type specific initialization. |
48 | */ | 53 | */ |
49 | } | 54 | } |
50 | 55 | ||
51 | static int iio_trig_hrtimer_remove(struct iio_sw_trigger *swt) | 56 | static int iio_trig_hrtimer_remove(struct iio_sw_trigger *swt) |
52 | { | 57 | { |
53 | /* | 58 | /* |
54 | * This undoes the actions in iio_trig_sample_probe | 59 | * This undoes the actions in iio_trig_sample_probe |
55 | */ | 60 | */ |
56 | } | 61 | } |
57 | 62 | ||
58 | static const struct iio_sw_trigger_ops iio_trig_sample_ops = { | 63 | static const struct iio_sw_trigger_ops iio_trig_sample_ops = { |
59 | .probe = iio_trig_sample_probe, | 64 | .probe = iio_trig_sample_probe, |
60 | .remove = iio_trig_sample_remove, | 65 | .remove = iio_trig_sample_remove, |
61 | }; | 66 | }; |
62 | 67 | ||
63 | static struct iio_sw_trigger_type iio_trig_sample = { | 68 | static struct iio_sw_trigger_type iio_trig_sample = { |
64 | .name = "trig-sample", | 69 | .name = "trig-sample", |
65 | .owner = THIS_MODULE, | 70 | .owner = THIS_MODULE, |
66 | .ops = &iio_trig_sample_ops, | 71 | .ops = &iio_trig_sample_ops, |
67 | }; | 72 | }; |
68 | 73 | ||
69 | module_iio_sw_trigger_driver(iio_trig_sample); | 74 | module_iio_sw_trigger_driver(iio_trig_sample); |
70 | 75 | ||
@@ -73,21 +78,24 @@ iio-trig-sample module will create 'trig-sample' trigger type directory | |||
73 | /config/iio/triggers/trig-sample. | 78 | /config/iio/triggers/trig-sample. |
74 | 79 | ||
75 | We support the following interrupt sources (trigger types): | 80 | We support the following interrupt sources (trigger types): |
81 | |||
76 | * hrtimer, uses high resolution timers as interrupt source | 82 | * hrtimer, uses high resolution timers as interrupt source |
77 | 83 | ||
78 | 3.1 Hrtimer triggers creation and destruction | 84 | 3.1 Hrtimer triggers creation and destruction |
85 | --------------------------------------------- | ||
79 | 86 | ||
80 | Loading iio-trig-hrtimer module will register hrtimer trigger types allowing | 87 | Loading iio-trig-hrtimer module will register hrtimer trigger types allowing |
81 | users to create hrtimer triggers under /config/iio/triggers/hrtimer. | 88 | users to create hrtimer triggers under /config/iio/triggers/hrtimer. |
82 | 89 | ||
83 | e.g: | 90 | e.g:: |
84 | 91 | ||
85 | $ mkdir /config/iio/triggers/hrtimer/instance1 | 92 | $ mkdir /config/iio/triggers/hrtimer/instance1 |
86 | $ rmdir /config/iio/triggers/hrtimer/instance1 | 93 | $ rmdir /config/iio/triggers/hrtimer/instance1 |
87 | 94 | ||
88 | Each trigger can have one or more attributes specific to the trigger type. | 95 | Each trigger can have one or more attributes specific to the trigger type. |
89 | 96 | ||
90 | 3.2 "hrtimer" trigger types attributes | 97 | 3.2 "hrtimer" trigger types attributes |
98 | -------------------------------------- | ||
91 | 99 | ||
92 | "hrtimer" trigger type doesn't have any configurable attribute from /config dir. | 100 | "hrtimer" trigger type doesn't have any configurable attribute from /config dir. |
93 | It does introduce the sampling_frequency attribute to trigger directory. | 101 | It does introduce the sampling_frequency attribute to trigger directory. |
diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst new file mode 100644 index 000000000000..0593dca89a94 --- /dev/null +++ b/Documentation/iio/index.rst | |||
@@ -0,0 +1,12 @@ | |||
1 | :orphan: | ||
2 | |||
3 | ============== | ||
4 | Industrial I/O | ||
5 | ============== | ||
6 | |||
7 | .. toctree:: | ||
8 | :maxdepth: 1 | ||
9 | |||
10 | iio_configfs | ||
11 | |||
12 | ep93xx_adc | ||
diff --git a/MAINTAINERS b/MAINTAINERS index aab4f97b5b2f..c0a02dccc869 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -560,7 +560,7 @@ S: Supported | |||
560 | F: drivers/iio/accel/adxl372.c | 560 | F: drivers/iio/accel/adxl372.c |
561 | F: drivers/iio/accel/adxl372_spi.c | 561 | F: drivers/iio/accel/adxl372_spi.c |
562 | F: drivers/iio/accel/adxl372_i2c.c | 562 | F: drivers/iio/accel/adxl372_i2c.c |
563 | F: Documentation/devicetree/bindings/iio/accel/adxl372.txt | 563 | F: Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml |
564 | 564 | ||
565 | AF9013 MEDIA DRIVER | 565 | AF9013 MEDIA DRIVER |
566 | M: Antti Palosaari <crope@iki.fi> | 566 | M: Antti Palosaari <crope@iki.fi> |
@@ -910,6 +910,15 @@ S: Supported | |||
910 | F: drivers/iio/adc/ad7768-1.c | 910 | F: drivers/iio/adc/ad7768-1.c |
911 | F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt | 911 | F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.txt |
912 | 912 | ||
913 | ANALOG DEVICES INC AD7780 DRIVER | ||
914 | M: Michael Hennerich <Michael.Hennerich@analog.com> | ||
915 | M: Renato Lui Geh <renatogeh@gmail.com> | ||
916 | L: linux-iio@vger.kernel.org | ||
917 | W: http://ez.analog.com/community/linux-device-drivers | ||
918 | S: Supported | ||
919 | F: drivers/iio/adc/ad7780.c | ||
920 | F: Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml | ||
921 | |||
913 | ANALOG DEVICES INC AD9389B DRIVER | 922 | ANALOG DEVICES INC AD9389B DRIVER |
914 | M: Hans Verkuil <hans.verkuil@cisco.com> | 923 | M: Hans Verkuil <hans.verkuil@cisco.com> |
915 | L: linux-media@vger.kernel.org | 924 | L: linux-media@vger.kernel.org |
@@ -922,6 +931,13 @@ S: Supported | |||
922 | F: drivers/mux/adgs1408.c | 931 | F: drivers/mux/adgs1408.c |
923 | F: Documentation/devicetree/bindings/mux/adi,adgs1408.txt | 932 | F: Documentation/devicetree/bindings/mux/adi,adgs1408.txt |
924 | 933 | ||
934 | ANALOG DEVICES INC ADIS DRIVER LIBRARY | ||
935 | M: Alexandru Ardelean <alexandru.ardelean@analog.com> | ||
936 | S: Supported | ||
937 | L: linux-iio@vger.kernel.org | ||
938 | F: include/linux/iio/imu/adis.h | ||
939 | F: drivers/iio/imu/adis.c | ||
940 | |||
925 | ANALOG DEVICES INC ADP5061 DRIVER | 941 | ANALOG DEVICES INC ADP5061 DRIVER |
926 | M: Stefan Popa <stefan.popa@analog.com> | 942 | M: Stefan Popa <stefan.popa@analog.com> |
927 | L: linux-pm@vger.kernel.org | 943 | L: linux-pm@vger.kernel.org |
@@ -6219,6 +6235,14 @@ M: Philip Kelleher <pjk1939@linux.ibm.com> | |||
6219 | S: Maintained | 6235 | S: Maintained |
6220 | F: drivers/block/rsxx/ | 6236 | F: drivers/block/rsxx/ |
6221 | 6237 | ||
6238 | FLEXTIMER FTM-QUADDEC DRIVER | ||
6239 | M: Patrick Havelange <patrick.havelange@essensium.com> | ||
6240 | L: linux-iio@vger.kernel.org | ||
6241 | S: Maintained | ||
6242 | F: Documentation/ABI/testing/sysfs-bus-counter-ftm-quadddec | ||
6243 | F: Documentation/devicetree/bindings/counter/ftm-quaddec.txt | ||
6244 | F: drivers/counter/ftm-quaddec.c | ||
6245 | |||
6222 | FLOPPY DRIVER | 6246 | FLOPPY DRIVER |
6223 | M: Jiri Kosina <jikos@kernel.org> | 6247 | M: Jiri Kosina <jikos@kernel.org> |
6224 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git | 6248 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git |
@@ -7773,6 +7797,12 @@ W: http://industrypack.sourceforge.net | |||
7773 | S: Maintained | 7797 | S: Maintained |
7774 | F: drivers/ipack/ | 7798 | F: drivers/ipack/ |
7775 | 7799 | ||
7800 | INFINEON DPS310 Driver | ||
7801 | M: Eddie James <eajames@linux.ibm.com> | ||
7802 | L: linux-iio@vger.kernel.org | ||
7803 | F: drivers/iio/pressure/dps310.c | ||
7804 | S: Maintained | ||
7805 | |||
7776 | INFINIBAND SUBSYSTEM | 7806 | INFINIBAND SUBSYSTEM |
7777 | M: Doug Ledford <dledford@redhat.com> | 7807 | M: Doug Ledford <dledford@redhat.com> |
7778 | M: Jason Gunthorpe <jgg@mellanox.com> | 7808 | M: Jason Gunthorpe <jgg@mellanox.com> |
@@ -14161,6 +14191,12 @@ S: Maintained | |||
14161 | F: drivers/misc/phantom.c | 14191 | F: drivers/misc/phantom.c |
14162 | F: include/uapi/linux/phantom.h | 14192 | F: include/uapi/linux/phantom.h |
14163 | 14193 | ||
14194 | SENSIRION SPS30 AIR POLLUTION SENSOR DRIVER | ||
14195 | M: Tomasz Duszynski <tduszyns@gmail.com> | ||
14196 | S: Maintained | ||
14197 | F: drivers/iio/chemical/sps30.c | ||
14198 | F: Documentation/devicetree/bindings/iio/chemical/sensirion,sps30.yaml | ||
14199 | |||
14164 | SERIAL DEVICE BUS | 14200 | SERIAL DEVICE BUS |
14165 | M: Rob Herring <robh@kernel.org> | 14201 | M: Rob Herring <robh@kernel.org> |
14166 | L: linux-serial@vger.kernel.org | 14202 | L: linux-serial@vger.kernel.org |
diff --git a/drivers/counter/ftm-quaddec.c b/drivers/counter/ftm-quaddec.c index c83c8875bf82..68a9b7393457 100644 --- a/drivers/counter/ftm-quaddec.c +++ b/drivers/counter/ftm-quaddec.c | |||
@@ -352,5 +352,5 @@ static struct platform_driver ftm_quaddec_driver = { | |||
352 | module_platform_driver(ftm_quaddec_driver); | 352 | module_platform_driver(ftm_quaddec_driver); |
353 | 353 | ||
354 | MODULE_LICENSE("GPL"); | 354 | MODULE_LICENSE("GPL"); |
355 | MODULE_AUTHOR("Kjeld Flarup <kfa@deif.com"); | 355 | MODULE_AUTHOR("Kjeld Flarup <kfa@deif.com>"); |
356 | MODULE_AUTHOR("Patrick Havelange <patrick.havelange@essensium.com"); | 356 | MODULE_AUTHOR("Patrick Havelange <patrick.havelange@essensium.com>"); |
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 1d736a4952ab..5bd51853b15e 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig | |||
@@ -28,7 +28,7 @@ config IIO_CONFIGFS | |||
28 | help | 28 | help |
29 | This allows configuring various IIO bits through configfs | 29 | This allows configuring various IIO bits through configfs |
30 | (e.g. software triggers). For more info see | 30 | (e.g. software triggers). For more info see |
31 | Documentation/iio/iio_configfs.txt. | 31 | Documentation/iio/iio_configfs.rst. |
32 | 32 | ||
33 | config IIO_TRIGGER | 33 | config IIO_TRIGGER |
34 | bool "Enable triggered sampling support" | 34 | bool "Enable triggered sampling support" |
diff --git a/drivers/iio/accel/adis16201.c b/drivers/iio/accel/adis16201.c index 0af4b289fc63..c4810c73b2a2 100644 --- a/drivers/iio/accel/adis16201.c +++ b/drivers/iio/accel/adis16201.c | |||
@@ -70,7 +70,7 @@ | |||
70 | #define ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT 2 | 70 | #define ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT 2 |
71 | /* Power supply above 3.625 V */ | 71 | /* Power supply above 3.625 V */ |
72 | #define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1 | 72 | #define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1 |
73 | /* Power supply below 3.15 V */ | 73 | /* Power supply below 2.975 V */ |
74 | #define ADIS16201_DIAG_STAT_POWER_LOW_BIT 0 | 74 | #define ADIS16201_DIAG_STAT_POWER_LOW_BIT 0 |
75 | 75 | ||
76 | /* System Command Register Definition */ | 76 | /* System Command Register Definition */ |
@@ -230,7 +230,7 @@ static const char * const adis16201_status_error_msgs[] = { | |||
230 | [ADIS16201_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", | 230 | [ADIS16201_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", |
231 | [ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed", | 231 | [ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed", |
232 | [ADIS16201_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", | 232 | [ADIS16201_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", |
233 | [ADIS16201_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", | 233 | [ADIS16201_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V", |
234 | }; | 234 | }; |
235 | 235 | ||
236 | static const struct adis_data adis16201_data = { | 236 | static const struct adis_data adis16201_data = { |
diff --git a/drivers/iio/accel/adis16209.c b/drivers/iio/accel/adis16209.c index 40be7adfa1f2..98d77af8a2b0 100644 --- a/drivers/iio/accel/adis16209.c +++ b/drivers/iio/accel/adis16209.c | |||
@@ -72,7 +72,7 @@ | |||
72 | #define ADIS16209_STAT_FLASH_UPT_FAIL_BIT 2 | 72 | #define ADIS16209_STAT_FLASH_UPT_FAIL_BIT 2 |
73 | /* Power supply above 3.625 V */ | 73 | /* Power supply above 3.625 V */ |
74 | #define ADIS16209_STAT_POWER_HIGH_BIT 1 | 74 | #define ADIS16209_STAT_POWER_HIGH_BIT 1 |
75 | /* Power supply below 3.15 V */ | 75 | /* Power supply below 2.975 V */ |
76 | #define ADIS16209_STAT_POWER_LOW_BIT 0 | 76 | #define ADIS16209_STAT_POWER_LOW_BIT 0 |
77 | 77 | ||
78 | #define ADIS16209_CMD_REG 0x3E | 78 | #define ADIS16209_CMD_REG 0x3E |
@@ -240,7 +240,7 @@ static const char * const adis16209_status_error_msgs[] = { | |||
240 | [ADIS16209_STAT_SPI_FAIL_BIT] = "SPI failure", | 240 | [ADIS16209_STAT_SPI_FAIL_BIT] = "SPI failure", |
241 | [ADIS16209_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed", | 241 | [ADIS16209_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed", |
242 | [ADIS16209_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", | 242 | [ADIS16209_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", |
243 | [ADIS16209_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", | 243 | [ADIS16209_STAT_POWER_LOW_BIT] = "Power supply below 2.975V", |
244 | }; | 244 | }; |
245 | 245 | ||
246 | static const struct adis_data adis16209_data = { | 246 | static const struct adis_data adis16209_data = { |
diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index 3b84cb243a87..055227cb3d43 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c | |||
@@ -782,10 +782,14 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) | |||
782 | unsigned int mask; | 782 | unsigned int mask; |
783 | int i, ret; | 783 | int i, ret; |
784 | 784 | ||
785 | ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0); | 785 | ret = iio_triggered_buffer_postenable(indio_dev); |
786 | if (ret < 0) | 786 | if (ret < 0) |
787 | return ret; | 787 | return ret; |
788 | 788 | ||
789 | ret = adxl372_set_interrupts(st, ADXL372_INT1_MAP_FIFO_FULL_MSK, 0); | ||
790 | if (ret < 0) | ||
791 | goto err; | ||
792 | |||
789 | mask = *indio_dev->active_scan_mask; | 793 | mask = *indio_dev->active_scan_mask; |
790 | 794 | ||
791 | for (i = 0; i < ARRAY_SIZE(adxl372_axis_lookup_table); i++) { | 795 | for (i = 0; i < ARRAY_SIZE(adxl372_axis_lookup_table); i++) { |
@@ -793,8 +797,10 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) | |||
793 | break; | 797 | break; |
794 | } | 798 | } |
795 | 799 | ||
796 | if (i == ARRAY_SIZE(adxl372_axis_lookup_table)) | 800 | if (i == ARRAY_SIZE(adxl372_axis_lookup_table)) { |
797 | return -EINVAL; | 801 | ret = -EINVAL; |
802 | goto err; | ||
803 | } | ||
798 | 804 | ||
799 | st->fifo_format = adxl372_axis_lookup_table[i].fifo_format; | 805 | st->fifo_format = adxl372_axis_lookup_table[i].fifo_format; |
800 | st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask, | 806 | st->fifo_set_size = bitmap_weight(indio_dev->active_scan_mask, |
@@ -814,26 +820,25 @@ static int adxl372_buffer_postenable(struct iio_dev *indio_dev) | |||
814 | if (ret < 0) { | 820 | if (ret < 0) { |
815 | st->fifo_mode = ADXL372_FIFO_BYPASSED; | 821 | st->fifo_mode = ADXL372_FIFO_BYPASSED; |
816 | adxl372_set_interrupts(st, 0, 0); | 822 | adxl372_set_interrupts(st, 0, 0); |
817 | return ret; | 823 | goto err; |
818 | } | 824 | } |
819 | 825 | ||
820 | return iio_triggered_buffer_postenable(indio_dev); | 826 | return 0; |
827 | |||
828 | err: | ||
829 | iio_triggered_buffer_predisable(indio_dev); | ||
830 | return ret; | ||
821 | } | 831 | } |
822 | 832 | ||
823 | static int adxl372_buffer_predisable(struct iio_dev *indio_dev) | 833 | static int adxl372_buffer_predisable(struct iio_dev *indio_dev) |
824 | { | 834 | { |
825 | struct adxl372_state *st = iio_priv(indio_dev); | 835 | struct adxl372_state *st = iio_priv(indio_dev); |
826 | int ret; | ||
827 | |||
828 | ret = iio_triggered_buffer_predisable(indio_dev); | ||
829 | if (ret < 0) | ||
830 | return ret; | ||
831 | 836 | ||
832 | adxl372_set_interrupts(st, 0, 0); | 837 | adxl372_set_interrupts(st, 0, 0); |
833 | st->fifo_mode = ADXL372_FIFO_BYPASSED; | 838 | st->fifo_mode = ADXL372_FIFO_BYPASSED; |
834 | adxl372_configure_fifo(st); | 839 | adxl372_configure_fifo(st); |
835 | 840 | ||
836 | return 0; | 841 | return iio_triggered_buffer_predisable(indio_dev); |
837 | } | 842 | } |
838 | 843 | ||
839 | static const struct iio_buffer_setup_ops adxl372_buffer_ops = { | 844 | static const struct iio_buffer_setup_ops adxl372_buffer_ops = { |
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index e589f64eab9d..6645771aa349 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c | |||
@@ -1487,6 +1487,7 @@ static const struct acpi_device_id kx_acpi_match[] = { | |||
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 inside the display of a 2-in-1 */ |
1490 | {"KIOX020A", KXCJ91008}, | ||
1490 | {"KXTJ1009", KXTJ21009}, | 1491 | {"KXTJ1009", KXTJ21009}, |
1491 | {"KXJ2109", KXTJ21009}, | 1492 | {"KXJ2109", KXTJ21009}, |
1492 | {"SMO8500", KXCJ91008}, | 1493 | {"SMO8500", KXCJ91008}, |
diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c index 274ce2f8bddf..a923f90f6e80 100644 --- a/drivers/iio/accel/sca3000.c +++ b/drivers/iio/accel/sca3000.c | |||
@@ -869,8 +869,9 @@ static int sca3000_read_event_value(struct iio_dev *indio_dev, | |||
869 | enum iio_event_info info, | 869 | enum iio_event_info info, |
870 | int *val, int *val2) | 870 | int *val, int *val2) |
871 | { | 871 | { |
872 | int ret, i; | ||
873 | struct sca3000_state *st = iio_priv(indio_dev); | 872 | struct sca3000_state *st = iio_priv(indio_dev); |
873 | long ret; | ||
874 | int i; | ||
874 | 875 | ||
875 | switch (info) { | 876 | switch (info) { |
876 | case IIO_EV_INFO_VALUE: | 877 | case IIO_EV_INFO_VALUE: |
@@ -882,11 +883,11 @@ static int sca3000_read_event_value(struct iio_dev *indio_dev, | |||
882 | return ret; | 883 | return ret; |
883 | *val = 0; | 884 | *val = 0; |
884 | if (chan->channel2 == IIO_MOD_Y) | 885 | if (chan->channel2 == IIO_MOD_Y) |
885 | for_each_set_bit(i, (unsigned long *)&ret, | 886 | for_each_set_bit(i, &ret, |
886 | ARRAY_SIZE(st->info->mot_det_mult_y)) | 887 | ARRAY_SIZE(st->info->mot_det_mult_y)) |
887 | *val += st->info->mot_det_mult_y[i]; | 888 | *val += st->info->mot_det_mult_y[i]; |
888 | else | 889 | else |
889 | for_each_set_bit(i, (unsigned long *)&ret, | 890 | for_each_set_bit(i, &ret, |
890 | ARRAY_SIZE(st->info->mot_det_mult_xz)) | 891 | ARRAY_SIZE(st->info->mot_det_mult_xz)) |
891 | *val += st->info->mot_det_mult_xz[i]; | 892 | *val += st->info->mot_det_mult_xz[i]; |
892 | 893 | ||
diff --git a/drivers/iio/accel/st_accel_buffer.c b/drivers/iio/accel/st_accel_buffer.c index 54f2ae91f614..0205c0167cdd 100644 --- a/drivers/iio/accel/st_accel_buffer.c +++ b/drivers/iio/accel/st_accel_buffer.c | |||
@@ -45,17 +45,19 @@ static int st_accel_buffer_postenable(struct iio_dev *indio_dev) | |||
45 | goto allocate_memory_error; | 45 | goto allocate_memory_error; |
46 | } | 46 | } |
47 | 47 | ||
48 | err = st_sensors_set_axis_enable(indio_dev, | 48 | err = iio_triggered_buffer_postenable(indio_dev); |
49 | (u8)indio_dev->active_scan_mask[0]); | ||
50 | if (err < 0) | 49 | if (err < 0) |
51 | goto st_accel_buffer_postenable_error; | 50 | goto st_accel_buffer_postenable_error; |
52 | 51 | ||
53 | err = iio_triggered_buffer_postenable(indio_dev); | 52 | err = st_sensors_set_axis_enable(indio_dev, |
53 | (u8)indio_dev->active_scan_mask[0]); | ||
54 | if (err < 0) | 54 | if (err < 0) |
55 | goto st_accel_buffer_postenable_error; | 55 | goto st_sensors_set_axis_enable_error; |
56 | 56 | ||
57 | return err; | 57 | return err; |
58 | 58 | ||
59 | st_sensors_set_axis_enable_error: | ||
60 | iio_triggered_buffer_predisable(indio_dev); | ||
59 | st_accel_buffer_postenable_error: | 61 | st_accel_buffer_postenable_error: |
60 | kfree(adata->buffer_data); | 62 | kfree(adata->buffer_data); |
61 | allocate_memory_error: | 63 | allocate_memory_error: |
@@ -64,20 +66,22 @@ allocate_memory_error: | |||
64 | 66 | ||
65 | static int st_accel_buffer_predisable(struct iio_dev *indio_dev) | 67 | static int st_accel_buffer_predisable(struct iio_dev *indio_dev) |
66 | { | 68 | { |
67 | int err; | 69 | int err, err2; |
68 | struct st_sensor_data *adata = iio_priv(indio_dev); | 70 | struct st_sensor_data *adata = iio_priv(indio_dev); |
69 | 71 | ||
70 | err = iio_triggered_buffer_predisable(indio_dev); | ||
71 | if (err < 0) | ||
72 | goto st_accel_buffer_predisable_error; | ||
73 | |||
74 | err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS); | 72 | err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS); |
75 | if (err < 0) | 73 | if (err < 0) |
76 | goto st_accel_buffer_predisable_error; | 74 | goto st_accel_buffer_predisable_error; |
77 | 75 | ||
78 | err = st_sensors_set_enable(indio_dev, false); | 76 | err = st_sensors_set_enable(indio_dev, false); |
77 | if (err < 0) | ||
78 | goto st_accel_buffer_predisable_error; | ||
79 | 79 | ||
80 | st_accel_buffer_predisable_error: | 80 | st_accel_buffer_predisable_error: |
81 | err2 = iio_triggered_buffer_predisable(indio_dev); | ||
82 | if (!err) | ||
83 | err = err2; | ||
84 | |||
81 | kfree(adata->buffer_data); | 85 | kfree(adata->buffer_data); |
82 | return err; | 86 | return err; |
83 | } | 87 | } |
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index f96a7702b020..7e3286265a38 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
@@ -1085,7 +1085,6 @@ config VIPERBOARD_ADC | |||
1085 | 1085 | ||
1086 | config XILINX_XADC | 1086 | config XILINX_XADC |
1087 | tristate "Xilinx XADC driver" | 1087 | tristate "Xilinx XADC driver" |
1088 | depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST | ||
1089 | depends on HAS_IOMEM | 1088 | depends on HAS_IOMEM |
1090 | select IIO_BUFFER | 1089 | select IIO_BUFFER |
1091 | select IIO_TRIGGERED_BUFFER | 1090 | select IIO_TRIGGERED_BUFFER |
diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c index 659ef37d5fe8..edc6f1cc90b2 100644 --- a/drivers/iio/adc/ad7124.c +++ b/drivers/iio/adc/ad7124.c | |||
@@ -61,6 +61,8 @@ | |||
61 | #define AD7124_CONFIG_REF_SEL(x) FIELD_PREP(AD7124_CONFIG_REF_SEL_MSK, x) | 61 | #define AD7124_CONFIG_REF_SEL(x) FIELD_PREP(AD7124_CONFIG_REF_SEL_MSK, x) |
62 | #define AD7124_CONFIG_PGA_MSK GENMASK(2, 0) | 62 | #define AD7124_CONFIG_PGA_MSK GENMASK(2, 0) |
63 | #define AD7124_CONFIG_PGA(x) FIELD_PREP(AD7124_CONFIG_PGA_MSK, x) | 63 | #define AD7124_CONFIG_PGA(x) FIELD_PREP(AD7124_CONFIG_PGA_MSK, x) |
64 | #define AD7124_CONFIG_IN_BUFF_MSK GENMASK(7, 6) | ||
65 | #define AD7124_CONFIG_IN_BUFF(x) FIELD_PREP(AD7124_CONFIG_IN_BUFF_MSK, x) | ||
64 | 66 | ||
65 | /* AD7124_FILTER_X */ | 67 | /* AD7124_FILTER_X */ |
66 | #define AD7124_FILTER_FS_MSK GENMASK(10, 0) | 68 | #define AD7124_FILTER_FS_MSK GENMASK(10, 0) |
@@ -108,6 +110,8 @@ struct ad7124_chip_info { | |||
108 | struct ad7124_channel_config { | 110 | struct ad7124_channel_config { |
109 | enum ad7124_ref_sel refsel; | 111 | enum ad7124_ref_sel refsel; |
110 | bool bipolar; | 112 | bool bipolar; |
113 | bool buf_positive; | ||
114 | bool buf_negative; | ||
111 | unsigned int ain; | 115 | unsigned int ain; |
112 | unsigned int vref_mv; | 116 | unsigned int vref_mv; |
113 | unsigned int pga_bits; | 117 | unsigned int pga_bits; |
@@ -117,7 +121,7 @@ struct ad7124_channel_config { | |||
117 | struct ad7124_state { | 121 | struct ad7124_state { |
118 | const struct ad7124_chip_info *chip_info; | 122 | const struct ad7124_chip_info *chip_info; |
119 | struct ad_sigma_delta sd; | 123 | struct ad_sigma_delta sd; |
120 | struct ad7124_channel_config channel_config[4]; | 124 | struct ad7124_channel_config *channel_config; |
121 | struct regulator *vref[4]; | 125 | struct regulator *vref[4]; |
122 | struct clk *mclk; | 126 | struct clk *mclk; |
123 | unsigned int adc_control; | 127 | unsigned int adc_control; |
@@ -435,6 +439,7 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, | |||
435 | struct ad7124_state *st = iio_priv(indio_dev); | 439 | struct ad7124_state *st = iio_priv(indio_dev); |
436 | struct device_node *child; | 440 | struct device_node *child; |
437 | struct iio_chan_spec *chan; | 441 | struct iio_chan_spec *chan; |
442 | struct ad7124_channel_config *chan_config; | ||
438 | unsigned int ain[2], channel = 0, tmp; | 443 | unsigned int ain[2], channel = 0, tmp; |
439 | int ret; | 444 | int ret; |
440 | 445 | ||
@@ -449,8 +454,14 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, | |||
449 | if (!chan) | 454 | if (!chan) |
450 | return -ENOMEM; | 455 | return -ENOMEM; |
451 | 456 | ||
457 | chan_config = devm_kcalloc(indio_dev->dev.parent, st->num_channels, | ||
458 | sizeof(*chan_config), GFP_KERNEL); | ||
459 | if (!chan_config) | ||
460 | return -ENOMEM; | ||
461 | |||
452 | indio_dev->channels = chan; | 462 | indio_dev->channels = chan; |
453 | indio_dev->num_channels = st->num_channels; | 463 | indio_dev->num_channels = st->num_channels; |
464 | st->channel_config = chan_config; | ||
454 | 465 | ||
455 | for_each_available_child_of_node(np, child) { | 466 | for_each_available_child_of_node(np, child) { |
456 | ret = of_property_read_u32(child, "reg", &channel); | 467 | ret = of_property_read_u32(child, "reg", &channel); |
@@ -462,13 +473,6 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, | |||
462 | if (ret) | 473 | if (ret) |
463 | goto err; | 474 | goto err; |
464 | 475 | ||
465 | if (ain[0] >= st->chip_info->num_inputs || | ||
466 | ain[1] >= st->chip_info->num_inputs) { | ||
467 | dev_err(indio_dev->dev.parent, | ||
468 | "Input pin number out of range.\n"); | ||
469 | ret = -EINVAL; | ||
470 | goto err; | ||
471 | } | ||
472 | st->channel_config[channel].ain = AD7124_CHANNEL_AINP(ain[0]) | | 476 | st->channel_config[channel].ain = AD7124_CHANNEL_AINP(ain[0]) | |
473 | AD7124_CHANNEL_AINM(ain[1]); | 477 | AD7124_CHANNEL_AINM(ain[1]); |
474 | st->channel_config[channel].bipolar = | 478 | st->channel_config[channel].bipolar = |
@@ -480,6 +484,11 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, | |||
480 | else | 484 | else |
481 | st->channel_config[channel].refsel = tmp; | 485 | st->channel_config[channel].refsel = tmp; |
482 | 486 | ||
487 | st->channel_config[channel].buf_positive = | ||
488 | of_property_read_bool(child, "adi,buffered-positive"); | ||
489 | st->channel_config[channel].buf_negative = | ||
490 | of_property_read_bool(child, "adi,buffered-negative"); | ||
491 | |||
483 | *chan = ad7124_channel_template; | 492 | *chan = ad7124_channel_template; |
484 | chan->address = channel; | 493 | chan->address = channel; |
485 | chan->scan_index = channel; | 494 | chan->scan_index = channel; |
@@ -499,7 +508,7 @@ err: | |||
499 | static int ad7124_setup(struct ad7124_state *st) | 508 | static int ad7124_setup(struct ad7124_state *st) |
500 | { | 509 | { |
501 | unsigned int val, fclk, power_mode; | 510 | unsigned int val, fclk, power_mode; |
502 | int i, ret; | 511 | int i, ret, tmp; |
503 | 512 | ||
504 | fclk = clk_get_rate(st->mclk); | 513 | fclk = clk_get_rate(st->mclk); |
505 | if (!fclk) | 514 | if (!fclk) |
@@ -532,8 +541,12 @@ static int ad7124_setup(struct ad7124_state *st) | |||
532 | if (ret < 0) | 541 | if (ret < 0) |
533 | return ret; | 542 | return ret; |
534 | 543 | ||
544 | tmp = (st->channel_config[i].buf_positive << 1) + | ||
545 | st->channel_config[i].buf_negative; | ||
546 | |||
535 | val = AD7124_CONFIG_BIPOLAR(st->channel_config[i].bipolar) | | 547 | val = AD7124_CONFIG_BIPOLAR(st->channel_config[i].bipolar) | |
536 | AD7124_CONFIG_REF_SEL(st->channel_config[i].refsel); | 548 | AD7124_CONFIG_REF_SEL(st->channel_config[i].refsel) | |
549 | AD7124_CONFIG_IN_BUFF(tmp); | ||
537 | ret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(i), 2, val); | 550 | ret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(i), 2, val); |
538 | if (ret < 0) | 551 | if (ret < 0) |
539 | return ret; | 552 | return ret; |
diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index 24c70c3cefb4..aba0fd123a51 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c | |||
@@ -140,7 +140,7 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, | |||
140 | int *val2, | 140 | int *val2, |
141 | long m) | 141 | long m) |
142 | { | 142 | { |
143 | int ret; | 143 | int ret, ch = 0; |
144 | struct ad7606_state *st = iio_priv(indio_dev); | 144 | struct ad7606_state *st = iio_priv(indio_dev); |
145 | 145 | ||
146 | switch (m) { | 146 | switch (m) { |
@@ -157,8 +157,10 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, | |||
157 | *val = (short)ret; | 157 | *val = (short)ret; |
158 | return IIO_VAL_INT; | 158 | return IIO_VAL_INT; |
159 | case IIO_CHAN_INFO_SCALE: | 159 | case IIO_CHAN_INFO_SCALE: |
160 | if (st->sw_mode_en) | ||
161 | ch = chan->address; | ||
160 | *val = 0; | 162 | *val = 0; |
161 | *val2 = st->scale_avail[st->range]; | 163 | *val2 = st->scale_avail[st->range[ch]]; |
162 | return IIO_VAL_INT_PLUS_MICRO; | 164 | return IIO_VAL_INT_PLUS_MICRO; |
163 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: | 165 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: |
164 | *val = st->oversampling; | 166 | *val = st->oversampling; |
@@ -194,6 +196,32 @@ static ssize_t in_voltage_scale_available_show(struct device *dev, | |||
194 | 196 | ||
195 | static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); | 197 | static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); |
196 | 198 | ||
199 | static int ad7606_write_scale_hw(struct iio_dev *indio_dev, int ch, int val) | ||
200 | { | ||
201 | struct ad7606_state *st = iio_priv(indio_dev); | ||
202 | |||
203 | gpiod_set_value(st->gpio_range, val); | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static int ad7606_write_os_hw(struct iio_dev *indio_dev, int val) | ||
209 | { | ||
210 | struct ad7606_state *st = iio_priv(indio_dev); | ||
211 | DECLARE_BITMAP(values, 3); | ||
212 | |||
213 | values[0] = val; | ||
214 | |||
215 | gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc, | ||
216 | st->gpio_os->info, values); | ||
217 | |||
218 | /* AD7616 requires a reset to update value */ | ||
219 | if (st->chip_info->os_req_reset) | ||
220 | ad7606_reset(st); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
197 | static int ad7606_write_raw(struct iio_dev *indio_dev, | 225 | static int ad7606_write_raw(struct iio_dev *indio_dev, |
198 | struct iio_chan_spec const *chan, | 226 | struct iio_chan_spec const *chan, |
199 | int val, | 227 | int val, |
@@ -201,15 +229,20 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, | |||
201 | long mask) | 229 | long mask) |
202 | { | 230 | { |
203 | struct ad7606_state *st = iio_priv(indio_dev); | 231 | struct ad7606_state *st = iio_priv(indio_dev); |
204 | DECLARE_BITMAP(values, 3); | 232 | int i, ret, ch = 0; |
205 | int i; | ||
206 | 233 | ||
207 | switch (mask) { | 234 | switch (mask) { |
208 | case IIO_CHAN_INFO_SCALE: | 235 | case IIO_CHAN_INFO_SCALE: |
209 | mutex_lock(&st->lock); | 236 | mutex_lock(&st->lock); |
210 | i = find_closest(val2, st->scale_avail, st->num_scales); | 237 | i = find_closest(val2, st->scale_avail, st->num_scales); |
211 | gpiod_set_value(st->gpio_range, i); | 238 | if (st->sw_mode_en) |
212 | st->range = i; | 239 | ch = chan->address; |
240 | ret = st->write_scale(indio_dev, ch, i); | ||
241 | if (ret < 0) { | ||
242 | mutex_unlock(&st->lock); | ||
243 | return ret; | ||
244 | } | ||
245 | st->range[ch] = i; | ||
213 | mutex_unlock(&st->lock); | 246 | mutex_unlock(&st->lock); |
214 | 247 | ||
215 | return 0; | 248 | return 0; |
@@ -218,17 +251,12 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, | |||
218 | return -EINVAL; | 251 | return -EINVAL; |
219 | i = find_closest(val, st->oversampling_avail, | 252 | i = find_closest(val, st->oversampling_avail, |
220 | st->num_os_ratios); | 253 | st->num_os_ratios); |
221 | |||
222 | values[0] = i; | ||
223 | |||
224 | mutex_lock(&st->lock); | 254 | mutex_lock(&st->lock); |
225 | gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc, | 255 | ret = st->write_os(indio_dev, i); |
226 | st->gpio_os->info, values); | 256 | if (ret < 0) { |
227 | 257 | mutex_unlock(&st->lock); | |
228 | /* AD7616 requires a reset to update value */ | 258 | return ret; |
229 | if (st->chip_info->os_req_reset) | 259 | } |
230 | ad7606_reset(st); | ||
231 | |||
232 | st->oversampling = st->oversampling_avail[i]; | 260 | st->oversampling = st->oversampling_avail[i]; |
233 | mutex_unlock(&st->lock); | 261 | mutex_unlock(&st->lock); |
234 | 262 | ||
@@ -536,7 +564,7 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, | |||
536 | st->bops = bops; | 564 | st->bops = bops; |
537 | st->base_address = base_address; | 565 | st->base_address = base_address; |
538 | /* tied to logic low, analog input range is +/- 5V */ | 566 | /* tied to logic low, analog input range is +/- 5V */ |
539 | st->range = 0; | 567 | st->range[0] = 0; |
540 | st->oversampling = 1; | 568 | st->oversampling = 1; |
541 | st->scale_avail = ad7606_scale_avail; | 569 | st->scale_avail = ad7606_scale_avail; |
542 | st->num_scales = ARRAY_SIZE(ad7606_scale_avail); | 570 | st->num_scales = ARRAY_SIZE(ad7606_scale_avail); |
@@ -589,6 +617,39 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address, | |||
589 | if (ret) | 617 | if (ret) |
590 | dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n"); | 618 | dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n"); |
591 | 619 | ||
620 | st->write_scale = ad7606_write_scale_hw; | ||
621 | st->write_os = ad7606_write_os_hw; | ||
622 | |||
623 | if (st->chip_info->sw_mode_config) | ||
624 | st->sw_mode_en = device_property_present(st->dev, | ||
625 | "adi,sw-mode"); | ||
626 | |||
627 | if (st->sw_mode_en) { | ||
628 | /* After reset, in software mode, ±10 V is set by default */ | ||
629 | memset32(st->range, 2, ARRAY_SIZE(st->range)); | ||
630 | indio_dev->info = &ad7606_info_os_and_range; | ||
631 | |||
632 | /* | ||
633 | * In software mode, the range gpio has no longer its function. | ||
634 | * Instead, the scale can be configured individually for each | ||
635 | * channel from the range registers. | ||
636 | */ | ||
637 | if (st->chip_info->write_scale_sw) | ||
638 | st->write_scale = st->chip_info->write_scale_sw; | ||
639 | |||
640 | /* | ||
641 | * In software mode, the oversampling is no longer configured | ||
642 | * with GPIO pins. Instead, the oversampling can be configured | ||
643 | * in configuratiion register. | ||
644 | */ | ||
645 | if (st->chip_info->write_os_sw) | ||
646 | st->write_os = st->chip_info->write_os_sw; | ||
647 | |||
648 | ret = st->chip_info->sw_mode_config(indio_dev); | ||
649 | if (ret < 0) | ||
650 | return ret; | ||
651 | } | ||
652 | |||
592 | st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", | 653 | st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", |
593 | indio_dev->name, indio_dev->id); | 654 | indio_dev->name, indio_dev->id); |
594 | if (!st->trig) | 655 | if (!st->trig) |
@@ -643,7 +704,7 @@ static int ad7606_resume(struct device *dev) | |||
643 | struct ad7606_state *st = iio_priv(indio_dev); | 704 | struct ad7606_state *st = iio_priv(indio_dev); |
644 | 705 | ||
645 | if (st->gpio_standby) { | 706 | if (st->gpio_standby) { |
646 | gpiod_set_value(st->gpio_range, st->range); | 707 | gpiod_set_value(st->gpio_range, st->range[0]); |
647 | gpiod_set_value(st->gpio_standby, 1); | 708 | gpiod_set_value(st->gpio_standby, 1); |
648 | ad7606_reset(st); | 709 | ad7606_reset(st); |
649 | } | 710 | } |
diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h index f9ef52131e74..d8a509c2c428 100644 --- a/drivers/iio/adc/ad7606.h +++ b/drivers/iio/adc/ad7606.h | |||
@@ -16,6 +16,12 @@ | |||
16 | * oversampling ratios. | 16 | * oversampling ratios. |
17 | * @oversampling_num number of elements stored in oversampling_avail array | 17 | * @oversampling_num number of elements stored in oversampling_avail array |
18 | * @os_req_reset some devices require a reset to update oversampling | 18 | * @os_req_reset some devices require a reset to update oversampling |
19 | * @write_scale_sw pointer to the function which writes the scale via spi | ||
20 | in software mode | ||
21 | * @write_os_sw pointer to the function which writes the os via spi | ||
22 | in software mode | ||
23 | * @sw_mode_config: pointer to a function which configured the device | ||
24 | * for software mode | ||
19 | */ | 25 | */ |
20 | struct ad7606_chip_info { | 26 | struct ad7606_chip_info { |
21 | const struct iio_chan_spec *channels; | 27 | const struct iio_chan_spec *channels; |
@@ -23,6 +29,9 @@ struct ad7606_chip_info { | |||
23 | const unsigned int *oversampling_avail; | 29 | const unsigned int *oversampling_avail; |
24 | unsigned int oversampling_num; | 30 | unsigned int oversampling_num; |
25 | bool os_req_reset; | 31 | bool os_req_reset; |
32 | int (*write_scale_sw)(struct iio_dev *indio_dev, int ch, int val); | ||
33 | int (*write_os_sw)(struct iio_dev *indio_dev, int val); | ||
34 | int (*sw_mode_config)(struct iio_dev *indio_dev); | ||
26 | }; | 35 | }; |
27 | 36 | ||
28 | /** | 37 | /** |
@@ -34,11 +43,14 @@ struct ad7606_chip_info { | |||
34 | * @range voltage range selection, selects which scale to apply | 43 | * @range voltage range selection, selects which scale to apply |
35 | * @oversampling oversampling selection | 44 | * @oversampling oversampling selection |
36 | * @base_address address from where to read data in parallel operation | 45 | * @base_address address from where to read data in parallel operation |
46 | * @sw_mode_en software mode enabled | ||
37 | * @scale_avail pointer to the array which stores the available scales | 47 | * @scale_avail pointer to the array which stores the available scales |
38 | * @num_scales number of elements stored in the scale_avail array | 48 | * @num_scales number of elements stored in the scale_avail array |
39 | * @oversampling_avail pointer to the array which stores the available | 49 | * @oversampling_avail pointer to the array which stores the available |
40 | * oversampling ratios. | 50 | * oversampling ratios. |
41 | * @num_os_ratios number of elements stored in oversampling_avail array | 51 | * @num_os_ratios number of elements stored in oversampling_avail array |
52 | * @write_scale pointer to the function which writes the scale | ||
53 | * @write_os pointer to the function which writes the os | ||
42 | * @lock protect sensor state from concurrent accesses to GPIOs | 54 | * @lock protect sensor state from concurrent accesses to GPIOs |
43 | * @gpio_convst GPIO descriptor for conversion start signal (CONVST) | 55 | * @gpio_convst GPIO descriptor for conversion start signal (CONVST) |
44 | * @gpio_reset GPIO descriptor for device hard-reset | 56 | * @gpio_reset GPIO descriptor for device hard-reset |
@@ -57,13 +69,16 @@ struct ad7606_state { | |||
57 | const struct ad7606_chip_info *chip_info; | 69 | const struct ad7606_chip_info *chip_info; |
58 | struct regulator *reg; | 70 | struct regulator *reg; |
59 | const struct ad7606_bus_ops *bops; | 71 | const struct ad7606_bus_ops *bops; |
60 | unsigned int range; | 72 | unsigned int range[16]; |
61 | unsigned int oversampling; | 73 | unsigned int oversampling; |
62 | void __iomem *base_address; | 74 | void __iomem *base_address; |
75 | bool sw_mode_en; | ||
63 | const unsigned int *scale_avail; | 76 | const unsigned int *scale_avail; |
64 | unsigned int num_scales; | 77 | unsigned int num_scales; |
65 | const unsigned int *oversampling_avail; | 78 | const unsigned int *oversampling_avail; |
66 | unsigned int num_os_ratios; | 79 | unsigned int num_os_ratios; |
80 | int (*write_scale)(struct iio_dev *indio_dev, int ch, int val); | ||
81 | int (*write_os)(struct iio_dev *indio_dev, int val); | ||
67 | 82 | ||
68 | struct mutex lock; /* protect sensor state */ | 83 | struct mutex lock; /* protect sensor state */ |
69 | struct gpio_desc *gpio_convst; | 84 | struct gpio_desc *gpio_convst; |
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index 1423221c6e06..2640b75fb774 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c | |||
@@ -357,7 +357,7 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev) | |||
357 | ret = ad_sigma_delta_set_channel(sigma_delta, | 357 | ret = ad_sigma_delta_set_channel(sigma_delta, |
358 | indio_dev->channels[channel].address); | 358 | indio_dev->channels[channel].address); |
359 | if (ret) | 359 | if (ret) |
360 | goto err_predisable; | 360 | return ret; |
361 | 361 | ||
362 | spi_bus_lock(sigma_delta->spi->master); | 362 | spi_bus_lock(sigma_delta->spi->master); |
363 | sigma_delta->bus_locked = true; | 363 | sigma_delta->bus_locked = true; |
@@ -374,7 +374,6 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev) | |||
374 | 374 | ||
375 | err_unlock: | 375 | err_unlock: |
376 | spi_bus_unlock(sigma_delta->spi->master); | 376 | spi_bus_unlock(sigma_delta->spi->master); |
377 | err_predisable: | ||
378 | 377 | ||
379 | return ret; | 378 | return ret; |
380 | } | 379 | } |
diff --git a/drivers/iio/adc/imx7d_adc.c b/drivers/iio/adc/imx7d_adc.c index 4fe97c2a0f43..26a7bbe4d534 100644 --- a/drivers/iio/adc/imx7d_adc.c +++ b/drivers/iio/adc/imx7d_adc.c | |||
@@ -78,6 +78,7 @@ | |||
78 | #define IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT 0xf0000 | 78 | #define IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT 0xf0000 |
79 | 79 | ||
80 | #define IMX7D_ADC_TIMEOUT msecs_to_jiffies(100) | 80 | #define IMX7D_ADC_TIMEOUT msecs_to_jiffies(100) |
81 | #define IMX7D_ADC_INPUT_CLK 24000000 | ||
81 | 82 | ||
82 | enum imx7d_adc_clk_pre_div { | 83 | enum imx7d_adc_clk_pre_div { |
83 | IMX7D_ADC_ANALOG_CLK_PRE_DIV_4, | 84 | IMX7D_ADC_ANALOG_CLK_PRE_DIV_4, |
@@ -100,8 +101,6 @@ struct imx7d_adc_feature { | |||
100 | enum imx7d_adc_average_num avg_num; | 101 | enum imx7d_adc_average_num avg_num; |
101 | 102 | ||
102 | u32 core_time_unit; /* impact the sample rate */ | 103 | u32 core_time_unit; /* impact the sample rate */ |
103 | |||
104 | bool average_en; | ||
105 | }; | 104 | }; |
106 | 105 | ||
107 | struct imx7d_adc { | 106 | struct imx7d_adc { |
@@ -179,7 +178,6 @@ static void imx7d_adc_feature_config(struct imx7d_adc *info) | |||
179 | info->adc_feature.clk_pre_div = IMX7D_ADC_ANALOG_CLK_PRE_DIV_4; | 178 | info->adc_feature.clk_pre_div = IMX7D_ADC_ANALOG_CLK_PRE_DIV_4; |
180 | info->adc_feature.avg_num = IMX7D_ADC_AVERAGE_NUM_32; | 179 | info->adc_feature.avg_num = IMX7D_ADC_AVERAGE_NUM_32; |
181 | info->adc_feature.core_time_unit = 1; | 180 | info->adc_feature.core_time_unit = 1; |
182 | info->adc_feature.average_en = true; | ||
183 | } | 181 | } |
184 | 182 | ||
185 | static void imx7d_adc_sample_rate_set(struct imx7d_adc *info) | 183 | static void imx7d_adc_sample_rate_set(struct imx7d_adc *info) |
@@ -240,9 +238,8 @@ static void imx7d_adc_channel_set(struct imx7d_adc *info) | |||
240 | 238 | ||
241 | /* the channel choose single conversion, and enable average mode */ | 239 | /* the channel choose single conversion, and enable average mode */ |
242 | cfg1 |= (IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN | | 240 | cfg1 |= (IMX7D_REG_ADC_CH_CFG1_CHANNEL_EN | |
243 | IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE); | 241 | IMX7D_REG_ADC_CH_CFG1_CHANNEL_SINGLE | |
244 | if (info->adc_feature.average_en) | 242 | IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN); |
245 | cfg1 |= IMX7D_REG_ADC_CH_CFG1_CHANNEL_AVG_EN; | ||
246 | 243 | ||
247 | /* | 244 | /* |
248 | * physical channel 0 chose logical channel A | 245 | * physical channel 0 chose logical channel A |
@@ -272,13 +269,11 @@ static void imx7d_adc_channel_set(struct imx7d_adc *info) | |||
272 | 269 | ||
273 | static u32 imx7d_adc_get_sample_rate(struct imx7d_adc *info) | 270 | static u32 imx7d_adc_get_sample_rate(struct imx7d_adc *info) |
274 | { | 271 | { |
275 | /* input clock is always 24MHz */ | ||
276 | u32 input_clk = 24000000; | ||
277 | u32 analogue_core_clk; | 272 | u32 analogue_core_clk; |
278 | u32 core_time_unit = info->adc_feature.core_time_unit; | 273 | u32 core_time_unit = info->adc_feature.core_time_unit; |
279 | u32 tmp; | 274 | u32 tmp; |
280 | 275 | ||
281 | analogue_core_clk = input_clk / info->pre_div_num; | 276 | analogue_core_clk = IMX7D_ADC_INPUT_CLK / info->pre_div_num; |
282 | tmp = (core_time_unit + 1) * 6; | 277 | tmp = (core_time_unit + 1) * 6; |
283 | 278 | ||
284 | return analogue_core_clk / tmp; | 279 | return analogue_core_clk / tmp; |
@@ -493,11 +488,8 @@ static int imx7d_adc_probe(struct platform_device *pdev) | |||
493 | info->dev = dev; | 488 | info->dev = dev; |
494 | 489 | ||
495 | info->regs = devm_platform_ioremap_resource(pdev, 0); | 490 | info->regs = devm_platform_ioremap_resource(pdev, 0); |
496 | if (IS_ERR(info->regs)) { | 491 | if (IS_ERR(info->regs)) |
497 | ret = PTR_ERR(info->regs); | 492 | return PTR_ERR(info->regs); |
498 | dev_err(dev, "Failed to remap adc memory, err = %d\n", ret); | ||
499 | return ret; | ||
500 | } | ||
501 | 493 | ||
502 | irq = platform_get_irq(pdev, 0); | 494 | irq = platform_get_irq(pdev, 0); |
503 | if (irq < 0) { | 495 | if (irq < 0) { |
@@ -531,9 +523,7 @@ static int imx7d_adc_probe(struct platform_device *pdev) | |||
531 | indio_dev->channels = imx7d_adc_iio_channels; | 523 | indio_dev->channels = imx7d_adc_iio_channels; |
532 | indio_dev->num_channels = ARRAY_SIZE(imx7d_adc_iio_channels); | 524 | indio_dev->num_channels = ARRAY_SIZE(imx7d_adc_iio_channels); |
533 | 525 | ||
534 | ret = devm_request_irq(dev, irq, | 526 | ret = devm_request_irq(dev, irq, imx7d_adc_isr, 0, dev_name(dev), info); |
535 | imx7d_adc_isr, 0, | ||
536 | dev_name(dev), info); | ||
537 | if (ret < 0) { | 527 | if (ret < 0) { |
538 | dev_err(dev, "Failed requesting irq, irq = %d\n", irq); | 528 | dev_err(dev, "Failed requesting irq, irq = %d\n", irq); |
539 | return ret; | 529 | return ret; |
diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 70bbcf253cb6..7b28d045d271 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | 2 | /* |
3 | * Amlogic Meson Successive Approximation Register (SAR) A/D Converter | 3 | * Amlogic Meson Successive Approximation Register (SAR) A/D Converter |
4 | * | 4 | * |
diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c index 2327ec18b40c..1f7ce5186dfc 100644 --- a/drivers/iio/adc/stm32-adc-core.c +++ b/drivers/iio/adc/stm32-adc-core.c | |||
@@ -87,6 +87,7 @@ struct stm32_adc_priv_cfg { | |||
87 | * @domain: irq domain reference | 87 | * @domain: irq domain reference |
88 | * @aclk: clock reference for the analog circuitry | 88 | * @aclk: clock reference for the analog circuitry |
89 | * @bclk: bus clock common for all ADCs, depends on part used | 89 | * @bclk: bus clock common for all ADCs, depends on part used |
90 | * @vdda: vdda analog supply reference | ||
90 | * @vref: regulator reference | 91 | * @vref: regulator reference |
91 | * @cfg: compatible configuration data | 92 | * @cfg: compatible configuration data |
92 | * @common: common data for all ADC instances | 93 | * @common: common data for all ADC instances |
@@ -97,6 +98,7 @@ struct stm32_adc_priv { | |||
97 | struct irq_domain *domain; | 98 | struct irq_domain *domain; |
98 | struct clk *aclk; | 99 | struct clk *aclk; |
99 | struct clk *bclk; | 100 | struct clk *bclk; |
101 | struct regulator *vdda; | ||
100 | struct regulator *vref; | 102 | struct regulator *vref; |
101 | const struct stm32_adc_priv_cfg *cfg; | 103 | const struct stm32_adc_priv_cfg *cfg; |
102 | struct stm32_adc_common common; | 104 | struct stm32_adc_common common; |
@@ -394,10 +396,16 @@ static int stm32_adc_core_hw_start(struct device *dev) | |||
394 | struct stm32_adc_priv *priv = to_stm32_adc_priv(common); | 396 | struct stm32_adc_priv *priv = to_stm32_adc_priv(common); |
395 | int ret; | 397 | int ret; |
396 | 398 | ||
399 | ret = regulator_enable(priv->vdda); | ||
400 | if (ret < 0) { | ||
401 | dev_err(dev, "vdda enable failed %d\n", ret); | ||
402 | return ret; | ||
403 | } | ||
404 | |||
397 | ret = regulator_enable(priv->vref); | 405 | ret = regulator_enable(priv->vref); |
398 | if (ret < 0) { | 406 | if (ret < 0) { |
399 | dev_err(dev, "vref enable failed\n"); | 407 | dev_err(dev, "vref enable failed\n"); |
400 | return ret; | 408 | goto err_vdda_disable; |
401 | } | 409 | } |
402 | 410 | ||
403 | if (priv->bclk) { | 411 | if (priv->bclk) { |
@@ -425,6 +433,8 @@ err_bclk_disable: | |||
425 | clk_disable_unprepare(priv->bclk); | 433 | clk_disable_unprepare(priv->bclk); |
426 | err_regulator_disable: | 434 | err_regulator_disable: |
427 | regulator_disable(priv->vref); | 435 | regulator_disable(priv->vref); |
436 | err_vdda_disable: | ||
437 | regulator_disable(priv->vdda); | ||
428 | 438 | ||
429 | return ret; | 439 | return ret; |
430 | } | 440 | } |
@@ -441,6 +451,7 @@ static void stm32_adc_core_hw_stop(struct device *dev) | |||
441 | if (priv->bclk) | 451 | if (priv->bclk) |
442 | clk_disable_unprepare(priv->bclk); | 452 | clk_disable_unprepare(priv->bclk); |
443 | regulator_disable(priv->vref); | 453 | regulator_disable(priv->vref); |
454 | regulator_disable(priv->vdda); | ||
444 | } | 455 | } |
445 | 456 | ||
446 | static int stm32_adc_probe(struct platform_device *pdev) | 457 | static int stm32_adc_probe(struct platform_device *pdev) |
@@ -468,6 +479,14 @@ static int stm32_adc_probe(struct platform_device *pdev) | |||
468 | return PTR_ERR(priv->common.base); | 479 | return PTR_ERR(priv->common.base); |
469 | priv->common.phys_base = res->start; | 480 | priv->common.phys_base = res->start; |
470 | 481 | ||
482 | priv->vdda = devm_regulator_get(&pdev->dev, "vdda"); | ||
483 | if (IS_ERR(priv->vdda)) { | ||
484 | ret = PTR_ERR(priv->vdda); | ||
485 | if (ret != -EPROBE_DEFER) | ||
486 | dev_err(&pdev->dev, "vdda get failed, %d\n", ret); | ||
487 | return ret; | ||
488 | } | ||
489 | |||
471 | priv->vref = devm_regulator_get(&pdev->dev, "vref"); | 490 | priv->vref = devm_regulator_get(&pdev->dev, "vref"); |
472 | if (IS_ERR(priv->vref)) { | 491 | if (IS_ERR(priv->vref)) { |
473 | ret = PTR_ERR(priv->vref); | 492 | ret = PTR_ERR(priv->vref); |
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c index 588907cc3b6b..ee1e0569d0e1 100644 --- a/drivers/iio/adc/stm32-dfsdm-adc.c +++ b/drivers/iio/adc/stm32-dfsdm-adc.c | |||
@@ -39,9 +39,16 @@ | |||
39 | #define DFSDM_MAX_INT_OVERSAMPLING 256 | 39 | #define DFSDM_MAX_INT_OVERSAMPLING 256 |
40 | #define DFSDM_MAX_FL_OVERSAMPLING 1024 | 40 | #define DFSDM_MAX_FL_OVERSAMPLING 1024 |
41 | 41 | ||
42 | /* Max sample resolutions */ | 42 | /* Limit filter output resolution to 31 bits. (i.e. sample range is +/-2^30) */ |
43 | #define DFSDM_MAX_RES BIT(31) | 43 | #define DFSDM_DATA_MAX BIT(30) |
44 | #define DFSDM_DATA_RES BIT(23) | 44 | /* |
45 | * Data are output as two's complement data in a 24 bit field. | ||
46 | * Data from filters are in the range +/-2^(n-1) | ||
47 | * 2^(n-1) maximum positive value cannot be coded in 2's complement n bits | ||
48 | * An extra bit is required to avoid wrap-around of the binary code for 2^(n-1) | ||
49 | * So, the resolution of samples from filter is actually limited to 23 bits | ||
50 | */ | ||
51 | #define DFSDM_DATA_RES 24 | ||
45 | 52 | ||
46 | /* Filter configuration */ | 53 | /* Filter configuration */ |
47 | #define DFSDM_CR1_CFG_MASK (DFSDM_CR1_RCH_MASK | DFSDM_CR1_RCONT_MASK | \ | 54 | #define DFSDM_CR1_CFG_MASK (DFSDM_CR1_RCH_MASK | DFSDM_CR1_RCONT_MASK | \ |
@@ -181,14 +188,15 @@ static int stm32_dfsdm_get_jextsel(struct iio_dev *indio_dev, | |||
181 | return -EINVAL; | 188 | return -EINVAL; |
182 | } | 189 | } |
183 | 190 | ||
184 | static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl, | 191 | static int stm32_dfsdm_compute_osrs(struct stm32_dfsdm_filter *fl, |
185 | unsigned int fast, unsigned int oversamp) | 192 | unsigned int fast, unsigned int oversamp) |
186 | { | 193 | { |
187 | unsigned int i, d, fosr, iosr; | 194 | unsigned int i, d, fosr, iosr; |
188 | u64 res; | 195 | u64 res, max; |
189 | s64 delta; | 196 | int bits, shift; |
190 | unsigned int m = 1; /* multiplication factor */ | 197 | unsigned int m = 1; /* multiplication factor */ |
191 | unsigned int p = fl->ford; /* filter order (ford) */ | 198 | unsigned int p = fl->ford; /* filter order (ford) */ |
199 | struct stm32_dfsdm_filter_osr *flo = &fl->flo[fast]; | ||
192 | 200 | ||
193 | pr_debug("%s: Requested oversampling: %d\n", __func__, oversamp); | 201 | pr_debug("%s: Requested oversampling: %d\n", __func__, oversamp); |
194 | /* | 202 | /* |
@@ -207,11 +215,8 @@ static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl, | |||
207 | 215 | ||
208 | /* | 216 | /* |
209 | * Look for filter and integrator oversampling ratios which allows | 217 | * Look for filter and integrator oversampling ratios which allows |
210 | * to reach 24 bits data output resolution. | 218 | * to maximize data output resolution. |
211 | * Leave as soon as if exact resolution if reached. | ||
212 | * Otherwise the higher resolution below 32 bits is kept. | ||
213 | */ | 219 | */ |
214 | fl->res = 0; | ||
215 | for (fosr = 1; fosr <= DFSDM_MAX_FL_OVERSAMPLING; fosr++) { | 220 | for (fosr = 1; fosr <= DFSDM_MAX_FL_OVERSAMPLING; fosr++) { |
216 | for (iosr = 1; iosr <= DFSDM_MAX_INT_OVERSAMPLING; iosr++) { | 221 | for (iosr = 1; iosr <= DFSDM_MAX_INT_OVERSAMPLING; iosr++) { |
217 | if (fast) | 222 | if (fast) |
@@ -236,33 +241,91 @@ static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl, | |||
236 | res = fosr; | 241 | res = fosr; |
237 | for (i = p - 1; i > 0; i--) { | 242 | for (i = p - 1; i > 0; i--) { |
238 | res = res * (u64)fosr; | 243 | res = res * (u64)fosr; |
239 | if (res > DFSDM_MAX_RES) | 244 | if (res > DFSDM_DATA_MAX) |
240 | break; | 245 | break; |
241 | } | 246 | } |
242 | if (res > DFSDM_MAX_RES) | 247 | if (res > DFSDM_DATA_MAX) |
243 | continue; | 248 | continue; |
249 | |||
244 | res = res * (u64)m * (u64)iosr; | 250 | res = res * (u64)m * (u64)iosr; |
245 | if (res > DFSDM_MAX_RES) | 251 | if (res > DFSDM_DATA_MAX) |
246 | continue; | 252 | continue; |
247 | 253 | ||
248 | delta = res - DFSDM_DATA_RES; | 254 | if (res >= flo->res) { |
249 | 255 | flo->res = res; | |
250 | if (res >= fl->res) { | 256 | flo->fosr = fosr; |
251 | fl->res = res; | 257 | flo->iosr = iosr; |
252 | fl->fosr = fosr; | 258 | |
253 | fl->iosr = iosr; | 259 | bits = fls(flo->res); |
254 | fl->fast = fast; | 260 | /* 8 LBSs in data register contain chan info */ |
255 | pr_debug("%s: fosr = %d, iosr = %d\n", | 261 | max = flo->res << 8; |
256 | __func__, fl->fosr, fl->iosr); | 262 | |
263 | /* if resolution is not a power of two */ | ||
264 | if (flo->res > BIT(bits - 1)) | ||
265 | bits++; | ||
266 | else | ||
267 | max--; | ||
268 | |||
269 | shift = DFSDM_DATA_RES - bits; | ||
270 | /* | ||
271 | * Compute right/left shift | ||
272 | * Right shift is performed by hardware | ||
273 | * when transferring samples to data register. | ||
274 | * Left shift is done by software on buffer | ||
275 | */ | ||
276 | if (shift > 0) { | ||
277 | /* Resolution is lower than 24 bits */ | ||
278 | flo->rshift = 0; | ||
279 | flo->lshift = shift; | ||
280 | } else { | ||
281 | /* | ||
282 | * If resolution is 24 bits or more, | ||
283 | * max positive value may be ambiguous | ||
284 | * (equal to max negative value as sign | ||
285 | * bit is dropped). | ||
286 | * Reduce resolution to 23 bits (rshift) | ||
287 | * to keep the sign on bit 23 and treat | ||
288 | * saturation before rescaling on 24 | ||
289 | * bits (lshift). | ||
290 | */ | ||
291 | flo->rshift = 1 - shift; | ||
292 | flo->lshift = 1; | ||
293 | max >>= flo->rshift; | ||
294 | } | ||
295 | flo->max = (s32)max; | ||
296 | |||
297 | pr_debug("%s: fast %d, fosr %d, iosr %d, res 0x%llx/%d bits, rshift %d, lshift %d\n", | ||
298 | __func__, fast, flo->fosr, flo->iosr, | ||
299 | flo->res, bits, flo->rshift, | ||
300 | flo->lshift); | ||
257 | } | 301 | } |
258 | |||
259 | if (!delta) | ||
260 | return 0; | ||
261 | } | 302 | } |
262 | } | 303 | } |
263 | 304 | ||
264 | if (!fl->res) | 305 | if (!flo->res) |
306 | return -EINVAL; | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int stm32_dfsdm_compute_all_osrs(struct iio_dev *indio_dev, | ||
312 | unsigned int oversamp) | ||
313 | { | ||
314 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
315 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; | ||
316 | int ret0, ret1; | ||
317 | |||
318 | memset(&fl->flo[0], 0, sizeof(fl->flo[0])); | ||
319 | memset(&fl->flo[1], 0, sizeof(fl->flo[1])); | ||
320 | |||
321 | ret0 = stm32_dfsdm_compute_osrs(fl, 0, oversamp); | ||
322 | ret1 = stm32_dfsdm_compute_osrs(fl, 1, oversamp); | ||
323 | if (ret0 < 0 && ret1 < 0) { | ||
324 | dev_err(&indio_dev->dev, | ||
325 | "Filter parameters not found: errors %d/%d\n", | ||
326 | ret0, ret1); | ||
265 | return -EINVAL; | 327 | return -EINVAL; |
328 | } | ||
266 | 329 | ||
267 | return 0; | 330 | return 0; |
268 | } | 331 | } |
@@ -384,6 +447,50 @@ static int stm32_dfsdm_filter_set_trig(struct stm32_dfsdm_adc *adc, | |||
384 | return 0; | 447 | return 0; |
385 | } | 448 | } |
386 | 449 | ||
450 | static int stm32_dfsdm_channels_configure(struct stm32_dfsdm_adc *adc, | ||
451 | unsigned int fl_id, | ||
452 | struct iio_trigger *trig) | ||
453 | { | ||
454 | struct iio_dev *indio_dev = iio_priv_to_dev(adc); | ||
455 | struct regmap *regmap = adc->dfsdm->regmap; | ||
456 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[fl_id]; | ||
457 | struct stm32_dfsdm_filter_osr *flo = &fl->flo[0]; | ||
458 | const struct iio_chan_spec *chan; | ||
459 | unsigned int bit; | ||
460 | int ret; | ||
461 | |||
462 | fl->fast = 0; | ||
463 | |||
464 | /* | ||
465 | * In continuous mode, use fast mode configuration, | ||
466 | * if it provides a better resolution. | ||
467 | */ | ||
468 | if (adc->nconv == 1 && !trig && | ||
469 | (indio_dev->currentmode & INDIO_BUFFER_SOFTWARE)) { | ||
470 | if (fl->flo[1].res >= fl->flo[0].res) { | ||
471 | fl->fast = 1; | ||
472 | flo = &fl->flo[1]; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | if (!flo->res) | ||
477 | return -EINVAL; | ||
478 | |||
479 | for_each_set_bit(bit, &adc->smask, | ||
480 | sizeof(adc->smask) * BITS_PER_BYTE) { | ||
481 | chan = indio_dev->channels + bit; | ||
482 | |||
483 | ret = regmap_update_bits(regmap, | ||
484 | DFSDM_CHCFGR2(chan->channel), | ||
485 | DFSDM_CHCFGR2_DTRBS_MASK, | ||
486 | DFSDM_CHCFGR2_DTRBS(flo->rshift)); | ||
487 | if (ret) | ||
488 | return ret; | ||
489 | } | ||
490 | |||
491 | return 0; | ||
492 | } | ||
493 | |||
387 | static int stm32_dfsdm_filter_configure(struct stm32_dfsdm_adc *adc, | 494 | static int stm32_dfsdm_filter_configure(struct stm32_dfsdm_adc *adc, |
388 | unsigned int fl_id, | 495 | unsigned int fl_id, |
389 | struct iio_trigger *trig) | 496 | struct iio_trigger *trig) |
@@ -391,6 +498,7 @@ static int stm32_dfsdm_filter_configure(struct stm32_dfsdm_adc *adc, | |||
391 | struct iio_dev *indio_dev = iio_priv_to_dev(adc); | 498 | struct iio_dev *indio_dev = iio_priv_to_dev(adc); |
392 | struct regmap *regmap = adc->dfsdm->regmap; | 499 | struct regmap *regmap = adc->dfsdm->regmap; |
393 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[fl_id]; | 500 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[fl_id]; |
501 | struct stm32_dfsdm_filter_osr *flo = &fl->flo[fl->fast]; | ||
394 | u32 cr1; | 502 | u32 cr1; |
395 | const struct iio_chan_spec *chan; | 503 | const struct iio_chan_spec *chan; |
396 | unsigned int bit, jchg = 0; | 504 | unsigned int bit, jchg = 0; |
@@ -398,13 +506,13 @@ static int stm32_dfsdm_filter_configure(struct stm32_dfsdm_adc *adc, | |||
398 | 506 | ||
399 | /* Average integrator oversampling */ | 507 | /* Average integrator oversampling */ |
400 | ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_IOSR_MASK, | 508 | ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_IOSR_MASK, |
401 | DFSDM_FCR_IOSR(fl->iosr - 1)); | 509 | DFSDM_FCR_IOSR(flo->iosr - 1)); |
402 | if (ret) | 510 | if (ret) |
403 | return ret; | 511 | return ret; |
404 | 512 | ||
405 | /* Filter order and Oversampling */ | 513 | /* Filter order and Oversampling */ |
406 | ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_FOSR_MASK, | 514 | ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_FOSR_MASK, |
407 | DFSDM_FCR_FOSR(fl->fosr - 1)); | 515 | DFSDM_FCR_FOSR(flo->fosr - 1)); |
408 | if (ret) | 516 | if (ret) |
409 | return ret; | 517 | return ret; |
410 | 518 | ||
@@ -417,6 +525,12 @@ static int stm32_dfsdm_filter_configure(struct stm32_dfsdm_adc *adc, | |||
417 | if (ret) | 525 | if (ret) |
418 | return ret; | 526 | return ret; |
419 | 527 | ||
528 | ret = regmap_update_bits(regmap, DFSDM_CR1(fl_id), | ||
529 | DFSDM_CR1_FAST_MASK, | ||
530 | DFSDM_CR1_FAST(fl->fast)); | ||
531 | if (ret) | ||
532 | return ret; | ||
533 | |||
420 | /* | 534 | /* |
421 | * DFSDM modes configuration W.R.T audio/iio type modes | 535 | * DFSDM modes configuration W.R.T audio/iio type modes |
422 | * ---------------------------------------------------------------- | 536 | * ---------------------------------------------------------------- |
@@ -563,7 +677,6 @@ static int dfsdm_adc_set_samp_freq(struct iio_dev *indio_dev, | |||
563 | unsigned int spi_freq) | 677 | unsigned int spi_freq) |
564 | { | 678 | { |
565 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | 679 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
566 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; | ||
567 | unsigned int oversamp; | 680 | unsigned int oversamp; |
568 | int ret; | 681 | int ret; |
569 | 682 | ||
@@ -573,11 +686,10 @@ static int dfsdm_adc_set_samp_freq(struct iio_dev *indio_dev, | |||
573 | "Rate not accurate. requested (%u), actual (%u)\n", | 686 | "Rate not accurate. requested (%u), actual (%u)\n", |
574 | sample_freq, spi_freq / oversamp); | 687 | sample_freq, spi_freq / oversamp); |
575 | 688 | ||
576 | ret = stm32_dfsdm_set_osrs(fl, 0, oversamp); | 689 | ret = stm32_dfsdm_compute_all_osrs(indio_dev, oversamp); |
577 | if (ret < 0) { | 690 | if (ret < 0) |
578 | dev_err(&indio_dev->dev, "No filter parameters that match!\n"); | ||
579 | return ret; | 691 | return ret; |
580 | } | 692 | |
581 | adc->sample_freq = spi_freq / oversamp; | 693 | adc->sample_freq = spi_freq / oversamp; |
582 | adc->oversamp = oversamp; | 694 | adc->oversamp = oversamp; |
583 | 695 | ||
@@ -623,6 +735,10 @@ static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, | |||
623 | struct regmap *regmap = adc->dfsdm->regmap; | 735 | struct regmap *regmap = adc->dfsdm->regmap; |
624 | int ret; | 736 | int ret; |
625 | 737 | ||
738 | ret = stm32_dfsdm_channels_configure(adc, adc->fl_id, trig); | ||
739 | if (ret < 0) | ||
740 | return ret; | ||
741 | |||
626 | ret = stm32_dfsdm_start_channel(adc); | 742 | ret = stm32_dfsdm_start_channel(adc); |
627 | if (ret < 0) | 743 | if (ret < 0) |
628 | return ret; | 744 | return ret; |
@@ -702,6 +818,30 @@ static unsigned int stm32_dfsdm_adc_dma_residue(struct stm32_dfsdm_adc *adc) | |||
702 | return 0; | 818 | return 0; |
703 | } | 819 | } |
704 | 820 | ||
821 | static inline void stm32_dfsdm_process_data(struct stm32_dfsdm_adc *adc, | ||
822 | s32 *buffer) | ||
823 | { | ||
824 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; | ||
825 | struct stm32_dfsdm_filter_osr *flo = &fl->flo[fl->fast]; | ||
826 | unsigned int i = adc->nconv; | ||
827 | s32 *ptr = buffer; | ||
828 | |||
829 | while (i--) { | ||
830 | /* Mask 8 LSB that contains the channel ID */ | ||
831 | *ptr &= 0xFFFFFF00; | ||
832 | /* Convert 2^(n-1) sample to 2^(n-1)-1 to avoid wrap-around */ | ||
833 | if (*ptr > flo->max) | ||
834 | *ptr -= 1; | ||
835 | /* | ||
836 | * Samples from filter are retrieved with 23 bits resolution | ||
837 | * or less. Shift left to align MSB on 24 bits. | ||
838 | */ | ||
839 | *ptr <<= flo->lshift; | ||
840 | |||
841 | ptr++; | ||
842 | } | ||
843 | } | ||
844 | |||
705 | static irqreturn_t stm32_dfsdm_adc_trigger_handler(int irq, void *p) | 845 | static irqreturn_t stm32_dfsdm_adc_trigger_handler(int irq, void *p) |
706 | { | 846 | { |
707 | struct iio_poll_func *pf = p; | 847 | struct iio_poll_func *pf = p; |
@@ -710,7 +850,9 @@ static irqreturn_t stm32_dfsdm_adc_trigger_handler(int irq, void *p) | |||
710 | int available = stm32_dfsdm_adc_dma_residue(adc); | 850 | int available = stm32_dfsdm_adc_dma_residue(adc); |
711 | 851 | ||
712 | while (available >= indio_dev->scan_bytes) { | 852 | while (available >= indio_dev->scan_bytes) { |
713 | u32 *buffer = (u32 *)&adc->rx_buf[adc->bufi]; | 853 | s32 *buffer = (s32 *)&adc->rx_buf[adc->bufi]; |
854 | |||
855 | stm32_dfsdm_process_data(adc, buffer); | ||
714 | 856 | ||
715 | iio_push_to_buffers_with_timestamp(indio_dev, buffer, | 857 | iio_push_to_buffers_with_timestamp(indio_dev, buffer, |
716 | pf->timestamp); | 858 | pf->timestamp); |
@@ -751,10 +893,10 @@ static void stm32_dfsdm_dma_buffer_done(void *data) | |||
751 | old_pos = adc->bufi; | 893 | old_pos = adc->bufi; |
752 | 894 | ||
753 | while (available >= indio_dev->scan_bytes) { | 895 | while (available >= indio_dev->scan_bytes) { |
754 | u32 *buffer = (u32 *)&adc->rx_buf[adc->bufi]; | 896 | s32 *buffer = (s32 *)&adc->rx_buf[adc->bufi]; |
897 | |||
898 | stm32_dfsdm_process_data(adc, buffer); | ||
755 | 899 | ||
756 | /* Mask 8 LSB that contains the channel ID */ | ||
757 | *buffer = (*buffer & 0xFFFFFF00) << 8; | ||
758 | available -= indio_dev->scan_bytes; | 900 | available -= indio_dev->scan_bytes; |
759 | adc->bufi += indio_dev->scan_bytes; | 901 | adc->bufi += indio_dev->scan_bytes; |
760 | if (adc->bufi >= adc->buf_sz) { | 902 | if (adc->bufi >= adc->buf_sz) { |
@@ -776,6 +918,11 @@ static void stm32_dfsdm_dma_buffer_done(void *data) | |||
776 | static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev) | 918 | static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev) |
777 | { | 919 | { |
778 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | 920 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
921 | /* | ||
922 | * The DFSDM supports half-word transfers. However, for 16 bits record, | ||
923 | * 4 bytes buswidth is kept, to avoid losing samples LSBs when left | ||
924 | * shift is required. | ||
925 | */ | ||
779 | struct dma_slave_config config = { | 926 | struct dma_slave_config config = { |
780 | .src_addr = (dma_addr_t)adc->dfsdm->phys_base, | 927 | .src_addr = (dma_addr_t)adc->dfsdm->phys_base, |
781 | .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, | 928 | .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, |
@@ -1068,7 +1215,6 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev, | |||
1068 | int val, int val2, long mask) | 1215 | int val, int val2, long mask) |
1069 | { | 1216 | { |
1070 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | 1217 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); |
1071 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; | ||
1072 | struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel]; | 1218 | struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel]; |
1073 | unsigned int spi_freq; | 1219 | unsigned int spi_freq; |
1074 | int ret = -EINVAL; | 1220 | int ret = -EINVAL; |
@@ -1078,7 +1224,7 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev, | |||
1078 | ret = iio_device_claim_direct_mode(indio_dev); | 1224 | ret = iio_device_claim_direct_mode(indio_dev); |
1079 | if (ret) | 1225 | if (ret) |
1080 | return ret; | 1226 | return ret; |
1081 | ret = stm32_dfsdm_set_osrs(fl, 0, val); | 1227 | ret = stm32_dfsdm_compute_all_osrs(indio_dev, val); |
1082 | if (!ret) | 1228 | if (!ret) |
1083 | adc->oversamp = val; | 1229 | adc->oversamp = val; |
1084 | iio_device_release_direct_mode(indio_dev); | 1230 | iio_device_release_direct_mode(indio_dev); |
@@ -1277,11 +1423,11 @@ static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev, | |||
1277 | BIT(IIO_CHAN_INFO_SAMP_FREQ); | 1423 | BIT(IIO_CHAN_INFO_SAMP_FREQ); |
1278 | 1424 | ||
1279 | if (adc->dev_data->type == DFSDM_AUDIO) { | 1425 | if (adc->dev_data->type == DFSDM_AUDIO) { |
1280 | ch->scan_type.sign = 's'; | ||
1281 | ch->ext_info = dfsdm_adc_audio_ext_info; | 1426 | ch->ext_info = dfsdm_adc_audio_ext_info; |
1282 | } else { | 1427 | } else { |
1283 | ch->scan_type.sign = 'u'; | 1428 | ch->scan_type.shift = 8; |
1284 | } | 1429 | } |
1430 | ch->scan_type.sign = 's'; | ||
1285 | ch->scan_type.realbits = 24; | 1431 | ch->scan_type.realbits = 24; |
1286 | ch->scan_type.storagebits = 32; | 1432 | ch->scan_type.storagebits = 32; |
1287 | 1433 | ||
@@ -1327,8 +1473,7 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev) | |||
1327 | int ret, chan_idx; | 1473 | int ret, chan_idx; |
1328 | 1474 | ||
1329 | adc->oversamp = DFSDM_DEFAULT_OVERSAMPLING; | 1475 | adc->oversamp = DFSDM_DEFAULT_OVERSAMPLING; |
1330 | ret = stm32_dfsdm_set_osrs(&adc->dfsdm->fl_list[adc->fl_id], 0, | 1476 | ret = stm32_dfsdm_compute_all_osrs(indio_dev, adc->oversamp); |
1331 | adc->oversamp); | ||
1332 | if (ret < 0) | 1477 | if (ret < 0) |
1333 | return ret; | 1478 | return ret; |
1334 | 1479 | ||
diff --git a/drivers/iio/adc/stm32-dfsdm.h b/drivers/iio/adc/stm32-dfsdm.h index 8708394b0725..5dbdae4ed881 100644 --- a/drivers/iio/adc/stm32-dfsdm.h +++ b/drivers/iio/adc/stm32-dfsdm.h | |||
@@ -243,19 +243,33 @@ enum stm32_dfsdm_sinc_order { | |||
243 | }; | 243 | }; |
244 | 244 | ||
245 | /** | 245 | /** |
246 | * struct stm32_dfsdm_filter - structure relative to stm32 FDSDM filter | 246 | * struct stm32_dfsdm_filter_osr - DFSDM filter settings linked to oversampling |
247 | * @iosr: integrator oversampling | 247 | * @iosr: integrator oversampling |
248 | * @fosr: filter oversampling | 248 | * @fosr: filter oversampling |
249 | * @ford: filter order | 249 | * @rshift: output sample right shift (hardware shift) |
250 | * @lshift: output sample left shift (software shift) | ||
250 | * @res: output sample resolution | 251 | * @res: output sample resolution |
252 | * @max: output sample maximum positive value | ||
253 | */ | ||
254 | struct stm32_dfsdm_filter_osr { | ||
255 | unsigned int iosr; | ||
256 | unsigned int fosr; | ||
257 | unsigned int rshift; | ||
258 | unsigned int lshift; | ||
259 | u64 res; | ||
260 | s32 max; | ||
261 | }; | ||
262 | |||
263 | /** | ||
264 | * struct stm32_dfsdm_filter - structure relative to stm32 FDSDM filter | ||
265 | * @ford: filter order | ||
266 | * @flo: filter oversampling data table indexed by fast mode flag | ||
251 | * @sync_mode: filter synchronized with filter 0 | 267 | * @sync_mode: filter synchronized with filter 0 |
252 | * @fast: filter fast mode | 268 | * @fast: filter fast mode |
253 | */ | 269 | */ |
254 | struct stm32_dfsdm_filter { | 270 | struct stm32_dfsdm_filter { |
255 | unsigned int iosr; | ||
256 | unsigned int fosr; | ||
257 | enum stm32_dfsdm_sinc_order ford; | 271 | enum stm32_dfsdm_sinc_order ford; |
258 | u64 res; | 272 | struct stm32_dfsdm_filter_osr flo[2]; |
259 | unsigned int sync_mode; | 273 | unsigned int sync_mode; |
260 | unsigned int fast; | 274 | unsigned int fast; |
261 | }; | 275 | }; |
diff --git a/drivers/iio/amplifiers/Kconfig b/drivers/iio/amplifiers/Kconfig index 863d73519c0d..da7f126d197b 100644 --- a/drivers/iio/amplifiers/Kconfig +++ b/drivers/iio/amplifiers/Kconfig | |||
@@ -1,4 +1,4 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | # | 2 | # |
3 | # Gain Amplifiers, etc. | 3 | # Gain Amplifiers, etc. |
4 | # | 4 | # |
@@ -7,12 +7,17 @@ | |||
7 | menu "Amplifiers" | 7 | menu "Amplifiers" |
8 | 8 | ||
9 | config AD8366 | 9 | config AD8366 |
10 | tristate "Analog Devices AD8366 VGA" | 10 | tristate "Analog Devices AD8366 and similar Gain Amplifiers" |
11 | depends on SPI | 11 | depends on SPI |
12 | depends on GPIOLIB | ||
12 | select BITREVERSE | 13 | select BITREVERSE |
13 | help | 14 | help |
14 | Say yes here to build support for Analog Devices AD8366 | 15 | Say yes here to build support for Analog Devices AD8366 and similar |
15 | SPI Dual-Digital Variable Gain Amplifier (VGA). | 16 | gain amplifiers. This driver supports the following gain amplifiers |
17 | from Analog Devices: | ||
18 | AD8366 Dual-Digital Variable Gain Amplifier (VGA) | ||
19 | ADA4961 BiCMOS RF Digital Gain Amplifier (DGA) | ||
20 | ADL5240 Digitally controlled variable gain amplifier (VGA) | ||
16 | 21 | ||
17 | To compile this driver as a module, choose M here: the | 22 | To compile this driver as a module, choose M here: the |
18 | module will be called ad8366. | 23 | module will be called ad8366. |
diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c index 3d6246f86429..0176d3d8cc9c 100644 --- a/drivers/iio/amplifiers/ad8366.c +++ b/drivers/iio/amplifiers/ad8366.c | |||
@@ -1,8 +1,12 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | 2 | /* |
3 | * AD8366 SPI Dual-Digital Variable Gain Amplifier (VGA) | 3 | * AD8366 and similar Gain Amplifiers |
4 | * This driver supports the following gain amplifiers: | ||
5 | * AD8366 Dual-Digital Variable Gain Amplifier (VGA) | ||
6 | * ADA4961 BiCMOS RF Digital Gain Amplifier (DGA) | ||
7 | * ADL5240 Digitally controlled variable gain amplifier (VGA) | ||
4 | * | 8 | * |
5 | * Copyright 2012 Analog Devices Inc. | 9 | * Copyright 2012-2019 Analog Devices Inc. |
6 | */ | 10 | */ |
7 | 11 | ||
8 | #include <linux/device.h> | 12 | #include <linux/device.h> |
@@ -11,6 +15,7 @@ | |||
11 | #include <linux/sysfs.h> | 15 | #include <linux/sysfs.h> |
12 | #include <linux/spi/spi.h> | 16 | #include <linux/spi/spi.h> |
13 | #include <linux/regulator/consumer.h> | 17 | #include <linux/regulator/consumer.h> |
18 | #include <linux/gpio/consumer.h> | ||
14 | #include <linux/err.h> | 19 | #include <linux/err.h> |
15 | #include <linux/module.h> | 20 | #include <linux/module.h> |
16 | #include <linux/bitrev.h> | 21 | #include <linux/bitrev.h> |
@@ -18,10 +23,25 @@ | |||
18 | #include <linux/iio/iio.h> | 23 | #include <linux/iio/iio.h> |
19 | #include <linux/iio/sysfs.h> | 24 | #include <linux/iio/sysfs.h> |
20 | 25 | ||
26 | enum ad8366_type { | ||
27 | ID_AD8366, | ||
28 | ID_ADA4961, | ||
29 | ID_ADL5240, | ||
30 | }; | ||
31 | |||
32 | struct ad8366_info { | ||
33 | int gain_min; | ||
34 | int gain_max; | ||
35 | }; | ||
36 | |||
21 | struct ad8366_state { | 37 | struct ad8366_state { |
22 | struct spi_device *spi; | 38 | struct spi_device *spi; |
23 | struct regulator *reg; | 39 | struct regulator *reg; |
40 | struct mutex lock; /* protect sensor state */ | ||
41 | struct gpio_desc *reset_gpio; | ||
24 | unsigned char ch[2]; | 42 | unsigned char ch[2]; |
43 | enum ad8366_type type; | ||
44 | struct ad8366_info *info; | ||
25 | /* | 45 | /* |
26 | * DMA (thus cache coherency maintenance) requires the | 46 | * DMA (thus cache coherency maintenance) requires the |
27 | * transfer buffers to live in their own cache lines. | 47 | * transfer buffers to live in their own cache lines. |
@@ -29,19 +49,44 @@ struct ad8366_state { | |||
29 | unsigned char data[2] ____cacheline_aligned; | 49 | unsigned char data[2] ____cacheline_aligned; |
30 | }; | 50 | }; |
31 | 51 | ||
52 | static struct ad8366_info ad8366_infos[] = { | ||
53 | [ID_AD8366] = { | ||
54 | .gain_min = 4500, | ||
55 | .gain_max = 20500, | ||
56 | }, | ||
57 | [ID_ADA4961] = { | ||
58 | .gain_min = -6000, | ||
59 | .gain_max = 15000, | ||
60 | }, | ||
61 | [ID_ADL5240] = { | ||
62 | .gain_min = -11500, | ||
63 | .gain_max = 20000, | ||
64 | }, | ||
65 | }; | ||
66 | |||
32 | static int ad8366_write(struct iio_dev *indio_dev, | 67 | static int ad8366_write(struct iio_dev *indio_dev, |
33 | unsigned char ch_a, unsigned char ch_b) | 68 | unsigned char ch_a, unsigned char ch_b) |
34 | { | 69 | { |
35 | struct ad8366_state *st = iio_priv(indio_dev); | 70 | struct ad8366_state *st = iio_priv(indio_dev); |
36 | int ret; | 71 | int ret; |
37 | 72 | ||
38 | ch_a = bitrev8(ch_a & 0x3F); | 73 | switch (st->type) { |
39 | ch_b = bitrev8(ch_b & 0x3F); | 74 | case ID_AD8366: |
75 | ch_a = bitrev8(ch_a & 0x3F); | ||
76 | ch_b = bitrev8(ch_b & 0x3F); | ||
40 | 77 | ||
41 | st->data[0] = ch_b >> 4; | 78 | st->data[0] = ch_b >> 4; |
42 | st->data[1] = (ch_b << 4) | (ch_a >> 2); | 79 | st->data[1] = (ch_b << 4) | (ch_a >> 2); |
80 | break; | ||
81 | case ID_ADA4961: | ||
82 | st->data[0] = ch_a & 0x1F; | ||
83 | break; | ||
84 | case ID_ADL5240: | ||
85 | st->data[0] = (ch_a & 0x3F); | ||
86 | break; | ||
87 | } | ||
43 | 88 | ||
44 | ret = spi_write(st->spi, st->data, ARRAY_SIZE(st->data)); | 89 | ret = spi_write(st->spi, st->data, indio_dev->num_channels); |
45 | if (ret < 0) | 90 | if (ret < 0) |
46 | dev_err(&indio_dev->dev, "write failed (%d)", ret); | 91 | dev_err(&indio_dev->dev, "write failed (%d)", ret); |
47 | 92 | ||
@@ -56,24 +101,35 @@ static int ad8366_read_raw(struct iio_dev *indio_dev, | |||
56 | { | 101 | { |
57 | struct ad8366_state *st = iio_priv(indio_dev); | 102 | struct ad8366_state *st = iio_priv(indio_dev); |
58 | int ret; | 103 | int ret; |
59 | unsigned code; | 104 | int code, gain = 0; |
60 | 105 | ||
61 | mutex_lock(&indio_dev->mlock); | 106 | mutex_lock(&st->lock); |
62 | switch (m) { | 107 | switch (m) { |
63 | case IIO_CHAN_INFO_HARDWAREGAIN: | 108 | case IIO_CHAN_INFO_HARDWAREGAIN: |
64 | code = st->ch[chan->channel]; | 109 | code = st->ch[chan->channel]; |
65 | 110 | ||
111 | switch (st->type) { | ||
112 | case ID_AD8366: | ||
113 | gain = code * 253 + 4500; | ||
114 | break; | ||
115 | case ID_ADA4961: | ||
116 | gain = 15000 - code * 1000; | ||
117 | break; | ||
118 | case ID_ADL5240: | ||
119 | gain = 20000 - 31500 + code * 500; | ||
120 | break; | ||
121 | } | ||
122 | |||
66 | /* Values in dB */ | 123 | /* Values in dB */ |
67 | code = code * 253 + 4500; | 124 | *val = gain / 1000; |
68 | *val = code / 1000; | 125 | *val2 = (gain % 1000) * 1000; |
69 | *val2 = (code % 1000) * 1000; | ||
70 | 126 | ||
71 | ret = IIO_VAL_INT_PLUS_MICRO_DB; | 127 | ret = IIO_VAL_INT_PLUS_MICRO_DB; |
72 | break; | 128 | break; |
73 | default: | 129 | default: |
74 | ret = -EINVAL; | 130 | ret = -EINVAL; |
75 | } | 131 | } |
76 | mutex_unlock(&indio_dev->mlock); | 132 | mutex_unlock(&st->lock); |
77 | 133 | ||
78 | return ret; | 134 | return ret; |
79 | }; | 135 | }; |
@@ -85,21 +141,32 @@ static int ad8366_write_raw(struct iio_dev *indio_dev, | |||
85 | long mask) | 141 | long mask) |
86 | { | 142 | { |
87 | struct ad8366_state *st = iio_priv(indio_dev); | 143 | struct ad8366_state *st = iio_priv(indio_dev); |
88 | unsigned code; | 144 | struct ad8366_info *inf = st->info; |
145 | int code = 0, gain; | ||
89 | int ret; | 146 | int ret; |
90 | 147 | ||
91 | if (val < 0 || val2 < 0) | ||
92 | return -EINVAL; | ||
93 | |||
94 | /* Values in dB */ | 148 | /* Values in dB */ |
95 | code = (((u8)val * 1000) + ((u32)val2 / 1000)); | 149 | if (val < 0) |
150 | gain = (val * 1000) - (val2 / 1000); | ||
151 | else | ||
152 | gain = (val * 1000) + (val2 / 1000); | ||
96 | 153 | ||
97 | if (code > 20500 || code < 4500) | 154 | if (gain > inf->gain_max || gain < inf->gain_min) |
98 | return -EINVAL; | 155 | return -EINVAL; |
99 | 156 | ||
100 | code = (code - 4500) / 253; | 157 | switch (st->type) { |
158 | case ID_AD8366: | ||
159 | code = (gain - 4500) / 253; | ||
160 | break; | ||
161 | case ID_ADA4961: | ||
162 | code = (15000 - gain) / 1000; | ||
163 | break; | ||
164 | case ID_ADL5240: | ||
165 | code = ((gain - 500 - 20000) / 500) & 0x3F; | ||
166 | break; | ||
167 | } | ||
101 | 168 | ||
102 | mutex_lock(&indio_dev->mlock); | 169 | mutex_lock(&st->lock); |
103 | switch (mask) { | 170 | switch (mask) { |
104 | case IIO_CHAN_INFO_HARDWAREGAIN: | 171 | case IIO_CHAN_INFO_HARDWAREGAIN: |
105 | st->ch[chan->channel] = code; | 172 | st->ch[chan->channel] = code; |
@@ -108,7 +175,7 @@ static int ad8366_write_raw(struct iio_dev *indio_dev, | |||
108 | default: | 175 | default: |
109 | ret = -EINVAL; | 176 | ret = -EINVAL; |
110 | } | 177 | } |
111 | mutex_unlock(&indio_dev->mlock); | 178 | mutex_unlock(&st->lock); |
112 | 179 | ||
113 | return ret; | 180 | return ret; |
114 | } | 181 | } |
@@ -131,6 +198,10 @@ static const struct iio_chan_spec ad8366_channels[] = { | |||
131 | AD8366_CHAN(1), | 198 | AD8366_CHAN(1), |
132 | }; | 199 | }; |
133 | 200 | ||
201 | static const struct iio_chan_spec ada4961_channels[] = { | ||
202 | AD8366_CHAN(0), | ||
203 | }; | ||
204 | |||
134 | static int ad8366_probe(struct spi_device *spi) | 205 | static int ad8366_probe(struct spi_device *spi) |
135 | { | 206 | { |
136 | struct iio_dev *indio_dev; | 207 | struct iio_dev *indio_dev; |
@@ -151,14 +222,33 @@ static int ad8366_probe(struct spi_device *spi) | |||
151 | } | 222 | } |
152 | 223 | ||
153 | spi_set_drvdata(spi, indio_dev); | 224 | spi_set_drvdata(spi, indio_dev); |
225 | mutex_init(&st->lock); | ||
154 | st->spi = spi; | 226 | st->spi = spi; |
227 | st->type = spi_get_device_id(spi)->driver_data; | ||
228 | |||
229 | switch (st->type) { | ||
230 | case ID_AD8366: | ||
231 | indio_dev->channels = ad8366_channels; | ||
232 | indio_dev->num_channels = ARRAY_SIZE(ad8366_channels); | ||
233 | break; | ||
234 | case ID_ADA4961: | ||
235 | case ID_ADL5240: | ||
236 | st->reset_gpio = devm_gpiod_get(&spi->dev, "reset", | ||
237 | GPIOD_OUT_HIGH); | ||
238 | indio_dev->channels = ada4961_channels; | ||
239 | indio_dev->num_channels = ARRAY_SIZE(ada4961_channels); | ||
240 | break; | ||
241 | default: | ||
242 | dev_err(&spi->dev, "Invalid device ID\n"); | ||
243 | ret = -EINVAL; | ||
244 | goto error_disable_reg; | ||
245 | } | ||
155 | 246 | ||
247 | st->info = &ad8366_infos[st->type]; | ||
156 | indio_dev->dev.parent = &spi->dev; | 248 | indio_dev->dev.parent = &spi->dev; |
157 | indio_dev->name = spi_get_device_id(spi)->name; | 249 | indio_dev->name = spi_get_device_id(spi)->name; |
158 | indio_dev->info = &ad8366_info; | 250 | indio_dev->info = &ad8366_info; |
159 | indio_dev->modes = INDIO_DIRECT_MODE; | 251 | indio_dev->modes = INDIO_DIRECT_MODE; |
160 | indio_dev->channels = ad8366_channels; | ||
161 | indio_dev->num_channels = ARRAY_SIZE(ad8366_channels); | ||
162 | 252 | ||
163 | ret = ad8366_write(indio_dev, 0 , 0); | 253 | ret = ad8366_write(indio_dev, 0 , 0); |
164 | if (ret < 0) | 254 | if (ret < 0) |
@@ -192,7 +282,9 @@ static int ad8366_remove(struct spi_device *spi) | |||
192 | } | 282 | } |
193 | 283 | ||
194 | static const struct spi_device_id ad8366_id[] = { | 284 | static const struct spi_device_id ad8366_id[] = { |
195 | {"ad8366", 0}, | 285 | {"ad8366", ID_AD8366}, |
286 | {"ada4961", ID_ADA4961}, | ||
287 | {"adl5240", ID_ADL5240}, | ||
196 | {} | 288 | {} |
197 | }; | 289 | }; |
198 | MODULE_DEVICE_TABLE(spi, ad8366_id); | 290 | MODULE_DEVICE_TABLE(spi, ad8366_id); |
@@ -209,5 +301,5 @@ static struct spi_driver ad8366_driver = { | |||
209 | module_spi_driver(ad8366_driver); | 301 | module_spi_driver(ad8366_driver); |
210 | 302 | ||
211 | MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); | 303 | MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); |
212 | MODULE_DESCRIPTION("Analog Devices AD8366 VGA"); | 304 | MODULE_DESCRIPTION("Analog Devices AD8366 and similar Gain Amplifiers"); |
213 | MODULE_LICENSE("GPL v2"); | 305 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/iio/frequency/Kconfig b/drivers/iio/frequency/Kconfig index c86db8b42380..240b81502512 100644 --- a/drivers/iio/frequency/Kconfig +++ b/drivers/iio/frequency/Kconfig | |||
@@ -39,5 +39,15 @@ config ADF4350 | |||
39 | To compile this driver as a module, choose M here: the | 39 | To compile this driver as a module, choose M here: the |
40 | module will be called adf4350. | 40 | module will be called adf4350. |
41 | 41 | ||
42 | config ADF4371 | ||
43 | tristate "Analog Devices ADF4371/ADF4372 Wideband Synthesizers" | ||
44 | depends on SPI | ||
45 | select REGMAP_SPI | ||
46 | help | ||
47 | Say yes here to build support for Analog Devices ADF4371 and ADF4372 | ||
48 | Wideband Synthesizers. The driver provides direct access via sysfs. | ||
49 | |||
50 | To compile this driver as a module, choose M here: the | ||
51 | module will be called adf4371. | ||
42 | endmenu | 52 | endmenu |
43 | endmenu | 53 | endmenu |
diff --git a/drivers/iio/frequency/Makefile b/drivers/iio/frequency/Makefile index f2e396d40ddd..518b1e50caef 100644 --- a/drivers/iio/frequency/Makefile +++ b/drivers/iio/frequency/Makefile | |||
@@ -6,3 +6,4 @@ | |||
6 | # When adding new entries keep the list in alphabetical order | 6 | # When adding new entries keep the list in alphabetical order |
7 | obj-$(CONFIG_AD9523) += ad9523.o | 7 | obj-$(CONFIG_AD9523) += ad9523.o |
8 | obj-$(CONFIG_ADF4350) += adf4350.o | 8 | obj-$(CONFIG_ADF4350) += adf4350.o |
9 | obj-$(CONFIG_ADF4371) += adf4371.o | ||
diff --git a/drivers/iio/frequency/adf4371.c b/drivers/iio/frequency/adf4371.c new file mode 100644 index 000000000000..e48f15cc9ab5 --- /dev/null +++ b/drivers/iio/frequency/adf4371.c | |||
@@ -0,0 +1,632 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Analog Devices ADF4371 SPI Wideband Synthesizer driver | ||
4 | * | ||
5 | * Copyright 2019 Analog Devices Inc. | ||
6 | */ | ||
7 | #include <linux/bitfield.h> | ||
8 | #include <linux/clk.h> | ||
9 | #include <linux/device.h> | ||
10 | #include <linux/err.h> | ||
11 | #include <linux/gcd.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/regmap.h> | ||
15 | #include <linux/sysfs.h> | ||
16 | #include <linux/spi/spi.h> | ||
17 | |||
18 | #include <linux/iio/iio.h> | ||
19 | |||
20 | /* Registers address macro */ | ||
21 | #define ADF4371_REG(x) (x) | ||
22 | |||
23 | /* ADF4371_REG0 */ | ||
24 | #define ADF4371_ADDR_ASC_MSK BIT(2) | ||
25 | #define ADF4371_ADDR_ASC(x) FIELD_PREP(ADF4371_ADDR_ASC_MSK, x) | ||
26 | #define ADF4371_ADDR_ASC_R_MSK BIT(5) | ||
27 | #define ADF4371_ADDR_ASC_R(x) FIELD_PREP(ADF4371_ADDR_ASC_R_MSK, x) | ||
28 | #define ADF4371_RESET_CMD 0x81 | ||
29 | |||
30 | /* ADF4371_REG17 */ | ||
31 | #define ADF4371_FRAC2WORD_L_MSK GENMASK(7, 1) | ||
32 | #define ADF4371_FRAC2WORD_L(x) FIELD_PREP(ADF4371_FRAC2WORD_L_MSK, x) | ||
33 | #define ADF4371_FRAC1WORD_MSK BIT(0) | ||
34 | #define ADF4371_FRAC1WORD(x) FIELD_PREP(ADF4371_FRAC1WORD_MSK, x) | ||
35 | |||
36 | /* ADF4371_REG18 */ | ||
37 | #define ADF4371_FRAC2WORD_H_MSK GENMASK(6, 0) | ||
38 | #define ADF4371_FRAC2WORD_H(x) FIELD_PREP(ADF4371_FRAC2WORD_H_MSK, x) | ||
39 | |||
40 | /* ADF4371_REG1A */ | ||
41 | #define ADF4371_MOD2WORD_MSK GENMASK(5, 0) | ||
42 | #define ADF4371_MOD2WORD(x) FIELD_PREP(ADF4371_MOD2WORD_MSK, x) | ||
43 | |||
44 | /* ADF4371_REG24 */ | ||
45 | #define ADF4371_RF_DIV_SEL_MSK GENMASK(6, 4) | ||
46 | #define ADF4371_RF_DIV_SEL(x) FIELD_PREP(ADF4371_RF_DIV_SEL_MSK, x) | ||
47 | |||
48 | /* ADF4371_REG25 */ | ||
49 | #define ADF4371_MUTE_LD_MSK BIT(7) | ||
50 | #define ADF4371_MUTE_LD(x) FIELD_PREP(ADF4371_MUTE_LD_MSK, x) | ||
51 | |||
52 | /* ADF4371_REG32 */ | ||
53 | #define ADF4371_TIMEOUT_MSK GENMASK(1, 0) | ||
54 | #define ADF4371_TIMEOUT(x) FIELD_PREP(ADF4371_TIMEOUT_MSK, x) | ||
55 | |||
56 | /* ADF4371_REG34 */ | ||
57 | #define ADF4371_VCO_ALC_TOUT_MSK GENMASK(4, 0) | ||
58 | #define ADF4371_VCO_ALC_TOUT(x) FIELD_PREP(ADF4371_VCO_ALC_TOUT_MSK, x) | ||
59 | |||
60 | /* Specifications */ | ||
61 | #define ADF4371_MIN_VCO_FREQ 4000000000ULL /* 4000 MHz */ | ||
62 | #define ADF4371_MAX_VCO_FREQ 8000000000ULL /* 8000 MHz */ | ||
63 | #define ADF4371_MAX_OUT_RF8_FREQ ADF4371_MAX_VCO_FREQ /* Hz */ | ||
64 | #define ADF4371_MIN_OUT_RF8_FREQ (ADF4371_MIN_VCO_FREQ / 64) /* Hz */ | ||
65 | #define ADF4371_MAX_OUT_RF16_FREQ (ADF4371_MAX_VCO_FREQ * 2) /* Hz */ | ||
66 | #define ADF4371_MIN_OUT_RF16_FREQ (ADF4371_MIN_VCO_FREQ * 2) /* Hz */ | ||
67 | #define ADF4371_MAX_OUT_RF32_FREQ (ADF4371_MAX_VCO_FREQ * 4) /* Hz */ | ||
68 | #define ADF4371_MIN_OUT_RF32_FREQ (ADF4371_MIN_VCO_FREQ * 4) /* Hz */ | ||
69 | |||
70 | #define ADF4371_MAX_FREQ_PFD 250000000UL /* Hz */ | ||
71 | #define ADF4371_MAX_FREQ_REFIN 600000000UL /* Hz */ | ||
72 | |||
73 | /* MOD1 is a 24-bit primary modulus with fixed value of 2^25 */ | ||
74 | #define ADF4371_MODULUS1 33554432ULL | ||
75 | /* MOD2 is the programmable, 14-bit auxiliary fractional modulus */ | ||
76 | #define ADF4371_MAX_MODULUS2 BIT(14) | ||
77 | |||
78 | #define ADF4371_CHECK_RANGE(freq, range) \ | ||
79 | ((freq > ADF4371_MAX_ ## range) || (freq < ADF4371_MIN_ ## range)) | ||
80 | |||
81 | enum { | ||
82 | ADF4371_FREQ, | ||
83 | ADF4371_POWER_DOWN, | ||
84 | ADF4371_CHANNEL_NAME | ||
85 | }; | ||
86 | |||
87 | enum { | ||
88 | ADF4371_CH_RF8, | ||
89 | ADF4371_CH_RFAUX8, | ||
90 | ADF4371_CH_RF16, | ||
91 | ADF4371_CH_RF32 | ||
92 | }; | ||
93 | |||
94 | enum adf4371_variant { | ||
95 | ADF4371, | ||
96 | ADF4372 | ||
97 | }; | ||
98 | |||
99 | struct adf4371_pwrdown { | ||
100 | unsigned int reg; | ||
101 | unsigned int bit; | ||
102 | }; | ||
103 | |||
104 | static const char * const adf4371_ch_names[] = { | ||
105 | "RF8x", "RFAUX8x", "RF16x", "RF32x" | ||
106 | }; | ||
107 | |||
108 | static const struct adf4371_pwrdown adf4371_pwrdown_ch[4] = { | ||
109 | [ADF4371_CH_RF8] = { ADF4371_REG(0x25), 2 }, | ||
110 | [ADF4371_CH_RFAUX8] = { ADF4371_REG(0x72), 3 }, | ||
111 | [ADF4371_CH_RF16] = { ADF4371_REG(0x25), 3 }, | ||
112 | [ADF4371_CH_RF32] = { ADF4371_REG(0x25), 4 }, | ||
113 | }; | ||
114 | |||
115 | static const struct reg_sequence adf4371_reg_defaults[] = { | ||
116 | { ADF4371_REG(0x0), 0x18 }, | ||
117 | { ADF4371_REG(0x12), 0x40 }, | ||
118 | { ADF4371_REG(0x1E), 0x48 }, | ||
119 | { ADF4371_REG(0x20), 0x14 }, | ||
120 | { ADF4371_REG(0x22), 0x00 }, | ||
121 | { ADF4371_REG(0x23), 0x00 }, | ||
122 | { ADF4371_REG(0x24), 0x80 }, | ||
123 | { ADF4371_REG(0x25), 0x07 }, | ||
124 | { ADF4371_REG(0x27), 0xC5 }, | ||
125 | { ADF4371_REG(0x28), 0x83 }, | ||
126 | { ADF4371_REG(0x2C), 0x44 }, | ||
127 | { ADF4371_REG(0x2D), 0x11 }, | ||
128 | { ADF4371_REG(0x2E), 0x12 }, | ||
129 | { ADF4371_REG(0x2F), 0x94 }, | ||
130 | { ADF4371_REG(0x32), 0x04 }, | ||
131 | { ADF4371_REG(0x35), 0xFA }, | ||
132 | { ADF4371_REG(0x36), 0x30 }, | ||
133 | { ADF4371_REG(0x39), 0x07 }, | ||
134 | { ADF4371_REG(0x3A), 0x55 }, | ||
135 | { ADF4371_REG(0x3E), 0x0C }, | ||
136 | { ADF4371_REG(0x3F), 0x80 }, | ||
137 | { ADF4371_REG(0x40), 0x50 }, | ||
138 | { ADF4371_REG(0x41), 0x28 }, | ||
139 | { ADF4371_REG(0x47), 0xC0 }, | ||
140 | { ADF4371_REG(0x52), 0xF4 }, | ||
141 | { ADF4371_REG(0x70), 0x03 }, | ||
142 | { ADF4371_REG(0x71), 0x60 }, | ||
143 | { ADF4371_REG(0x72), 0x32 }, | ||
144 | }; | ||
145 | |||
146 | static const struct regmap_config adf4371_regmap_config = { | ||
147 | .reg_bits = 16, | ||
148 | .val_bits = 8, | ||
149 | .read_flag_mask = BIT(7), | ||
150 | }; | ||
151 | |||
152 | struct adf4371_chip_info { | ||
153 | unsigned int num_channels; | ||
154 | const struct iio_chan_spec *channels; | ||
155 | }; | ||
156 | |||
157 | struct adf4371_state { | ||
158 | struct spi_device *spi; | ||
159 | struct regmap *regmap; | ||
160 | struct clk *clkin; | ||
161 | /* | ||
162 | * Lock for accessing device registers. Some operations require | ||
163 | * multiple consecutive R/W operations, during which the device | ||
164 | * shouldn't be interrupted. The buffers are also shared across | ||
165 | * all operations so need to be protected on stand alone reads and | ||
166 | * writes. | ||
167 | */ | ||
168 | struct mutex lock; | ||
169 | const struct adf4371_chip_info *chip_info; | ||
170 | unsigned long clkin_freq; | ||
171 | unsigned long fpfd; | ||
172 | unsigned int integer; | ||
173 | unsigned int fract1; | ||
174 | unsigned int fract2; | ||
175 | unsigned int mod2; | ||
176 | unsigned int rf_div_sel; | ||
177 | unsigned int ref_div_factor; | ||
178 | u8 buf[10] ____cacheline_aligned; | ||
179 | }; | ||
180 | |||
181 | static unsigned long long adf4371_pll_fract_n_get_rate(struct adf4371_state *st, | ||
182 | u32 channel) | ||
183 | { | ||
184 | unsigned long long val, tmp; | ||
185 | unsigned int ref_div_sel; | ||
186 | |||
187 | val = (((u64)st->integer * ADF4371_MODULUS1) + st->fract1) * st->fpfd; | ||
188 | tmp = (u64)st->fract2 * st->fpfd; | ||
189 | do_div(tmp, st->mod2); | ||
190 | val += tmp + ADF4371_MODULUS1 / 2; | ||
191 | |||
192 | if (channel == ADF4371_CH_RF8 || channel == ADF4371_CH_RFAUX8) | ||
193 | ref_div_sel = st->rf_div_sel; | ||
194 | else | ||
195 | ref_div_sel = 0; | ||
196 | |||
197 | do_div(val, ADF4371_MODULUS1 * (1 << ref_div_sel)); | ||
198 | |||
199 | if (channel == ADF4371_CH_RF16) | ||
200 | val <<= 1; | ||
201 | else if (channel == ADF4371_CH_RF32) | ||
202 | val <<= 2; | ||
203 | |||
204 | return val; | ||
205 | } | ||
206 | |||
207 | static void adf4371_pll_fract_n_compute(unsigned long long vco, | ||
208 | unsigned long long pfd, | ||
209 | unsigned int *integer, | ||
210 | unsigned int *fract1, | ||
211 | unsigned int *fract2, | ||
212 | unsigned int *mod2) | ||
213 | { | ||
214 | unsigned long long tmp; | ||
215 | u32 gcd_div; | ||
216 | |||
217 | tmp = do_div(vco, pfd); | ||
218 | tmp = tmp * ADF4371_MODULUS1; | ||
219 | *fract2 = do_div(tmp, pfd); | ||
220 | |||
221 | *integer = vco; | ||
222 | *fract1 = tmp; | ||
223 | |||
224 | *mod2 = pfd; | ||
225 | |||
226 | while (*mod2 > ADF4371_MAX_MODULUS2) { | ||
227 | *mod2 >>= 1; | ||
228 | *fract2 >>= 1; | ||
229 | } | ||
230 | |||
231 | gcd_div = gcd(*fract2, *mod2); | ||
232 | *mod2 /= gcd_div; | ||
233 | *fract2 /= gcd_div; | ||
234 | } | ||
235 | |||
236 | static int adf4371_set_freq(struct adf4371_state *st, unsigned long long freq, | ||
237 | unsigned int channel) | ||
238 | { | ||
239 | u32 cp_bleed; | ||
240 | u8 int_mode = 0; | ||
241 | int ret; | ||
242 | |||
243 | switch (channel) { | ||
244 | case ADF4371_CH_RF8: | ||
245 | case ADF4371_CH_RFAUX8: | ||
246 | if (ADF4371_CHECK_RANGE(freq, OUT_RF8_FREQ)) | ||
247 | return -EINVAL; | ||
248 | |||
249 | st->rf_div_sel = 0; | ||
250 | |||
251 | while (freq < ADF4371_MIN_VCO_FREQ) { | ||
252 | freq <<= 1; | ||
253 | st->rf_div_sel++; | ||
254 | } | ||
255 | break; | ||
256 | case ADF4371_CH_RF16: | ||
257 | /* ADF4371 RF16 8000...16000 MHz */ | ||
258 | if (ADF4371_CHECK_RANGE(freq, OUT_RF16_FREQ)) | ||
259 | return -EINVAL; | ||
260 | |||
261 | freq >>= 1; | ||
262 | break; | ||
263 | case ADF4371_CH_RF32: | ||
264 | /* ADF4371 RF32 16000...32000 MHz */ | ||
265 | if (ADF4371_CHECK_RANGE(freq, OUT_RF32_FREQ)) | ||
266 | return -EINVAL; | ||
267 | |||
268 | freq >>= 2; | ||
269 | break; | ||
270 | default: | ||
271 | return -EINVAL; | ||
272 | } | ||
273 | |||
274 | adf4371_pll_fract_n_compute(freq, st->fpfd, &st->integer, &st->fract1, | ||
275 | &st->fract2, &st->mod2); | ||
276 | st->buf[0] = st->integer >> 8; | ||
277 | st->buf[1] = 0x40; /* REG12 default */ | ||
278 | st->buf[2] = 0x00; | ||
279 | st->buf[3] = st->fract2 & 0xFF; | ||
280 | st->buf[4] = st->fract2 >> 7; | ||
281 | st->buf[5] = st->fract2 >> 15; | ||
282 | st->buf[6] = ADF4371_FRAC2WORD_L(st->fract2 & 0x7F) | | ||
283 | ADF4371_FRAC1WORD(st->fract1 >> 23); | ||
284 | st->buf[7] = ADF4371_FRAC2WORD_H(st->fract2 >> 7); | ||
285 | st->buf[8] = st->mod2 & 0xFF; | ||
286 | st->buf[9] = ADF4371_MOD2WORD(st->mod2 >> 8); | ||
287 | |||
288 | ret = regmap_bulk_write(st->regmap, ADF4371_REG(0x11), st->buf, 10); | ||
289 | if (ret < 0) | ||
290 | return ret; | ||
291 | /* | ||
292 | * The R counter allows the input reference frequency to be | ||
293 | * divided down to produce the reference clock to the PFD | ||
294 | */ | ||
295 | ret = regmap_write(st->regmap, ADF4371_REG(0x1F), st->ref_div_factor); | ||
296 | if (ret < 0) | ||
297 | return ret; | ||
298 | |||
299 | ret = regmap_update_bits(st->regmap, ADF4371_REG(0x24), | ||
300 | ADF4371_RF_DIV_SEL_MSK, | ||
301 | ADF4371_RF_DIV_SEL(st->rf_div_sel)); | ||
302 | if (ret < 0) | ||
303 | return ret; | ||
304 | |||
305 | cp_bleed = DIV_ROUND_UP(400 * 1750, st->integer * 375); | ||
306 | cp_bleed = clamp(cp_bleed, 1U, 255U); | ||
307 | ret = regmap_write(st->regmap, ADF4371_REG(0x26), cp_bleed); | ||
308 | if (ret < 0) | ||
309 | return ret; | ||
310 | /* | ||
311 | * Set to 1 when in INT mode (when FRAC1 = FRAC2 = 0), | ||
312 | * and set to 0 when in FRAC mode. | ||
313 | */ | ||
314 | if (st->fract1 == 0 && st->fract2 == 0) | ||
315 | int_mode = 0x01; | ||
316 | |||
317 | ret = regmap_write(st->regmap, ADF4371_REG(0x2B), int_mode); | ||
318 | if (ret < 0) | ||
319 | return ret; | ||
320 | |||
321 | return regmap_write(st->regmap, ADF4371_REG(0x10), st->integer & 0xFF); | ||
322 | } | ||
323 | |||
324 | static ssize_t adf4371_read(struct iio_dev *indio_dev, | ||
325 | uintptr_t private, | ||
326 | const struct iio_chan_spec *chan, | ||
327 | char *buf) | ||
328 | { | ||
329 | struct adf4371_state *st = iio_priv(indio_dev); | ||
330 | unsigned long long val = 0; | ||
331 | unsigned int readval, reg, bit; | ||
332 | int ret; | ||
333 | |||
334 | switch ((u32)private) { | ||
335 | case ADF4371_FREQ: | ||
336 | val = adf4371_pll_fract_n_get_rate(st, chan->channel); | ||
337 | ret = regmap_read(st->regmap, ADF4371_REG(0x7C), &readval); | ||
338 | if (ret < 0) | ||
339 | break; | ||
340 | |||
341 | if (readval == 0x00) { | ||
342 | dev_dbg(&st->spi->dev, "PLL un-locked\n"); | ||
343 | ret = -EBUSY; | ||
344 | } | ||
345 | break; | ||
346 | case ADF4371_POWER_DOWN: | ||
347 | reg = adf4371_pwrdown_ch[chan->channel].reg; | ||
348 | bit = adf4371_pwrdown_ch[chan->channel].bit; | ||
349 | |||
350 | ret = regmap_read(st->regmap, reg, &readval); | ||
351 | if (ret < 0) | ||
352 | break; | ||
353 | |||
354 | val = !(readval & BIT(bit)); | ||
355 | break; | ||
356 | case ADF4371_CHANNEL_NAME: | ||
357 | return sprintf(buf, "%s\n", adf4371_ch_names[chan->channel]); | ||
358 | default: | ||
359 | ret = -EINVAL; | ||
360 | val = 0; | ||
361 | break; | ||
362 | } | ||
363 | |||
364 | return ret < 0 ? ret : sprintf(buf, "%llu\n", val); | ||
365 | } | ||
366 | |||
367 | static ssize_t adf4371_write(struct iio_dev *indio_dev, | ||
368 | uintptr_t private, | ||
369 | const struct iio_chan_spec *chan, | ||
370 | const char *buf, size_t len) | ||
371 | { | ||
372 | struct adf4371_state *st = iio_priv(indio_dev); | ||
373 | unsigned long long freq; | ||
374 | bool power_down; | ||
375 | unsigned int bit, readval, reg; | ||
376 | int ret; | ||
377 | |||
378 | mutex_lock(&st->lock); | ||
379 | switch ((u32)private) { | ||
380 | case ADF4371_FREQ: | ||
381 | ret = kstrtoull(buf, 10, &freq); | ||
382 | if (ret) | ||
383 | break; | ||
384 | |||
385 | ret = adf4371_set_freq(st, freq, chan->channel); | ||
386 | break; | ||
387 | case ADF4371_POWER_DOWN: | ||
388 | ret = kstrtobool(buf, &power_down); | ||
389 | if (ret) | ||
390 | break; | ||
391 | |||
392 | reg = adf4371_pwrdown_ch[chan->channel].reg; | ||
393 | bit = adf4371_pwrdown_ch[chan->channel].bit; | ||
394 | ret = regmap_read(st->regmap, reg, &readval); | ||
395 | if (ret < 0) | ||
396 | break; | ||
397 | |||
398 | readval &= ~BIT(bit); | ||
399 | readval |= (!power_down << bit); | ||
400 | |||
401 | ret = regmap_write(st->regmap, reg, readval); | ||
402 | break; | ||
403 | default: | ||
404 | ret = -EINVAL; | ||
405 | break; | ||
406 | } | ||
407 | mutex_unlock(&st->lock); | ||
408 | |||
409 | return ret ? ret : len; | ||
410 | } | ||
411 | |||
412 | #define _ADF4371_EXT_INFO(_name, _ident) { \ | ||
413 | .name = _name, \ | ||
414 | .read = adf4371_read, \ | ||
415 | .write = adf4371_write, \ | ||
416 | .private = _ident, \ | ||
417 | .shared = IIO_SEPARATE, \ | ||
418 | } | ||
419 | |||
420 | static const struct iio_chan_spec_ext_info adf4371_ext_info[] = { | ||
421 | /* | ||
422 | * Ideally we use IIO_CHAN_INFO_FREQUENCY, but there are | ||
423 | * values > 2^32 in order to support the entire frequency range | ||
424 | * in Hz. Using scale is a bit ugly. | ||
425 | */ | ||
426 | _ADF4371_EXT_INFO("frequency", ADF4371_FREQ), | ||
427 | _ADF4371_EXT_INFO("powerdown", ADF4371_POWER_DOWN), | ||
428 | _ADF4371_EXT_INFO("name", ADF4371_CHANNEL_NAME), | ||
429 | { }, | ||
430 | }; | ||
431 | |||
432 | #define ADF4371_CHANNEL(index) { \ | ||
433 | .type = IIO_ALTVOLTAGE, \ | ||
434 | .output = 1, \ | ||
435 | .channel = index, \ | ||
436 | .ext_info = adf4371_ext_info, \ | ||
437 | .indexed = 1, \ | ||
438 | } | ||
439 | |||
440 | static const struct iio_chan_spec adf4371_chan[] = { | ||
441 | ADF4371_CHANNEL(ADF4371_CH_RF8), | ||
442 | ADF4371_CHANNEL(ADF4371_CH_RFAUX8), | ||
443 | ADF4371_CHANNEL(ADF4371_CH_RF16), | ||
444 | ADF4371_CHANNEL(ADF4371_CH_RF32), | ||
445 | }; | ||
446 | |||
447 | static const struct adf4371_chip_info adf4371_chip_info[] = { | ||
448 | [ADF4371] = { | ||
449 | .channels = adf4371_chan, | ||
450 | .num_channels = 4, | ||
451 | }, | ||
452 | [ADF4372] = { | ||
453 | .channels = adf4371_chan, | ||
454 | .num_channels = 3, | ||
455 | } | ||
456 | }; | ||
457 | |||
458 | static int adf4371_reg_access(struct iio_dev *indio_dev, | ||
459 | unsigned int reg, | ||
460 | unsigned int writeval, | ||
461 | unsigned int *readval) | ||
462 | { | ||
463 | struct adf4371_state *st = iio_priv(indio_dev); | ||
464 | |||
465 | if (readval) | ||
466 | return regmap_read(st->regmap, reg, readval); | ||
467 | else | ||
468 | return regmap_write(st->regmap, reg, writeval); | ||
469 | } | ||
470 | |||
471 | static const struct iio_info adf4371_info = { | ||
472 | .debugfs_reg_access = &adf4371_reg_access, | ||
473 | }; | ||
474 | |||
475 | static int adf4371_setup(struct adf4371_state *st) | ||
476 | { | ||
477 | unsigned int synth_timeout = 2, timeout = 1, vco_alc_timeout = 1; | ||
478 | unsigned int vco_band_div, tmp; | ||
479 | int ret; | ||
480 | |||
481 | /* Perform a software reset */ | ||
482 | ret = regmap_write(st->regmap, ADF4371_REG(0x0), ADF4371_RESET_CMD); | ||
483 | if (ret < 0) | ||
484 | return ret; | ||
485 | |||
486 | ret = regmap_multi_reg_write(st->regmap, adf4371_reg_defaults, | ||
487 | ARRAY_SIZE(adf4371_reg_defaults)); | ||
488 | if (ret < 0) | ||
489 | return ret; | ||
490 | |||
491 | /* Mute to Lock Detect */ | ||
492 | if (device_property_read_bool(&st->spi->dev, "adi,mute-till-lock-en")) { | ||
493 | ret = regmap_update_bits(st->regmap, ADF4371_REG(0x25), | ||
494 | ADF4371_MUTE_LD_MSK, | ||
495 | ADF4371_MUTE_LD(1)); | ||
496 | if (ret < 0) | ||
497 | return ret; | ||
498 | } | ||
499 | |||
500 | /* Set address in ascending order, so the bulk_write() will work */ | ||
501 | ret = regmap_update_bits(st->regmap, ADF4371_REG(0x0), | ||
502 | ADF4371_ADDR_ASC_MSK | ADF4371_ADDR_ASC_R_MSK, | ||
503 | ADF4371_ADDR_ASC(1) | ADF4371_ADDR_ASC_R(1)); | ||
504 | if (ret < 0) | ||
505 | return ret; | ||
506 | /* | ||
507 | * Calculate and maximize PFD frequency | ||
508 | * fPFD = REFIN × ((1 + D)/(R × (1 + T))) | ||
509 | * Where D is the REFIN doubler bit, T is the reference divide by 2, | ||
510 | * R is the reference division factor | ||
511 | * TODO: it is assumed D and T equal 0. | ||
512 | */ | ||
513 | do { | ||
514 | st->ref_div_factor++; | ||
515 | st->fpfd = st->clkin_freq / st->ref_div_factor; | ||
516 | } while (st->fpfd > ADF4371_MAX_FREQ_PFD); | ||
517 | |||
518 | /* Calculate Timeouts */ | ||
519 | vco_band_div = DIV_ROUND_UP(st->fpfd, 2400000U); | ||
520 | |||
521 | tmp = DIV_ROUND_CLOSEST(st->fpfd, 1000000U); | ||
522 | do { | ||
523 | timeout++; | ||
524 | if (timeout > 1023) { | ||
525 | timeout = 2; | ||
526 | synth_timeout++; | ||
527 | } | ||
528 | } while (synth_timeout * 1024 + timeout <= 20 * tmp); | ||
529 | |||
530 | do { | ||
531 | vco_alc_timeout++; | ||
532 | } while (vco_alc_timeout * 1024 - timeout <= 50 * tmp); | ||
533 | |||
534 | st->buf[0] = vco_band_div; | ||
535 | st->buf[1] = timeout & 0xFF; | ||
536 | st->buf[2] = ADF4371_TIMEOUT(timeout >> 8) | 0x04; | ||
537 | st->buf[3] = synth_timeout; | ||
538 | st->buf[4] = ADF4371_VCO_ALC_TOUT(vco_alc_timeout); | ||
539 | |||
540 | return regmap_bulk_write(st->regmap, ADF4371_REG(0x30), st->buf, 5); | ||
541 | } | ||
542 | |||
543 | static void adf4371_clk_disable(void *data) | ||
544 | { | ||
545 | struct adf4371_state *st = data; | ||
546 | |||
547 | clk_disable_unprepare(st->clkin); | ||
548 | } | ||
549 | |||
550 | static int adf4371_probe(struct spi_device *spi) | ||
551 | { | ||
552 | const struct spi_device_id *id = spi_get_device_id(spi); | ||
553 | struct iio_dev *indio_dev; | ||
554 | struct adf4371_state *st; | ||
555 | struct regmap *regmap; | ||
556 | int ret; | ||
557 | |||
558 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | ||
559 | if (!indio_dev) | ||
560 | return -ENOMEM; | ||
561 | |||
562 | regmap = devm_regmap_init_spi(spi, &adf4371_regmap_config); | ||
563 | if (IS_ERR(regmap)) { | ||
564 | dev_err(&spi->dev, "Error initializing spi regmap: %ld\n", | ||
565 | PTR_ERR(regmap)); | ||
566 | return PTR_ERR(regmap); | ||
567 | } | ||
568 | |||
569 | st = iio_priv(indio_dev); | ||
570 | spi_set_drvdata(spi, indio_dev); | ||
571 | st->spi = spi; | ||
572 | st->regmap = regmap; | ||
573 | mutex_init(&st->lock); | ||
574 | |||
575 | st->chip_info = &adf4371_chip_info[id->driver_data]; | ||
576 | indio_dev->dev.parent = &spi->dev; | ||
577 | indio_dev->name = id->name; | ||
578 | indio_dev->info = &adf4371_info; | ||
579 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
580 | indio_dev->channels = st->chip_info->channels; | ||
581 | indio_dev->num_channels = st->chip_info->num_channels; | ||
582 | |||
583 | st->clkin = devm_clk_get(&spi->dev, "clkin"); | ||
584 | if (IS_ERR(st->clkin)) | ||
585 | return PTR_ERR(st->clkin); | ||
586 | |||
587 | ret = clk_prepare_enable(st->clkin); | ||
588 | if (ret < 0) | ||
589 | return ret; | ||
590 | |||
591 | ret = devm_add_action_or_reset(&spi->dev, adf4371_clk_disable, st); | ||
592 | if (ret) | ||
593 | return ret; | ||
594 | |||
595 | st->clkin_freq = clk_get_rate(st->clkin); | ||
596 | |||
597 | ret = adf4371_setup(st); | ||
598 | if (ret < 0) { | ||
599 | dev_err(&spi->dev, "ADF4371 setup failed\n"); | ||
600 | return ret; | ||
601 | } | ||
602 | |||
603 | return devm_iio_device_register(&spi->dev, indio_dev); | ||
604 | } | ||
605 | |||
606 | static const struct spi_device_id adf4371_id_table[] = { | ||
607 | { "adf4371", ADF4371 }, | ||
608 | { "adf4372", ADF4372 }, | ||
609 | {} | ||
610 | }; | ||
611 | MODULE_DEVICE_TABLE(spi, adf4371_id_table); | ||
612 | |||
613 | static const struct of_device_id adf4371_of_match[] = { | ||
614 | { .compatible = "adi,adf4371" }, | ||
615 | { .compatible = "adi,adf4372" }, | ||
616 | { }, | ||
617 | }; | ||
618 | MODULE_DEVICE_TABLE(of, adf4371_of_match); | ||
619 | |||
620 | static struct spi_driver adf4371_driver = { | ||
621 | .driver = { | ||
622 | .name = "adf4371", | ||
623 | .of_match_table = adf4371_of_match, | ||
624 | }, | ||
625 | .probe = adf4371_probe, | ||
626 | .id_table = adf4371_id_table, | ||
627 | }; | ||
628 | module_spi_driver(adf4371_driver); | ||
629 | |||
630 | MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>"); | ||
631 | MODULE_DESCRIPTION("Analog Devices ADF4371 SPI PLL"); | ||
632 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/iio/humidity/dht11.c b/drivers/iio/humidity/dht11.c index c8159205c77d..f5128d8f777a 100644 --- a/drivers/iio/humidity/dht11.c +++ b/drivers/iio/humidity/dht11.c | |||
@@ -22,8 +22,7 @@ | |||
22 | #include <linux/completion.h> | 22 | #include <linux/completion.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/gpio.h> | 25 | #include <linux/gpio/consumer.h> |
26 | #include <linux/of_gpio.h> | ||
27 | #include <linux/timekeeping.h> | 26 | #include <linux/timekeeping.h> |
28 | 27 | ||
29 | #include <linux/iio/iio.h> | 28 | #include <linux/iio/iio.h> |
@@ -72,7 +71,7 @@ | |||
72 | struct dht11 { | 71 | struct dht11 { |
73 | struct device *dev; | 72 | struct device *dev; |
74 | 73 | ||
75 | int gpio; | 74 | struct gpio_desc *gpiod; |
76 | int irq; | 75 | int irq; |
77 | 76 | ||
78 | struct completion completion; | 77 | struct completion completion; |
@@ -179,7 +178,7 @@ static irqreturn_t dht11_handle_irq(int irq, void *data) | |||
179 | if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) { | 178 | if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) { |
180 | dht11->edges[dht11->num_edges].ts = ktime_get_boot_ns(); | 179 | dht11->edges[dht11->num_edges].ts = ktime_get_boot_ns(); |
181 | dht11->edges[dht11->num_edges++].value = | 180 | dht11->edges[dht11->num_edges++].value = |
182 | gpio_get_value(dht11->gpio); | 181 | gpiod_get_value(dht11->gpiod); |
183 | 182 | ||
184 | if (dht11->num_edges >= DHT11_EDGES_PER_READ) | 183 | if (dht11->num_edges >= DHT11_EDGES_PER_READ) |
185 | complete(&dht11->completion); | 184 | complete(&dht11->completion); |
@@ -217,12 +216,12 @@ static int dht11_read_raw(struct iio_dev *iio_dev, | |||
217 | reinit_completion(&dht11->completion); | 216 | reinit_completion(&dht11->completion); |
218 | 217 | ||
219 | dht11->num_edges = 0; | 218 | dht11->num_edges = 0; |
220 | ret = gpio_direction_output(dht11->gpio, 0); | 219 | ret = gpiod_direction_output(dht11->gpiod, 0); |
221 | if (ret) | 220 | if (ret) |
222 | goto err; | 221 | goto err; |
223 | usleep_range(DHT11_START_TRANSMISSION_MIN, | 222 | usleep_range(DHT11_START_TRANSMISSION_MIN, |
224 | DHT11_START_TRANSMISSION_MAX); | 223 | DHT11_START_TRANSMISSION_MAX); |
225 | ret = gpio_direction_input(dht11->gpio); | 224 | ret = gpiod_direction_input(dht11->gpiod); |
226 | if (ret) | 225 | if (ret) |
227 | goto err; | 226 | goto err; |
228 | 227 | ||
@@ -294,10 +293,8 @@ MODULE_DEVICE_TABLE(of, dht11_dt_ids); | |||
294 | static int dht11_probe(struct platform_device *pdev) | 293 | static int dht11_probe(struct platform_device *pdev) |
295 | { | 294 | { |
296 | struct device *dev = &pdev->dev; | 295 | struct device *dev = &pdev->dev; |
297 | struct device_node *node = dev->of_node; | ||
298 | struct dht11 *dht11; | 296 | struct dht11 *dht11; |
299 | struct iio_dev *iio; | 297 | struct iio_dev *iio; |
300 | int ret; | ||
301 | 298 | ||
302 | iio = devm_iio_device_alloc(dev, sizeof(*dht11)); | 299 | iio = devm_iio_device_alloc(dev, sizeof(*dht11)); |
303 | if (!iio) { | 300 | if (!iio) { |
@@ -307,18 +304,13 @@ static int dht11_probe(struct platform_device *pdev) | |||
307 | 304 | ||
308 | dht11 = iio_priv(iio); | 305 | dht11 = iio_priv(iio); |
309 | dht11->dev = dev; | 306 | dht11->dev = dev; |
307 | dht11->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN); | ||
308 | if (IS_ERR(dht11->gpiod)) | ||
309 | return PTR_ERR(dht11->gpiod); | ||
310 | 310 | ||
311 | ret = of_get_gpio(node, 0); | 311 | dht11->irq = gpiod_to_irq(dht11->gpiod); |
312 | if (ret < 0) | ||
313 | return ret; | ||
314 | dht11->gpio = ret; | ||
315 | ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name); | ||
316 | if (ret) | ||
317 | return ret; | ||
318 | |||
319 | dht11->irq = gpio_to_irq(dht11->gpio); | ||
320 | if (dht11->irq < 0) { | 312 | if (dht11->irq < 0) { |
321 | dev_err(dev, "GPIO %d has no interrupt\n", dht11->gpio); | 313 | dev_err(dev, "GPIO %d has no interrupt\n", desc_to_gpio(dht11->gpiod)); |
322 | return -EINVAL; | 314 | return -EINVAL; |
323 | } | 315 | } |
324 | 316 | ||
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 5e461f0e759c..c14bf533b66b 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | |||
@@ -197,7 +197,7 @@ struct st_lsm6dsx_ext_dev_settings { | |||
197 | * struct st_lsm6dsx_settings - ST IMU sensor settings | 197 | * struct st_lsm6dsx_settings - ST IMU sensor settings |
198 | * @wai: Sensor WhoAmI default value. | 198 | * @wai: Sensor WhoAmI default value. |
199 | * @max_fifo_size: Sensor max fifo length in FIFO words. | 199 | * @max_fifo_size: Sensor max fifo length in FIFO words. |
200 | * @id: List of hw id supported by the driver configuration. | 200 | * @id: List of hw id/device name supported by the driver configuration. |
201 | * @decimator: List of decimator register info (addr + mask). | 201 | * @decimator: List of decimator register info (addr + mask). |
202 | * @batch: List of FIFO batching register info (addr + mask). | 202 | * @batch: List of FIFO batching register info (addr + mask). |
203 | * @fifo_ops: Sensor hw FIFO parameters. | 203 | * @fifo_ops: Sensor hw FIFO parameters. |
@@ -207,7 +207,10 @@ struct st_lsm6dsx_ext_dev_settings { | |||
207 | struct st_lsm6dsx_settings { | 207 | struct st_lsm6dsx_settings { |
208 | u8 wai; | 208 | u8 wai; |
209 | u16 max_fifo_size; | 209 | u16 max_fifo_size; |
210 | enum st_lsm6dsx_hw_id id[ST_LSM6DSX_MAX_ID]; | 210 | struct { |
211 | enum st_lsm6dsx_hw_id hw_id; | ||
212 | const char *name; | ||
213 | } id[ST_LSM6DSX_MAX_ID]; | ||
211 | struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID]; | 214 | struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID]; |
212 | struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID]; | 215 | struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID]; |
213 | struct st_lsm6dsx_fifo_ops fifo_ops; | 216 | struct st_lsm6dsx_fifo_ops fifo_ops; |
@@ -303,7 +306,7 @@ struct st_lsm6dsx_hw { | |||
303 | static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0}; | 306 | static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0}; |
304 | extern const struct dev_pm_ops st_lsm6dsx_pm_ops; | 307 | extern const struct dev_pm_ops st_lsm6dsx_pm_ops; |
305 | 308 | ||
306 | int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, | 309 | int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, |
307 | struct regmap *regmap); | 310 | struct regmap *regmap); |
308 | int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, | 311 | int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, |
309 | bool enable); | 312 | bool enable); |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index fd95d924a996..a6702a74570e 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | |||
@@ -124,7 +124,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
124 | .wai = 0x69, | 124 | .wai = 0x69, |
125 | .max_fifo_size = 1365, | 125 | .max_fifo_size = 1365, |
126 | .id = { | 126 | .id = { |
127 | [0] = ST_LSM6DS3_ID, | 127 | { |
128 | .hw_id = ST_LSM6DS3_ID, | ||
129 | .name = ST_LSM6DS3_DEV_NAME, | ||
130 | }, | ||
128 | }, | 131 | }, |
129 | .decimator = { | 132 | .decimator = { |
130 | [ST_LSM6DSX_ID_ACC] = { | 133 | [ST_LSM6DSX_ID_ACC] = { |
@@ -171,7 +174,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
171 | .wai = 0x69, | 174 | .wai = 0x69, |
172 | .max_fifo_size = 682, | 175 | .max_fifo_size = 682, |
173 | .id = { | 176 | .id = { |
174 | [0] = ST_LSM6DS3H_ID, | 177 | { |
178 | .hw_id = ST_LSM6DS3H_ID, | ||
179 | .name = ST_LSM6DS3H_DEV_NAME, | ||
180 | }, | ||
175 | }, | 181 | }, |
176 | .decimator = { | 182 | .decimator = { |
177 | [ST_LSM6DSX_ID_ACC] = { | 183 | [ST_LSM6DSX_ID_ACC] = { |
@@ -218,9 +224,16 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
218 | .wai = 0x6a, | 224 | .wai = 0x6a, |
219 | .max_fifo_size = 682, | 225 | .max_fifo_size = 682, |
220 | .id = { | 226 | .id = { |
221 | [0] = ST_LSM6DSL_ID, | 227 | { |
222 | [1] = ST_LSM6DSM_ID, | 228 | .hw_id = ST_LSM6DSL_ID, |
223 | [2] = ST_ISM330DLC_ID, | 229 | .name = ST_LSM6DSL_DEV_NAME, |
230 | }, { | ||
231 | .hw_id = ST_LSM6DSM_ID, | ||
232 | .name = ST_LSM6DSM_DEV_NAME, | ||
233 | }, { | ||
234 | .hw_id = ST_ISM330DLC_ID, | ||
235 | .name = ST_ISM330DLC_DEV_NAME, | ||
236 | }, | ||
224 | }, | 237 | }, |
225 | .decimator = { | 238 | .decimator = { |
226 | [ST_LSM6DSX_ID_ACC] = { | 239 | [ST_LSM6DSX_ID_ACC] = { |
@@ -267,8 +280,13 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
267 | .wai = 0x6c, | 280 | .wai = 0x6c, |
268 | .max_fifo_size = 512, | 281 | .max_fifo_size = 512, |
269 | .id = { | 282 | .id = { |
270 | [0] = ST_LSM6DSO_ID, | 283 | { |
271 | [1] = ST_LSM6DSOX_ID, | 284 | .hw_id = ST_LSM6DSO_ID, |
285 | .name = ST_LSM6DSO_DEV_NAME, | ||
286 | }, { | ||
287 | .hw_id = ST_LSM6DSOX_ID, | ||
288 | .name = ST_LSM6DSOX_DEV_NAME, | ||
289 | }, | ||
272 | }, | 290 | }, |
273 | .batch = { | 291 | .batch = { |
274 | [ST_LSM6DSX_ID_ACC] = { | 292 | [ST_LSM6DSX_ID_ACC] = { |
@@ -333,7 +351,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
333 | .wai = 0x6b, | 351 | .wai = 0x6b, |
334 | .max_fifo_size = 512, | 352 | .max_fifo_size = 512, |
335 | .id = { | 353 | .id = { |
336 | [0] = ST_ASM330LHH_ID, | 354 | { |
355 | .hw_id = ST_ASM330LHH_ID, | ||
356 | .name = ST_ASM330LHH_DEV_NAME, | ||
357 | }, | ||
337 | }, | 358 | }, |
338 | .batch = { | 359 | .batch = { |
339 | [ST_LSM6DSX_ID_ACC] = { | 360 | [ST_LSM6DSX_ID_ACC] = { |
@@ -372,7 +393,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
372 | .wai = 0x6b, | 393 | .wai = 0x6b, |
373 | .max_fifo_size = 512, | 394 | .max_fifo_size = 512, |
374 | .id = { | 395 | .id = { |
375 | [0] = ST_LSM6DSR_ID, | 396 | { |
397 | .hw_id = ST_LSM6DSR_ID, | ||
398 | .name = ST_LSM6DSR_DEV_NAME, | ||
399 | }, | ||
376 | }, | 400 | }, |
377 | .batch = { | 401 | .batch = { |
378 | [ST_LSM6DSX_ID_ACC] = { | 402 | [ST_LSM6DSX_ID_ACC] = { |
@@ -470,13 +494,14 @@ int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) | |||
470 | return err; | 494 | return err; |
471 | } | 495 | } |
472 | 496 | ||
473 | static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id) | 497 | static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id, |
498 | const char **name) | ||
474 | { | 499 | { |
475 | int err, i, j, data; | 500 | int err, i, j, data; |
476 | 501 | ||
477 | for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { | 502 | for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { |
478 | for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) { | 503 | for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) { |
479 | if (id == st_lsm6dsx_sensor_settings[i].id[j]) | 504 | if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id) |
480 | break; | 505 | break; |
481 | } | 506 | } |
482 | if (j < ST_LSM6DSX_MAX_ID) | 507 | if (j < ST_LSM6DSX_MAX_ID) |
@@ -499,6 +524,7 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id) | |||
499 | return -ENODEV; | 524 | return -ENODEV; |
500 | } | 525 | } |
501 | 526 | ||
527 | *name = st_lsm6dsx_sensor_settings[i].id[j].name; | ||
502 | hw->settings = &st_lsm6dsx_sensor_settings[i]; | 528 | hw->settings = &st_lsm6dsx_sensor_settings[i]; |
503 | 529 | ||
504 | return 0; | 530 | return 0; |
@@ -1040,11 +1066,12 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, | |||
1040 | return iio_dev; | 1066 | return iio_dev; |
1041 | } | 1067 | } |
1042 | 1068 | ||
1043 | int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, | 1069 | int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, |
1044 | struct regmap *regmap) | 1070 | struct regmap *regmap) |
1045 | { | 1071 | { |
1046 | const struct st_lsm6dsx_shub_settings *hub_settings; | 1072 | const struct st_lsm6dsx_shub_settings *hub_settings; |
1047 | struct st_lsm6dsx_hw *hw; | 1073 | struct st_lsm6dsx_hw *hw; |
1074 | const char *name = NULL; | ||
1048 | int i, err; | 1075 | int i, err; |
1049 | 1076 | ||
1050 | hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); | 1077 | hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); |
@@ -1065,7 +1092,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, | |||
1065 | hw->irq = irq; | 1092 | hw->irq = irq; |
1066 | hw->regmap = regmap; | 1093 | hw->regmap = regmap; |
1067 | 1094 | ||
1068 | err = st_lsm6dsx_check_whoami(hw, hw_id); | 1095 | err = st_lsm6dsx_check_whoami(hw, hw_id, &name); |
1069 | if (err < 0) | 1096 | if (err < 0) |
1070 | return err; | 1097 | return err; |
1071 | 1098 | ||
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c index 966d52a4bf1d..b3211e0ac07b 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c | |||
@@ -35,8 +35,7 @@ static int st_lsm6dsx_i2c_probe(struct i2c_client *client, | |||
35 | return PTR_ERR(regmap); | 35 | return PTR_ERR(regmap); |
36 | } | 36 | } |
37 | 37 | ||
38 | return st_lsm6dsx_probe(&client->dev, client->irq, | 38 | return st_lsm6dsx_probe(&client->dev, client->irq, hw_id, regmap); |
39 | hw_id, id->name, regmap); | ||
40 | } | 39 | } |
41 | 40 | ||
42 | static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { | 41 | static const struct of_device_id st_lsm6dsx_i2c_of_match[] = { |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c index 24e4e50414e6..c9d3c4711018 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c | |||
@@ -35,8 +35,7 @@ static int st_lsm6dsx_spi_probe(struct spi_device *spi) | |||
35 | return PTR_ERR(regmap); | 35 | return PTR_ERR(regmap); |
36 | } | 36 | } |
37 | 37 | ||
38 | return st_lsm6dsx_probe(&spi->dev, spi->irq, | 38 | return st_lsm6dsx_probe(&spi->dev, spi->irq, hw_id, regmap); |
39 | hw_id, id->name, regmap); | ||
40 | } | 39 | } |
41 | 40 | ||
42 | static const struct of_device_id st_lsm6dsx_spi_of_match[] = { | 41 | static const struct of_device_id st_lsm6dsx_spi_of_match[] = { |
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 245b5844028d..65de9980b82c 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c | |||
@@ -366,39 +366,25 @@ static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) | |||
366 | debugfs_remove_recursive(indio_dev->debugfs_dentry); | 366 | debugfs_remove_recursive(indio_dev->debugfs_dentry); |
367 | } | 367 | } |
368 | 368 | ||
369 | static int iio_device_register_debugfs(struct iio_dev *indio_dev) | 369 | static void iio_device_register_debugfs(struct iio_dev *indio_dev) |
370 | { | 370 | { |
371 | struct dentry *d; | ||
372 | |||
373 | if (indio_dev->info->debugfs_reg_access == NULL) | 371 | if (indio_dev->info->debugfs_reg_access == NULL) |
374 | return 0; | 372 | return; |
375 | 373 | ||
376 | if (!iio_debugfs_dentry) | 374 | if (!iio_debugfs_dentry) |
377 | return 0; | 375 | return; |
378 | 376 | ||
379 | indio_dev->debugfs_dentry = | 377 | indio_dev->debugfs_dentry = |
380 | debugfs_create_dir(dev_name(&indio_dev->dev), | 378 | debugfs_create_dir(dev_name(&indio_dev->dev), |
381 | iio_debugfs_dentry); | 379 | iio_debugfs_dentry); |
382 | if (indio_dev->debugfs_dentry == NULL) { | ||
383 | dev_warn(indio_dev->dev.parent, | ||
384 | "Failed to create debugfs directory\n"); | ||
385 | return -EFAULT; | ||
386 | } | ||
387 | |||
388 | d = debugfs_create_file("direct_reg_access", 0644, | ||
389 | indio_dev->debugfs_dentry, | ||
390 | indio_dev, &iio_debugfs_reg_fops); | ||
391 | if (!d) { | ||
392 | iio_device_unregister_debugfs(indio_dev); | ||
393 | return -ENOMEM; | ||
394 | } | ||
395 | 380 | ||
396 | return 0; | 381 | debugfs_create_file("direct_reg_access", 0644, |
382 | indio_dev->debugfs_dentry, indio_dev, | ||
383 | &iio_debugfs_reg_fops); | ||
397 | } | 384 | } |
398 | #else | 385 | #else |
399 | static int iio_device_register_debugfs(struct iio_dev *indio_dev) | 386 | static void iio_device_register_debugfs(struct iio_dev *indio_dev) |
400 | { | 387 | { |
401 | return 0; | ||
402 | } | 388 | } |
403 | 389 | ||
404 | static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) | 390 | static void iio_device_unregister_debugfs(struct iio_dev *indio_dev) |
@@ -1104,6 +1090,8 @@ static int iio_device_add_info_mask_type_avail(struct iio_dev *indio_dev, | |||
1104 | char *avail_postfix; | 1090 | char *avail_postfix; |
1105 | 1091 | ||
1106 | for_each_set_bit(i, infomask, sizeof(*infomask) * 8) { | 1092 | for_each_set_bit(i, infomask, sizeof(*infomask) * 8) { |
1093 | if (i >= ARRAY_SIZE(iio_chan_info_postfix)) | ||
1094 | return -EINVAL; | ||
1107 | avail_postfix = kasprintf(GFP_KERNEL, | 1095 | avail_postfix = kasprintf(GFP_KERNEL, |
1108 | "%s_available", | 1096 | "%s_available", |
1109 | iio_chan_info_postfix[i]); | 1097 | iio_chan_info_postfix[i]); |
@@ -1669,12 +1657,7 @@ int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod) | |||
1669 | /* configure elements for the chrdev */ | 1657 | /* configure elements for the chrdev */ |
1670 | indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); | 1658 | indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id); |
1671 | 1659 | ||
1672 | ret = iio_device_register_debugfs(indio_dev); | 1660 | iio_device_register_debugfs(indio_dev); |
1673 | if (ret) { | ||
1674 | dev_err(indio_dev->dev.parent, | ||
1675 | "Failed to register debugfs interfaces\n"); | ||
1676 | return ret; | ||
1677 | } | ||
1678 | 1661 | ||
1679 | ret = iio_buffer_alloc_sysfs_and_mask(indio_dev); | 1662 | ret = iio_buffer_alloc_sysfs_and_mask(indio_dev); |
1680 | if (ret) { | 1663 | if (ret) { |
diff --git a/drivers/iio/light/bh1780.c b/drivers/iio/light/bh1780.c index 340d64d0ac59..a8361006dcd9 100644 --- a/drivers/iio/light/bh1780.c +++ b/drivers/iio/light/bh1780.c | |||
@@ -146,7 +146,7 @@ static int bh1780_probe(struct i2c_client *client, | |||
146 | { | 146 | { |
147 | int ret; | 147 | int ret; |
148 | struct bh1780_data *bh1780; | 148 | struct bh1780_data *bh1780; |
149 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 149 | struct i2c_adapter *adapter = client->adapter; |
150 | struct iio_dev *indio_dev; | 150 | struct iio_dev *indio_dev; |
151 | 151 | ||
152 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) | 152 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) |
diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c index eff7ac9ae669..b955183edfe8 100644 --- a/drivers/iio/light/stk3310.c +++ b/drivers/iio/light/stk3310.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #define STK3310_CHIP_ID_VAL 0x13 | 38 | #define STK3310_CHIP_ID_VAL 0x13 |
39 | #define STK3311_CHIP_ID_VAL 0x1D | 39 | #define STK3311_CHIP_ID_VAL 0x1D |
40 | #define STK3335_CHIP_ID_VAL 0x51 | ||
40 | #define STK3310_PSINT_EN 0x01 | 41 | #define STK3310_PSINT_EN 0x01 |
41 | #define STK3310_PS_MAX_VAL 0xFFFF | 42 | #define STK3310_PS_MAX_VAL 0xFFFF |
42 | 43 | ||
@@ -451,7 +452,8 @@ static int stk3310_init(struct iio_dev *indio_dev) | |||
451 | return ret; | 452 | return ret; |
452 | 453 | ||
453 | if (chipid != STK3310_CHIP_ID_VAL && | 454 | if (chipid != STK3310_CHIP_ID_VAL && |
454 | chipid != STK3311_CHIP_ID_VAL) { | 455 | chipid != STK3311_CHIP_ID_VAL && |
456 | chipid != STK3335_CHIP_ID_VAL) { | ||
455 | dev_err(&client->dev, "invalid chip id: 0x%x\n", chipid); | 457 | dev_err(&client->dev, "invalid chip id: 0x%x\n", chipid); |
456 | return -ENODEV; | 458 | return -ENODEV; |
457 | } | 459 | } |
@@ -663,6 +665,7 @@ static SIMPLE_DEV_PM_OPS(stk3310_pm_ops, stk3310_suspend, stk3310_resume); | |||
663 | static const struct i2c_device_id stk3310_i2c_id[] = { | 665 | static const struct i2c_device_id stk3310_i2c_id[] = { |
664 | {"STK3310", 0}, | 666 | {"STK3310", 0}, |
665 | {"STK3311", 0}, | 667 | {"STK3311", 0}, |
668 | {"STK3335", 0}, | ||
666 | {} | 669 | {} |
667 | }; | 670 | }; |
668 | MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id); | 671 | MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id); |
@@ -670,6 +673,7 @@ MODULE_DEVICE_TABLE(i2c, stk3310_i2c_id); | |||
670 | static const struct acpi_device_id stk3310_acpi_id[] = { | 673 | static const struct acpi_device_id stk3310_acpi_id[] = { |
671 | {"STK3310", 0}, | 674 | {"STK3310", 0}, |
672 | {"STK3311", 0}, | 675 | {"STK3311", 0}, |
676 | {"STK3335", 0}, | ||
673 | {} | 677 | {} |
674 | }; | 678 | }; |
675 | 679 | ||
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index b191811fd749..ba420e484787 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig | |||
@@ -53,6 +53,17 @@ config IIO_CROS_EC_BARO | |||
53 | To compile this driver as a module, choose M here: the module | 53 | To compile this driver as a module, choose M here: the module |
54 | will be called cros_ec_baro. | 54 | will be called cros_ec_baro. |
55 | 55 | ||
56 | config DPS310 | ||
57 | tristate "Infineon DPS310 pressure and temperature sensor" | ||
58 | depends on I2C | ||
59 | select REGMAP_I2C | ||
60 | help | ||
61 | Support for the Infineon DPS310 digital barometric pressure sensor. | ||
62 | It can be accessed over I2C bus. | ||
63 | |||
64 | This driver can also be built as a module. If so, the module will be | ||
65 | called dps310. | ||
66 | |||
56 | config HID_SENSOR_PRESS | 67 | config HID_SENSOR_PRESS |
57 | depends on HID_SENSOR_HUB | 68 | depends on HID_SENSOR_HUB |
58 | select IIO_BUFFER | 69 | select IIO_BUFFER |
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index c2058d7b2f93..d8f5ace1f25d 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_BMP280) += bmp280.o | |||
9 | bmp280-objs := bmp280-core.o bmp280-regmap.o | 9 | bmp280-objs := bmp280-core.o bmp280-regmap.o |
10 | obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o | 10 | obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o |
11 | obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o | 11 | obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o |
12 | obj-$(CONFIG_DPS310) += dps310.o | ||
12 | obj-$(CONFIG_IIO_CROS_EC_BARO) += cros_ec_baro.o | 13 | obj-$(CONFIG_IIO_CROS_EC_BARO) += cros_ec_baro.o |
13 | obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o | 14 | obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o |
14 | obj-$(CONFIG_HP03) += hp03.o | 15 | obj-$(CONFIG_HP03) += hp03.o |
diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c new file mode 100644 index 000000000000..2c1943bbc433 --- /dev/null +++ b/drivers/iio/pressure/dps310.c | |||
@@ -0,0 +1,827 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | // Copyright IBM Corp 2019 | ||
3 | /* | ||
4 | * The DPS310 is a barometric pressure and temperature sensor. | ||
5 | * Currently only reading a single temperature is supported by | ||
6 | * this driver. | ||
7 | * | ||
8 | * https://www.infineon.com/dgdl/?fileId=5546d462576f34750157750826c42242 | ||
9 | * | ||
10 | * Temperature calculation: | ||
11 | * c0 * 0.5 + c1 * T_raw / kT °C | ||
12 | * | ||
13 | * TODO: | ||
14 | * - Optionally support the FIFO | ||
15 | */ | ||
16 | |||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/limits.h> | ||
19 | #include <linux/math64.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/regmap.h> | ||
22 | |||
23 | #include <linux/iio/iio.h> | ||
24 | #include <linux/iio/sysfs.h> | ||
25 | |||
26 | #define DPS310_DEV_NAME "dps310" | ||
27 | |||
28 | #define DPS310_PRS_B0 0x00 | ||
29 | #define DPS310_PRS_B1 0x01 | ||
30 | #define DPS310_PRS_B2 0x02 | ||
31 | #define DPS310_TMP_B0 0x03 | ||
32 | #define DPS310_TMP_B1 0x04 | ||
33 | #define DPS310_TMP_B2 0x05 | ||
34 | #define DPS310_PRS_CFG 0x06 | ||
35 | #define DPS310_PRS_RATE_BITS GENMASK(6, 4) | ||
36 | #define DPS310_PRS_PRC_BITS GENMASK(3, 0) | ||
37 | #define DPS310_TMP_CFG 0x07 | ||
38 | #define DPS310_TMP_RATE_BITS GENMASK(6, 4) | ||
39 | #define DPS310_TMP_PRC_BITS GENMASK(3, 0) | ||
40 | #define DPS310_TMP_EXT BIT(7) | ||
41 | #define DPS310_MEAS_CFG 0x08 | ||
42 | #define DPS310_MEAS_CTRL_BITS GENMASK(2, 0) | ||
43 | #define DPS310_PRS_EN BIT(0) | ||
44 | #define DPS310_TEMP_EN BIT(1) | ||
45 | #define DPS310_BACKGROUND BIT(2) | ||
46 | #define DPS310_PRS_RDY BIT(4) | ||
47 | #define DPS310_TMP_RDY BIT(5) | ||
48 | #define DPS310_SENSOR_RDY BIT(6) | ||
49 | #define DPS310_COEF_RDY BIT(7) | ||
50 | #define DPS310_CFG_REG 0x09 | ||
51 | #define DPS310_INT_HL BIT(7) | ||
52 | #define DPS310_TMP_SHIFT_EN BIT(3) | ||
53 | #define DPS310_PRS_SHIFT_EN BIT(4) | ||
54 | #define DPS310_FIFO_EN BIT(5) | ||
55 | #define DPS310_SPI_EN BIT(6) | ||
56 | #define DPS310_RESET 0x0c | ||
57 | #define DPS310_RESET_MAGIC 0x09 | ||
58 | #define DPS310_COEF_BASE 0x10 | ||
59 | |||
60 | /* Make sure sleep time is <= 20ms for usleep_range */ | ||
61 | #define DPS310_POLL_SLEEP_US(t) min(20000, (t) / 8) | ||
62 | /* Silently handle error in rate value here */ | ||
63 | #define DPS310_POLL_TIMEOUT_US(rc) ((rc) <= 0 ? 1000000 : 1000000 / (rc)) | ||
64 | |||
65 | #define DPS310_PRS_BASE DPS310_PRS_B0 | ||
66 | #define DPS310_TMP_BASE DPS310_TMP_B0 | ||
67 | |||
68 | /* | ||
69 | * These values (defined in the spec) indicate how to scale the raw register | ||
70 | * values for each level of precision available. | ||
71 | */ | ||
72 | static const int scale_factors[] = { | ||
73 | 524288, | ||
74 | 1572864, | ||
75 | 3670016, | ||
76 | 7864320, | ||
77 | 253952, | ||
78 | 516096, | ||
79 | 1040384, | ||
80 | 2088960, | ||
81 | }; | ||
82 | |||
83 | struct dps310_data { | ||
84 | struct i2c_client *client; | ||
85 | struct regmap *regmap; | ||
86 | struct mutex lock; /* Lock for sequential HW access functions */ | ||
87 | |||
88 | s32 c0, c1; | ||
89 | s32 c00, c10, c20, c30, c01, c11, c21; | ||
90 | s32 pressure_raw; | ||
91 | s32 temp_raw; | ||
92 | }; | ||
93 | |||
94 | static const struct iio_chan_spec dps310_channels[] = { | ||
95 | { | ||
96 | .type = IIO_TEMP, | ||
97 | .info_mask_separate = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | | ||
98 | BIT(IIO_CHAN_INFO_SAMP_FREQ) | | ||
99 | BIT(IIO_CHAN_INFO_PROCESSED), | ||
100 | }, | ||
101 | { | ||
102 | .type = IIO_PRESSURE, | ||
103 | .info_mask_separate = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | | ||
104 | BIT(IIO_CHAN_INFO_SAMP_FREQ) | | ||
105 | BIT(IIO_CHAN_INFO_PROCESSED), | ||
106 | }, | ||
107 | }; | ||
108 | |||
109 | /* To be called after checking the COEF_RDY bit in MEAS_CFG */ | ||
110 | static int dps310_get_coefs(struct dps310_data *data) | ||
111 | { | ||
112 | int rc; | ||
113 | u8 coef[18]; | ||
114 | u32 c0, c1; | ||
115 | u32 c00, c10, c20, c30, c01, c11, c21; | ||
116 | |||
117 | /* Read all sensor calibration coefficients from the COEF registers. */ | ||
118 | rc = regmap_bulk_read(data->regmap, DPS310_COEF_BASE, coef, | ||
119 | sizeof(coef)); | ||
120 | if (rc < 0) | ||
121 | return rc; | ||
122 | |||
123 | /* | ||
124 | * Calculate temperature calibration coefficients c0 and c1. The | ||
125 | * numbers are 12-bit 2's complement numbers. | ||
126 | */ | ||
127 | c0 = (coef[0] << 4) | (coef[1] >> 4); | ||
128 | data->c0 = sign_extend32(c0, 11); | ||
129 | |||
130 | c1 = ((coef[1] & GENMASK(3, 0)) << 8) | coef[2]; | ||
131 | data->c1 = sign_extend32(c1, 11); | ||
132 | |||
133 | /* | ||
134 | * Calculate pressure calibration coefficients. c00 and c10 are 20 bit | ||
135 | * 2's complement numbers, while the rest are 16 bit 2's complement | ||
136 | * numbers. | ||
137 | */ | ||
138 | c00 = (coef[3] << 12) | (coef[4] << 4) | (coef[5] >> 4); | ||
139 | data->c00 = sign_extend32(c00, 19); | ||
140 | |||
141 | c10 = ((coef[5] & GENMASK(3, 0)) << 16) | (coef[6] << 8) | coef[7]; | ||
142 | data->c10 = sign_extend32(c10, 19); | ||
143 | |||
144 | c01 = (coef[8] << 8) | coef[9]; | ||
145 | data->c01 = sign_extend32(c01, 15); | ||
146 | |||
147 | c11 = (coef[10] << 8) | coef[11]; | ||
148 | data->c11 = sign_extend32(c11, 15); | ||
149 | |||
150 | c20 = (coef[12] << 8) | coef[13]; | ||
151 | data->c20 = sign_extend32(c20, 15); | ||
152 | |||
153 | c21 = (coef[14] << 8) | coef[15]; | ||
154 | data->c21 = sign_extend32(c21, 15); | ||
155 | |||
156 | c30 = (coef[16] << 8) | coef[17]; | ||
157 | data->c30 = sign_extend32(c30, 15); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int dps310_get_pres_precision(struct dps310_data *data) | ||
163 | { | ||
164 | int rc; | ||
165 | int val; | ||
166 | |||
167 | rc = regmap_read(data->regmap, DPS310_PRS_CFG, &val); | ||
168 | if (rc < 0) | ||
169 | return rc; | ||
170 | |||
171 | return BIT(val & GENMASK(2, 0)); | ||
172 | } | ||
173 | |||
174 | static int dps310_get_temp_precision(struct dps310_data *data) | ||
175 | { | ||
176 | int rc; | ||
177 | int val; | ||
178 | |||
179 | rc = regmap_read(data->regmap, DPS310_TMP_CFG, &val); | ||
180 | if (rc < 0) | ||
181 | return rc; | ||
182 | |||
183 | /* | ||
184 | * Scale factor is bottom 4 bits of the register, but 1111 is | ||
185 | * reserved so just grab bottom three | ||
186 | */ | ||
187 | return BIT(val & GENMASK(2, 0)); | ||
188 | } | ||
189 | |||
190 | /* Called with lock held */ | ||
191 | static int dps310_set_pres_precision(struct dps310_data *data, int val) | ||
192 | { | ||
193 | int rc; | ||
194 | u8 shift_en; | ||
195 | |||
196 | if (val < 0 || val > 128) | ||
197 | return -EINVAL; | ||
198 | |||
199 | shift_en = val >= 16 ? DPS310_PRS_SHIFT_EN : 0; | ||
200 | rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, | ||
201 | DPS310_PRS_SHIFT_EN, shift_en); | ||
202 | if (rc) | ||
203 | return rc; | ||
204 | |||
205 | return regmap_update_bits(data->regmap, DPS310_PRS_CFG, | ||
206 | DPS310_PRS_PRC_BITS, ilog2(val)); | ||
207 | } | ||
208 | |||
209 | /* Called with lock held */ | ||
210 | static int dps310_set_temp_precision(struct dps310_data *data, int val) | ||
211 | { | ||
212 | int rc; | ||
213 | u8 shift_en; | ||
214 | |||
215 | if (val < 0 || val > 128) | ||
216 | return -EINVAL; | ||
217 | |||
218 | shift_en = val >= 16 ? DPS310_TMP_SHIFT_EN : 0; | ||
219 | rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, | ||
220 | DPS310_TMP_SHIFT_EN, shift_en); | ||
221 | if (rc) | ||
222 | return rc; | ||
223 | |||
224 | return regmap_update_bits(data->regmap, DPS310_TMP_CFG, | ||
225 | DPS310_TMP_PRC_BITS, ilog2(val)); | ||
226 | } | ||
227 | |||
228 | /* Called with lock held */ | ||
229 | static int dps310_set_pres_samp_freq(struct dps310_data *data, int freq) | ||
230 | { | ||
231 | u8 val; | ||
232 | |||
233 | if (freq < 0 || freq > 128) | ||
234 | return -EINVAL; | ||
235 | |||
236 | val = ilog2(freq) << 4; | ||
237 | |||
238 | return regmap_update_bits(data->regmap, DPS310_PRS_CFG, | ||
239 | DPS310_PRS_RATE_BITS, val); | ||
240 | } | ||
241 | |||
242 | /* Called with lock held */ | ||
243 | static int dps310_set_temp_samp_freq(struct dps310_data *data, int freq) | ||
244 | { | ||
245 | u8 val; | ||
246 | |||
247 | if (freq < 0 || freq > 128) | ||
248 | return -EINVAL; | ||
249 | |||
250 | val = ilog2(freq) << 4; | ||
251 | |||
252 | return regmap_update_bits(data->regmap, DPS310_TMP_CFG, | ||
253 | DPS310_TMP_RATE_BITS, val); | ||
254 | } | ||
255 | |||
256 | static int dps310_get_pres_samp_freq(struct dps310_data *data) | ||
257 | { | ||
258 | int rc; | ||
259 | int val; | ||
260 | |||
261 | rc = regmap_read(data->regmap, DPS310_PRS_CFG, &val); | ||
262 | if (rc < 0) | ||
263 | return rc; | ||
264 | |||
265 | return BIT((val & DPS310_PRS_RATE_BITS) >> 4); | ||
266 | } | ||
267 | |||
268 | static int dps310_get_temp_samp_freq(struct dps310_data *data) | ||
269 | { | ||
270 | int rc; | ||
271 | int val; | ||
272 | |||
273 | rc = regmap_read(data->regmap, DPS310_TMP_CFG, &val); | ||
274 | if (rc < 0) | ||
275 | return rc; | ||
276 | |||
277 | return BIT((val & DPS310_TMP_RATE_BITS) >> 4); | ||
278 | } | ||
279 | |||
280 | static int dps310_get_pres_k(struct dps310_data *data) | ||
281 | { | ||
282 | int rc = dps310_get_pres_precision(data); | ||
283 | |||
284 | if (rc < 0) | ||
285 | return rc; | ||
286 | |||
287 | return scale_factors[ilog2(rc)]; | ||
288 | } | ||
289 | |||
290 | static int dps310_get_temp_k(struct dps310_data *data) | ||
291 | { | ||
292 | int rc = dps310_get_temp_precision(data); | ||
293 | |||
294 | if (rc < 0) | ||
295 | return rc; | ||
296 | |||
297 | return scale_factors[ilog2(rc)]; | ||
298 | } | ||
299 | |||
300 | static int dps310_read_pres_raw(struct dps310_data *data) | ||
301 | { | ||
302 | int rc; | ||
303 | int rate; | ||
304 | int ready; | ||
305 | int timeout; | ||
306 | s32 raw; | ||
307 | u8 val[3]; | ||
308 | |||
309 | if (mutex_lock_interruptible(&data->lock)) | ||
310 | return -EINTR; | ||
311 | |||
312 | rate = dps310_get_pres_samp_freq(data); | ||
313 | timeout = DPS310_POLL_TIMEOUT_US(rate); | ||
314 | |||
315 | /* Poll for sensor readiness; base the timeout upon the sample rate. */ | ||
316 | rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, | ||
317 | ready & DPS310_PRS_RDY, | ||
318 | DPS310_POLL_SLEEP_US(timeout), timeout); | ||
319 | if (rc) | ||
320 | goto done; | ||
321 | |||
322 | rc = regmap_bulk_read(data->regmap, DPS310_PRS_BASE, val, sizeof(val)); | ||
323 | if (rc < 0) | ||
324 | goto done; | ||
325 | |||
326 | raw = (val[0] << 16) | (val[1] << 8) | val[2]; | ||
327 | data->pressure_raw = sign_extend32(raw, 23); | ||
328 | |||
329 | done: | ||
330 | mutex_unlock(&data->lock); | ||
331 | return rc; | ||
332 | } | ||
333 | |||
334 | /* Called with lock held */ | ||
335 | static int dps310_read_temp_ready(struct dps310_data *data) | ||
336 | { | ||
337 | int rc; | ||
338 | u8 val[3]; | ||
339 | s32 raw; | ||
340 | |||
341 | rc = regmap_bulk_read(data->regmap, DPS310_TMP_BASE, val, sizeof(val)); | ||
342 | if (rc < 0) | ||
343 | return rc; | ||
344 | |||
345 | raw = (val[0] << 16) | (val[1] << 8) | val[2]; | ||
346 | data->temp_raw = sign_extend32(raw, 23); | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static int dps310_read_temp_raw(struct dps310_data *data) | ||
352 | { | ||
353 | int rc; | ||
354 | int rate; | ||
355 | int ready; | ||
356 | int timeout; | ||
357 | |||
358 | if (mutex_lock_interruptible(&data->lock)) | ||
359 | return -EINTR; | ||
360 | |||
361 | rate = dps310_get_temp_samp_freq(data); | ||
362 | timeout = DPS310_POLL_TIMEOUT_US(rate); | ||
363 | |||
364 | /* Poll for sensor readiness; base the timeout upon the sample rate. */ | ||
365 | rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, | ||
366 | ready & DPS310_TMP_RDY, | ||
367 | DPS310_POLL_SLEEP_US(timeout), timeout); | ||
368 | if (rc < 0) | ||
369 | goto done; | ||
370 | |||
371 | rc = dps310_read_temp_ready(data); | ||
372 | |||
373 | done: | ||
374 | mutex_unlock(&data->lock); | ||
375 | return rc; | ||
376 | } | ||
377 | |||
378 | static bool dps310_is_writeable_reg(struct device *dev, unsigned int reg) | ||
379 | { | ||
380 | switch (reg) { | ||
381 | case DPS310_PRS_CFG: | ||
382 | case DPS310_TMP_CFG: | ||
383 | case DPS310_MEAS_CFG: | ||
384 | case DPS310_CFG_REG: | ||
385 | case DPS310_RESET: | ||
386 | /* No documentation available on the registers below */ | ||
387 | case 0x0e: | ||
388 | case 0x0f: | ||
389 | case 0x62: | ||
390 | return true; | ||
391 | default: | ||
392 | return false; | ||
393 | } | ||
394 | } | ||
395 | |||
396 | static bool dps310_is_volatile_reg(struct device *dev, unsigned int reg) | ||
397 | { | ||
398 | switch (reg) { | ||
399 | case DPS310_PRS_B0: | ||
400 | case DPS310_PRS_B1: | ||
401 | case DPS310_PRS_B2: | ||
402 | case DPS310_TMP_B0: | ||
403 | case DPS310_TMP_B1: | ||
404 | case DPS310_TMP_B2: | ||
405 | case DPS310_MEAS_CFG: | ||
406 | case 0x32: /* No documentation available on this register */ | ||
407 | return true; | ||
408 | default: | ||
409 | return false; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | static int dps310_write_raw(struct iio_dev *iio, | ||
414 | struct iio_chan_spec const *chan, int val, | ||
415 | int val2, long mask) | ||
416 | { | ||
417 | int rc; | ||
418 | struct dps310_data *data = iio_priv(iio); | ||
419 | |||
420 | if (mutex_lock_interruptible(&data->lock)) | ||
421 | return -EINTR; | ||
422 | |||
423 | switch (mask) { | ||
424 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
425 | switch (chan->type) { | ||
426 | case IIO_PRESSURE: | ||
427 | rc = dps310_set_pres_samp_freq(data, val); | ||
428 | break; | ||
429 | |||
430 | case IIO_TEMP: | ||
431 | rc = dps310_set_temp_samp_freq(data, val); | ||
432 | break; | ||
433 | |||
434 | default: | ||
435 | rc = -EINVAL; | ||
436 | break; | ||
437 | } | ||
438 | break; | ||
439 | |||
440 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: | ||
441 | switch (chan->type) { | ||
442 | case IIO_PRESSURE: | ||
443 | rc = dps310_set_pres_precision(data, val); | ||
444 | break; | ||
445 | |||
446 | case IIO_TEMP: | ||
447 | rc = dps310_set_temp_precision(data, val); | ||
448 | break; | ||
449 | |||
450 | default: | ||
451 | rc = -EINVAL; | ||
452 | break; | ||
453 | } | ||
454 | break; | ||
455 | |||
456 | default: | ||
457 | rc = -EINVAL; | ||
458 | break; | ||
459 | } | ||
460 | |||
461 | mutex_unlock(&data->lock); | ||
462 | return rc; | ||
463 | } | ||
464 | |||
465 | static int dps310_calculate_pressure(struct dps310_data *data) | ||
466 | { | ||
467 | int i; | ||
468 | int rc; | ||
469 | int t_ready; | ||
470 | int kpi = dps310_get_pres_k(data); | ||
471 | int kti = dps310_get_temp_k(data); | ||
472 | s64 rem = 0ULL; | ||
473 | s64 pressure = 0ULL; | ||
474 | s64 p; | ||
475 | s64 t; | ||
476 | s64 denoms[7]; | ||
477 | s64 nums[7]; | ||
478 | s64 rems[7]; | ||
479 | s64 kp; | ||
480 | s64 kt; | ||
481 | |||
482 | if (kpi < 0) | ||
483 | return kpi; | ||
484 | |||
485 | if (kti < 0) | ||
486 | return kti; | ||
487 | |||
488 | kp = (s64)kpi; | ||
489 | kt = (s64)kti; | ||
490 | |||
491 | /* Refresh temp if it's ready, otherwise just use the latest value */ | ||
492 | if (mutex_trylock(&data->lock)) { | ||
493 | rc = regmap_read(data->regmap, DPS310_MEAS_CFG, &t_ready); | ||
494 | if (rc >= 0 && t_ready & DPS310_TMP_RDY) | ||
495 | dps310_read_temp_ready(data); | ||
496 | |||
497 | mutex_unlock(&data->lock); | ||
498 | } | ||
499 | |||
500 | p = (s64)data->pressure_raw; | ||
501 | t = (s64)data->temp_raw; | ||
502 | |||
503 | /* Section 4.9.1 of the DPS310 spec; algebra'd to avoid underflow */ | ||
504 | nums[0] = (s64)data->c00; | ||
505 | denoms[0] = 1LL; | ||
506 | nums[1] = p * (s64)data->c10; | ||
507 | denoms[1] = kp; | ||
508 | nums[2] = p * p * (s64)data->c20; | ||
509 | denoms[2] = kp * kp; | ||
510 | nums[3] = p * p * p * (s64)data->c30; | ||
511 | denoms[3] = kp * kp * kp; | ||
512 | nums[4] = t * (s64)data->c01; | ||
513 | denoms[4] = kt; | ||
514 | nums[5] = t * p * (s64)data->c11; | ||
515 | denoms[5] = kp * kt; | ||
516 | nums[6] = t * p * p * (s64)data->c21; | ||
517 | denoms[6] = kp * kp * kt; | ||
518 | |||
519 | /* Kernel lacks a div64_s64_rem function; denoms are all positive */ | ||
520 | for (i = 0; i < 7; ++i) { | ||
521 | u64 irem; | ||
522 | |||
523 | if (nums[i] < 0LL) { | ||
524 | pressure -= div64_u64_rem(-nums[i], denoms[i], &irem); | ||
525 | rems[i] = -irem; | ||
526 | } else { | ||
527 | pressure += div64_u64_rem(nums[i], denoms[i], &irem); | ||
528 | rems[i] = (s64)irem; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | /* Increase precision and calculate the remainder sum */ | ||
533 | for (i = 0; i < 7; ++i) | ||
534 | rem += div64_s64((s64)rems[i] * 1000000000LL, denoms[i]); | ||
535 | |||
536 | pressure += div_s64(rem, 1000000000LL); | ||
537 | if (pressure < 0LL) | ||
538 | return -ERANGE; | ||
539 | |||
540 | return (int)min_t(s64, pressure, INT_MAX); | ||
541 | } | ||
542 | |||
543 | static int dps310_read_pressure(struct dps310_data *data, int *val, int *val2, | ||
544 | long mask) | ||
545 | { | ||
546 | int rc; | ||
547 | |||
548 | switch (mask) { | ||
549 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
550 | rc = dps310_get_pres_samp_freq(data); | ||
551 | if (rc < 0) | ||
552 | return rc; | ||
553 | |||
554 | *val = rc; | ||
555 | return IIO_VAL_INT; | ||
556 | |||
557 | case IIO_CHAN_INFO_PROCESSED: | ||
558 | rc = dps310_read_pres_raw(data); | ||
559 | if (rc) | ||
560 | return rc; | ||
561 | |||
562 | rc = dps310_calculate_pressure(data); | ||
563 | if (rc < 0) | ||
564 | return rc; | ||
565 | |||
566 | *val = rc; | ||
567 | *val2 = 1000; /* Convert Pa to KPa per IIO ABI */ | ||
568 | return IIO_VAL_FRACTIONAL; | ||
569 | |||
570 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: | ||
571 | rc = dps310_get_pres_precision(data); | ||
572 | if (rc < 0) | ||
573 | return rc; | ||
574 | |||
575 | *val = rc; | ||
576 | return IIO_VAL_INT; | ||
577 | |||
578 | default: | ||
579 | return -EINVAL; | ||
580 | } | ||
581 | } | ||
582 | |||
583 | static int dps310_calculate_temp(struct dps310_data *data) | ||
584 | { | ||
585 | s64 c0; | ||
586 | s64 t; | ||
587 | int kt = dps310_get_temp_k(data); | ||
588 | |||
589 | if (kt < 0) | ||
590 | return kt; | ||
591 | |||
592 | /* Obtain inverse-scaled offset */ | ||
593 | c0 = div_s64((s64)kt * (s64)data->c0, 2); | ||
594 | |||
595 | /* Add the offset to the unscaled temperature */ | ||
596 | t = c0 + ((s64)data->temp_raw * (s64)data->c1); | ||
597 | |||
598 | /* Convert to milliCelsius and scale the temperature */ | ||
599 | return (int)div_s64(t * 1000LL, kt); | ||
600 | } | ||
601 | |||
602 | static int dps310_read_temp(struct dps310_data *data, int *val, int *val2, | ||
603 | long mask) | ||
604 | { | ||
605 | int rc; | ||
606 | |||
607 | switch (mask) { | ||
608 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
609 | rc = dps310_get_temp_samp_freq(data); | ||
610 | if (rc < 0) | ||
611 | return rc; | ||
612 | |||
613 | *val = rc; | ||
614 | return IIO_VAL_INT; | ||
615 | |||
616 | case IIO_CHAN_INFO_PROCESSED: | ||
617 | rc = dps310_read_temp_raw(data); | ||
618 | if (rc) | ||
619 | return rc; | ||
620 | |||
621 | rc = dps310_calculate_temp(data); | ||
622 | if (rc < 0) | ||
623 | return rc; | ||
624 | |||
625 | *val = rc; | ||
626 | return IIO_VAL_INT; | ||
627 | |||
628 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: | ||
629 | rc = dps310_get_temp_precision(data); | ||
630 | if (rc < 0) | ||
631 | return rc; | ||
632 | |||
633 | *val = rc; | ||
634 | return IIO_VAL_INT; | ||
635 | |||
636 | default: | ||
637 | return -EINVAL; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | static int dps310_read_raw(struct iio_dev *iio, | ||
642 | struct iio_chan_spec const *chan, | ||
643 | int *val, int *val2, long mask) | ||
644 | { | ||
645 | struct dps310_data *data = iio_priv(iio); | ||
646 | |||
647 | switch (chan->type) { | ||
648 | case IIO_PRESSURE: | ||
649 | return dps310_read_pressure(data, val, val2, mask); | ||
650 | |||
651 | case IIO_TEMP: | ||
652 | return dps310_read_temp(data, val, val2, mask); | ||
653 | |||
654 | default: | ||
655 | return -EINVAL; | ||
656 | } | ||
657 | } | ||
658 | |||
659 | static void dps310_reset(void *action_data) | ||
660 | { | ||
661 | struct dps310_data *data = action_data; | ||
662 | |||
663 | regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC); | ||
664 | } | ||
665 | |||
666 | static const struct regmap_config dps310_regmap_config = { | ||
667 | .reg_bits = 8, | ||
668 | .val_bits = 8, | ||
669 | .writeable_reg = dps310_is_writeable_reg, | ||
670 | .volatile_reg = dps310_is_volatile_reg, | ||
671 | .cache_type = REGCACHE_RBTREE, | ||
672 | .max_register = 0x62, /* No documentation available on this register */ | ||
673 | }; | ||
674 | |||
675 | static const struct iio_info dps310_info = { | ||
676 | .read_raw = dps310_read_raw, | ||
677 | .write_raw = dps310_write_raw, | ||
678 | }; | ||
679 | |||
680 | /* | ||
681 | * Some verions of chip will read temperatures in the ~60C range when | ||
682 | * its actually ~20C. This is the manufacturer recommended workaround | ||
683 | * to correct the issue. The registers used below are undocumented. | ||
684 | */ | ||
685 | static int dps310_temp_workaround(struct dps310_data *data) | ||
686 | { | ||
687 | int rc; | ||
688 | int reg; | ||
689 | |||
690 | rc = regmap_read(data->regmap, 0x32, ®); | ||
691 | if (rc < 0) | ||
692 | return rc; | ||
693 | |||
694 | /* | ||
695 | * If bit 1 is set then the device is okay, and the workaround does not | ||
696 | * need to be applied | ||
697 | */ | ||
698 | if (reg & BIT(1)) | ||
699 | return 0; | ||
700 | |||
701 | rc = regmap_write(data->regmap, 0x0e, 0xA5); | ||
702 | if (rc < 0) | ||
703 | return rc; | ||
704 | |||
705 | rc = regmap_write(data->regmap, 0x0f, 0x96); | ||
706 | if (rc < 0) | ||
707 | return rc; | ||
708 | |||
709 | rc = regmap_write(data->regmap, 0x62, 0x02); | ||
710 | if (rc < 0) | ||
711 | return rc; | ||
712 | |||
713 | rc = regmap_write(data->regmap, 0x0e, 0x00); | ||
714 | if (rc < 0) | ||
715 | return rc; | ||
716 | |||
717 | return regmap_write(data->regmap, 0x0f, 0x00); | ||
718 | } | ||
719 | |||
720 | static int dps310_probe(struct i2c_client *client, | ||
721 | const struct i2c_device_id *id) | ||
722 | { | ||
723 | struct dps310_data *data; | ||
724 | struct iio_dev *iio; | ||
725 | int rc, ready; | ||
726 | |||
727 | iio = devm_iio_device_alloc(&client->dev, sizeof(*data)); | ||
728 | if (!iio) | ||
729 | return -ENOMEM; | ||
730 | |||
731 | data = iio_priv(iio); | ||
732 | data->client = client; | ||
733 | mutex_init(&data->lock); | ||
734 | |||
735 | iio->dev.parent = &client->dev; | ||
736 | iio->name = id->name; | ||
737 | iio->channels = dps310_channels; | ||
738 | iio->num_channels = ARRAY_SIZE(dps310_channels); | ||
739 | iio->info = &dps310_info; | ||
740 | iio->modes = INDIO_DIRECT_MODE; | ||
741 | |||
742 | data->regmap = devm_regmap_init_i2c(client, &dps310_regmap_config); | ||
743 | if (IS_ERR(data->regmap)) | ||
744 | return PTR_ERR(data->regmap); | ||
745 | |||
746 | /* Register to run the device reset when the device is removed */ | ||
747 | rc = devm_add_action_or_reset(&client->dev, dps310_reset, data); | ||
748 | if (rc) | ||
749 | return rc; | ||
750 | |||
751 | /* | ||
752 | * Set up pressure sensor in single sample, one measurement per second | ||
753 | * mode | ||
754 | */ | ||
755 | rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0); | ||
756 | |||
757 | /* | ||
758 | * Set up external (MEMS) temperature sensor in single sample, one | ||
759 | * measurement per second mode | ||
760 | */ | ||
761 | rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT); | ||
762 | if (rc < 0) | ||
763 | return rc; | ||
764 | |||
765 | /* Temp and pressure shifts are disabled when PRC <= 8 */ | ||
766 | rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, | ||
767 | DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0); | ||
768 | if (rc < 0) | ||
769 | return rc; | ||
770 | |||
771 | /* MEAS_CFG doesn't update correctly unless first written with 0 */ | ||
772 | rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, | ||
773 | DPS310_MEAS_CTRL_BITS, 0); | ||
774 | if (rc < 0) | ||
775 | return rc; | ||
776 | |||
777 | /* Turn on temperature and pressure measurement in the background */ | ||
778 | rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, | ||
779 | DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN | | ||
780 | DPS310_TEMP_EN | DPS310_BACKGROUND); | ||
781 | if (rc < 0) | ||
782 | return rc; | ||
783 | |||
784 | /* | ||
785 | * Calibration coefficients required for reporting temperature. | ||
786 | * They are available 40ms after the device has started | ||
787 | */ | ||
788 | rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, | ||
789 | ready & DPS310_COEF_RDY, 10000, 40000); | ||
790 | if (rc < 0) | ||
791 | return rc; | ||
792 | |||
793 | rc = dps310_get_coefs(data); | ||
794 | if (rc < 0) | ||
795 | return rc; | ||
796 | |||
797 | rc = dps310_temp_workaround(data); | ||
798 | if (rc < 0) | ||
799 | return rc; | ||
800 | |||
801 | rc = devm_iio_device_register(&client->dev, iio); | ||
802 | if (rc) | ||
803 | return rc; | ||
804 | |||
805 | i2c_set_clientdata(client, iio); | ||
806 | |||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | static const struct i2c_device_id dps310_id[] = { | ||
811 | { DPS310_DEV_NAME, 0 }, | ||
812 | {} | ||
813 | }; | ||
814 | MODULE_DEVICE_TABLE(i2c, dps310_id); | ||
815 | |||
816 | static struct i2c_driver dps310_driver = { | ||
817 | .driver = { | ||
818 | .name = DPS310_DEV_NAME, | ||
819 | }, | ||
820 | .probe = dps310_probe, | ||
821 | .id_table = dps310_id, | ||
822 | }; | ||
823 | module_i2c_driver(dps310_driver); | ||
824 | |||
825 | MODULE_AUTHOR("Joel Stanley <joel@jms.id.au>"); | ||
826 | MODULE_DESCRIPTION("Infineon DPS310 pressure and temperature sensor"); | ||
827 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/staging/iio/accel/adis16203.c b/drivers/staging/iio/accel/adis16203.c index 70381756a64a..39687139a7d3 100644 --- a/drivers/staging/iio/accel/adis16203.c +++ b/drivers/staging/iio/accel/adis16203.c | |||
@@ -122,7 +122,7 @@ | |||
122 | /* Power supply above 3.625 V */ | 122 | /* Power supply above 3.625 V */ |
123 | #define ADIS16203_DIAG_STAT_POWER_HIGH_BIT 1 | 123 | #define ADIS16203_DIAG_STAT_POWER_HIGH_BIT 1 |
124 | 124 | ||
125 | /* Power supply below 3.15 V */ | 125 | /* Power supply below 2.975 V */ |
126 | #define ADIS16203_DIAG_STAT_POWER_LOW_BIT 0 | 126 | #define ADIS16203_DIAG_STAT_POWER_LOW_BIT 0 |
127 | 127 | ||
128 | /* GLOB_CMD */ | 128 | /* GLOB_CMD */ |
@@ -234,7 +234,7 @@ static const char * const adis16203_status_error_msgs[] = { | |||
234 | [ADIS16203_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", | 234 | [ADIS16203_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", |
235 | [ADIS16203_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", | 235 | [ADIS16203_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", |
236 | [ADIS16203_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", | 236 | [ADIS16203_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", |
237 | [ADIS16203_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", | 237 | [ADIS16203_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V", |
238 | }; | 238 | }; |
239 | 239 | ||
240 | static const struct adis_data adis16203_data = { | 240 | static const struct adis_data adis16203_data = { |
@@ -311,9 +311,17 @@ static int adis16203_remove(struct spi_device *spi) | |||
311 | return 0; | 311 | return 0; |
312 | } | 312 | } |
313 | 313 | ||
314 | static const struct of_device_id adis16203_of_match[] = { | ||
315 | { .compatible = "adi,adis16203" }, | ||
316 | { }, | ||
317 | }; | ||
318 | |||
319 | MODULE_DEVICE_TABLE(of, adis16203_of_match); | ||
320 | |||
314 | static struct spi_driver adis16203_driver = { | 321 | static struct spi_driver adis16203_driver = { |
315 | .driver = { | 322 | .driver = { |
316 | .name = "adis16203", | 323 | .name = "adis16203", |
324 | .of_match_table = adis16203_of_match, | ||
317 | }, | 325 | }, |
318 | .probe = adis16203_probe, | 326 | .probe = adis16203_probe, |
319 | .remove = adis16203_remove, | 327 | .remove = adis16203_remove, |
diff --git a/drivers/staging/iio/accel/adis16240.c b/drivers/staging/iio/accel/adis16240.c index b80e0d248b0f..62f4b3b1b457 100644 --- a/drivers/staging/iio/accel/adis16240.c +++ b/drivers/staging/iio/accel/adis16240.c | |||
@@ -175,7 +175,7 @@ | |||
175 | /* Power supply above 3.625 V */ | 175 | /* Power supply above 3.625 V */ |
176 | #define ADIS16240_DIAG_STAT_POWER_HIGH_BIT 1 | 176 | #define ADIS16240_DIAG_STAT_POWER_HIGH_BIT 1 |
177 | 177 | ||
178 | /* Power supply below 3.15 V */ | 178 | /* Power supply below 2.225 V */ |
179 | #define ADIS16240_DIAG_STAT_POWER_LOW_BIT 0 | 179 | #define ADIS16240_DIAG_STAT_POWER_LOW_BIT 0 |
180 | 180 | ||
181 | /* GLOB_CMD */ | 181 | /* GLOB_CMD */ |
@@ -435,9 +435,16 @@ static int adis16240_remove(struct spi_device *spi) | |||
435 | return 0; | 435 | return 0; |
436 | } | 436 | } |
437 | 437 | ||
438 | static const struct of_device_id adis16240_of_match[] = { | ||
439 | { .compatible = "adi,adis16240" }, | ||
440 | { }, | ||
441 | }; | ||
442 | MODULE_DEVICE_TABLE(of, adis16240_of_match); | ||
443 | |||
438 | static struct spi_driver adis16240_driver = { | 444 | static struct spi_driver adis16240_driver = { |
439 | .driver = { | 445 | .driver = { |
440 | .name = "adis16240", | 446 | .name = "adis16240", |
447 | .of_match_table = adis16240_of_match, | ||
441 | }, | 448 | }, |
442 | .probe = adis16240_probe, | 449 | .probe = adis16240_probe, |
443 | .remove = adis16240_remove, | 450 | .remove = adis16240_remove, |
diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c index 2066241b15b1..af513e003da7 100644 --- a/drivers/staging/iio/addac/adt7316-spi.c +++ b/drivers/staging/iio/addac/adt7316-spi.c | |||
@@ -126,9 +126,22 @@ static const struct spi_device_id adt7316_spi_id[] = { | |||
126 | 126 | ||
127 | MODULE_DEVICE_TABLE(spi, adt7316_spi_id); | 127 | MODULE_DEVICE_TABLE(spi, adt7316_spi_id); |
128 | 128 | ||
129 | static const struct of_device_id adt7316_of_spi_match[] = { | ||
130 | { .compatible = "adi,adt7316" }, | ||
131 | { .compatible = "adi,adt7317" }, | ||
132 | { .compatible = "adi,adt7318" }, | ||
133 | { .compatible = "adi,adt7516" }, | ||
134 | { .compatible = "adi,adt7517" }, | ||
135 | { .compatible = "adi,adt7519" }, | ||
136 | { } | ||
137 | }; | ||
138 | |||
139 | MODULE_DEVICE_TABLE(of, adt7316_of_spi_match); | ||
140 | |||
129 | static struct spi_driver adt7316_driver = { | 141 | static struct spi_driver adt7316_driver = { |
130 | .driver = { | 142 | .driver = { |
131 | .name = "adt7316", | 143 | .name = "adt7316", |
144 | .of_match_table = adt7316_of_spi_match, | ||
132 | .pm = ADT7316_PM_OPS, | 145 | .pm = ADT7316_PM_OPS, |
133 | }, | 146 | }, |
134 | .probe = adt7316_spi_probe, | 147 | .probe = adt7316_spi_probe, |
diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index e075244c602b..f4954d85553e 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c | |||
@@ -46,6 +46,9 @@ | |||
46 | #define AD7150_SN0 22 | 46 | #define AD7150_SN0 22 |
47 | #define AD7150_ID 23 | 47 | #define AD7150_ID 23 |
48 | 48 | ||
49 | /* AD7150 masks */ | ||
50 | #define AD7150_THRESHTYPE_MSK GENMASK(6, 5) | ||
51 | |||
49 | /** | 52 | /** |
50 | * struct ad7150_chip_info - instance specific chip data | 53 | * struct ad7150_chip_info - instance specific chip data |
51 | * @client: i2c client for this device | 54 | * @client: i2c client for this device |
@@ -138,7 +141,7 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, | |||
138 | if (ret < 0) | 141 | if (ret < 0) |
139 | return ret; | 142 | return ret; |
140 | 143 | ||
141 | threshtype = (ret >> 5) & 0x03; | 144 | threshtype = FIELD_GET(AD7150_THRESHTYPE_MSK, ret); |
142 | 145 | ||
143 | /*check if threshold mode is fixed or adaptive*/ | 146 | /*check if threshold mode is fixed or adaptive*/ |
144 | thrfixed = FIELD_GET(AD7150_CFG_FIX, ret); | 147 | thrfixed = FIELD_GET(AD7150_CFG_FIX, ret); |
@@ -162,7 +165,8 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, | |||
162 | return -EINVAL; | 165 | return -EINVAL; |
163 | } | 166 | } |
164 | 167 | ||
165 | /* lock should be held */ | 168 | /* state_lock should be held to ensure consistent state*/ |
169 | |||
166 | static int ad7150_write_event_params(struct iio_dev *indio_dev, | 170 | static int ad7150_write_event_params(struct iio_dev *indio_dev, |
167 | unsigned int chan, | 171 | unsigned int chan, |
168 | enum iio_event_type type, | 172 | enum iio_event_type type, |
@@ -201,16 +205,11 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev, | |||
201 | ret = i2c_smbus_write_byte_data(chip->client, | 205 | ret = i2c_smbus_write_byte_data(chip->client, |
202 | ad7150_addresses[chan][4], | 206 | ad7150_addresses[chan][4], |
203 | sens); | 207 | sens); |
204 | if (ret < 0) | 208 | if (ret) |
205 | return ret; | 209 | return ret; |
206 | 210 | return i2c_smbus_write_byte_data(chip->client, | |
207 | ret = i2c_smbus_write_byte_data(chip->client, | ||
208 | ad7150_addresses[chan][5], | 211 | ad7150_addresses[chan][5], |
209 | timeout); | 212 | timeout); |
210 | if (ret < 0) | ||
211 | return ret; | ||
212 | |||
213 | return 0; | ||
214 | } | 213 | } |
215 | 214 | ||
216 | static int ad7150_write_event_config(struct iio_dev *indio_dev, | 215 | static int ad7150_write_event_config(struct iio_dev *indio_dev, |
@@ -353,8 +352,8 @@ static ssize_t ad7150_show_timeout(struct device *dev, | |||
353 | 352 | ||
354 | /* use the event code for consistency reasons */ | 353 | /* use the event code for consistency reasons */ |
355 | int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address); | 354 | int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address); |
356 | int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address) | 355 | int rising = (IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address) |
357 | == IIO_EV_DIR_RISING); | 356 | == IIO_EV_DIR_RISING) ? 1 : 0; |
358 | 357 | ||
359 | switch (IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address)) { | 358 | switch (IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address)) { |
360 | case IIO_EV_TYPE_MAG_ADAPTIVE: | 359 | case IIO_EV_TYPE_MAG_ADAPTIVE: |
@@ -468,30 +467,21 @@ static const struct iio_event_spec ad7150_events[] = { | |||
468 | }, | 467 | }, |
469 | }; | 468 | }; |
470 | 469 | ||
470 | #define AD7150_CAPACITANCE_CHAN(_chan) { \ | ||
471 | .type = IIO_CAPACITANCE, \ | ||
472 | .indexed = 1, \ | ||
473 | .channel = _chan, \ | ||
474 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | ||
475 | BIT(IIO_CHAN_INFO_AVERAGE_RAW), \ | ||
476 | .event_spec = ad7150_events, \ | ||
477 | .num_event_specs = ARRAY_SIZE(ad7150_events), \ | ||
478 | } | ||
479 | |||
471 | static const struct iio_chan_spec ad7150_channels[] = { | 480 | static const struct iio_chan_spec ad7150_channels[] = { |
472 | { | 481 | AD7150_CAPACITANCE_CHAN(0), |
473 | .type = IIO_CAPACITANCE, | 482 | AD7150_CAPACITANCE_CHAN(1) |
474 | .indexed = 1, | ||
475 | .channel = 0, | ||
476 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | ||
477 | BIT(IIO_CHAN_INFO_AVERAGE_RAW), | ||
478 | .event_spec = ad7150_events, | ||
479 | .num_event_specs = ARRAY_SIZE(ad7150_events), | ||
480 | }, { | ||
481 | .type = IIO_CAPACITANCE, | ||
482 | .indexed = 1, | ||
483 | .channel = 1, | ||
484 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | ||
485 | BIT(IIO_CHAN_INFO_AVERAGE_RAW), | ||
486 | .event_spec = ad7150_events, | ||
487 | .num_event_specs = ARRAY_SIZE(ad7150_events), | ||
488 | }, | ||
489 | }; | 483 | }; |
490 | 484 | ||
491 | /* | ||
492 | * threshold events | ||
493 | */ | ||
494 | |||
495 | static irqreturn_t ad7150_event_handler(int irq, void *private) | 485 | static irqreturn_t ad7150_event_handler(int irq, void *private) |
496 | { | 486 | { |
497 | struct iio_dev *indio_dev = private; | 487 | struct iio_dev *indio_dev = private; |
@@ -580,10 +570,6 @@ static const struct iio_info ad7150_info = { | |||
580 | .write_event_value = &ad7150_write_event_value, | 570 | .write_event_value = &ad7150_write_event_value, |
581 | }; | 571 | }; |
582 | 572 | ||
583 | /* | ||
584 | * device probe and remove | ||
585 | */ | ||
586 | |||
587 | static int ad7150_probe(struct i2c_client *client, | 573 | static int ad7150_probe(struct i2c_client *client, |
588 | const struct i2c_device_id *id) | 574 | const struct i2c_device_id *id) |
589 | { | 575 | { |
diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 47610d863908..21527d84f940 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c | |||
@@ -748,9 +748,19 @@ static const struct i2c_device_id ad7746_id[] = { | |||
748 | 748 | ||
749 | MODULE_DEVICE_TABLE(i2c, ad7746_id); | 749 | MODULE_DEVICE_TABLE(i2c, ad7746_id); |
750 | 750 | ||
751 | static const struct of_device_id ad7746_of_match[] = { | ||
752 | { .compatible = "adi,ad7745" }, | ||
753 | { .compatible = "adi,ad7746" }, | ||
754 | { .compatible = "adi,ad7747" }, | ||
755 | { }, | ||
756 | }; | ||
757 | |||
758 | MODULE_DEVICE_TABLE(of, ad7746_of_match); | ||
759 | |||
751 | static struct i2c_driver ad7746_driver = { | 760 | static struct i2c_driver ad7746_driver = { |
752 | .driver = { | 761 | .driver = { |
753 | .name = KBUILD_MODNAME, | 762 | .name = KBUILD_MODNAME, |
763 | .of_match_table = ad7746_of_match, | ||
754 | }, | 764 | }, |
755 | .probe = ad7746_probe, | 765 | .probe = ad7746_probe, |
756 | .id_table = ad7746_id, | 766 | .id_table = ad7746_id, |
diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c index 6de3cd7363d7..038d6732c3fd 100644 --- a/drivers/staging/iio/frequency/ad9834.c +++ b/drivers/staging/iio/frequency/ad9834.c | |||
@@ -521,9 +521,20 @@ static const struct spi_device_id ad9834_id[] = { | |||
521 | }; | 521 | }; |
522 | MODULE_DEVICE_TABLE(spi, ad9834_id); | 522 | MODULE_DEVICE_TABLE(spi, ad9834_id); |
523 | 523 | ||
524 | static const struct of_device_id ad9834_of_match[] = { | ||
525 | {.compatible = "adi,ad9833"}, | ||
526 | {.compatible = "adi,ad9834"}, | ||
527 | {.compatible = "adi,ad9837"}, | ||
528 | {.compatible = "adi,ad9838"}, | ||
529 | {} | ||
530 | }; | ||
531 | |||
532 | MODULE_DEVICE_TABLE(of, ad9834_of_match); | ||
533 | |||
524 | static struct spi_driver ad9834_driver = { | 534 | static struct spi_driver ad9834_driver = { |
525 | .driver = { | 535 | .driver = { |
526 | .name = "ad9834", | 536 | .name = "ad9834", |
537 | .of_match_table = ad9834_of_match | ||
527 | }, | 538 | }, |
528 | .probe = ad9834_probe, | 539 | .probe = ad9834_probe, |
529 | .remove = ad9834_remove, | 540 | .remove = ad9834_remove, |
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index b6be0bc202f5..0c1bd108c386 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c | |||
@@ -647,9 +647,6 @@ static int ad2s1210_probe(struct spi_device *spi) | |||
647 | struct ad2s1210_state *st; | 647 | struct ad2s1210_state *st; |
648 | int ret; | 648 | int ret; |
649 | 649 | ||
650 | if (!spi->dev.platform_data) | ||
651 | return -EINVAL; | ||
652 | |||
653 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | 650 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); |
654 | if (!indio_dev) | 651 | if (!indio_dev) |
655 | return -ENOMEM; | 652 | return -ENOMEM; |
diff --git a/tools/iio/iio_utils.c b/tools/iio/iio_utils.c index a22b6e8fad46..7399eb7f1378 100644 --- a/tools/iio/iio_utils.c +++ b/tools/iio/iio_utils.c | |||
@@ -156,9 +156,9 @@ int iioutils_get_type(unsigned *is_signed, unsigned *bytes, unsigned *bits_used, | |||
156 | *be = (endianchar == 'b'); | 156 | *be = (endianchar == 'b'); |
157 | *bytes = padint / 8; | 157 | *bytes = padint / 8; |
158 | if (*bits_used == 64) | 158 | if (*bits_used == 64) |
159 | *mask = ~0; | 159 | *mask = ~(0ULL); |
160 | else | 160 | else |
161 | *mask = (1ULL << *bits_used) - 1; | 161 | *mask = (1ULL << *bits_used) - 1ULL; |
162 | 162 | ||
163 | *is_signed = (signchar == 's'); | 163 | *is_signed = (signchar == 's'); |
164 | if (fclose(sysfsfp)) { | 164 | if (fclose(sysfsfp)) { |