diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-11-22 03:39:45 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-11-22 03:39:45 -0500 |
| commit | 7c0bc65c84035cd2d7561ba47d7bad1cae62c4c3 (patch) | |
| tree | dc3d2be87e28788beae297afecfa83a4846397b8 | |
| parent | 0e2c8fb54d7ae0c3e816dc8b1eedbeb345e9cdad (diff) | |
| parent | 00426e99789357dbff7e719a092ce36a3ce49d94 (diff) | |
Merge tag 'iio-for-4.21a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-testing
Jonathan writes:
First set of new device support, features and cleanups for IIO in the 4.21 cycle
Along with the headline feature of 5 new drivers, we have the
substantial addition of auxilliary sensor support on the lsm6sdx
parts for ST. There has also been a good set of staging cleanup
in this period with more underway.
An ever increasing number of devices supported with just a new
ID which is a good sign that at least some manufacturers are
continuing to stabilise their interfaces.
New device support,
* ad7124
- New driver supporting Analog Devices' ad7124-4 and ad7124-8 parts
with the inevitable DT binding.
* ad7949
- New driver supporting Analog Devices' ad7949, AD7682 and AD7689 ADCs.
* rm3100
- New driver supporting PNIs RM3100 magnometer with bindings and
vendor prefix.
* ti-dac7311
- New driver supporting DAC7311, DAC6311 and DAC5311 TI DACs, with
DT bindings.
* vcnl5035
- New driver supporting the light sensor part of the VCNL4035, with
DT bindings
Features,
* bindings
- Add a generic ADC channel binding as we keep reinventing this
wheel.
* adc128s052
- Add IDs for additional pin compatible parts.
- Add APCI ID seen on E3940 UP squared boards.
* ad_sigma_delta
- Allow for custom data register overiding default.
* kxcjk1013
- Add KIOX0009 ACPI ID as seen on the Acer One 10.
* lsm6dsx
- Rework leading to...
- External sensor support using the built in I2C master.
- Initial support for a slave lis2mdl magnetometer.
* meson-saradc
- Add temperature sensor support and bindings.
* st_magn
- New ID for lsm9dsl_magn with bindings
- New ID for lis3de accelerometer
* tpl0102
- Add supprot for IIO_AVAIL_RANGE to report the range available
from this device to userspace and in kernel users.
Cleanups and minor fixes
* tools
- Allow outside specification of CFLAGS
* ad2s90
- Handle and spi_read error.
- Handle spi_setup failure
- Drop a pointless assignment.
- Prevent a potentail race by moving device registration to after
all other setup.
- Add missing scale attribute.
- Add a sanity check on channel type before trying to read it.
* ad2s1210
- Move to modern gpio descriptors.
- Drop a gpioin flag which made no sense as far as we can tell.
- Add dt table (bindings doc to follow when this is ready for
moving out of staging).
* ad5933
- Drop camel-case naming of ext_clk_hz.
- White space fixes.
* ad7150
- Local variable to shorten overly long line.
- Alignment and line break fixes.
* ad7280a
- Handle an error path that was previously ignored.
- Use crc8.h to build the crc table replacing custom code.
- Avoid unecessary cast.
- Power down the device if an error happens in probe
- Use devm routines to simplify probe and remove.
* ad7606
- Alignment fixes.
* ad7780
- This worked as long as by coincidence an uninitialized value
was 0. Lets not rely on that.
- Ensure gain update is only used with the ad778x chips that
actually support it.
- Tidy up pattern mask generation.
- Read regulator when scale is requested (which should be infrequent)
as it might have changed from initialization.
* ad7816
- Move to modern gpio descriptors
- Don't use a busy_pin for ad7818 as there isn't one.
- Ensure RD/WR and CONVST pins are outputs (previously they
were brought up as inputs which doesn't seem to make any sense)
- DT id table.
* adc128s052
- SPDX
* adt7316
- Alignment fix.
- Fix data reading. When using I2C the driver never actually
used the value read. This has been broken a very long time
hence no rush to fix it now + the driver is undergoing a lot
of cleanup.
- Sanity check that the i2c read didn't fail to actually read
anything.
* dpot-dac
- Mark a switch full through with slightly different text so that
gcc doesn't warn on it.
* gyro-adc
- Fix a wrong file in the MAINTAINERS entry and add binding doc to the
listed files.
* ina2xx
- Add some early returns to clarify error paths in switch.
* lsm6dsx
- MAINTAINERS entry.
* max11100
- SPDX
* max9611
- SPDX
* mcp4131
- use of_device_get_match_data in preference to spi_get_device_id
approach.
* rcar-adc
- SPDX
* sc27xx
- Add ADC conversion timeout support to avoid possible fault.
* ssp_sensors
- Don't free managed resources manually.
* st-magn
- Add a comment to avoid future confusion over when to use -magn
postfix (on multi chip in package parts)
- Add BDU register for LIS3MDL where it seems to have been missed.
* st-sensors
- Minor spelling, grammar etc fixes.
* tpl0102
- Use a pointer rather than an index of an array to improve conciseness.
* tag 'iio-for-4.21a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (80 commits)
Staging: iio: adt7316: Add an extra check for 'ret' equals to 0
Staging: iio: adt7316: Fix i2c data reading, set the data field
dt-bindings: iio: adc: Add docs for ad7124
iio: adc: Add ad7124 support
dt-bindings: iio: adc: Add common ADCs properties to a separate file
iio: ad_sigma_delta: Allow to provide custom data register address
staging: iio: ad7816: Add device tree table.
iio: imu: st_lsm6dsx: add entry in MAINTAINERS file
iio: potentiometer: mcp4131: use of_device_get_match_data()
staging: iio: adc: ad7280a: use devm_* APIs
staging: iio: adc: ad7280a: power down the device on error in probe
dt-bindings: iio: imu: st_lsm6dsx: add support to i2c pullup resistors
iio: imu: st_lsm6dsx: add hw FIFO support to i2c controller
iio: imu: st_lsm6dsx: add st_lsm6dsx_push_tagged_data routine
iio: imu: st_lsm6dsx: add i2c embedded controller support
iio: imu: st_lsm6dsx: introduce st_lsm6dsx_sensor_set_enable routine
iio: imu: st_lsm6dsx: introduce ST_LSM6DSX_ID_EXT sensor ids
iio: imu: st_lsm6dsx: remove static from st_lsm6dsx_set_watermark
iio: imu: st_lsm6dsx: reload trimming parameter at bootstrap
iio: imu: st_lsm6dsx: introduce locked read/write utility routines
...
74 files changed, 5240 insertions, 763 deletions
diff --git a/Documentation/devicetree/bindings/iio/adc/ad7949.txt b/Documentation/devicetree/bindings/iio/adc/ad7949.txt new file mode 100644 index 000000000000..c7f5057356b1 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ad7949.txt | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | * Analog Devices AD7949/AD7682/AD7689 | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: Should be one of | ||
| 5 | * "adi,ad7949" | ||
| 6 | * "adi,ad7682" | ||
| 7 | * "adi,ad7689" | ||
| 8 | - reg: spi chip select number for the device | ||
| 9 | - vref-supply: The regulator supply for ADC reference voltage | ||
| 10 | |||
| 11 | Example: | ||
| 12 | adc@0 { | ||
| 13 | compatible = "adi,ad7949"; | ||
| 14 | reg = <0>; | ||
| 15 | vref-supply = <&vdd_supply>; | ||
| 16 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/adc.txt b/Documentation/devicetree/bindings/iio/adc/adc.txt new file mode 100644 index 000000000000..5bbaa330a250 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adc.txt | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | Common ADCs properties | ||
| 2 | |||
| 3 | Optional properties for child nodes: | ||
| 4 | - bipolar : Boolean, if set the channel is used in bipolar mode. | ||
| 5 | - diff-channels : Differential channels muxed for this ADC. The first value | ||
| 6 | specifies the positive input pin, the second value the negative | ||
| 7 | input pin. | ||
| 8 | |||
| 9 | Example: | ||
| 10 | adc@0 { | ||
| 11 | compatible = "some,adc"; | ||
| 12 | ... | ||
| 13 | channel@0 { | ||
| 14 | bipolar; | ||
| 15 | diff-channels = <0 1>; | ||
| 16 | ... | ||
| 17 | }; | ||
| 18 | |||
| 19 | channel@1 { | ||
| 20 | diff-channels = <2 3>; | ||
| 21 | ... | ||
| 22 | }; | ||
| 23 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7124.txt b/Documentation/devicetree/bindings/iio/adc/adi,ad7124.txt new file mode 100644 index 000000000000..416273dce569 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7124.txt | |||
| @@ -0,0 +1,75 @@ | |||
| 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/amlogic,meson-saradc.txt b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt index 54b823f3a453..325090e43ce6 100644 --- a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt +++ b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt | |||
| @@ -22,6 +22,12 @@ Required properties: | |||
| 22 | - vref-supply: the regulator supply for the ADC reference voltage | 22 | - vref-supply: the regulator supply for the ADC reference voltage |
| 23 | - #io-channel-cells: must be 1, see ../iio-bindings.txt | 23 | - #io-channel-cells: must be 1, see ../iio-bindings.txt |
| 24 | 24 | ||
| 25 | Optional properties: | ||
| 26 | - nvmem-cells: phandle to the temperature_calib eFuse cells | ||
| 27 | - nvmem-cell-names: if present (to enable the temperature sensor | ||
| 28 | calibration) this must contain "temperature_calib" | ||
| 29 | |||
| 30 | |||
| 25 | Example: | 31 | Example: |
| 26 | saradc: adc@8680 { | 32 | saradc: adc@8680 { |
| 27 | compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; | 33 | compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc"; |
diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt index daa2b2c29428..c07ce1a3f5c4 100644 --- a/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt +++ b/Documentation/devicetree/bindings/iio/adc/ti-adc128s052.txt | |||
| @@ -1,7 +1,14 @@ | |||
| 1 | * Texas Instruments' ADC128S052, ADC122S021 and ADC124S021 ADC chip | 1 | * Texas Instruments' ADC128S052, ADC122S021 and ADC124S021 ADC chip |
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: Should be "ti,adc128s052", "ti,adc122s021" or "ti,adc124s021" | 4 | - compatible: Should be one of: |
| 5 | - "ti,adc128s052" | ||
| 6 | - "ti,adc122s021" | ||
| 7 | - "ti,adc122s051" | ||
| 8 | - "ti,adc122s101" | ||
| 9 | - "ti,adc124s021" | ||
| 10 | - "ti,adc124s051" | ||
| 11 | - "ti,adc124s101" | ||
| 5 | - reg: spi chip select number for the device | 12 | - reg: spi chip select number for the device |
| 6 | - vref-supply: The regulator supply for ADC reference voltage | 13 | - vref-supply: The regulator supply for ADC reference voltage |
| 7 | 14 | ||
diff --git a/Documentation/devicetree/bindings/iio/dac/ti,dac7311.txt b/Documentation/devicetree/bindings/iio/dac/ti,dac7311.txt new file mode 100644 index 000000000000..e5a507db5e01 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/ti,dac7311.txt | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | TI DAC7311 device tree bindings | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: must be set to: | ||
| 5 | * "ti,dac7311" | ||
| 6 | * "ti,dac6311" | ||
| 7 | * "ti,dac5311" | ||
| 8 | - reg: spi chip select number for the device | ||
| 9 | - vref-supply: The regulator supply for ADC reference voltage | ||
| 10 | |||
| 11 | Optional properties: | ||
| 12 | - spi-max-frequency: Max SPI frequency to use | ||
| 13 | |||
| 14 | Example: | ||
| 15 | |||
| 16 | spi_master { | ||
| 17 | dac@0 { | ||
| 18 | compatible = "ti,dac7311"; | ||
| 19 | reg = <0>; /* CS0 */ | ||
| 20 | spi-max-frequency = <1000000>; | ||
| 21 | vref-supply = <&vdd_supply>; | ||
| 22 | }; | ||
| 23 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt index 879322ad50fd..69d53d98d0f0 100644 --- a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt +++ b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt | |||
| @@ -13,6 +13,7 @@ Required properties: | |||
| 13 | Optional properties: | 13 | Optional properties: |
| 14 | - st,drdy-int-pin: the pin on the package that will be used to signal | 14 | - st,drdy-int-pin: the pin on the package that will be used to signal |
| 15 | "data ready" (valid values: 1 or 2). | 15 | "data ready" (valid values: 1 or 2). |
| 16 | - st,pullups : enable/disable internal i2c controller pullup resistors. | ||
| 16 | - drive-open-drain: the interrupt/data ready line will be configured | 17 | - drive-open-drain: the interrupt/data ready line will be configured |
| 17 | as open drain, which is useful if several sensors share the same | 18 | as open drain, which is useful if several sensors share the same |
| 18 | interrupt line. This is a boolean property. | 19 | interrupt line. This is a boolean property. |
diff --git a/Documentation/devicetree/bindings/iio/light/vcnl4035.txt b/Documentation/devicetree/bindings/iio/light/vcnl4035.txt new file mode 100644 index 000000000000..c07c7f052556 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/vcnl4035.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | VISHAY VCNL4035 - Ambient Light and proximity sensor | ||
| 2 | |||
| 3 | Link to datasheet: https://www.vishay.com/docs/84251/vcnl4035x01.pdf | ||
| 4 | |||
| 5 | Required properties: | ||
| 6 | |||
| 7 | -compatible: should be "vishay,vcnl4035" | ||
| 8 | -reg: I2C address of the sensor, should be 0x60 | ||
| 9 | -interrupts: interrupt mapping for GPIO IRQ (level active low) | ||
| 10 | |||
| 11 | Example: | ||
| 12 | |||
| 13 | light-sensor@60 { | ||
| 14 | compatible = "vishay,vcnl4035"; | ||
| 15 | reg = <0x60>; | ||
| 16 | interrupt-parent = <&gpio4>; | ||
| 17 | interrupts = <11 IRQ_TYPE_LEVEL_LOW>; | ||
| 18 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/magnetometer/pni,rm3100.txt b/Documentation/devicetree/bindings/iio/magnetometer/pni,rm3100.txt new file mode 100644 index 000000000000..497c932e9e39 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/magnetometer/pni,rm3100.txt | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | * PNI RM3100 3-axis magnetometer sensor | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | |||
| 5 | - compatible : should be "pni,rm3100" | ||
| 6 | - reg : the I2C address or SPI chip select number of the sensor. | ||
| 7 | |||
| 8 | Optional properties: | ||
| 9 | |||
| 10 | - interrupts: data ready (DRDY) from the chip. | ||
| 11 | The interrupts can be triggered on level high. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | rm3100: rm3100@20 { | ||
| 16 | compatible = "pni,rm3100"; | ||
| 17 | reg = <0x20>; | ||
| 18 | interrupt-parent = <&gpio0>; | ||
| 19 | interrupts = <4 IRQ_TYPE_LEVEL_HIGH>; | ||
| 20 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/st-sensors.txt b/Documentation/devicetree/bindings/iio/st-sensors.txt index 6f626f73417e..ddcb95509599 100644 --- a/Documentation/devicetree/bindings/iio/st-sensors.txt +++ b/Documentation/devicetree/bindings/iio/st-sensors.txt | |||
| @@ -48,6 +48,7 @@ Accelerometers: | |||
| 48 | - st,lis3l02dq | 48 | - st,lis3l02dq |
| 49 | - st,lis2dw12 | 49 | - st,lis2dw12 |
| 50 | - st,lis3dhh | 50 | - st,lis3dhh |
| 51 | - st,lis3de | ||
| 51 | 52 | ||
| 52 | Gyroscopes: | 53 | Gyroscopes: |
| 53 | - st,l3g4200d-gyro | 54 | - st,l3g4200d-gyro |
| @@ -67,6 +68,7 @@ Magnetometers: | |||
| 67 | - st,lsm303dlm-magn | 68 | - st,lsm303dlm-magn |
| 68 | - st,lis3mdl-magn | 69 | - st,lis3mdl-magn |
| 69 | - st,lis2mdl | 70 | - st,lis2mdl |
| 71 | - st,lsm9ds1-magn | ||
| 70 | 72 | ||
| 71 | Pressure sensors: | 73 | Pressure sensors: |
| 72 | - st,lps001wp-press | 74 | - st,lps001wp-press |
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 4b1a2a8fcc16..3cfe0c8b8250 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
| @@ -303,6 +303,7 @@ pixcir PIXCIR MICROELECTRONICS Co., Ltd | |||
| 303 | plathome Plat'Home Co., Ltd. | 303 | plathome Plat'Home Co., Ltd. |
| 304 | plda PLDA | 304 | plda PLDA |
| 305 | plx Broadcom Corporation (formerly PLX Technology) | 305 | plx Broadcom Corporation (formerly PLX Technology) |
| 306 | pni PNI Sensor Corporation | ||
| 306 | portwell Portwell Inc. | 307 | portwell Portwell Inc. |
| 307 | poslab Poslab Technology Co., Ltd. | 308 | poslab Poslab Technology Co., Ltd. |
| 308 | powervr PowerVR (deprecated, use img) | 309 | powervr PowerVR (deprecated, use img) |
| @@ -415,6 +416,7 @@ vamrs Vamrs Ltd. | |||
| 415 | variscite Variscite Ltd. | 416 | variscite Variscite Ltd. |
| 416 | via VIA Technologies, Inc. | 417 | via VIA Technologies, Inc. |
| 417 | virtio Virtual I/O Device Specification, developed by the OASIS consortium | 418 | virtio Virtual I/O Device Specification, developed by the OASIS consortium |
| 419 | vishay Vishay Intertechnology, Inc | ||
| 418 | vitesse Vitesse Semiconductor Corporation | 420 | vitesse Vitesse Semiconductor Corporation |
| 419 | vivante Vivante Corporation | 421 | vivante Vivante Corporation |
| 420 | vocore VoCore Studio | 422 | vocore VoCore Studio |
diff --git a/MAINTAINERS b/MAINTAINERS index 49ae03fac21c..f4d94fb0666d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -845,6 +845,14 @@ S: Supported | |||
| 845 | F: drivers/iio/dac/ad5758.c | 845 | F: drivers/iio/dac/ad5758.c |
| 846 | F: Documentation/devicetree/bindings/iio/dac/ad5758.txt | 846 | F: Documentation/devicetree/bindings/iio/dac/ad5758.txt |
| 847 | 847 | ||
| 848 | ANALOG DEVICES INC AD7124 DRIVER | ||
| 849 | M: Stefan Popa <stefan.popa@analog.com> | ||
| 850 | L: linux-iio@vger.kernel.org | ||
| 851 | W: http://ez.analog.com/community/linux-device-drivers | ||
| 852 | S: Supported | ||
| 853 | F: drivers/iio/adc/ad7124.c | ||
| 854 | F: Documentation/devicetree/bindings/iio/adc/adi,ad7124.txt | ||
| 855 | |||
| 848 | ANALOG DEVICES INC AD9389B DRIVER | 856 | ANALOG DEVICES INC AD9389B DRIVER |
| 849 | M: Hans Verkuil <hans.verkuil@cisco.com> | 857 | M: Hans Verkuil <hans.verkuil@cisco.com> |
| 850 | L: linux-media@vger.kernel.org | 858 | L: linux-media@vger.kernel.org |
| @@ -11858,6 +11866,13 @@ M: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> | |||
| 11858 | S: Maintained | 11866 | S: Maintained |
| 11859 | F: drivers/pnp/ | 11867 | F: drivers/pnp/ |
| 11860 | 11868 | ||
| 11869 | PNI RM3100 IIO DRIVER | ||
| 11870 | M: Song Qiang <songqiang1304521@gmail.com> | ||
| 11871 | L: linux-iio@vger.kernel.org | ||
| 11872 | S: Maintained | ||
| 11873 | F: drivers/iio/magnetometer/rm3100* | ||
| 11874 | F: Documentation/devicetree/bindings/iio/magnetometer/pni,rm3100.txt | ||
| 11875 | |||
| 11861 | POSIX CLOCKS and TIMERS | 11876 | POSIX CLOCKS and TIMERS |
| 11862 | M: Thomas Gleixner <tglx@linutronix.de> | 11877 | M: Thomas Gleixner <tglx@linutronix.de> |
| 11863 | L: linux-kernel@vger.kernel.org | 11878 | L: linux-kernel@vger.kernel.org |
| @@ -12641,7 +12656,8 @@ RENESAS R-CAR GYROADC DRIVER | |||
| 12641 | M: Marek Vasut <marek.vasut@gmail.com> | 12656 | M: Marek Vasut <marek.vasut@gmail.com> |
| 12642 | L: linux-iio@vger.kernel.org | 12657 | L: linux-iio@vger.kernel.org |
| 12643 | S: Supported | 12658 | S: Supported |
| 12644 | F: drivers/iio/adc/rcar_gyro_adc.c | 12659 | F: Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt |
| 12660 | F: drivers/iio/adc/rcar-gyroadc.c | ||
| 12645 | 12661 | ||
| 12646 | RENESAS R-CAR I2C DRIVERS | 12662 | RENESAS R-CAR I2C DRIVERS |
| 12647 | M: Wolfram Sang <wsa+renesas@sang-engineering.com> | 12663 | M: Wolfram Sang <wsa+renesas@sang-engineering.com> |
| @@ -14048,6 +14064,14 @@ M: Jan-Benedict Glaw <jbglaw@lug-owl.de> | |||
| 14048 | S: Maintained | 14064 | S: Maintained |
| 14049 | F: arch/alpha/kernel/srm_env.c | 14065 | F: arch/alpha/kernel/srm_env.c |
| 14050 | 14066 | ||
| 14067 | ST LSM6DSx IMU IIO DRIVER | ||
| 14068 | M: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> | ||
| 14069 | L: linux-iio@vger.kernel.org | ||
| 14070 | W: http://www.st.com/ | ||
| 14071 | S: Maintained | ||
| 14072 | F: drivers/iio/imu/st_lsm6dsx/ | ||
| 14073 | F: Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt | ||
| 14074 | |||
| 14051 | ST STM32 I2C/SMBUS DRIVER | 14075 | ST STM32 I2C/SMBUS DRIVER |
| 14052 | M: Pierre-Yves MORDRET <pierre-yves.mordret@st.com> | 14076 | M: Pierre-Yves MORDRET <pierre-yves.mordret@st.com> |
| 14053 | L: linux-i2c@vger.kernel.org | 14077 | L: linux-i2c@vger.kernel.org |
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index 7993a67bd351..898839ca164a 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig | |||
| @@ -223,7 +223,7 @@ config IIO_ST_ACCEL_3AXIS | |||
| 223 | Say yes here to build support for STMicroelectronics accelerometers: | 223 | Say yes here to build support for STMicroelectronics accelerometers: |
| 224 | LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC, | 224 | LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC, |
| 225 | LIS331DLH, LSM303DL, LSM303DLM, LSM330, LIS2DH12, H3LIS331DL, | 225 | LIS331DLH, LSM303DL, LSM303DLM, LSM330, LIS2DH12, H3LIS331DL, |
| 226 | LNG2DM | 226 | LNG2DM, LIS3DE |
| 227 | 227 | ||
| 228 | This driver can also be built as a module. If so, these modules | 228 | This driver can also be built as a module. If so, these modules |
| 229 | will be created: | 229 | will be created: |
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index af53a1084ee5..8600e4be88ad 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c | |||
| @@ -1489,6 +1489,7 @@ static const struct acpi_device_id kx_acpi_match[] = { | |||
| 1489 | {"KXCJ1013", KXCJK1013}, | 1489 | {"KXCJ1013", KXCJK1013}, |
| 1490 | {"KXCJ1008", KXCJ91008}, | 1490 | {"KXCJ1008", KXCJ91008}, |
| 1491 | {"KXCJ9000", KXCJ91008}, | 1491 | {"KXCJ9000", KXCJ91008}, |
| 1492 | {"KIOX0009", KXTJ21009}, | ||
| 1492 | {"KIOX000A", KXCJ91008}, | 1493 | {"KIOX000A", KXCJ91008}, |
| 1493 | {"KXTJ1009", KXTJ21009}, | 1494 | {"KXTJ1009", KXTJ21009}, |
| 1494 | {"SMO8500", KXCJ91008}, | 1495 | {"SMO8500", KXCJ91008}, |
diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h index 2f931e4837e5..fd53258656ca 100644 --- a/drivers/iio/accel/st_accel.h +++ b/drivers/iio/accel/st_accel.h | |||
| @@ -56,6 +56,7 @@ enum st_accel_type { | |||
| 56 | #define LNG2DM_ACCEL_DEV_NAME "lng2dm" | 56 | #define LNG2DM_ACCEL_DEV_NAME "lng2dm" |
| 57 | #define LIS2DW12_ACCEL_DEV_NAME "lis2dw12" | 57 | #define LIS2DW12_ACCEL_DEV_NAME "lis2dw12" |
| 58 | #define LIS3DHH_ACCEL_DEV_NAME "lis3dhh" | 58 | #define LIS3DHH_ACCEL_DEV_NAME "lis3dhh" |
| 59 | #define LIS3DE_ACCEL_DEV_NAME "lis3de" | ||
| 59 | 60 | ||
| 60 | /** | 61 | /** |
| 61 | * struct st_sensors_platform_data - default accel platform data | 62 | * struct st_sensors_platform_data - default accel platform data |
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c index 3e6fd5a8ac5b..f7b471121508 100644 --- a/drivers/iio/accel/st_accel_core.c +++ b/drivers/iio/accel/st_accel_core.c | |||
| @@ -103,6 +103,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { | |||
| 103 | [4] = LSM330DLC_ACCEL_DEV_NAME, | 103 | [4] = LSM330DLC_ACCEL_DEV_NAME, |
| 104 | [5] = LSM303AGR_ACCEL_DEV_NAME, | 104 | [5] = LSM303AGR_ACCEL_DEV_NAME, |
| 105 | [6] = LIS2DH12_ACCEL_DEV_NAME, | 105 | [6] = LIS2DH12_ACCEL_DEV_NAME, |
| 106 | [7] = LIS3DE_ACCEL_DEV_NAME, | ||
| 106 | }, | 107 | }, |
| 107 | .ch = (struct iio_chan_spec *)st_accel_12bit_channels, | 108 | .ch = (struct iio_chan_spec *)st_accel_12bit_channels, |
| 108 | .odr = { | 109 | .odr = { |
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index 2ca5d1f6ade0..de8ae4327094 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c | |||
| @@ -98,6 +98,10 @@ static const struct of_device_id st_accel_of_match[] = { | |||
| 98 | .compatible = "st,lis2dw12", | 98 | .compatible = "st,lis2dw12", |
| 99 | .data = LIS2DW12_ACCEL_DEV_NAME, | 99 | .data = LIS2DW12_ACCEL_DEV_NAME, |
| 100 | }, | 100 | }, |
| 101 | { | ||
| 102 | .compatible = "st,lis3de", | ||
| 103 | .data = LIS3DE_ACCEL_DEV_NAME, | ||
| 104 | }, | ||
| 101 | {}, | 105 | {}, |
| 102 | }; | 106 | }; |
| 103 | MODULE_DEVICE_TABLE(of, st_accel_of_match); | 107 | MODULE_DEVICE_TABLE(of, st_accel_of_match); |
| @@ -135,6 +139,7 @@ static const struct i2c_device_id st_accel_id_table[] = { | |||
| 135 | { LIS331DL_ACCEL_DEV_NAME }, | 139 | { LIS331DL_ACCEL_DEV_NAME }, |
| 136 | { LIS3LV02DL_ACCEL_DEV_NAME }, | 140 | { LIS3LV02DL_ACCEL_DEV_NAME }, |
| 137 | { LIS2DW12_ACCEL_DEV_NAME }, | 141 | { LIS2DW12_ACCEL_DEV_NAME }, |
| 142 | { LIS3DE_ACCEL_DEV_NAME }, | ||
| 138 | {}, | 143 | {}, |
| 139 | }; | 144 | }; |
| 140 | MODULE_DEVICE_TABLE(i2c, st_accel_id_table); | 145 | MODULE_DEVICE_TABLE(i2c, st_accel_id_table); |
diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c index dcc9bd243a52..73bfb5d04e2b 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c | |||
| @@ -90,6 +90,10 @@ static const struct of_device_id st_accel_of_match[] = { | |||
| 90 | .compatible = "st,lis3dhh", | 90 | .compatible = "st,lis3dhh", |
| 91 | .data = LIS3DHH_ACCEL_DEV_NAME, | 91 | .data = LIS3DHH_ACCEL_DEV_NAME, |
| 92 | }, | 92 | }, |
| 93 | { | ||
| 94 | .compatible = "st,lis3de", | ||
| 95 | .data = LIS3DE_ACCEL_DEV_NAME, | ||
| 96 | }, | ||
| 93 | {} | 97 | {} |
| 94 | }; | 98 | }; |
| 95 | MODULE_DEVICE_TABLE(of, st_accel_of_match); | 99 | MODULE_DEVICE_TABLE(of, st_accel_of_match); |
| @@ -143,6 +147,7 @@ static const struct spi_device_id st_accel_id_table[] = { | |||
| 143 | { LIS3LV02DL_ACCEL_DEV_NAME }, | 147 | { LIS3LV02DL_ACCEL_DEV_NAME }, |
| 144 | { LIS2DW12_ACCEL_DEV_NAME }, | 148 | { LIS2DW12_ACCEL_DEV_NAME }, |
| 145 | { LIS3DHH_ACCEL_DEV_NAME }, | 149 | { LIS3DHH_ACCEL_DEV_NAME }, |
| 150 | { LIS3DE_ACCEL_DEV_NAME }, | ||
| 146 | {}, | 151 | {}, |
| 147 | }; | 152 | }; |
| 148 | MODULE_DEVICE_TABLE(spi, st_accel_id_table); | 153 | MODULE_DEVICE_TABLE(spi, st_accel_id_table); |
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index a52fea8749a9..da9644b50846 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
| @@ -10,6 +10,17 @@ config AD_SIGMA_DELTA | |||
| 10 | select IIO_BUFFER | 10 | select IIO_BUFFER |
| 11 | select IIO_TRIGGERED_BUFFER | 11 | select IIO_TRIGGERED_BUFFER |
| 12 | 12 | ||
| 13 | config AD7124 | ||
| 14 | tristate "Analog Devices AD7124 and similar sigma-delta ADCs driver" | ||
| 15 | depends on SPI_MASTER | ||
| 16 | select AD_SIGMA_DELTA | ||
| 17 | help | ||
| 18 | Say yes here to build support for Analog Devices AD7124-4 and AD7124-8 | ||
| 19 | SPI analog to digital converters (ADC). | ||
| 20 | |||
| 21 | To compile this driver as a module, choose M here: the module will be | ||
| 22 | called ad7124. | ||
| 23 | |||
| 13 | config AD7266 | 24 | config AD7266 |
| 14 | tristate "Analog Devices AD7265/AD7266 ADC driver" | 25 | tristate "Analog Devices AD7265/AD7266 ADC driver" |
| 15 | depends on SPI_MASTER | 26 | depends on SPI_MASTER |
| @@ -116,6 +127,16 @@ config AD7923 | |||
| 116 | To compile this driver as a module, choose M here: the | 127 | To compile this driver as a module, choose M here: the |
| 117 | module will be called ad7923. | 128 | module will be called ad7923. |
| 118 | 129 | ||
| 130 | config AD7949 | ||
| 131 | tristate "Analog Devices AD7949 and similar ADCs driver" | ||
| 132 | depends on SPI | ||
| 133 | help | ||
| 134 | Say yes here to build support for Analog Devices | ||
| 135 | AD7949, AD7682, AD7689 8 Channel ADCs. | ||
| 136 | |||
| 137 | To compile this driver as a module, choose M here: the | ||
| 138 | module will be called ad7949. | ||
| 139 | |||
| 119 | config AD799X | 140 | config AD799X |
| 120 | tristate "Analog Devices AD799x ADC driver" | 141 | tristate "Analog Devices AD799x ADC driver" |
| 121 | depends on I2C | 142 | depends on I2C |
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index a6e6a0b659e2..07df37f621bd 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 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_AD_SIGMA_DELTA) += ad_sigma_delta.o | 7 | obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o |
| 8 | obj-$(CONFIG_AD7124) += ad7124.o | ||
| 8 | obj-$(CONFIG_AD7266) += ad7266.o | 9 | obj-$(CONFIG_AD7266) += ad7266.o |
| 9 | obj-$(CONFIG_AD7291) += ad7291.o | 10 | obj-$(CONFIG_AD7291) += ad7291.o |
| 10 | obj-$(CONFIG_AD7298) += ad7298.o | 11 | obj-$(CONFIG_AD7298) += ad7298.o |
| @@ -14,6 +15,7 @@ obj-$(CONFIG_AD7766) += ad7766.o | |||
| 14 | obj-$(CONFIG_AD7791) += ad7791.o | 15 | obj-$(CONFIG_AD7791) += ad7791.o |
| 15 | obj-$(CONFIG_AD7793) += ad7793.o | 16 | obj-$(CONFIG_AD7793) += ad7793.o |
| 16 | obj-$(CONFIG_AD7887) += ad7887.o | 17 | obj-$(CONFIG_AD7887) += ad7887.o |
| 18 | obj-$(CONFIG_AD7949) += ad7949.o | ||
| 17 | obj-$(CONFIG_AD799X) += ad799x.o | 19 | obj-$(CONFIG_AD799X) += ad799x.o |
| 18 | obj-$(CONFIG_ASPEED_ADC) += aspeed_adc.o | 20 | obj-$(CONFIG_ASPEED_ADC) += aspeed_adc.o |
| 19 | obj-$(CONFIG_AT91_ADC) += at91_adc.o | 21 | obj-$(CONFIG_AT91_ADC) += at91_adc.o |
diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c new file mode 100644 index 000000000000..7d5e5311d8de --- /dev/null +++ b/drivers/iio/adc/ad7124.c | |||
| @@ -0,0 +1,684 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * AD7124 SPI ADC driver | ||
| 4 | * | ||
| 5 | * Copyright 2018 Analog Devices Inc. | ||
| 6 | */ | ||
| 7 | #include <linux/bitfield.h> | ||
| 8 | #include <linux/clk.h> | ||
| 9 | #include <linux/delay.h> | ||
| 10 | #include <linux/device.h> | ||
| 11 | #include <linux/err.h> | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/regulator/consumer.h> | ||
| 15 | #include <linux/spi/spi.h> | ||
| 16 | |||
| 17 | #include <linux/iio/iio.h> | ||
| 18 | #include <linux/iio/adc/ad_sigma_delta.h> | ||
| 19 | #include <linux/iio/sysfs.h> | ||
| 20 | |||
| 21 | /* AD7124 registers */ | ||
| 22 | #define AD7124_COMMS 0x00 | ||
| 23 | #define AD7124_STATUS 0x00 | ||
| 24 | #define AD7124_ADC_CONTROL 0x01 | ||
| 25 | #define AD7124_DATA 0x02 | ||
| 26 | #define AD7124_IO_CONTROL_1 0x03 | ||
| 27 | #define AD7124_IO_CONTROL_2 0x04 | ||
| 28 | #define AD7124_ID 0x05 | ||
| 29 | #define AD7124_ERROR 0x06 | ||
| 30 | #define AD7124_ERROR_EN 0x07 | ||
| 31 | #define AD7124_MCLK_COUNT 0x08 | ||
| 32 | #define AD7124_CHANNEL(x) (0x09 + (x)) | ||
| 33 | #define AD7124_CONFIG(x) (0x19 + (x)) | ||
| 34 | #define AD7124_FILTER(x) (0x21 + (x)) | ||
| 35 | #define AD7124_OFFSET(x) (0x29 + (x)) | ||
| 36 | #define AD7124_GAIN(x) (0x31 + (x)) | ||
| 37 | |||
| 38 | /* AD7124_STATUS */ | ||
| 39 | #define AD7124_STATUS_POR_FLAG_MSK BIT(4) | ||
| 40 | |||
| 41 | /* AD7124_ADC_CONTROL */ | ||
| 42 | #define AD7124_ADC_CTRL_PWR_MSK GENMASK(7, 6) | ||
| 43 | #define AD7124_ADC_CTRL_PWR(x) FIELD_PREP(AD7124_ADC_CTRL_PWR_MSK, x) | ||
| 44 | #define AD7124_ADC_CTRL_MODE_MSK GENMASK(5, 2) | ||
| 45 | #define AD7124_ADC_CTRL_MODE(x) FIELD_PREP(AD7124_ADC_CTRL_MODE_MSK, x) | ||
| 46 | |||
| 47 | /* AD7124_CHANNEL_X */ | ||
| 48 | #define AD7124_CHANNEL_EN_MSK BIT(15) | ||
| 49 | #define AD7124_CHANNEL_EN(x) FIELD_PREP(AD7124_CHANNEL_EN_MSK, x) | ||
| 50 | #define AD7124_CHANNEL_SETUP_MSK GENMASK(14, 12) | ||
| 51 | #define AD7124_CHANNEL_SETUP(x) FIELD_PREP(AD7124_CHANNEL_SETUP_MSK, x) | ||
| 52 | #define AD7124_CHANNEL_AINP_MSK GENMASK(9, 5) | ||
| 53 | #define AD7124_CHANNEL_AINP(x) FIELD_PREP(AD7124_CHANNEL_AINP_MSK, x) | ||
| 54 | #define AD7124_CHANNEL_AINM_MSK GENMASK(4, 0) | ||
| 55 | #define AD7124_CHANNEL_AINM(x) FIELD_PREP(AD7124_CHANNEL_AINM_MSK, x) | ||
| 56 | |||
| 57 | /* AD7124_CONFIG_X */ | ||
| 58 | #define AD7124_CONFIG_BIPOLAR_MSK BIT(11) | ||
| 59 | #define AD7124_CONFIG_BIPOLAR(x) FIELD_PREP(AD7124_CONFIG_BIPOLAR_MSK, x) | ||
| 60 | #define AD7124_CONFIG_REF_SEL_MSK GENMASK(4, 3) | ||
| 61 | #define AD7124_CONFIG_REF_SEL(x) FIELD_PREP(AD7124_CONFIG_REF_SEL_MSK, x) | ||
| 62 | #define AD7124_CONFIG_PGA_MSK GENMASK(2, 0) | ||
| 63 | #define AD7124_CONFIG_PGA(x) FIELD_PREP(AD7124_CONFIG_PGA_MSK, x) | ||
| 64 | |||
| 65 | /* AD7124_FILTER_X */ | ||
| 66 | #define AD7124_FILTER_FS_MSK GENMASK(10, 0) | ||
| 67 | #define AD7124_FILTER_FS(x) FIELD_PREP(AD7124_FILTER_FS_MSK, x) | ||
| 68 | |||
| 69 | enum ad7124_ids { | ||
| 70 | ID_AD7124_4, | ||
| 71 | ID_AD7124_8, | ||
| 72 | }; | ||
| 73 | |||
| 74 | enum ad7124_ref_sel { | ||
| 75 | AD7124_REFIN1, | ||
| 76 | AD7124_REFIN2, | ||
| 77 | AD7124_INT_REF, | ||
| 78 | AD7124_AVDD_REF, | ||
| 79 | }; | ||
| 80 | |||
| 81 | enum ad7124_power_mode { | ||
| 82 | AD7124_LOW_POWER, | ||
| 83 | AD7124_MID_POWER, | ||
| 84 | AD7124_FULL_POWER, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static const unsigned int ad7124_gain[8] = { | ||
| 88 | 1, 2, 4, 8, 16, 32, 64, 128 | ||
| 89 | }; | ||
| 90 | |||
| 91 | static const int ad7124_master_clk_freq_hz[3] = { | ||
| 92 | [AD7124_LOW_POWER] = 76800, | ||
| 93 | [AD7124_MID_POWER] = 153600, | ||
| 94 | [AD7124_FULL_POWER] = 614400, | ||
| 95 | }; | ||
| 96 | |||
| 97 | static const char * const ad7124_ref_names[] = { | ||
| 98 | [AD7124_REFIN1] = "refin1", | ||
| 99 | [AD7124_REFIN2] = "refin2", | ||
| 100 | [AD7124_INT_REF] = "int", | ||
| 101 | [AD7124_AVDD_REF] = "avdd", | ||
| 102 | }; | ||
| 103 | |||
| 104 | struct ad7124_chip_info { | ||
| 105 | unsigned int num_inputs; | ||
| 106 | }; | ||
| 107 | |||
| 108 | struct ad7124_channel_config { | ||
| 109 | enum ad7124_ref_sel refsel; | ||
| 110 | bool bipolar; | ||
| 111 | unsigned int ain; | ||
| 112 | unsigned int vref_mv; | ||
| 113 | unsigned int pga_bits; | ||
| 114 | unsigned int odr; | ||
| 115 | }; | ||
| 116 | |||
| 117 | struct ad7124_state { | ||
| 118 | const struct ad7124_chip_info *chip_info; | ||
| 119 | struct ad_sigma_delta sd; | ||
| 120 | struct ad7124_channel_config channel_config[4]; | ||
| 121 | struct regulator *vref[4]; | ||
| 122 | struct clk *mclk; | ||
| 123 | unsigned int adc_control; | ||
| 124 | unsigned int num_channels; | ||
| 125 | }; | ||
| 126 | |||
| 127 | static const struct iio_chan_spec ad7124_channel_template = { | ||
| 128 | .type = IIO_VOLTAGE, | ||
| 129 | .indexed = 1, | ||
| 130 | .differential = 1, | ||
| 131 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | ||
| 132 | BIT(IIO_CHAN_INFO_SCALE) | | ||
| 133 | BIT(IIO_CHAN_INFO_OFFSET) | | ||
| 134 | BIT(IIO_CHAN_INFO_SAMP_FREQ), | ||
| 135 | .scan_type = { | ||
| 136 | .sign = 'u', | ||
| 137 | .realbits = 24, | ||
| 138 | .storagebits = 32, | ||
| 139 | .shift = 8, | ||
| 140 | .endianness = IIO_BE, | ||
| 141 | }, | ||
| 142 | }; | ||
| 143 | |||
| 144 | static struct ad7124_chip_info ad7124_chip_info_tbl[] = { | ||
| 145 | [ID_AD7124_4] = { | ||
| 146 | .num_inputs = 8, | ||
| 147 | }, | ||
| 148 | [ID_AD7124_8] = { | ||
| 149 | .num_inputs = 16, | ||
| 150 | }, | ||
| 151 | }; | ||
| 152 | |||
| 153 | static int ad7124_find_closest_match(const int *array, | ||
| 154 | unsigned int size, int val) | ||
| 155 | { | ||
| 156 | int i, idx; | ||
| 157 | unsigned int diff_new, diff_old; | ||
| 158 | |||
| 159 | diff_old = U32_MAX; | ||
| 160 | idx = 0; | ||
| 161 | |||
| 162 | for (i = 0; i < size; i++) { | ||
| 163 | diff_new = abs(val - array[i]); | ||
| 164 | if (diff_new < diff_old) { | ||
| 165 | diff_old = diff_new; | ||
| 166 | idx = i; | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | return idx; | ||
| 171 | } | ||
| 172 | |||
| 173 | static int ad7124_spi_write_mask(struct ad7124_state *st, | ||
| 174 | unsigned int addr, | ||
| 175 | unsigned long mask, | ||
| 176 | unsigned int val, | ||
| 177 | unsigned int bytes) | ||
| 178 | { | ||
| 179 | unsigned int readval; | ||
| 180 | int ret; | ||
| 181 | |||
| 182 | ret = ad_sd_read_reg(&st->sd, addr, bytes, &readval); | ||
| 183 | if (ret < 0) | ||
| 184 | return ret; | ||
| 185 | |||
| 186 | readval &= ~mask; | ||
| 187 | readval |= val; | ||
| 188 | |||
| 189 | return ad_sd_write_reg(&st->sd, addr, bytes, readval); | ||
| 190 | } | ||
| 191 | |||
| 192 | static int ad7124_set_mode(struct ad_sigma_delta *sd, | ||
| 193 | enum ad_sigma_delta_mode mode) | ||
| 194 | { | ||
| 195 | struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); | ||
| 196 | |||
| 197 | st->adc_control &= ~AD7124_ADC_CTRL_MODE_MSK; | ||
| 198 | st->adc_control |= AD7124_ADC_CTRL_MODE(mode); | ||
| 199 | |||
| 200 | return ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st->adc_control); | ||
| 201 | } | ||
| 202 | |||
| 203 | static int ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel) | ||
| 204 | { | ||
| 205 | struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); | ||
| 206 | unsigned int val; | ||
| 207 | |||
| 208 | val = st->channel_config[channel].ain | AD7124_CHANNEL_EN(1) | | ||
| 209 | AD7124_CHANNEL_SETUP(channel); | ||
| 210 | |||
| 211 | return ad_sd_write_reg(&st->sd, AD7124_CHANNEL(channel), 2, val); | ||
| 212 | } | ||
| 213 | |||
| 214 | static const struct ad_sigma_delta_info ad7124_sigma_delta_info = { | ||
| 215 | .set_channel = ad7124_set_channel, | ||
| 216 | .set_mode = ad7124_set_mode, | ||
| 217 | .has_registers = true, | ||
| 218 | .addr_shift = 0, | ||
| 219 | .read_mask = BIT(6), | ||
| 220 | .data_reg = AD7124_DATA, | ||
| 221 | }; | ||
| 222 | |||
| 223 | static int ad7124_set_channel_odr(struct ad7124_state *st, | ||
| 224 | unsigned int channel, | ||
| 225 | unsigned int odr) | ||
| 226 | { | ||
| 227 | unsigned int fclk, odr_sel_bits; | ||
| 228 | int ret; | ||
| 229 | |||
| 230 | fclk = clk_get_rate(st->mclk); | ||
| 231 | /* | ||
| 232 | * FS[10:0] = fCLK / (fADC x 32) where: | ||
| 233 | * fADC is the output data rate | ||
| 234 | * fCLK is the master clock frequency | ||
| 235 | * FS[10:0] are the bits in the filter register | ||
| 236 | * FS[10:0] can have a value from 1 to 2047 | ||
| 237 | */ | ||
| 238 | odr_sel_bits = DIV_ROUND_CLOSEST(fclk, odr * 32); | ||
| 239 | if (odr_sel_bits < 1) | ||
| 240 | odr_sel_bits = 1; | ||
| 241 | else if (odr_sel_bits > 2047) | ||
| 242 | odr_sel_bits = 2047; | ||
| 243 | |||
| 244 | ret = ad7124_spi_write_mask(st, AD7124_FILTER(channel), | ||
| 245 | AD7124_FILTER_FS_MSK, | ||
| 246 | AD7124_FILTER_FS(odr_sel_bits), 3); | ||
| 247 | if (ret < 0) | ||
| 248 | return ret; | ||
| 249 | /* fADC = fCLK / (FS[10:0] x 32) */ | ||
| 250 | st->channel_config[channel].odr = | ||
| 251 | DIV_ROUND_CLOSEST(fclk, odr_sel_bits * 32); | ||
| 252 | |||
| 253 | return 0; | ||
| 254 | } | ||
| 255 | |||
| 256 | static int ad7124_set_channel_gain(struct ad7124_state *st, | ||
| 257 | unsigned int channel, | ||
| 258 | unsigned int gain) | ||
| 259 | { | ||
| 260 | unsigned int res; | ||
| 261 | int ret; | ||
| 262 | |||
| 263 | res = ad7124_find_closest_match(ad7124_gain, | ||
| 264 | ARRAY_SIZE(ad7124_gain), gain); | ||
| 265 | ret = ad7124_spi_write_mask(st, AD7124_CONFIG(channel), | ||
| 266 | AD7124_CONFIG_PGA_MSK, | ||
| 267 | AD7124_CONFIG_PGA(res), 2); | ||
| 268 | if (ret < 0) | ||
| 269 | return ret; | ||
| 270 | |||
| 271 | st->channel_config[channel].pga_bits = res; | ||
| 272 | |||
| 273 | return 0; | ||
| 274 | } | ||
| 275 | |||
| 276 | static int ad7124_read_raw(struct iio_dev *indio_dev, | ||
| 277 | struct iio_chan_spec const *chan, | ||
| 278 | int *val, int *val2, long info) | ||
| 279 | { | ||
| 280 | struct ad7124_state *st = iio_priv(indio_dev); | ||
| 281 | int idx, ret; | ||
| 282 | |||
| 283 | switch (info) { | ||
| 284 | case IIO_CHAN_INFO_RAW: | ||
| 285 | ret = ad_sigma_delta_single_conversion(indio_dev, chan, val); | ||
| 286 | if (ret < 0) | ||
| 287 | return ret; | ||
| 288 | |||
| 289 | /* After the conversion is performed, disable the channel */ | ||
| 290 | ret = ad_sd_write_reg(&st->sd, | ||
| 291 | AD7124_CHANNEL(chan->address), 2, | ||
| 292 | st->channel_config[chan->address].ain | | ||
| 293 | AD7124_CHANNEL_EN(0)); | ||
| 294 | if (ret < 0) | ||
| 295 | return ret; | ||
| 296 | |||
| 297 | return IIO_VAL_INT; | ||
| 298 | case IIO_CHAN_INFO_SCALE: | ||
| 299 | idx = st->channel_config[chan->address].pga_bits; | ||
| 300 | *val = st->channel_config[chan->address].vref_mv; | ||
| 301 | if (st->channel_config[chan->address].bipolar) | ||
| 302 | *val2 = chan->scan_type.realbits - 1 + idx; | ||
| 303 | else | ||
| 304 | *val2 = chan->scan_type.realbits + idx; | ||
| 305 | |||
| 306 | return IIO_VAL_FRACTIONAL_LOG2; | ||
| 307 | case IIO_CHAN_INFO_OFFSET: | ||
| 308 | if (st->channel_config[chan->address].bipolar) | ||
| 309 | *val = -(1 << (chan->scan_type.realbits - 1)); | ||
| 310 | else | ||
| 311 | *val = 0; | ||
| 312 | |||
| 313 | return IIO_VAL_INT; | ||
| 314 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
| 315 | *val = st->channel_config[chan->address].odr; | ||
| 316 | |||
| 317 | return IIO_VAL_INT; | ||
| 318 | default: | ||
| 319 | return -EINVAL; | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | static int ad7124_write_raw(struct iio_dev *indio_dev, | ||
| 324 | struct iio_chan_spec const *chan, | ||
| 325 | int val, int val2, long info) | ||
| 326 | { | ||
| 327 | struct ad7124_state *st = iio_priv(indio_dev); | ||
| 328 | unsigned int res, gain, full_scale, vref; | ||
| 329 | |||
| 330 | switch (info) { | ||
| 331 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
| 332 | if (val2 != 0) | ||
| 333 | return -EINVAL; | ||
| 334 | |||
| 335 | return ad7124_set_channel_odr(st, chan->address, val); | ||
| 336 | case IIO_CHAN_INFO_SCALE: | ||
| 337 | if (val != 0) | ||
| 338 | return -EINVAL; | ||
| 339 | |||
| 340 | if (st->channel_config[chan->address].bipolar) | ||
| 341 | full_scale = 1 << (chan->scan_type.realbits - 1); | ||
| 342 | else | ||
| 343 | full_scale = 1 << chan->scan_type.realbits; | ||
| 344 | |||
| 345 | vref = st->channel_config[chan->address].vref_mv * 1000000LL; | ||
| 346 | res = DIV_ROUND_CLOSEST(vref, full_scale); | ||
| 347 | gain = DIV_ROUND_CLOSEST(res, val2); | ||
| 348 | |||
| 349 | return ad7124_set_channel_gain(st, chan->address, gain); | ||
| 350 | default: | ||
| 351 | return -EINVAL; | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | static IIO_CONST_ATTR(in_voltage_scale_available, | ||
| 356 | "0.000001164 0.000002328 0.000004656 0.000009313 0.000018626 0.000037252 0.000074505 0.000149011 0.000298023"); | ||
| 357 | |||
| 358 | static struct attribute *ad7124_attributes[] = { | ||
| 359 | &iio_const_attr_in_voltage_scale_available.dev_attr.attr, | ||
| 360 | NULL, | ||
| 361 | }; | ||
| 362 | |||
| 363 | static const struct attribute_group ad7124_attrs_group = { | ||
| 364 | .attrs = ad7124_attributes, | ||
| 365 | }; | ||
| 366 | |||
| 367 | static const struct iio_info ad7124_info = { | ||
| 368 | .read_raw = ad7124_read_raw, | ||
| 369 | .write_raw = ad7124_write_raw, | ||
| 370 | .validate_trigger = ad_sd_validate_trigger, | ||
| 371 | .attrs = &ad7124_attrs_group, | ||
| 372 | }; | ||
| 373 | |||
| 374 | static int ad7124_soft_reset(struct ad7124_state *st) | ||
| 375 | { | ||
| 376 | unsigned int readval, timeout; | ||
| 377 | int ret; | ||
| 378 | |||
| 379 | ret = ad_sd_reset(&st->sd, 64); | ||
| 380 | if (ret < 0) | ||
| 381 | return ret; | ||
| 382 | |||
| 383 | timeout = 100; | ||
| 384 | do { | ||
| 385 | ret = ad_sd_read_reg(&st->sd, AD7124_STATUS, 1, &readval); | ||
| 386 | if (ret < 0) | ||
| 387 | return ret; | ||
| 388 | |||
| 389 | if (!(readval & AD7124_STATUS_POR_FLAG_MSK)) | ||
| 390 | return 0; | ||
| 391 | |||
| 392 | /* The AD7124 requires typically 2ms to power up and settle */ | ||
| 393 | usleep_range(100, 2000); | ||
| 394 | } while (--timeout); | ||
| 395 | |||
| 396 | dev_err(&st->sd.spi->dev, "Soft reset failed\n"); | ||
| 397 | |||
| 398 | return -EIO; | ||
| 399 | } | ||
| 400 | |||
| 401 | static int ad7124_init_channel_vref(struct ad7124_state *st, | ||
| 402 | unsigned int channel_number) | ||
| 403 | { | ||
| 404 | unsigned int refsel = st->channel_config[channel_number].refsel; | ||
| 405 | |||
| 406 | switch (refsel) { | ||
| 407 | case AD7124_REFIN1: | ||
| 408 | case AD7124_REFIN2: | ||
| 409 | case AD7124_AVDD_REF: | ||
| 410 | if (IS_ERR(st->vref[refsel])) { | ||
| 411 | dev_err(&st->sd.spi->dev, | ||
| 412 | "Error, trying to use external voltage reference without a %s regulator.\n", | ||
| 413 | ad7124_ref_names[refsel]); | ||
| 414 | return PTR_ERR(st->vref[refsel]); | ||
| 415 | } | ||
| 416 | st->channel_config[channel_number].vref_mv = | ||
| 417 | regulator_get_voltage(st->vref[refsel]); | ||
| 418 | /* Conversion from uV to mV */ | ||
| 419 | st->channel_config[channel_number].vref_mv /= 1000; | ||
| 420 | break; | ||
| 421 | case AD7124_INT_REF: | ||
| 422 | st->channel_config[channel_number].vref_mv = 2500; | ||
| 423 | break; | ||
| 424 | default: | ||
| 425 | dev_err(&st->sd.spi->dev, "Invalid reference %d\n", refsel); | ||
| 426 | return -EINVAL; | ||
| 427 | } | ||
| 428 | |||
| 429 | return 0; | ||
| 430 | } | ||
| 431 | |||
| 432 | static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev, | ||
| 433 | struct device_node *np) | ||
| 434 | { | ||
| 435 | struct ad7124_state *st = iio_priv(indio_dev); | ||
| 436 | struct device_node *child; | ||
| 437 | struct iio_chan_spec *chan; | ||
| 438 | unsigned int ain[2], channel = 0, tmp; | ||
| 439 | int ret; | ||
| 440 | |||
| 441 | st->num_channels = of_get_available_child_count(np); | ||
| 442 | if (!st->num_channels) { | ||
| 443 | dev_err(indio_dev->dev.parent, "no channel children\n"); | ||
| 444 | return -ENODEV; | ||
| 445 | } | ||
| 446 | |||
| 447 | chan = devm_kcalloc(indio_dev->dev.parent, st->num_channels, | ||
| 448 | sizeof(*chan), GFP_KERNEL); | ||
| 449 | if (!chan) | ||
| 450 | return -ENOMEM; | ||
| 451 | |||
| 452 | indio_dev->channels = chan; | ||
| 453 | indio_dev->num_channels = st->num_channels; | ||
| 454 | |||
| 455 | for_each_available_child_of_node(np, child) { | ||
| 456 | ret = of_property_read_u32(child, "reg", &channel); | ||
| 457 | if (ret) | ||
| 458 | goto err; | ||
| 459 | |||
| 460 | ret = of_property_read_u32_array(child, "diff-channels", | ||
| 461 | ain, 2); | ||
| 462 | if (ret) | ||
| 463 | goto err; | ||
| 464 | |||
| 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]) | | ||
| 473 | AD7124_CHANNEL_AINM(ain[1]); | ||
| 474 | st->channel_config[channel].bipolar = | ||
| 475 | of_property_read_bool(child, "bipolar"); | ||
| 476 | |||
| 477 | ret = of_property_read_u32(child, "adi,reference-select", &tmp); | ||
| 478 | if (ret) | ||
| 479 | st->channel_config[channel].refsel = AD7124_INT_REF; | ||
| 480 | else | ||
| 481 | st->channel_config[channel].refsel = tmp; | ||
| 482 | |||
| 483 | *chan = ad7124_channel_template; | ||
| 484 | chan->address = channel; | ||
| 485 | chan->scan_index = channel; | ||
| 486 | chan->channel = ain[0]; | ||
| 487 | chan->channel2 = ain[1]; | ||
| 488 | |||
| 489 | chan++; | ||
| 490 | } | ||
| 491 | |||
| 492 | return 0; | ||
| 493 | err: | ||
| 494 | of_node_put(child); | ||
| 495 | |||
| 496 | return ret; | ||
| 497 | } | ||
| 498 | |||
| 499 | static int ad7124_setup(struct ad7124_state *st) | ||
| 500 | { | ||
| 501 | unsigned int val, fclk, power_mode; | ||
| 502 | int i, ret; | ||
| 503 | |||
| 504 | fclk = clk_get_rate(st->mclk); | ||
| 505 | if (!fclk) | ||
| 506 | return -EINVAL; | ||
| 507 | |||
| 508 | /* The power mode changes the master clock frequency */ | ||
| 509 | power_mode = ad7124_find_closest_match(ad7124_master_clk_freq_hz, | ||
| 510 | ARRAY_SIZE(ad7124_master_clk_freq_hz), | ||
| 511 | fclk); | ||
| 512 | if (fclk != ad7124_master_clk_freq_hz[power_mode]) { | ||
| 513 | ret = clk_set_rate(st->mclk, fclk); | ||
| 514 | if (ret) | ||
| 515 | return ret; | ||
| 516 | } | ||
| 517 | |||
| 518 | /* Set the power mode */ | ||
| 519 | st->adc_control &= ~AD7124_ADC_CTRL_PWR_MSK; | ||
| 520 | st->adc_control |= AD7124_ADC_CTRL_PWR(power_mode); | ||
| 521 | ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st->adc_control); | ||
| 522 | if (ret < 0) | ||
| 523 | return ret; | ||
| 524 | |||
| 525 | for (i = 0; i < st->num_channels; i++) { | ||
| 526 | val = st->channel_config[i].ain | AD7124_CHANNEL_SETUP(i); | ||
| 527 | ret = ad_sd_write_reg(&st->sd, AD7124_CHANNEL(i), 2, val); | ||
| 528 | if (ret < 0) | ||
| 529 | return ret; | ||
| 530 | |||
| 531 | ret = ad7124_init_channel_vref(st, i); | ||
| 532 | if (ret < 0) | ||
| 533 | return ret; | ||
| 534 | |||
| 535 | val = AD7124_CONFIG_BIPOLAR(st->channel_config[i].bipolar) | | ||
| 536 | AD7124_CONFIG_REF_SEL(st->channel_config[i].refsel); | ||
| 537 | ret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(i), 2, val); | ||
| 538 | if (ret < 0) | ||
| 539 | return ret; | ||
| 540 | /* | ||
| 541 | * 9.38 SPS is the minimum output data rate supported | ||
| 542 | * regardless of the selected power mode. Round it up to 10 and | ||
| 543 | * set all the enabled channels to this default value. | ||
| 544 | */ | ||
| 545 | ret = ad7124_set_channel_odr(st, i, 10); | ||
| 546 | } | ||
| 547 | |||
| 548 | return ret; | ||
| 549 | } | ||
| 550 | |||
| 551 | static int ad7124_probe(struct spi_device *spi) | ||
| 552 | { | ||
| 553 | const struct spi_device_id *id; | ||
| 554 | struct ad7124_state *st; | ||
| 555 | struct iio_dev *indio_dev; | ||
| 556 | int i, ret; | ||
| 557 | |||
| 558 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | ||
| 559 | if (!indio_dev) | ||
| 560 | return -ENOMEM; | ||
| 561 | |||
| 562 | st = iio_priv(indio_dev); | ||
| 563 | |||
| 564 | id = spi_get_device_id(spi); | ||
| 565 | st->chip_info = &ad7124_chip_info_tbl[id->driver_data]; | ||
| 566 | |||
| 567 | ad_sd_init(&st->sd, indio_dev, spi, &ad7124_sigma_delta_info); | ||
| 568 | |||
| 569 | spi_set_drvdata(spi, indio_dev); | ||
| 570 | |||
| 571 | indio_dev->dev.parent = &spi->dev; | ||
| 572 | indio_dev->name = spi_get_device_id(spi)->name; | ||
| 573 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
| 574 | indio_dev->info = &ad7124_info; | ||
| 575 | |||
| 576 | ret = ad7124_of_parse_channel_config(indio_dev, spi->dev.of_node); | ||
| 577 | if (ret < 0) | ||
| 578 | return ret; | ||
| 579 | |||
| 580 | for (i = 0; i < ARRAY_SIZE(st->vref); i++) { | ||
| 581 | if (i == AD7124_INT_REF) | ||
| 582 | continue; | ||
| 583 | |||
| 584 | st->vref[i] = devm_regulator_get_optional(&spi->dev, | ||
| 585 | ad7124_ref_names[i]); | ||
| 586 | if (PTR_ERR(st->vref[i]) == -ENODEV) | ||
| 587 | continue; | ||
| 588 | else if (IS_ERR(st->vref[i])) | ||
| 589 | return PTR_ERR(st->vref[i]); | ||
| 590 | |||
| 591 | ret = regulator_enable(st->vref[i]); | ||
| 592 | if (ret) | ||
| 593 | return ret; | ||
| 594 | } | ||
| 595 | |||
| 596 | st->mclk = devm_clk_get(&spi->dev, "mclk"); | ||
| 597 | if (IS_ERR(st->mclk)) { | ||
| 598 | ret = PTR_ERR(st->mclk); | ||
| 599 | goto error_regulator_disable; | ||
| 600 | } | ||
| 601 | |||
| 602 | ret = clk_prepare_enable(st->mclk); | ||
| 603 | if (ret < 0) | ||
| 604 | goto error_regulator_disable; | ||
| 605 | |||
| 606 | ret = ad7124_soft_reset(st); | ||
| 607 | if (ret < 0) | ||
| 608 | goto error_clk_disable_unprepare; | ||
| 609 | |||
| 610 | ret = ad7124_setup(st); | ||
| 611 | if (ret < 0) | ||
| 612 | goto error_clk_disable_unprepare; | ||
| 613 | |||
| 614 | ret = ad_sd_setup_buffer_and_trigger(indio_dev); | ||
| 615 | if (ret < 0) | ||
| 616 | goto error_clk_disable_unprepare; | ||
| 617 | |||
| 618 | ret = iio_device_register(indio_dev); | ||
| 619 | if (ret < 0) { | ||
| 620 | dev_err(&spi->dev, "Failed to register iio device\n"); | ||
| 621 | goto error_remove_trigger; | ||
| 622 | } | ||
| 623 | |||
| 624 | return 0; | ||
| 625 | |||
| 626 | error_remove_trigger: | ||
| 627 | ad_sd_cleanup_buffer_and_trigger(indio_dev); | ||
| 628 | error_clk_disable_unprepare: | ||
| 629 | clk_disable_unprepare(st->mclk); | ||
| 630 | error_regulator_disable: | ||
| 631 | for (i = ARRAY_SIZE(st->vref) - 1; i >= 0; i--) { | ||
| 632 | if (!IS_ERR_OR_NULL(st->vref[i])) | ||
| 633 | regulator_disable(st->vref[i]); | ||
| 634 | } | ||
| 635 | |||
| 636 | return ret; | ||
| 637 | } | ||
| 638 | |||
| 639 | static int ad7124_remove(struct spi_device *spi) | ||
| 640 | { | ||
| 641 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
| 642 | struct ad7124_state *st = iio_priv(indio_dev); | ||
| 643 | int i; | ||
| 644 | |||
| 645 | iio_device_unregister(indio_dev); | ||
| 646 | ad_sd_cleanup_buffer_and_trigger(indio_dev); | ||
| 647 | clk_disable_unprepare(st->mclk); | ||
| 648 | |||
| 649 | for (i = ARRAY_SIZE(st->vref) - 1; i >= 0; i--) { | ||
| 650 | if (!IS_ERR_OR_NULL(st->vref[i])) | ||
| 651 | regulator_disable(st->vref[i]); | ||
| 652 | } | ||
| 653 | |||
| 654 | return 0; | ||
| 655 | } | ||
| 656 | |||
| 657 | static const struct spi_device_id ad7124_id_table[] = { | ||
| 658 | { "ad7124-4", ID_AD7124_4 }, | ||
| 659 | { "ad7124-8", ID_AD7124_8 }, | ||
| 660 | {} | ||
| 661 | }; | ||
| 662 | MODULE_DEVICE_TABLE(spi, ad7124_id_table); | ||
| 663 | |||
| 664 | static const struct of_device_id ad7124_of_match[] = { | ||
| 665 | { .compatible = "adi,ad7124-4" }, | ||
| 666 | { .compatible = "adi,ad7124-8" }, | ||
| 667 | { }, | ||
| 668 | }; | ||
| 669 | MODULE_DEVICE_TABLE(of, ad7124_of_match); | ||
| 670 | |||
| 671 | static struct spi_driver ad71124_driver = { | ||
| 672 | .driver = { | ||
| 673 | .name = "ad7124", | ||
| 674 | .of_match_table = ad7124_of_match, | ||
| 675 | }, | ||
| 676 | .probe = ad7124_probe, | ||
| 677 | .remove = ad7124_remove, | ||
| 678 | .id_table = ad7124_id_table, | ||
| 679 | }; | ||
| 680 | module_spi_driver(ad71124_driver); | ||
| 681 | |||
| 682 | MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>"); | ||
| 683 | MODULE_DESCRIPTION("Analog Devices AD7124 SPI driver"); | ||
| 684 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/iio/adc/ad7949.c b/drivers/iio/adc/ad7949.c new file mode 100644 index 000000000000..ac0ffff6c5ae --- /dev/null +++ b/drivers/iio/adc/ad7949.c | |||
| @@ -0,0 +1,347 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* ad7949.c - Analog Devices ADC driver 14/16 bits 4/8 channels | ||
| 3 | * | ||
| 4 | * Copyright (C) 2018 CMC NV | ||
| 5 | * | ||
| 6 | * http://www.analog.com/media/en/technical-documentation/data-sheets/AD7949.pdf | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/delay.h> | ||
| 10 | #include <linux/iio/iio.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/regulator/consumer.h> | ||
| 13 | #include <linux/spi/spi.h> | ||
| 14 | |||
| 15 | #define AD7949_MASK_CHANNEL_SEL GENMASK(9, 7) | ||
| 16 | #define AD7949_MASK_TOTAL GENMASK(13, 0) | ||
| 17 | #define AD7949_OFFSET_CHANNEL_SEL 7 | ||
| 18 | #define AD7949_CFG_READ_BACK 0x1 | ||
| 19 | #define AD7949_CFG_REG_SIZE_BITS 14 | ||
| 20 | |||
| 21 | enum { | ||
| 22 | ID_AD7949 = 0, | ||
| 23 | ID_AD7682, | ||
| 24 | ID_AD7689, | ||
| 25 | }; | ||
| 26 | |||
| 27 | struct ad7949_adc_spec { | ||
| 28 | u8 num_channels; | ||
| 29 | u8 resolution; | ||
| 30 | }; | ||
| 31 | |||
| 32 | static const struct ad7949_adc_spec ad7949_adc_spec[] = { | ||
| 33 | [ID_AD7949] = { .num_channels = 8, .resolution = 14 }, | ||
| 34 | [ID_AD7682] = { .num_channels = 4, .resolution = 16 }, | ||
| 35 | [ID_AD7689] = { .num_channels = 8, .resolution = 16 }, | ||
| 36 | }; | ||
| 37 | |||
| 38 | /** | ||
| 39 | * struct ad7949_adc_chip - AD ADC chip | ||
| 40 | * @lock: protects write sequences | ||
| 41 | * @vref: regulator generating Vref | ||
| 42 | * @iio_dev: reference to iio structure | ||
| 43 | * @spi: reference to spi structure | ||
| 44 | * @resolution: resolution of the chip | ||
| 45 | * @cfg: copy of the configuration register | ||
| 46 | * @current_channel: current channel in use | ||
| 47 | * @buffer: buffer to send / receive data to / from device | ||
| 48 | */ | ||
| 49 | struct ad7949_adc_chip { | ||
| 50 | struct mutex lock; | ||
| 51 | struct regulator *vref; | ||
| 52 | struct iio_dev *indio_dev; | ||
| 53 | struct spi_device *spi; | ||
| 54 | u8 resolution; | ||
| 55 | u16 cfg; | ||
| 56 | unsigned int current_channel; | ||
| 57 | u32 buffer ____cacheline_aligned; | ||
| 58 | }; | ||
| 59 | |||
| 60 | static bool ad7949_spi_cfg_is_read_back(struct ad7949_adc_chip *ad7949_adc) | ||
| 61 | { | ||
| 62 | if (!(ad7949_adc->cfg & AD7949_CFG_READ_BACK)) | ||
| 63 | return true; | ||
| 64 | |||
| 65 | return false; | ||
| 66 | } | ||
| 67 | |||
| 68 | static int ad7949_spi_bits_per_word(struct ad7949_adc_chip *ad7949_adc) | ||
| 69 | { | ||
| 70 | int ret = ad7949_adc->resolution; | ||
| 71 | |||
| 72 | if (ad7949_spi_cfg_is_read_back(ad7949_adc)) | ||
| 73 | ret += AD7949_CFG_REG_SIZE_BITS; | ||
| 74 | |||
| 75 | return ret; | ||
| 76 | } | ||
| 77 | |||
| 78 | static int ad7949_spi_write_cfg(struct ad7949_adc_chip *ad7949_adc, u16 val, | ||
| 79 | u16 mask) | ||
| 80 | { | ||
| 81 | int ret; | ||
| 82 | int bits_per_word = ad7949_spi_bits_per_word(ad7949_adc); | ||
| 83 | int shift = bits_per_word - AD7949_CFG_REG_SIZE_BITS; | ||
| 84 | struct spi_message msg; | ||
| 85 | struct spi_transfer tx[] = { | ||
| 86 | { | ||
| 87 | .tx_buf = &ad7949_adc->buffer, | ||
| 88 | .len = 4, | ||
| 89 | .bits_per_word = bits_per_word, | ||
| 90 | }, | ||
| 91 | }; | ||
| 92 | |||
| 93 | ad7949_adc->cfg = (val & mask) | (ad7949_adc->cfg & ~mask); | ||
| 94 | ad7949_adc->buffer = ad7949_adc->cfg << shift; | ||
| 95 | spi_message_init_with_transfers(&msg, tx, 1); | ||
| 96 | ret = spi_sync(ad7949_adc->spi, &msg); | ||
| 97 | |||
| 98 | /* | ||
| 99 | * This delay is to avoid a new request before the required time to | ||
| 100 | * send a new command to the device | ||
| 101 | */ | ||
| 102 | udelay(2); | ||
| 103 | return ret; | ||
| 104 | } | ||
| 105 | |||
| 106 | static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val, | ||
| 107 | unsigned int channel) | ||
| 108 | { | ||
| 109 | int ret; | ||
| 110 | int bits_per_word = ad7949_spi_bits_per_word(ad7949_adc); | ||
| 111 | int mask = GENMASK(ad7949_adc->resolution, 0); | ||
| 112 | struct spi_message msg; | ||
| 113 | struct spi_transfer tx[] = { | ||
| 114 | { | ||
| 115 | .rx_buf = &ad7949_adc->buffer, | ||
| 116 | .len = 4, | ||
| 117 | .bits_per_word = bits_per_word, | ||
| 118 | }, | ||
| 119 | }; | ||
| 120 | |||
| 121 | ret = ad7949_spi_write_cfg(ad7949_adc, | ||
| 122 | channel << AD7949_OFFSET_CHANNEL_SEL, | ||
| 123 | AD7949_MASK_CHANNEL_SEL); | ||
| 124 | if (ret) | ||
| 125 | return ret; | ||
| 126 | |||
| 127 | ad7949_adc->buffer = 0; | ||
| 128 | spi_message_init_with_transfers(&msg, tx, 1); | ||
| 129 | ret = spi_sync(ad7949_adc->spi, &msg); | ||
| 130 | if (ret) | ||
| 131 | return ret; | ||
| 132 | |||
| 133 | /* | ||
| 134 | * This delay is to avoid a new request before the required time to | ||
| 135 | * send a new command to the device | ||
| 136 | */ | ||
| 137 | udelay(2); | ||
| 138 | |||
| 139 | ad7949_adc->current_channel = channel; | ||
| 140 | |||
| 141 | if (ad7949_spi_cfg_is_read_back(ad7949_adc)) | ||
| 142 | *val = (ad7949_adc->buffer >> AD7949_CFG_REG_SIZE_BITS) & mask; | ||
| 143 | else | ||
| 144 | *val = ad7949_adc->buffer & mask; | ||
| 145 | |||
| 146 | return 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | #define AD7949_ADC_CHANNEL(chan) { \ | ||
| 150 | .type = IIO_VOLTAGE, \ | ||
| 151 | .indexed = 1, \ | ||
| 152 | .channel = (chan), \ | ||
| 153 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ | ||
| 154 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ | ||
| 155 | } | ||
| 156 | |||
| 157 | static const struct iio_chan_spec ad7949_adc_channels[] = { | ||
| 158 | AD7949_ADC_CHANNEL(0), | ||
| 159 | AD7949_ADC_CHANNEL(1), | ||
| 160 | AD7949_ADC_CHANNEL(2), | ||
| 161 | AD7949_ADC_CHANNEL(3), | ||
| 162 | AD7949_ADC_CHANNEL(4), | ||
| 163 | AD7949_ADC_CHANNEL(5), | ||
| 164 | AD7949_ADC_CHANNEL(6), | ||
| 165 | AD7949_ADC_CHANNEL(7), | ||
| 166 | }; | ||
| 167 | |||
| 168 | static int ad7949_spi_read_raw(struct iio_dev *indio_dev, | ||
| 169 | struct iio_chan_spec const *chan, | ||
| 170 | int *val, int *val2, long mask) | ||
| 171 | { | ||
| 172 | struct ad7949_adc_chip *ad7949_adc = iio_priv(indio_dev); | ||
| 173 | int ret; | ||
| 174 | |||
| 175 | if (!val) | ||
| 176 | return -EINVAL; | ||
| 177 | |||
| 178 | switch (mask) { | ||
| 179 | case IIO_CHAN_INFO_RAW: | ||
| 180 | mutex_lock(&ad7949_adc->lock); | ||
| 181 | ret = ad7949_spi_read_channel(ad7949_adc, val, chan->channel); | ||
| 182 | mutex_unlock(&ad7949_adc->lock); | ||
| 183 | |||
| 184 | if (ret < 0) | ||
| 185 | return ret; | ||
| 186 | |||
| 187 | return IIO_VAL_INT; | ||
| 188 | |||
| 189 | case IIO_CHAN_INFO_SCALE: | ||
| 190 | ret = regulator_get_voltage(ad7949_adc->vref); | ||
| 191 | if (ret < 0) | ||
| 192 | return ret; | ||
| 193 | |||
| 194 | *val = ret / 5000; | ||
| 195 | return IIO_VAL_INT; | ||
| 196 | } | ||
| 197 | |||
| 198 | return -EINVAL; | ||
| 199 | } | ||
| 200 | |||
| 201 | static int ad7949_spi_reg_access(struct iio_dev *indio_dev, | ||
| 202 | unsigned int reg, unsigned int writeval, | ||
| 203 | unsigned int *readval) | ||
| 204 | { | ||
| 205 | struct ad7949_adc_chip *ad7949_adc = iio_priv(indio_dev); | ||
| 206 | int ret = 0; | ||
| 207 | |||
| 208 | if (readval) | ||
| 209 | *readval = ad7949_adc->cfg; | ||
| 210 | else | ||
| 211 | ret = ad7949_spi_write_cfg(ad7949_adc, | ||
| 212 | writeval & AD7949_MASK_TOTAL, AD7949_MASK_TOTAL); | ||
| 213 | |||
| 214 | return ret; | ||
| 215 | } | ||
| 216 | |||
| 217 | static const struct iio_info ad7949_spi_info = { | ||
| 218 | .read_raw = ad7949_spi_read_raw, | ||
| 219 | .debugfs_reg_access = ad7949_spi_reg_access, | ||
| 220 | }; | ||
| 221 | |||
| 222 | static int ad7949_spi_init(struct ad7949_adc_chip *ad7949_adc) | ||
| 223 | { | ||
| 224 | int ret; | ||
| 225 | int val; | ||
| 226 | |||
| 227 | /* Sequencer disabled, CFG readback disabled, IN0 as default channel */ | ||
| 228 | ad7949_adc->current_channel = 0; | ||
| 229 | ret = ad7949_spi_write_cfg(ad7949_adc, 0x3C79, AD7949_MASK_TOTAL); | ||
| 230 | |||
| 231 | /* | ||
| 232 | * Do two dummy conversions to apply the first configuration setting. | ||
| 233 | * Required only after the start up of the device. | ||
| 234 | */ | ||
| 235 | ad7949_spi_read_channel(ad7949_adc, &val, ad7949_adc->current_channel); | ||
| 236 | ad7949_spi_read_channel(ad7949_adc, &val, ad7949_adc->current_channel); | ||
| 237 | |||
| 238 | return ret; | ||
| 239 | } | ||
| 240 | |||
| 241 | static int ad7949_spi_probe(struct spi_device *spi) | ||
| 242 | { | ||
| 243 | struct device *dev = &spi->dev; | ||
| 244 | const struct ad7949_adc_spec *spec; | ||
| 245 | struct ad7949_adc_chip *ad7949_adc; | ||
| 246 | struct iio_dev *indio_dev; | ||
| 247 | int ret; | ||
| 248 | |||
| 249 | indio_dev = devm_iio_device_alloc(dev, sizeof(*ad7949_adc)); | ||
| 250 | if (!indio_dev) { | ||
| 251 | dev_err(dev, "can not allocate iio device\n"); | ||
| 252 | return -ENOMEM; | ||
| 253 | } | ||
| 254 | |||
| 255 | indio_dev->dev.parent = dev; | ||
| 256 | indio_dev->dev.of_node = dev->of_node; | ||
| 257 | indio_dev->info = &ad7949_spi_info; | ||
| 258 | indio_dev->name = spi_get_device_id(spi)->name; | ||
| 259 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
| 260 | indio_dev->channels = ad7949_adc_channels; | ||
| 261 | spi_set_drvdata(spi, indio_dev); | ||
| 262 | |||
| 263 | ad7949_adc = iio_priv(indio_dev); | ||
| 264 | ad7949_adc->indio_dev = indio_dev; | ||
| 265 | ad7949_adc->spi = spi; | ||
| 266 | |||
| 267 | spec = &ad7949_adc_spec[spi_get_device_id(spi)->driver_data]; | ||
| 268 | indio_dev->num_channels = spec->num_channels; | ||
| 269 | ad7949_adc->resolution = spec->resolution; | ||
| 270 | |||
| 271 | ad7949_adc->vref = devm_regulator_get(dev, "vref"); | ||
| 272 | if (IS_ERR(ad7949_adc->vref)) { | ||
| 273 | dev_err(dev, "fail to request regulator\n"); | ||
| 274 | return PTR_ERR(ad7949_adc->vref); | ||
| 275 | } | ||
| 276 | |||
| 277 | ret = regulator_enable(ad7949_adc->vref); | ||
| 278 | if (ret < 0) { | ||
| 279 | dev_err(dev, "fail to enable regulator\n"); | ||
| 280 | return ret; | ||
| 281 | } | ||
| 282 | |||
| 283 | mutex_init(&ad7949_adc->lock); | ||
| 284 | |||
| 285 | ret = ad7949_spi_init(ad7949_adc); | ||
| 286 | if (ret) { | ||
| 287 | dev_err(dev, "enable to init this device: %d\n", ret); | ||
| 288 | goto err; | ||
| 289 | } | ||
| 290 | |||
| 291 | ret = iio_device_register(indio_dev); | ||
| 292 | if (ret) { | ||
| 293 | dev_err(dev, "fail to register iio device: %d\n", ret); | ||
| 294 | goto err; | ||
| 295 | } | ||
| 296 | |||
| 297 | return 0; | ||
| 298 | |||
| 299 | err: | ||
| 300 | mutex_destroy(&ad7949_adc->lock); | ||
| 301 | regulator_disable(ad7949_adc->vref); | ||
| 302 | |||
| 303 | return ret; | ||
| 304 | } | ||
| 305 | |||
| 306 | static int ad7949_spi_remove(struct spi_device *spi) | ||
| 307 | { | ||
| 308 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
| 309 | struct ad7949_adc_chip *ad7949_adc = iio_priv(indio_dev); | ||
| 310 | |||
| 311 | iio_device_unregister(indio_dev); | ||
| 312 | mutex_destroy(&ad7949_adc->lock); | ||
| 313 | regulator_disable(ad7949_adc->vref); | ||
| 314 | |||
| 315 | return 0; | ||
| 316 | } | ||
| 317 | |||
| 318 | static const struct of_device_id ad7949_spi_of_id[] = { | ||
| 319 | { .compatible = "adi,ad7949" }, | ||
| 320 | { .compatible = "adi,ad7682" }, | ||
| 321 | { .compatible = "adi,ad7689" }, | ||
| 322 | { } | ||
| 323 | }; | ||
| 324 | MODULE_DEVICE_TABLE(of, ad7949_spi_of_id); | ||
| 325 | |||
| 326 | static const struct spi_device_id ad7949_spi_id[] = { | ||
| 327 | { "ad7949", ID_AD7949 }, | ||
| 328 | { "ad7682", ID_AD7682 }, | ||
| 329 | { "ad7689", ID_AD7689 }, | ||
| 330 | { } | ||
| 331 | }; | ||
| 332 | MODULE_DEVICE_TABLE(spi, ad7949_spi_id); | ||
| 333 | |||
| 334 | static struct spi_driver ad7949_spi_driver = { | ||
| 335 | .driver = { | ||
| 336 | .name = "ad7949", | ||
| 337 | .of_match_table = ad7949_spi_of_id, | ||
| 338 | }, | ||
| 339 | .probe = ad7949_spi_probe, | ||
| 340 | .remove = ad7949_spi_remove, | ||
| 341 | .id_table = ad7949_spi_id, | ||
| 342 | }; | ||
| 343 | module_spi_driver(ad7949_spi_driver); | ||
| 344 | |||
| 345 | MODULE_AUTHOR("Charles-Antoine Couret <charles-antoine.couret@essensium.com>"); | ||
| 346 | MODULE_DESCRIPTION("Analog Devices 14/16-bit 8-channel ADC driver"); | ||
| 347 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index fc9510716ac7..ff5f2da2e1b1 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c | |||
| @@ -278,6 +278,7 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, | |||
| 278 | { | 278 | { |
| 279 | struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); | 279 | struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); |
| 280 | unsigned int sample, raw_sample; | 280 | unsigned int sample, raw_sample; |
| 281 | unsigned int data_reg; | ||
| 281 | int ret = 0; | 282 | int ret = 0; |
| 282 | 283 | ||
| 283 | if (iio_buffer_enabled(indio_dev)) | 284 | if (iio_buffer_enabled(indio_dev)) |
| @@ -305,7 +306,12 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, | |||
| 305 | if (ret < 0) | 306 | if (ret < 0) |
| 306 | goto out; | 307 | goto out; |
| 307 | 308 | ||
| 308 | ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_DATA, | 309 | if (sigma_delta->info->data_reg != 0) |
| 310 | data_reg = sigma_delta->info->data_reg; | ||
| 311 | else | ||
| 312 | data_reg = AD_SD_REG_DATA; | ||
| 313 | |||
| 314 | ret = ad_sd_read_reg(sigma_delta, data_reg, | ||
| 309 | DIV_ROUND_UP(chan->scan_type.realbits + chan->scan_type.shift, 8), | 315 | DIV_ROUND_UP(chan->scan_type.realbits + chan->scan_type.shift, 8), |
| 310 | &raw_sample); | 316 | &raw_sample); |
| 311 | 317 | ||
| @@ -392,6 +398,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) | |||
| 392 | struct iio_dev *indio_dev = pf->indio_dev; | 398 | struct iio_dev *indio_dev = pf->indio_dev; |
| 393 | struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); | 399 | struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev); |
| 394 | unsigned int reg_size; | 400 | unsigned int reg_size; |
| 401 | unsigned int data_reg; | ||
| 395 | uint8_t data[16]; | 402 | uint8_t data[16]; |
| 396 | int ret; | 403 | int ret; |
| 397 | 404 | ||
| @@ -401,18 +408,23 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) | |||
| 401 | indio_dev->channels[0].scan_type.shift; | 408 | indio_dev->channels[0].scan_type.shift; |
| 402 | reg_size = DIV_ROUND_UP(reg_size, 8); | 409 | reg_size = DIV_ROUND_UP(reg_size, 8); |
| 403 | 410 | ||
| 411 | if (sigma_delta->info->data_reg != 0) | ||
| 412 | data_reg = sigma_delta->info->data_reg; | ||
| 413 | else | ||
| 414 | data_reg = AD_SD_REG_DATA; | ||
| 415 | |||
| 404 | switch (reg_size) { | 416 | switch (reg_size) { |
| 405 | case 4: | 417 | case 4: |
| 406 | case 2: | 418 | case 2: |
| 407 | case 1: | 419 | case 1: |
| 408 | ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA, | 420 | ret = ad_sd_read_reg_raw(sigma_delta, data_reg, reg_size, |
| 409 | reg_size, &data[0]); | 421 | &data[0]); |
| 410 | break; | 422 | break; |
| 411 | case 3: | 423 | case 3: |
| 412 | /* We store 24 bit samples in a 32 bit word. Keep the upper | 424 | /* We store 24 bit samples in a 32 bit word. Keep the upper |
| 413 | * byte set to zero. */ | 425 | * byte set to zero. */ |
| 414 | ret = ad_sd_read_reg_raw(sigma_delta, AD_SD_REG_DATA, | 426 | ret = ad_sd_read_reg_raw(sigma_delta, data_reg, reg_size, |
| 415 | reg_size, &data[1]); | 427 | &data[1]); |
| 416 | break; | 428 | break; |
| 417 | } | 429 | } |
| 418 | 430 | ||
diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c index d1239624187d..bdd7cba6f6b0 100644 --- a/drivers/iio/adc/ina2xx-adc.c +++ b/drivers/iio/adc/ina2xx-adc.c | |||
| @@ -250,6 +250,7 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev, | |||
| 250 | *val2 = chip->shunt_resistor_uohm; | 250 | *val2 = chip->shunt_resistor_uohm; |
| 251 | return IIO_VAL_FRACTIONAL; | 251 | return IIO_VAL_FRACTIONAL; |
| 252 | } | 252 | } |
| 253 | return -EINVAL; | ||
| 253 | 254 | ||
| 254 | case IIO_CHAN_INFO_HARDWAREGAIN: | 255 | case IIO_CHAN_INFO_HARDWAREGAIN: |
| 255 | switch (chan->address) { | 256 | switch (chan->address) { |
| @@ -262,6 +263,7 @@ static int ina2xx_read_raw(struct iio_dev *indio_dev, | |||
| 262 | *val = chip->range_vbus == 32 ? 1 : 2; | 263 | *val = chip->range_vbus == 32 ? 1 : 2; |
| 263 | return IIO_VAL_INT; | 264 | return IIO_VAL_INT; |
| 264 | } | 265 | } |
| 266 | return -EINVAL; | ||
| 265 | } | 267 | } |
| 266 | 268 | ||
| 267 | return -EINVAL; | 269 | return -EINVAL; |
diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c index af59ab2e650c..3440539cfdba 100644 --- a/drivers/iio/adc/max11100.c +++ b/drivers/iio/adc/max11100.c | |||
| @@ -1,13 +1,10 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * iio/adc/max11100.c | 3 | * iio/adc/max11100.c |
| 3 | * Maxim max11100 ADC Driver with IIO interface | 4 | * Maxim max11100 ADC Driver with IIO interface |
| 4 | * | 5 | * |
| 5 | * Copyright (C) 2016-17 Renesas Electronics Corporation | 6 | * Copyright (C) 2016-17 Renesas Electronics Corporation |
| 6 | * Copyright (C) 2016-17 Jacopo Mondi | 7 | * Copyright (C) 2016-17 Jacopo Mondi |
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | 8 | */ |
| 12 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
| 13 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
diff --git a/drivers/iio/adc/max9611.c b/drivers/iio/adc/max9611.c index 643a4e66eb80..917223d5ff5b 100644 --- a/drivers/iio/adc/max9611.c +++ b/drivers/iio/adc/max9611.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * iio/adc/max9611.c | 3 | * iio/adc/max9611.c |
| 3 | * | 4 | * |
| @@ -5,10 +6,6 @@ | |||
| 5 | * 12-bit ADC interface. | 6 | * 12-bit ADC interface. |
| 6 | * | 7 | * |
| 7 | * Copyright (C) 2017 Jacopo Mondi | 8 | * Copyright (C) 2017 Jacopo Mondi |
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | 9 | */ |
| 13 | 10 | ||
| 14 | /* | 11 | /* |
diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 028ccd218f82..26011254ffbc 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
| 19 | #include <linux/iio/iio.h> | 19 | #include <linux/iio/iio.h> |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/nvmem-consumer.h> | ||
| 21 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
| 22 | #include <linux/of.h> | 23 | #include <linux/of.h> |
| 23 | #include <linux/of_irq.h> | 24 | #include <linux/of_irq.h> |
| @@ -165,6 +166,14 @@ | |||
| 165 | 166 | ||
| 166 | #define MESON_SAR_ADC_MAX_FIFO_SIZE 32 | 167 | #define MESON_SAR_ADC_MAX_FIFO_SIZE 32 |
| 167 | #define MESON_SAR_ADC_TIMEOUT 100 /* ms */ | 168 | #define MESON_SAR_ADC_TIMEOUT 100 /* ms */ |
| 169 | #define MESON_SAR_ADC_VOLTAGE_AND_TEMP_CHANNEL 6 | ||
| 170 | #define MESON_SAR_ADC_TEMP_OFFSET 27 | ||
| 171 | |||
| 172 | /* temperature sensor calibration information in eFuse */ | ||
| 173 | #define MESON_SAR_ADC_EFUSE_BYTES 4 | ||
| 174 | #define MESON_SAR_ADC_EFUSE_BYTE3_UPPER_ADC_VAL GENMASK(6, 0) | ||
| 175 | #define MESON_SAR_ADC_EFUSE_BYTE3_IS_CALIBRATED BIT(7) | ||
| 176 | |||
| 168 | /* for use with IIO_VAL_INT_PLUS_MICRO */ | 177 | /* for use with IIO_VAL_INT_PLUS_MICRO */ |
| 169 | #define MILLION 1000000 | 178 | #define MILLION 1000000 |
| 170 | 179 | ||
| @@ -175,16 +184,25 @@ | |||
| 175 | .address = _chan, \ | 184 | .address = _chan, \ |
| 176 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | 185 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
| 177 | BIT(IIO_CHAN_INFO_AVERAGE_RAW), \ | 186 | BIT(IIO_CHAN_INFO_AVERAGE_RAW), \ |
| 178 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ | 187 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
| 179 | BIT(IIO_CHAN_INFO_CALIBBIAS) | \ | 188 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_CALIBBIAS) | \ |
| 180 | BIT(IIO_CHAN_INFO_CALIBSCALE), \ | 189 | BIT(IIO_CHAN_INFO_CALIBSCALE), \ |
| 181 | .datasheet_name = "SAR_ADC_CH"#_chan, \ | 190 | .datasheet_name = "SAR_ADC_CH"#_chan, \ |
| 182 | } | 191 | } |
| 183 | 192 | ||
| 184 | /* | 193 | #define MESON_SAR_ADC_TEMP_CHAN(_chan) { \ |
| 185 | * TODO: the hardware supports IIO_TEMP for channel 6 as well which is | 194 | .type = IIO_TEMP, \ |
| 186 | * currently not supported by this driver. | 195 | .channel = _chan, \ |
| 187 | */ | 196 | .address = MESON_SAR_ADC_VOLTAGE_AND_TEMP_CHANNEL, \ |
| 197 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | ||
| 198 | BIT(IIO_CHAN_INFO_AVERAGE_RAW), \ | ||
| 199 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | \ | ||
| 200 | BIT(IIO_CHAN_INFO_SCALE), \ | ||
| 201 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_CALIBBIAS) | \ | ||
| 202 | BIT(IIO_CHAN_INFO_CALIBSCALE), \ | ||
| 203 | .datasheet_name = "TEMP_SENSOR", \ | ||
| 204 | } | ||
| 205 | |||
| 188 | static const struct iio_chan_spec meson_sar_adc_iio_channels[] = { | 206 | static const struct iio_chan_spec meson_sar_adc_iio_channels[] = { |
| 189 | MESON_SAR_ADC_CHAN(0), | 207 | MESON_SAR_ADC_CHAN(0), |
| 190 | MESON_SAR_ADC_CHAN(1), | 208 | MESON_SAR_ADC_CHAN(1), |
| @@ -197,6 +215,19 @@ static const struct iio_chan_spec meson_sar_adc_iio_channels[] = { | |||
| 197 | IIO_CHAN_SOFT_TIMESTAMP(8), | 215 | IIO_CHAN_SOFT_TIMESTAMP(8), |
| 198 | }; | 216 | }; |
| 199 | 217 | ||
| 218 | static const struct iio_chan_spec meson_sar_adc_and_temp_iio_channels[] = { | ||
| 219 | MESON_SAR_ADC_CHAN(0), | ||
| 220 | MESON_SAR_ADC_CHAN(1), | ||
| 221 | MESON_SAR_ADC_CHAN(2), | ||
| 222 | MESON_SAR_ADC_CHAN(3), | ||
| 223 | MESON_SAR_ADC_CHAN(4), | ||
| 224 | MESON_SAR_ADC_CHAN(5), | ||
| 225 | MESON_SAR_ADC_CHAN(6), | ||
| 226 | MESON_SAR_ADC_CHAN(7), | ||
| 227 | MESON_SAR_ADC_TEMP_CHAN(8), | ||
| 228 | IIO_CHAN_SOFT_TIMESTAMP(9), | ||
| 229 | }; | ||
| 230 | |||
| 200 | enum meson_sar_adc_avg_mode { | 231 | enum meson_sar_adc_avg_mode { |
| 201 | NO_AVERAGING = 0x0, | 232 | NO_AVERAGING = 0x0, |
| 202 | MEAN_AVERAGING = 0x1, | 233 | MEAN_AVERAGING = 0x1, |
| @@ -225,6 +256,9 @@ struct meson_sar_adc_param { | |||
| 225 | u32 bandgap_reg; | 256 | u32 bandgap_reg; |
| 226 | unsigned int resolution; | 257 | unsigned int resolution; |
| 227 | const struct regmap_config *regmap_config; | 258 | const struct regmap_config *regmap_config; |
| 259 | u8 temperature_trimming_bits; | ||
| 260 | unsigned int temperature_multiplier; | ||
| 261 | unsigned int temperature_divider; | ||
| 228 | }; | 262 | }; |
| 229 | 263 | ||
| 230 | struct meson_sar_adc_data { | 264 | struct meson_sar_adc_data { |
| @@ -246,6 +280,9 @@ struct meson_sar_adc_priv { | |||
| 246 | struct completion done; | 280 | struct completion done; |
| 247 | int calibbias; | 281 | int calibbias; |
| 248 | int calibscale; | 282 | int calibscale; |
| 283 | bool temperature_sensor_calibrated; | ||
| 284 | u8 temperature_sensor_coefficient; | ||
| 285 | u16 temperature_sensor_adc_val; | ||
| 249 | }; | 286 | }; |
| 250 | 287 | ||
| 251 | static const struct regmap_config meson_sar_adc_regmap_config_gxbb = { | 288 | static const struct regmap_config meson_sar_adc_regmap_config_gxbb = { |
| @@ -389,9 +426,16 @@ static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev, | |||
| 389 | MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK, | 426 | MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK, |
| 390 | regval); | 427 | regval); |
| 391 | 428 | ||
| 392 | if (chan->address == 6) | 429 | if (chan->address == MESON_SAR_ADC_VOLTAGE_AND_TEMP_CHANNEL) { |
| 393 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, | 430 | if (chan->type == IIO_TEMP) |
| 394 | MESON_SAR_ADC_DELTA_10_TEMP_SEL, 0); | 431 | regval = MESON_SAR_ADC_DELTA_10_TEMP_SEL; |
| 432 | else | ||
| 433 | regval = 0; | ||
| 434 | |||
| 435 | regmap_update_bits(priv->regmap, | ||
| 436 | MESON_SAR_ADC_DELTA_10, | ||
| 437 | MESON_SAR_ADC_DELTA_10_TEMP_SEL, regval); | ||
| 438 | } | ||
| 395 | } | 439 | } |
| 396 | 440 | ||
| 397 | static void meson_sar_adc_set_chan7_mux(struct iio_dev *indio_dev, | 441 | static void meson_sar_adc_set_chan7_mux(struct iio_dev *indio_dev, |
| @@ -506,8 +550,12 @@ static int meson_sar_adc_get_sample(struct iio_dev *indio_dev, | |||
| 506 | enum meson_sar_adc_num_samples avg_samples, | 550 | enum meson_sar_adc_num_samples avg_samples, |
| 507 | int *val) | 551 | int *val) |
| 508 | { | 552 | { |
| 553 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | ||
| 509 | int ret; | 554 | int ret; |
| 510 | 555 | ||
| 556 | if (chan->type == IIO_TEMP && !priv->temperature_sensor_calibrated) | ||
| 557 | return -ENOTSUPP; | ||
| 558 | |||
| 511 | ret = meson_sar_adc_lock(indio_dev); | 559 | ret = meson_sar_adc_lock(indio_dev); |
| 512 | if (ret) | 560 | if (ret) |
| 513 | return ret; | 561 | return ret; |
| @@ -555,17 +603,31 @@ static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev, | |||
| 555 | break; | 603 | break; |
| 556 | 604 | ||
| 557 | case IIO_CHAN_INFO_SCALE: | 605 | case IIO_CHAN_INFO_SCALE: |
| 558 | ret = regulator_get_voltage(priv->vref); | 606 | if (chan->type == IIO_VOLTAGE) { |
| 559 | if (ret < 0) { | 607 | ret = regulator_get_voltage(priv->vref); |
| 560 | dev_err(indio_dev->dev.parent, | 608 | if (ret < 0) { |
| 561 | "failed to get vref voltage: %d\n", ret); | 609 | dev_err(indio_dev->dev.parent, |
| 562 | return ret; | 610 | "failed to get vref voltage: %d\n", |
| 611 | ret); | ||
| 612 | return ret; | ||
| 613 | } | ||
| 614 | |||
| 615 | *val = ret / 1000; | ||
| 616 | *val2 = priv->param->resolution; | ||
| 617 | return IIO_VAL_FRACTIONAL_LOG2; | ||
| 618 | } else if (chan->type == IIO_TEMP) { | ||
| 619 | /* SoC specific multiplier and divider */ | ||
| 620 | *val = priv->param->temperature_multiplier; | ||
| 621 | *val2 = priv->param->temperature_divider; | ||
| 622 | |||
| 623 | /* celsius to millicelsius */ | ||
| 624 | *val *= 1000; | ||
| 625 | |||
| 626 | return IIO_VAL_FRACTIONAL; | ||
| 627 | } else { | ||
| 628 | return -EINVAL; | ||
| 563 | } | 629 | } |
| 564 | 630 | ||
| 565 | *val = ret / 1000; | ||
| 566 | *val2 = priv->param->resolution; | ||
| 567 | return IIO_VAL_FRACTIONAL_LOG2; | ||
| 568 | |||
| 569 | case IIO_CHAN_INFO_CALIBBIAS: | 631 | case IIO_CHAN_INFO_CALIBBIAS: |
| 570 | *val = priv->calibbias; | 632 | *val = priv->calibbias; |
| 571 | return IIO_VAL_INT; | 633 | return IIO_VAL_INT; |
| @@ -575,6 +637,13 @@ static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev, | |||
| 575 | *val2 = priv->calibscale % MILLION; | 637 | *val2 = priv->calibscale % MILLION; |
| 576 | return IIO_VAL_INT_PLUS_MICRO; | 638 | return IIO_VAL_INT_PLUS_MICRO; |
| 577 | 639 | ||
| 640 | case IIO_CHAN_INFO_OFFSET: | ||
| 641 | *val = DIV_ROUND_CLOSEST(MESON_SAR_ADC_TEMP_OFFSET * | ||
| 642 | priv->param->temperature_divider, | ||
| 643 | priv->param->temperature_multiplier); | ||
| 644 | *val -= priv->temperature_sensor_adc_val; | ||
| 645 | return IIO_VAL_INT; | ||
| 646 | |||
| 578 | default: | 647 | default: |
| 579 | return -EINVAL; | 648 | return -EINVAL; |
| 580 | } | 649 | } |
| @@ -625,6 +694,65 @@ static int meson_sar_adc_clk_init(struct iio_dev *indio_dev, | |||
| 625 | return 0; | 694 | return 0; |
| 626 | } | 695 | } |
| 627 | 696 | ||
| 697 | static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev) | ||
| 698 | { | ||
| 699 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | ||
| 700 | u8 *buf, trimming_bits, trimming_mask, upper_adc_val; | ||
| 701 | struct nvmem_cell *temperature_calib; | ||
| 702 | size_t read_len; | ||
| 703 | int ret; | ||
| 704 | |||
| 705 | temperature_calib = devm_nvmem_cell_get(&indio_dev->dev, | ||
| 706 | "temperature_calib"); | ||
| 707 | if (IS_ERR(temperature_calib)) { | ||
| 708 | ret = PTR_ERR(temperature_calib); | ||
| 709 | |||
| 710 | /* | ||
| 711 | * leave the temperature sensor disabled if no calibration data | ||
| 712 | * was passed via nvmem-cells. | ||
| 713 | */ | ||
| 714 | if (ret == -ENODEV) | ||
| 715 | return 0; | ||
| 716 | |||
| 717 | if (ret != -EPROBE_DEFER) | ||
| 718 | dev_err(indio_dev->dev.parent, | ||
| 719 | "failed to get temperature_calib cell\n"); | ||
| 720 | |||
| 721 | return ret; | ||
| 722 | } | ||
| 723 | |||
| 724 | read_len = MESON_SAR_ADC_EFUSE_BYTES; | ||
| 725 | buf = nvmem_cell_read(temperature_calib, &read_len); | ||
| 726 | if (IS_ERR(buf)) { | ||
| 727 | dev_err(indio_dev->dev.parent, | ||
| 728 | "failed to read temperature_calib cell\n"); | ||
| 729 | return PTR_ERR(buf); | ||
| 730 | } else if (read_len != MESON_SAR_ADC_EFUSE_BYTES) { | ||
| 731 | kfree(buf); | ||
| 732 | dev_err(indio_dev->dev.parent, | ||
| 733 | "invalid read size of temperature_calib cell\n"); | ||
| 734 | return -EINVAL; | ||
| 735 | } | ||
| 736 | |||
| 737 | trimming_bits = priv->param->temperature_trimming_bits; | ||
| 738 | trimming_mask = BIT(trimming_bits) - 1; | ||
| 739 | |||
| 740 | priv->temperature_sensor_calibrated = | ||
| 741 | buf[3] & MESON_SAR_ADC_EFUSE_BYTE3_IS_CALIBRATED; | ||
| 742 | priv->temperature_sensor_coefficient = buf[2] & trimming_mask; | ||
| 743 | |||
| 744 | upper_adc_val = FIELD_GET(MESON_SAR_ADC_EFUSE_BYTE3_UPPER_ADC_VAL, | ||
| 745 | buf[3]); | ||
| 746 | |||
| 747 | priv->temperature_sensor_adc_val = buf[2]; | ||
| 748 | priv->temperature_sensor_adc_val |= upper_adc_val << BITS_PER_BYTE; | ||
| 749 | priv->temperature_sensor_adc_val >>= trimming_bits; | ||
| 750 | |||
| 751 | kfree(buf); | ||
| 752 | |||
| 753 | return 0; | ||
| 754 | } | ||
| 755 | |||
| 628 | static int meson_sar_adc_init(struct iio_dev *indio_dev) | 756 | static int meson_sar_adc_init(struct iio_dev *indio_dev) |
| 629 | { | 757 | { |
| 630 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); | 758 | struct meson_sar_adc_priv *priv = iio_priv(indio_dev); |
| @@ -649,10 +777,12 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev) | |||
| 649 | 777 | ||
| 650 | meson_sar_adc_stop_sample_engine(indio_dev); | 778 | meson_sar_adc_stop_sample_engine(indio_dev); |
| 651 | 779 | ||
| 652 | /* update the channel 6 MUX to select the temperature sensor */ | 780 | /* |
| 781 | * disable this bit as seems to be only relevant for Meson6 (based | ||
| 782 | * on the vendor driver), which we don't support at the moment. | ||
| 783 | */ | ||
| 653 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, | 784 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0, |
| 654 | MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL, | 785 | MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL, 0); |
| 655 | MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL); | ||
| 656 | 786 | ||
| 657 | /* disable all channels by default */ | 787 | /* disable all channels by default */ |
| 658 | regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0); | 788 | regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0); |
| @@ -709,6 +839,29 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev) | |||
| 709 | regval |= MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW; | 839 | regval |= MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW; |
| 710 | regmap_write(priv->regmap, MESON_SAR_ADC_AUX_SW, regval); | 840 | regmap_write(priv->regmap, MESON_SAR_ADC_AUX_SW, regval); |
| 711 | 841 | ||
| 842 | if (priv->temperature_sensor_calibrated) { | ||
| 843 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, | ||
| 844 | MESON_SAR_ADC_DELTA_10_TS_REVE1, | ||
| 845 | MESON_SAR_ADC_DELTA_10_TS_REVE1); | ||
| 846 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, | ||
| 847 | MESON_SAR_ADC_DELTA_10_TS_REVE0, | ||
| 848 | MESON_SAR_ADC_DELTA_10_TS_REVE0); | ||
| 849 | |||
| 850 | /* | ||
| 851 | * set bits [3:0] of the TSC (temperature sensor coefficient) | ||
| 852 | * to get the correct values when reading the temperature. | ||
| 853 | */ | ||
| 854 | regval = FIELD_PREP(MESON_SAR_ADC_DELTA_10_TS_C_MASK, | ||
| 855 | priv->temperature_sensor_coefficient); | ||
| 856 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, | ||
| 857 | MESON_SAR_ADC_DELTA_10_TS_C_MASK, regval); | ||
| 858 | } else { | ||
| 859 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, | ||
| 860 | MESON_SAR_ADC_DELTA_10_TS_REVE1, 0); | ||
| 861 | regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10, | ||
| 862 | MESON_SAR_ADC_DELTA_10_TS_REVE0, 0); | ||
| 863 | } | ||
| 864 | |||
| 712 | ret = clk_set_parent(priv->adc_sel_clk, priv->clkin); | 865 | ret = clk_set_parent(priv->adc_sel_clk, priv->clkin); |
| 713 | if (ret) { | 866 | if (ret) { |
| 714 | dev_err(indio_dev->dev.parent, | 867 | dev_err(indio_dev->dev.parent, |
| @@ -894,6 +1047,17 @@ static const struct meson_sar_adc_param meson_sar_adc_meson8_param = { | |||
| 894 | .bandgap_reg = MESON_SAR_ADC_DELTA_10, | 1047 | .bandgap_reg = MESON_SAR_ADC_DELTA_10, |
| 895 | .regmap_config = &meson_sar_adc_regmap_config_meson8, | 1048 | .regmap_config = &meson_sar_adc_regmap_config_meson8, |
| 896 | .resolution = 10, | 1049 | .resolution = 10, |
| 1050 | .temperature_trimming_bits = 4, | ||
| 1051 | .temperature_multiplier = 18 * 10000, | ||
| 1052 | .temperature_divider = 1024 * 10 * 85, | ||
| 1053 | }; | ||
| 1054 | |||
| 1055 | static const struct meson_sar_adc_param meson_sar_adc_meson8b_param = { | ||
| 1056 | .has_bl30_integration = false, | ||
| 1057 | .clock_rate = 1150000, | ||
| 1058 | .bandgap_reg = MESON_SAR_ADC_DELTA_10, | ||
| 1059 | .regmap_config = &meson_sar_adc_regmap_config_meson8, | ||
| 1060 | .resolution = 10, | ||
| 897 | }; | 1061 | }; |
| 898 | 1062 | ||
| 899 | static const struct meson_sar_adc_param meson_sar_adc_gxbb_param = { | 1063 | static const struct meson_sar_adc_param meson_sar_adc_gxbb_param = { |
| @@ -918,12 +1082,12 @@ static const struct meson_sar_adc_data meson_sar_adc_meson8_data = { | |||
| 918 | }; | 1082 | }; |
| 919 | 1083 | ||
| 920 | static const struct meson_sar_adc_data meson_sar_adc_meson8b_data = { | 1084 | static const struct meson_sar_adc_data meson_sar_adc_meson8b_data = { |
| 921 | .param = &meson_sar_adc_meson8_param, | 1085 | .param = &meson_sar_adc_meson8b_param, |
| 922 | .name = "meson-meson8b-saradc", | 1086 | .name = "meson-meson8b-saradc", |
| 923 | }; | 1087 | }; |
| 924 | 1088 | ||
| 925 | static const struct meson_sar_adc_data meson_sar_adc_meson8m2_data = { | 1089 | static const struct meson_sar_adc_data meson_sar_adc_meson8m2_data = { |
| 926 | .param = &meson_sar_adc_meson8_param, | 1090 | .param = &meson_sar_adc_meson8b_param, |
| 927 | .name = "meson-meson8m2-saradc", | 1091 | .name = "meson-meson8m2-saradc", |
| 928 | }; | 1092 | }; |
| 929 | 1093 | ||
| @@ -1009,9 +1173,6 @@ static int meson_sar_adc_probe(struct platform_device *pdev) | |||
| 1009 | indio_dev->modes = INDIO_DIRECT_MODE; | 1173 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 1010 | indio_dev->info = &meson_sar_adc_iio_info; | 1174 | indio_dev->info = &meson_sar_adc_iio_info; |
| 1011 | 1175 | ||
| 1012 | indio_dev->channels = meson_sar_adc_iio_channels; | ||
| 1013 | indio_dev->num_channels = ARRAY_SIZE(meson_sar_adc_iio_channels); | ||
| 1014 | |||
| 1015 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1176 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1016 | base = devm_ioremap_resource(&pdev->dev, res); | 1177 | base = devm_ioremap_resource(&pdev->dev, res); |
| 1017 | if (IS_ERR(base)) | 1178 | if (IS_ERR(base)) |
| @@ -1078,6 +1239,22 @@ static int meson_sar_adc_probe(struct platform_device *pdev) | |||
| 1078 | 1239 | ||
| 1079 | priv->calibscale = MILLION; | 1240 | priv->calibscale = MILLION; |
| 1080 | 1241 | ||
| 1242 | if (priv->param->temperature_trimming_bits) { | ||
| 1243 | ret = meson_sar_adc_temp_sensor_init(indio_dev); | ||
| 1244 | if (ret) | ||
| 1245 | return ret; | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | if (priv->temperature_sensor_calibrated) { | ||
| 1249 | indio_dev->channels = meson_sar_adc_and_temp_iio_channels; | ||
| 1250 | indio_dev->num_channels = | ||
| 1251 | ARRAY_SIZE(meson_sar_adc_and_temp_iio_channels); | ||
| 1252 | } else { | ||
| 1253 | indio_dev->channels = meson_sar_adc_iio_channels; | ||
| 1254 | indio_dev->num_channels = | ||
| 1255 | ARRAY_SIZE(meson_sar_adc_iio_channels); | ||
| 1256 | } | ||
| 1257 | |||
| 1081 | ret = meson_sar_adc_init(indio_dev); | 1258 | ret = meson_sar_adc_init(indio_dev); |
| 1082 | if (ret) | 1259 | if (ret) |
| 1083 | goto err; | 1260 | goto err; |
diff --git a/drivers/iio/adc/rcar-gyroadc.c b/drivers/iio/adc/rcar-gyroadc.c index 4e982b51bcda..2c0d0316d149 100644 --- a/drivers/iio/adc/rcar-gyroadc.c +++ b/drivers/iio/adc/rcar-gyroadc.c | |||
| @@ -1,17 +1,8 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 1 | /* | 2 | /* |
| 2 | * Renesas R-Car GyroADC driver | 3 | * Renesas R-Car GyroADC driver |
| 3 | * | 4 | * |
| 4 | * Copyright 2016 Marek Vasut <marek.vasut@gmail.com> | 5 | * Copyright 2016 Marek Vasut <marek.vasut@gmail.com> |
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | */ | 6 | */ |
| 16 | 7 | ||
| 17 | #include <linux/module.h> | 8 | #include <linux/module.h> |
diff --git a/drivers/iio/adc/sc27xx_adc.c b/drivers/iio/adc/sc27xx_adc.c index 7940b23dcad9..f7f7a18904b4 100644 --- a/drivers/iio/adc/sc27xx_adc.c +++ b/drivers/iio/adc/sc27xx_adc.c | |||
| @@ -52,6 +52,9 @@ | |||
| 52 | /* Timeout (ms) for the trylock of hardware spinlocks */ | 52 | /* Timeout (ms) for the trylock of hardware spinlocks */ |
| 53 | #define SC27XX_ADC_HWLOCK_TIMEOUT 5000 | 53 | #define SC27XX_ADC_HWLOCK_TIMEOUT 5000 |
| 54 | 54 | ||
| 55 | /* Timeout (ms) for ADC data conversion according to ADC datasheet */ | ||
| 56 | #define SC27XX_ADC_RDY_TIMEOUT 100 | ||
| 57 | |||
| 55 | /* Maximum ADC channel number */ | 58 | /* Maximum ADC channel number */ |
| 56 | #define SC27XX_ADC_CHANNEL_MAX 32 | 59 | #define SC27XX_ADC_CHANNEL_MAX 32 |
| 57 | 60 | ||
| @@ -223,7 +226,14 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel, | |||
| 223 | if (ret) | 226 | if (ret) |
| 224 | goto disable_adc; | 227 | goto disable_adc; |
| 225 | 228 | ||
| 226 | wait_for_completion(&data->completion); | 229 | ret = wait_for_completion_timeout(&data->completion, |
| 230 | msecs_to_jiffies(SC27XX_ADC_RDY_TIMEOUT)); | ||
| 231 | if (!ret) { | ||
| 232 | dev_err(data->dev, "read ADC data timeout\n"); | ||
| 233 | ret = -ETIMEDOUT; | ||
| 234 | } else { | ||
| 235 | ret = 0; | ||
| 236 | } | ||
| 227 | 237 | ||
| 228 | disable_adc: | 238 | disable_adc: |
| 229 | regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL, | 239 | regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL, |
diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c index 7cf39b3e2416..1e5a936b5b6a 100644 --- a/drivers/iio/adc/ti-adc128s052.c +++ b/drivers/iio/adc/ti-adc128s052.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * Copyright (C) 2014 Angelo Compagnucci <angelo.compagnucci@gmail.com> | 3 | * Copyright (C) 2014 Angelo Compagnucci <angelo.compagnucci@gmail.com> |
| 3 | * | 4 | * |
| @@ -6,16 +7,14 @@ | |||
| 6 | * http://www.ti.com/lit/ds/symlink/adc128s052.pdf | 7 | * http://www.ti.com/lit/ds/symlink/adc128s052.pdf |
| 7 | * http://www.ti.com/lit/ds/symlink/adc122s021.pdf | 8 | * http://www.ti.com/lit/ds/symlink/adc122s021.pdf |
| 8 | * http://www.ti.com/lit/ds/symlink/adc124s021.pdf | 9 | * http://www.ti.com/lit/ds/symlink/adc124s021.pdf |
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | */ | 10 | */ |
| 14 | 11 | ||
| 12 | #include <linux/acpi.h> | ||
| 15 | #include <linux/err.h> | 13 | #include <linux/err.h> |
| 16 | #include <linux/spi/spi.h> | 14 | #include <linux/spi/spi.h> |
| 17 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 18 | #include <linux/iio/iio.h> | 16 | #include <linux/iio/iio.h> |
| 17 | #include <linux/property.h> | ||
| 19 | #include <linux/regulator/consumer.h> | 18 | #include <linux/regulator/consumer.h> |
| 20 | 19 | ||
| 21 | struct adc128_configuration { | 20 | struct adc128_configuration { |
| @@ -135,10 +134,15 @@ static const struct iio_info adc128_info = { | |||
| 135 | static int adc128_probe(struct spi_device *spi) | 134 | static int adc128_probe(struct spi_device *spi) |
| 136 | { | 135 | { |
| 137 | struct iio_dev *indio_dev; | 136 | struct iio_dev *indio_dev; |
| 137 | unsigned int config; | ||
| 138 | struct adc128 *adc; | 138 | struct adc128 *adc; |
| 139 | int config = spi_get_device_id(spi)->driver_data; | ||
| 140 | int ret; | 139 | int ret; |
| 141 | 140 | ||
| 141 | if (dev_fwnode(&spi->dev)) | ||
| 142 | config = (unsigned long) device_get_match_data(&spi->dev); | ||
| 143 | else | ||
| 144 | config = spi_get_device_id(spi)->driver_data; | ||
| 145 | |||
| 142 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); | 146 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); |
| 143 | if (!indio_dev) | 147 | if (!indio_dev) |
| 144 | return -ENOMEM; | 148 | return -ENOMEM; |
| @@ -186,23 +190,40 @@ static int adc128_remove(struct spi_device *spi) | |||
| 186 | static const struct of_device_id adc128_of_match[] = { | 190 | static const struct of_device_id adc128_of_match[] = { |
| 187 | { .compatible = "ti,adc128s052", }, | 191 | { .compatible = "ti,adc128s052", }, |
| 188 | { .compatible = "ti,adc122s021", }, | 192 | { .compatible = "ti,adc122s021", }, |
| 193 | { .compatible = "ti,adc122s051", }, | ||
| 194 | { .compatible = "ti,adc122s101", }, | ||
| 189 | { .compatible = "ti,adc124s021", }, | 195 | { .compatible = "ti,adc124s021", }, |
| 196 | { .compatible = "ti,adc124s051", }, | ||
| 197 | { .compatible = "ti,adc124s101", }, | ||
| 190 | { /* sentinel */ }, | 198 | { /* sentinel */ }, |
| 191 | }; | 199 | }; |
| 192 | MODULE_DEVICE_TABLE(of, adc128_of_match); | 200 | MODULE_DEVICE_TABLE(of, adc128_of_match); |
| 193 | 201 | ||
| 194 | static const struct spi_device_id adc128_id[] = { | 202 | static const struct spi_device_id adc128_id[] = { |
| 195 | { "adc128s052", 0}, /* index into adc128_config */ | 203 | { "adc128s052", 0 }, /* index into adc128_config */ |
| 196 | { "adc122s021", 1}, | 204 | { "adc122s021", 1 }, |
| 197 | { "adc124s021", 2}, | 205 | { "adc122s051", 1 }, |
| 206 | { "adc122s101", 1 }, | ||
| 207 | { "adc124s021", 2 }, | ||
| 208 | { "adc124s051", 2 }, | ||
| 209 | { "adc124s101", 2 }, | ||
| 198 | { } | 210 | { } |
| 199 | }; | 211 | }; |
| 200 | MODULE_DEVICE_TABLE(spi, adc128_id); | 212 | MODULE_DEVICE_TABLE(spi, adc128_id); |
| 201 | 213 | ||
| 214 | #ifdef CONFIG_ACPI | ||
| 215 | static const struct acpi_device_id adc128_acpi_match[] = { | ||
| 216 | { "AANT1280", 2 }, /* ADC124S021 compatible ACPI ID */ | ||
| 217 | { } | ||
| 218 | }; | ||
| 219 | MODULE_DEVICE_TABLE(acpi, adc128_acpi_match); | ||
| 220 | #endif | ||
| 221 | |||
| 202 | static struct spi_driver adc128_driver = { | 222 | static struct spi_driver adc128_driver = { |
| 203 | .driver = { | 223 | .driver = { |
| 204 | .name = "adc128s052", | 224 | .name = "adc128s052", |
| 205 | .of_match_table = of_match_ptr(adc128_of_match), | 225 | .of_match_table = of_match_ptr(adc128_of_match), |
| 226 | .acpi_match_table = ACPI_PTR(adc128_acpi_match), | ||
| 206 | }, | 227 | }, |
| 207 | .probe = adc128_probe, | 228 | .probe = adc128_probe, |
| 208 | .remove = adc128_remove, | 229 | .remove = adc128_remove, |
diff --git a/drivers/iio/common/ssp_sensors/ssp_dev.c b/drivers/iio/common/ssp_sensors/ssp_dev.c index af3aa38f67cd..9e13be2c0cb9 100644 --- a/drivers/iio/common/ssp_sensors/ssp_dev.c +++ b/drivers/iio/common/ssp_sensors/ssp_dev.c | |||
| @@ -462,43 +462,35 @@ static struct ssp_data *ssp_parse_dt(struct device *dev) | |||
| 462 | 462 | ||
| 463 | data->mcu_ap_gpio = of_get_named_gpio(node, "mcu-ap-gpios", 0); | 463 | data->mcu_ap_gpio = of_get_named_gpio(node, "mcu-ap-gpios", 0); |
| 464 | if (data->mcu_ap_gpio < 0) | 464 | if (data->mcu_ap_gpio < 0) |
| 465 | goto err_free_pd; | 465 | return NULL; |
| 466 | 466 | ||
| 467 | data->ap_mcu_gpio = of_get_named_gpio(node, "ap-mcu-gpios", 0); | 467 | data->ap_mcu_gpio = of_get_named_gpio(node, "ap-mcu-gpios", 0); |
| 468 | if (data->ap_mcu_gpio < 0) | 468 | if (data->ap_mcu_gpio < 0) |
| 469 | goto err_free_pd; | 469 | return NULL; |
| 470 | 470 | ||
| 471 | data->mcu_reset_gpio = of_get_named_gpio(node, "mcu-reset-gpios", 0); | 471 | data->mcu_reset_gpio = of_get_named_gpio(node, "mcu-reset-gpios", 0); |
| 472 | if (data->mcu_reset_gpio < 0) | 472 | if (data->mcu_reset_gpio < 0) |
| 473 | goto err_free_pd; | 473 | return NULL; |
| 474 | 474 | ||
| 475 | ret = devm_gpio_request_one(dev, data->ap_mcu_gpio, GPIOF_OUT_INIT_HIGH, | 475 | ret = devm_gpio_request_one(dev, data->ap_mcu_gpio, GPIOF_OUT_INIT_HIGH, |
| 476 | "ap-mcu-gpios"); | 476 | "ap-mcu-gpios"); |
| 477 | if (ret) | 477 | if (ret) |
| 478 | goto err_free_pd; | 478 | return NULL; |
| 479 | 479 | ||
| 480 | ret = devm_gpio_request_one(dev, data->mcu_reset_gpio, | 480 | ret = devm_gpio_request_one(dev, data->mcu_reset_gpio, |
| 481 | GPIOF_OUT_INIT_HIGH, "mcu-reset-gpios"); | 481 | GPIOF_OUT_INIT_HIGH, "mcu-reset-gpios"); |
| 482 | if (ret) | 482 | if (ret) |
| 483 | goto err_ap_mcu; | 483 | return NULL; |
| 484 | 484 | ||
| 485 | match = of_match_node(ssp_of_match, node); | 485 | match = of_match_node(ssp_of_match, node); |
| 486 | if (!match) | 486 | if (!match) |
| 487 | goto err_mcu_reset_gpio; | 487 | return NULL; |
| 488 | 488 | ||
| 489 | data->sensorhub_info = match->data; | 489 | data->sensorhub_info = match->data; |
| 490 | 490 | ||
| 491 | dev_set_drvdata(dev, data); | 491 | dev_set_drvdata(dev, data); |
| 492 | 492 | ||
| 493 | return data; | 493 | return data; |
| 494 | |||
| 495 | err_mcu_reset_gpio: | ||
| 496 | devm_gpio_free(dev, data->mcu_reset_gpio); | ||
| 497 | err_ap_mcu: | ||
| 498 | devm_gpio_free(dev, data->ap_mcu_gpio); | ||
| 499 | err_free_pd: | ||
| 500 | devm_kfree(dev, data); | ||
| 501 | return NULL; | ||
| 502 | } | 494 | } |
| 503 | #else | 495 | #else |
| 504 | static struct ssp_data *ssp_parse_dt(struct device *pdev) | 496 | static struct ssp_data *ssp_parse_dt(struct device *pdev) |
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 26fbd1bd9413..e50c975250e9 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c | |||
| @@ -133,7 +133,7 @@ static int st_sensors_match_fs(struct st_sensor_settings *sensor_settings, | |||
| 133 | 133 | ||
| 134 | for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) { | 134 | for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) { |
| 135 | if (sensor_settings->fs.fs_avl[i].num == 0) | 135 | if (sensor_settings->fs.fs_avl[i].num == 0) |
| 136 | goto st_sensors_match_odr_error; | 136 | return ret; |
| 137 | 137 | ||
| 138 | if (sensor_settings->fs.fs_avl[i].num == fs) { | 138 | if (sensor_settings->fs.fs_avl[i].num == fs) { |
| 139 | *index_fs_avl = i; | 139 | *index_fs_avl = i; |
| @@ -142,7 +142,6 @@ static int st_sensors_match_fs(struct st_sensor_settings *sensor_settings, | |||
| 142 | } | 142 | } |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | st_sensors_match_odr_error: | ||
| 146 | return ret; | 145 | return ret; |
| 147 | } | 146 | } |
| 148 | 147 | ||
diff --git a/drivers/iio/common/st_sensors/st_sensors_trigger.c b/drivers/iio/common/st_sensors/st_sensors_trigger.c index fdcc5a891958..224596b0e189 100644 --- a/drivers/iio/common/st_sensors/st_sensors_trigger.c +++ b/drivers/iio/common/st_sensors/st_sensors_trigger.c | |||
| @@ -104,7 +104,7 @@ static irqreturn_t st_sensors_irq_thread(int irq, void *p) | |||
| 104 | return IRQ_HANDLED; | 104 | return IRQ_HANDLED; |
| 105 | 105 | ||
| 106 | /* | 106 | /* |
| 107 | * If we are using egde IRQs, new samples arrived while processing | 107 | * If we are using edge IRQs, new samples arrived while processing |
| 108 | * the IRQ and those may be missed unless we pick them here, so poll | 108 | * the IRQ and those may be missed unless we pick them here, so poll |
| 109 | * again. If the sensor delivery frequency is very high, this thread | 109 | * again. If the sensor delivery frequency is very high, this thread |
| 110 | * turns into a polled loop handler. | 110 | * turns into a polled loop handler. |
| @@ -148,7 +148,7 @@ int st_sensors_allocate_trigger(struct iio_dev *indio_dev, | |||
| 148 | if (!sdata->sensor_settings->drdy_irq.addr_ihl) { | 148 | if (!sdata->sensor_settings->drdy_irq.addr_ihl) { |
| 149 | dev_err(&indio_dev->dev, | 149 | dev_err(&indio_dev->dev, |
| 150 | "falling/low specified for IRQ " | 150 | "falling/low specified for IRQ " |
| 151 | "but hardware only support rising/high: " | 151 | "but hardware supports only rising/high: " |
| 152 | "will request rising/high\n"); | 152 | "will request rising/high\n"); |
| 153 | if (irq_trig == IRQF_TRIGGER_FALLING) | 153 | if (irq_trig == IRQF_TRIGGER_FALLING) |
| 154 | irq_trig = IRQF_TRIGGER_RISING; | 154 | irq_trig = IRQF_TRIGGER_RISING; |
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index bb2057fd1b6f..851b61eaf3da 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig | |||
| @@ -366,6 +366,15 @@ config TI_DAC5571 | |||
| 366 | 366 | ||
| 367 | If compiled as a module, it will be called ti-dac5571. | 367 | If compiled as a module, it will be called ti-dac5571. |
| 368 | 368 | ||
| 369 | config TI_DAC7311 | ||
| 370 | tristate "Texas Instruments 8/10/12-bit 1-channel DAC driver" | ||
| 371 | depends on SPI | ||
| 372 | help | ||
| 373 | Driver for the Texas Instruments | ||
| 374 | DAC7311, DAC6311, DAC5311. | ||
| 375 | |||
| 376 | If compiled as a module, it will be called ti-dac7311. | ||
| 377 | |||
| 369 | config VF610_DAC | 378 | config VF610_DAC |
| 370 | tristate "Vybrid vf610 DAC driver" | 379 | tristate "Vybrid vf610 DAC driver" |
| 371 | depends on OF | 380 | depends on OF |
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 2ac93cc4a389..f0a37c93de8e 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile | |||
| @@ -40,4 +40,5 @@ obj-$(CONFIG_STM32_DAC_CORE) += stm32-dac-core.o | |||
| 40 | obj-$(CONFIG_STM32_DAC) += stm32-dac.o | 40 | obj-$(CONFIG_STM32_DAC) += stm32-dac.o |
| 41 | obj-$(CONFIG_TI_DAC082S085) += ti-dac082s085.o | 41 | obj-$(CONFIG_TI_DAC082S085) += ti-dac082s085.o |
| 42 | obj-$(CONFIG_TI_DAC5571) += ti-dac5571.o | 42 | obj-$(CONFIG_TI_DAC5571) += ti-dac5571.o |
| 43 | obj-$(CONFIG_TI_DAC7311) += ti-dac7311.o | ||
| 43 | obj-$(CONFIG_VF610_DAC) += vf610_dac.o | 44 | obj-$(CONFIG_VF610_DAC) += vf610_dac.o |
diff --git a/drivers/iio/dac/dpot-dac.c b/drivers/iio/dac/dpot-dac.c index a791d0a09d3b..4a6111b7e86c 100644 --- a/drivers/iio/dac/dpot-dac.c +++ b/drivers/iio/dac/dpot-dac.c | |||
| @@ -74,11 +74,11 @@ static int dpot_dac_read_raw(struct iio_dev *indio_dev, | |||
| 74 | case IIO_VAL_INT: | 74 | case IIO_VAL_INT: |
| 75 | /* | 75 | /* |
| 76 | * Convert integer scale to fractional scale by | 76 | * Convert integer scale to fractional scale by |
| 77 | * setting the denominator (val2) to one... | 77 | * setting the denominator (val2) to one, and... |
| 78 | */ | 78 | */ |
| 79 | *val2 = 1; | 79 | *val2 = 1; |
| 80 | ret = IIO_VAL_FRACTIONAL; | 80 | ret = IIO_VAL_FRACTIONAL; |
| 81 | /* ...and fall through. */ | 81 | /* fall through */ |
| 82 | case IIO_VAL_FRACTIONAL: | 82 | case IIO_VAL_FRACTIONAL: |
| 83 | *val *= regulator_get_voltage(dac->vref) / 1000; | 83 | *val *= regulator_get_voltage(dac->vref) / 1000; |
| 84 | *val2 *= dac->max_ohms; | 84 | *val2 *= dac->max_ohms; |
diff --git a/drivers/iio/dac/ti-dac7311.c b/drivers/iio/dac/ti-dac7311.c new file mode 100644 index 000000000000..6f5df1a30a1c --- /dev/null +++ b/drivers/iio/dac/ti-dac7311.c | |||
| @@ -0,0 +1,338 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* ti-dac7311.c - Texas Instruments 8/10/12-bit 1-channel DAC driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2018 CMC NV | ||
| 5 | * | ||
| 6 | * http://www.ti.com/lit/ds/symlink/dac7311.pdf | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/iio/iio.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/regulator/consumer.h> | ||
| 12 | #include <linux/spi/spi.h> | ||
| 13 | |||
| 14 | enum { | ||
| 15 | ID_DAC5311 = 0, | ||
| 16 | ID_DAC6311, | ||
| 17 | ID_DAC7311, | ||
| 18 | }; | ||
| 19 | |||
| 20 | enum { | ||
| 21 | POWER_1KOHM_TO_GND = 0, | ||
| 22 | POWER_100KOHM_TO_GND, | ||
| 23 | POWER_TRI_STATE, | ||
| 24 | }; | ||
| 25 | |||
| 26 | struct ti_dac_spec { | ||
| 27 | u8 resolution; | ||
| 28 | }; | ||
| 29 | |||
| 30 | static const struct ti_dac_spec ti_dac_spec[] = { | ||
| 31 | [ID_DAC5311] = { .resolution = 8 }, | ||
| 32 | [ID_DAC6311] = { .resolution = 10 }, | ||
| 33 | [ID_DAC7311] = { .resolution = 12 }, | ||
| 34 | }; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * struct ti_dac_chip - TI DAC chip | ||
| 38 | * @lock: protects write sequences | ||
| 39 | * @vref: regulator generating Vref | ||
| 40 | * @spi: SPI device to send data to the device | ||
| 41 | * @val: cached value | ||
| 42 | * @powerdown: whether the chip is powered down | ||
| 43 | * @powerdown_mode: selected by the user | ||
| 44 | * @resolution: resolution of the chip | ||
| 45 | * @buf: buffer for transfer data | ||
| 46 | */ | ||
| 47 | struct ti_dac_chip { | ||
| 48 | struct mutex lock; | ||
| 49 | struct regulator *vref; | ||
| 50 | struct spi_device *spi; | ||
| 51 | u16 val; | ||
| 52 | bool powerdown; | ||
| 53 | u8 powerdown_mode; | ||
| 54 | u8 resolution; | ||
| 55 | u8 buf[2] ____cacheline_aligned; | ||
| 56 | }; | ||
| 57 | |||
| 58 | static u8 ti_dac_get_power(struct ti_dac_chip *ti_dac, bool powerdown) | ||
| 59 | { | ||
| 60 | if (powerdown) | ||
| 61 | return ti_dac->powerdown_mode + 1; | ||
| 62 | |||
| 63 | return 0; | ||
| 64 | } | ||
| 65 | |||
| 66 | static int ti_dac_cmd(struct ti_dac_chip *ti_dac, u8 power, u16 val) | ||
| 67 | { | ||
| 68 | u8 shift = 14 - ti_dac->resolution; | ||
| 69 | |||
| 70 | ti_dac->buf[0] = (val << shift) & 0xFF; | ||
| 71 | ti_dac->buf[1] = (power << 6) | (val >> (8 - shift)); | ||
| 72 | return spi_write(ti_dac->spi, ti_dac->buf, 2); | ||
| 73 | } | ||
| 74 | |||
| 75 | static const char * const ti_dac_powerdown_modes[] = { | ||
| 76 | "1kohm_to_gnd", | ||
| 77 | "100kohm_to_gnd", | ||
| 78 | "three_state", | ||
| 79 | }; | ||
| 80 | |||
| 81 | static int ti_dac_get_powerdown_mode(struct iio_dev *indio_dev, | ||
| 82 | const struct iio_chan_spec *chan) | ||
| 83 | { | ||
| 84 | struct ti_dac_chip *ti_dac = iio_priv(indio_dev); | ||
| 85 | |||
| 86 | return ti_dac->powerdown_mode; | ||
| 87 | } | ||
| 88 | |||
| 89 | static int ti_dac_set_powerdown_mode(struct iio_dev *indio_dev, | ||
| 90 | const struct iio_chan_spec *chan, | ||
| 91 | unsigned int mode) | ||
| 92 | { | ||
| 93 | struct ti_dac_chip *ti_dac = iio_priv(indio_dev); | ||
| 94 | |||
| 95 | ti_dac->powerdown_mode = mode; | ||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | static const struct iio_enum ti_dac_powerdown_mode = { | ||
| 100 | .items = ti_dac_powerdown_modes, | ||
| 101 | .num_items = ARRAY_SIZE(ti_dac_powerdown_modes), | ||
| 102 | .get = ti_dac_get_powerdown_mode, | ||
| 103 | .set = ti_dac_set_powerdown_mode, | ||
| 104 | }; | ||
| 105 | |||
| 106 | static ssize_t ti_dac_read_powerdown(struct iio_dev *indio_dev, | ||
| 107 | uintptr_t private, | ||
| 108 | const struct iio_chan_spec *chan, | ||
| 109 | char *buf) | ||
| 110 | { | ||
| 111 | struct ti_dac_chip *ti_dac = iio_priv(indio_dev); | ||
| 112 | |||
| 113 | return sprintf(buf, "%d\n", ti_dac->powerdown); | ||
| 114 | } | ||
| 115 | |||
| 116 | static ssize_t ti_dac_write_powerdown(struct iio_dev *indio_dev, | ||
| 117 | uintptr_t private, | ||
| 118 | const struct iio_chan_spec *chan, | ||
| 119 | const char *buf, size_t len) | ||
| 120 | { | ||
| 121 | struct ti_dac_chip *ti_dac = iio_priv(indio_dev); | ||
| 122 | bool powerdown; | ||
| 123 | u8 power; | ||
| 124 | int ret; | ||
| 125 | |||
| 126 | ret = strtobool(buf, &powerdown); | ||
| 127 | if (ret) | ||
| 128 | return ret; | ||
| 129 | |||
| 130 | power = ti_dac_get_power(ti_dac, powerdown); | ||
| 131 | |||
| 132 | mutex_lock(&ti_dac->lock); | ||
| 133 | ret = ti_dac_cmd(ti_dac, power, 0); | ||
| 134 | if (!ret) | ||
| 135 | ti_dac->powerdown = powerdown; | ||
| 136 | mutex_unlock(&ti_dac->lock); | ||
| 137 | |||
| 138 | return ret ? ret : len; | ||
| 139 | } | ||
| 140 | |||
| 141 | static const struct iio_chan_spec_ext_info ti_dac_ext_info[] = { | ||
| 142 | { | ||
| 143 | .name = "powerdown", | ||
| 144 | .read = ti_dac_read_powerdown, | ||
| 145 | .write = ti_dac_write_powerdown, | ||
| 146 | .shared = IIO_SHARED_BY_TYPE, | ||
| 147 | }, | ||
| 148 | IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE, &ti_dac_powerdown_mode), | ||
| 149 | IIO_ENUM_AVAILABLE("powerdown_mode", &ti_dac_powerdown_mode), | ||
| 150 | { }, | ||
| 151 | }; | ||
| 152 | |||
| 153 | #define TI_DAC_CHANNEL(chan) { \ | ||
| 154 | .type = IIO_VOLTAGE, \ | ||
| 155 | .channel = (chan), \ | ||
| 156 | .output = true, \ | ||
| 157 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ | ||
| 158 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ | ||
| 159 | .ext_info = ti_dac_ext_info, \ | ||
| 160 | } | ||
| 161 | |||
| 162 | static const struct iio_chan_spec ti_dac_channels[] = { | ||
| 163 | TI_DAC_CHANNEL(0), | ||
| 164 | }; | ||
| 165 | |||
| 166 | static int ti_dac_read_raw(struct iio_dev *indio_dev, | ||
| 167 | struct iio_chan_spec const *chan, | ||
| 168 | int *val, int *val2, long mask) | ||
| 169 | { | ||
| 170 | struct ti_dac_chip *ti_dac = iio_priv(indio_dev); | ||
| 171 | int ret; | ||
| 172 | |||
| 173 | switch (mask) { | ||
| 174 | case IIO_CHAN_INFO_RAW: | ||
| 175 | *val = ti_dac->val; | ||
| 176 | return IIO_VAL_INT; | ||
| 177 | |||
| 178 | case IIO_CHAN_INFO_SCALE: | ||
| 179 | ret = regulator_get_voltage(ti_dac->vref); | ||
| 180 | if (ret < 0) | ||
| 181 | return ret; | ||
| 182 | |||
| 183 | *val = ret / 1000; | ||
| 184 | *val2 = ti_dac->resolution; | ||
| 185 | return IIO_VAL_FRACTIONAL_LOG2; | ||
| 186 | } | ||
| 187 | |||
| 188 | return -EINVAL; | ||
| 189 | } | ||
| 190 | |||
| 191 | static int ti_dac_write_raw(struct iio_dev *indio_dev, | ||
| 192 | struct iio_chan_spec const *chan, | ||
| 193 | int val, int val2, long mask) | ||
| 194 | { | ||
| 195 | struct ti_dac_chip *ti_dac = iio_priv(indio_dev); | ||
| 196 | u8 power = ti_dac_get_power(ti_dac, ti_dac->powerdown); | ||
| 197 | int ret; | ||
| 198 | |||
| 199 | switch (mask) { | ||
| 200 | case IIO_CHAN_INFO_RAW: | ||
| 201 | if (ti_dac->val == val) | ||
| 202 | return 0; | ||
| 203 | |||
| 204 | if (val >= (1 << ti_dac->resolution) || val < 0) | ||
| 205 | return -EINVAL; | ||
| 206 | |||
| 207 | if (ti_dac->powerdown) | ||
| 208 | return -EBUSY; | ||
| 209 | |||
| 210 | mutex_lock(&ti_dac->lock); | ||
| 211 | ret = ti_dac_cmd(ti_dac, power, val); | ||
| 212 | if (!ret) | ||
| 213 | ti_dac->val = val; | ||
| 214 | mutex_unlock(&ti_dac->lock); | ||
| 215 | break; | ||
| 216 | |||
| 217 | default: | ||
| 218 | ret = -EINVAL; | ||
| 219 | } | ||
| 220 | |||
| 221 | return ret; | ||
| 222 | } | ||
| 223 | |||
| 224 | static int ti_dac_write_raw_get_fmt(struct iio_dev *indio_dev, | ||
| 225 | struct iio_chan_spec const *chan, long mask) | ||
| 226 | { | ||
| 227 | return IIO_VAL_INT; | ||
| 228 | } | ||
| 229 | |||
| 230 | static const struct iio_info ti_dac_info = { | ||
| 231 | .read_raw = ti_dac_read_raw, | ||
| 232 | .write_raw = ti_dac_write_raw, | ||
| 233 | .write_raw_get_fmt = ti_dac_write_raw_get_fmt, | ||
| 234 | }; | ||
| 235 | |||
| 236 | static int ti_dac_probe(struct spi_device *spi) | ||
| 237 | { | ||
| 238 | struct device *dev = &spi->dev; | ||
| 239 | const struct ti_dac_spec *spec; | ||
| 240 | struct ti_dac_chip *ti_dac; | ||
| 241 | struct iio_dev *indio_dev; | ||
| 242 | int ret; | ||
| 243 | |||
| 244 | indio_dev = devm_iio_device_alloc(dev, sizeof(*ti_dac)); | ||
| 245 | if (!indio_dev) { | ||
| 246 | dev_err(dev, "can not allocate iio device\n"); | ||
| 247 | return -ENOMEM; | ||
| 248 | } | ||
| 249 | |||
| 250 | spi->mode = SPI_MODE_1; | ||
| 251 | spi->bits_per_word = 16; | ||
| 252 | spi_setup(spi); | ||
| 253 | |||
| 254 | indio_dev->dev.parent = dev; | ||
| 255 | indio_dev->dev.of_node = spi->dev.of_node; | ||
| 256 | indio_dev->info = &ti_dac_info; | ||
| 257 | indio_dev->name = spi_get_device_id(spi)->name; | ||
| 258 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
| 259 | indio_dev->channels = ti_dac_channels; | ||
| 260 | spi_set_drvdata(spi, indio_dev); | ||
| 261 | |||
| 262 | ti_dac = iio_priv(indio_dev); | ||
| 263 | ti_dac->powerdown = false; | ||
| 264 | ti_dac->spi = spi; | ||
| 265 | |||
| 266 | spec = &ti_dac_spec[spi_get_device_id(spi)->driver_data]; | ||
| 267 | indio_dev->num_channels = 1; | ||
| 268 | ti_dac->resolution = spec->resolution; | ||
| 269 | |||
| 270 | ti_dac->vref = devm_regulator_get(dev, "vref"); | ||
| 271 | if (IS_ERR(ti_dac->vref)) { | ||
| 272 | dev_err(dev, "error to get regulator\n"); | ||
| 273 | return PTR_ERR(ti_dac->vref); | ||
| 274 | } | ||
| 275 | |||
| 276 | ret = regulator_enable(ti_dac->vref); | ||
| 277 | if (ret < 0) { | ||
| 278 | dev_err(dev, "can not enable regulator\n"); | ||
| 279 | return ret; | ||
| 280 | } | ||
| 281 | |||
| 282 | mutex_init(&ti_dac->lock); | ||
| 283 | |||
| 284 | ret = iio_device_register(indio_dev); | ||
| 285 | if (ret) { | ||
| 286 | dev_err(dev, "fail to register iio device: %d\n", ret); | ||
| 287 | goto err; | ||
| 288 | } | ||
| 289 | |||
| 290 | return 0; | ||
| 291 | |||
| 292 | err: | ||
| 293 | mutex_destroy(&ti_dac->lock); | ||
| 294 | regulator_disable(ti_dac->vref); | ||
| 295 | return ret; | ||
| 296 | } | ||
| 297 | |||
| 298 | static int ti_dac_remove(struct spi_device *spi) | ||
| 299 | { | ||
| 300 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
| 301 | struct ti_dac_chip *ti_dac = iio_priv(indio_dev); | ||
| 302 | |||
| 303 | iio_device_unregister(indio_dev); | ||
| 304 | mutex_destroy(&ti_dac->lock); | ||
| 305 | regulator_disable(ti_dac->vref); | ||
| 306 | return 0; | ||
| 307 | } | ||
| 308 | |||
| 309 | static const struct of_device_id ti_dac_of_id[] = { | ||
| 310 | { .compatible = "ti,dac5311" }, | ||
| 311 | { .compatible = "ti,dac6311" }, | ||
| 312 | { .compatible = "ti,dac7311" }, | ||
| 313 | { } | ||
| 314 | }; | ||
| 315 | MODULE_DEVICE_TABLE(of, ti_dac_of_id); | ||
| 316 | |||
| 317 | static const struct spi_device_id ti_dac_spi_id[] = { | ||
| 318 | { "dac5311", ID_DAC5311 }, | ||
| 319 | { "dac6311", ID_DAC6311 }, | ||
| 320 | { "dac7311", ID_DAC7311 }, | ||
| 321 | { } | ||
| 322 | }; | ||
| 323 | MODULE_DEVICE_TABLE(spi, ti_dac_spi_id); | ||
| 324 | |||
| 325 | static struct spi_driver ti_dac_driver = { | ||
| 326 | .driver = { | ||
| 327 | .name = "ti-dac7311", | ||
| 328 | .of_match_table = ti_dac_of_id, | ||
| 329 | }, | ||
| 330 | .probe = ti_dac_probe, | ||
| 331 | .remove = ti_dac_remove, | ||
| 332 | .id_table = ti_dac_spi_id, | ||
| 333 | }; | ||
| 334 | module_spi_driver(ti_dac_driver); | ||
| 335 | |||
| 336 | MODULE_AUTHOR("Charles-Antoine Couret <charles-antoine.couret@essensium.com>"); | ||
| 337 | MODULE_DESCRIPTION("Texas Instruments 8/10/12-bit 1-channel DAC driver"); | ||
| 338 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/imu/st_lsm6dsx/Makefile b/drivers/iio/imu/st_lsm6dsx/Makefile index 35919febea2a..e5f733ce6e11 100644 --- a/drivers/iio/imu/st_lsm6dsx/Makefile +++ b/drivers/iio/imu/st_lsm6dsx/Makefile | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | st_lsm6dsx-y := st_lsm6dsx_core.o st_lsm6dsx_buffer.o | 1 | st_lsm6dsx-y := st_lsm6dsx_core.o st_lsm6dsx_buffer.o \ |
| 2 | st_lsm6dsx_shub.o | ||
| 2 | 3 | ||
| 3 | obj-$(CONFIG_IIO_ST_LSM6DSX) += st_lsm6dsx.o | 4 | obj-$(CONFIG_IIO_ST_LSM6DSX) += st_lsm6dsx.o |
| 4 | obj-$(CONFIG_IIO_ST_LSM6DSX_I2C) += st_lsm6dsx_i2c.o | 5 | obj-$(CONFIG_IIO_ST_LSM6DSX_I2C) += st_lsm6dsx_i2c.o |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index ef73519a0fb6..d1d8d07a0714 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | |||
| @@ -43,6 +43,24 @@ enum st_lsm6dsx_hw_id { | |||
| 43 | * ST_LSM6DSX_TAGGED_SAMPLE_SIZE) | 43 | * ST_LSM6DSX_TAGGED_SAMPLE_SIZE) |
| 44 | #define ST_LSM6DSX_SHIFT_VAL(val, mask) (((val) << __ffs(mask)) & (mask)) | 44 | #define ST_LSM6DSX_SHIFT_VAL(val, mask) (((val) << __ffs(mask)) & (mask)) |
| 45 | 45 | ||
| 46 | #define ST_LSM6DSX_CHANNEL(chan_type, addr, mod, scan_idx) \ | ||
| 47 | { \ | ||
| 48 | .type = chan_type, \ | ||
| 49 | .address = addr, \ | ||
| 50 | .modified = 1, \ | ||
| 51 | .channel2 = mod, \ | ||
| 52 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | ||
| 53 | BIT(IIO_CHAN_INFO_SCALE), \ | ||
| 54 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ | ||
| 55 | .scan_index = scan_idx, \ | ||
| 56 | .scan_type = { \ | ||
| 57 | .sign = 's', \ | ||
| 58 | .realbits = 16, \ | ||
| 59 | .storagebits = 16, \ | ||
| 60 | .endianness = IIO_LE, \ | ||
| 61 | }, \ | ||
| 62 | } | ||
| 63 | |||
| 46 | struct st_lsm6dsx_reg { | 64 | struct st_lsm6dsx_reg { |
| 47 | u8 addr; | 65 | u8 addr; |
| 48 | u8 mask; | 66 | u8 mask; |
| @@ -50,6 +68,28 @@ struct st_lsm6dsx_reg { | |||
| 50 | 68 | ||
| 51 | struct st_lsm6dsx_hw; | 69 | struct st_lsm6dsx_hw; |
| 52 | 70 | ||
| 71 | struct st_lsm6dsx_odr { | ||
| 72 | u16 hz; | ||
| 73 | u8 val; | ||
| 74 | }; | ||
| 75 | |||
| 76 | #define ST_LSM6DSX_ODR_LIST_SIZE 6 | ||
| 77 | struct st_lsm6dsx_odr_table_entry { | ||
| 78 | struct st_lsm6dsx_reg reg; | ||
| 79 | struct st_lsm6dsx_odr odr_avl[ST_LSM6DSX_ODR_LIST_SIZE]; | ||
| 80 | }; | ||
| 81 | |||
| 82 | struct st_lsm6dsx_fs { | ||
| 83 | u32 gain; | ||
| 84 | u8 val; | ||
| 85 | }; | ||
| 86 | |||
| 87 | #define ST_LSM6DSX_FS_LIST_SIZE 4 | ||
| 88 | struct st_lsm6dsx_fs_table_entry { | ||
| 89 | struct st_lsm6dsx_reg reg; | ||
| 90 | struct st_lsm6dsx_fs fs_avl[ST_LSM6DSX_FS_LIST_SIZE]; | ||
| 91 | }; | ||
| 92 | |||
| 53 | /** | 93 | /** |
| 54 | * struct st_lsm6dsx_fifo_ops - ST IMU FIFO settings | 94 | * struct st_lsm6dsx_fifo_ops - ST IMU FIFO settings |
| 55 | * @read_fifo: Read FIFO callback. | 95 | * @read_fifo: Read FIFO callback. |
| @@ -85,6 +125,70 @@ struct st_lsm6dsx_hw_ts_settings { | |||
| 85 | }; | 125 | }; |
| 86 | 126 | ||
| 87 | /** | 127 | /** |
| 128 | * struct st_lsm6dsx_shub_settings - ST IMU hw i2c controller settings | ||
| 129 | * @page_mux: register page mux info (addr + mask). | ||
| 130 | * @master_en: master config register info (addr + mask). | ||
| 131 | * @pullup_en: i2c controller pull-up register info (addr + mask). | ||
| 132 | * @aux_sens: aux sensor register info (addr + mask). | ||
| 133 | * @wr_once: write_once register info (addr + mask). | ||
| 134 | * @shub_out: sensor hub first output register info. | ||
| 135 | * @slv0_addr: slave0 address in secondary page. | ||
| 136 | * @dw_slv0_addr: slave0 write register address in secondary page. | ||
| 137 | * @batch_en: Enable/disable FIFO batching. | ||
| 138 | */ | ||
| 139 | struct st_lsm6dsx_shub_settings { | ||
| 140 | struct st_lsm6dsx_reg page_mux; | ||
| 141 | struct st_lsm6dsx_reg master_en; | ||
| 142 | struct st_lsm6dsx_reg pullup_en; | ||
| 143 | struct st_lsm6dsx_reg aux_sens; | ||
| 144 | struct st_lsm6dsx_reg wr_once; | ||
| 145 | u8 shub_out; | ||
| 146 | u8 slv0_addr; | ||
| 147 | u8 dw_slv0_addr; | ||
| 148 | u8 batch_en; | ||
| 149 | }; | ||
| 150 | |||
| 151 | enum st_lsm6dsx_ext_sensor_id { | ||
| 152 | ST_LSM6DSX_ID_MAGN, | ||
| 153 | }; | ||
| 154 | |||
| 155 | /** | ||
| 156 | * struct st_lsm6dsx_ext_dev_settings - i2c controller slave settings | ||
| 157 | * @i2c_addr: I2c slave address list. | ||
| 158 | * @wai: Wai address info. | ||
| 159 | * @id: external sensor id. | ||
| 160 | * @odr: Output data rate of the sensor [Hz]. | ||
| 161 | * @gain: Configured sensor sensitivity. | ||
| 162 | * @temp_comp: Temperature compensation register info (addr + mask). | ||
| 163 | * @pwr_table: Power on register info (addr + mask). | ||
| 164 | * @off_canc: Offset cancellation register info (addr + mask). | ||
| 165 | * @bdu: Block data update register info (addr + mask). | ||
| 166 | * @out: Output register info. | ||
| 167 | */ | ||
| 168 | struct st_lsm6dsx_ext_dev_settings { | ||
| 169 | u8 i2c_addr[2]; | ||
| 170 | struct { | ||
| 171 | u8 addr; | ||
| 172 | u8 val; | ||
| 173 | } wai; | ||
| 174 | enum st_lsm6dsx_ext_sensor_id id; | ||
| 175 | struct st_lsm6dsx_odr_table_entry odr_table; | ||
| 176 | struct st_lsm6dsx_fs_table_entry fs_table; | ||
| 177 | struct st_lsm6dsx_reg temp_comp; | ||
| 178 | struct { | ||
| 179 | struct st_lsm6dsx_reg reg; | ||
| 180 | u8 off_val; | ||
| 181 | u8 on_val; | ||
| 182 | } pwr_table; | ||
| 183 | struct st_lsm6dsx_reg off_canc; | ||
| 184 | struct st_lsm6dsx_reg bdu; | ||
| 185 | struct { | ||
| 186 | u8 addr; | ||
| 187 | u8 len; | ||
| 188 | } out; | ||
| 189 | }; | ||
| 190 | |||
| 191 | /** | ||
| 88 | * struct st_lsm6dsx_settings - ST IMU sensor settings | 192 | * struct st_lsm6dsx_settings - ST IMU sensor settings |
| 89 | * @wai: Sensor WhoAmI default value. | 193 | * @wai: Sensor WhoAmI default value. |
| 90 | * @max_fifo_size: Sensor max fifo length in FIFO words. | 194 | * @max_fifo_size: Sensor max fifo length in FIFO words. |
| @@ -93,6 +197,7 @@ struct st_lsm6dsx_hw_ts_settings { | |||
| 93 | * @batch: List of FIFO batching register info (addr + mask). | 197 | * @batch: List of FIFO batching register info (addr + mask). |
| 94 | * @fifo_ops: Sensor hw FIFO parameters. | 198 | * @fifo_ops: Sensor hw FIFO parameters. |
| 95 | * @ts_settings: Hw timer related settings. | 199 | * @ts_settings: Hw timer related settings. |
| 200 | * @shub_settings: i2c controller related settings. | ||
| 96 | */ | 201 | */ |
| 97 | struct st_lsm6dsx_settings { | 202 | struct st_lsm6dsx_settings { |
| 98 | u8 wai; | 203 | u8 wai; |
| @@ -102,11 +207,15 @@ struct st_lsm6dsx_settings { | |||
| 102 | struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID]; | 207 | struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID]; |
| 103 | struct st_lsm6dsx_fifo_ops fifo_ops; | 208 | struct st_lsm6dsx_fifo_ops fifo_ops; |
| 104 | struct st_lsm6dsx_hw_ts_settings ts_settings; | 209 | struct st_lsm6dsx_hw_ts_settings ts_settings; |
| 210 | struct st_lsm6dsx_shub_settings shub_settings; | ||
| 105 | }; | 211 | }; |
| 106 | 212 | ||
| 107 | enum st_lsm6dsx_sensor_id { | 213 | enum st_lsm6dsx_sensor_id { |
| 108 | ST_LSM6DSX_ID_ACC, | ||
| 109 | ST_LSM6DSX_ID_GYRO, | 214 | ST_LSM6DSX_ID_GYRO, |
| 215 | ST_LSM6DSX_ID_ACC, | ||
| 216 | ST_LSM6DSX_ID_EXT0, | ||
| 217 | ST_LSM6DSX_ID_EXT1, | ||
| 218 | ST_LSM6DSX_ID_EXT2, | ||
| 110 | ST_LSM6DSX_ID_MAX, | 219 | ST_LSM6DSX_ID_MAX, |
| 111 | }; | 220 | }; |
| 112 | 221 | ||
| @@ -126,6 +235,7 @@ enum st_lsm6dsx_fifo_mode { | |||
| 126 | * @sip: Number of samples in a given pattern. | 235 | * @sip: Number of samples in a given pattern. |
| 127 | * @decimator: FIFO decimation factor. | 236 | * @decimator: FIFO decimation factor. |
| 128 | * @ts_ref: Sensor timestamp reference for hw one. | 237 | * @ts_ref: Sensor timestamp reference for hw one. |
| 238 | * @ext_info: Sensor settings if it is connected to i2c controller | ||
| 129 | */ | 239 | */ |
| 130 | struct st_lsm6dsx_sensor { | 240 | struct st_lsm6dsx_sensor { |
| 131 | char name[32]; | 241 | char name[32]; |
| @@ -139,6 +249,11 @@ struct st_lsm6dsx_sensor { | |||
| 139 | u8 sip; | 249 | u8 sip; |
| 140 | u8 decimator; | 250 | u8 decimator; |
| 141 | s64 ts_ref; | 251 | s64 ts_ref; |
| 252 | |||
| 253 | struct { | ||
| 254 | const struct st_lsm6dsx_ext_dev_settings *settings; | ||
| 255 | u8 addr; | ||
| 256 | } ext_info; | ||
| 142 | }; | 257 | }; |
| 143 | 258 | ||
| 144 | /** | 259 | /** |
| @@ -148,6 +263,7 @@ struct st_lsm6dsx_sensor { | |||
| 148 | * @irq: Device interrupt line (I2C or SPI). | 263 | * @irq: Device interrupt line (I2C or SPI). |
| 149 | * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO. | 264 | * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO. |
| 150 | * @conf_lock: Mutex to prevent concurrent FIFO configuration update. | 265 | * @conf_lock: Mutex to prevent concurrent FIFO configuration update. |
| 266 | * @page_lock: Mutex to prevent concurrent memory page configuration. | ||
| 151 | * @fifo_mode: FIFO operating mode supported by the device. | 267 | * @fifo_mode: FIFO operating mode supported by the device. |
| 152 | * @enable_mask: Enabled sensor bitmask. | 268 | * @enable_mask: Enabled sensor bitmask. |
| 153 | * @ts_sip: Total number of timestamp samples in a given pattern. | 269 | * @ts_sip: Total number of timestamp samples in a given pattern. |
| @@ -163,6 +279,7 @@ struct st_lsm6dsx_hw { | |||
| 163 | 279 | ||
| 164 | struct mutex fifo_lock; | 280 | struct mutex fifo_lock; |
| 165 | struct mutex conf_lock; | 281 | struct mutex conf_lock; |
| 282 | struct mutex page_lock; | ||
| 166 | 283 | ||
| 167 | enum st_lsm6dsx_fifo_mode fifo_mode; | 284 | enum st_lsm6dsx_fifo_mode fifo_mode; |
| 168 | u8 enable_mask; | 285 | u8 enable_mask; |
| @@ -176,13 +293,15 @@ struct st_lsm6dsx_hw { | |||
| 176 | const struct st_lsm6dsx_settings *settings; | 293 | const struct st_lsm6dsx_settings *settings; |
| 177 | }; | 294 | }; |
| 178 | 295 | ||
| 296 | static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0}; | ||
| 179 | extern const struct dev_pm_ops st_lsm6dsx_pm_ops; | 297 | extern const struct dev_pm_ops st_lsm6dsx_pm_ops; |
| 180 | 298 | ||
| 181 | int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, | 299 | int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, |
| 182 | struct regmap *regmap); | 300 | struct regmap *regmap); |
| 183 | int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor); | 301 | int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, |
| 184 | int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor); | 302 | bool enable); |
| 185 | int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw); | 303 | int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw); |
| 304 | int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val); | ||
| 186 | int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, | 305 | int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, |
| 187 | u16 watermark); | 306 | u16 watermark); |
| 188 | int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw); | 307 | int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw); |
| @@ -191,5 +310,47 @@ int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, | |||
| 191 | int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw); | 310 | int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw); |
| 192 | int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw); | 311 | int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw); |
| 193 | int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val); | 312 | int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val); |
| 313 | int st_lsm6dsx_shub_probe(struct st_lsm6dsx_hw *hw, const char *name); | ||
| 314 | int st_lsm6dsx_shub_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable); | ||
| 315 | int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable); | ||
| 316 | |||
| 317 | static inline int | ||
| 318 | st_lsm6dsx_update_bits_locked(struct st_lsm6dsx_hw *hw, unsigned int addr, | ||
| 319 | unsigned int mask, unsigned int val) | ||
| 320 | { | ||
| 321 | int err; | ||
| 322 | |||
| 323 | mutex_lock(&hw->page_lock); | ||
| 324 | err = regmap_update_bits(hw->regmap, addr, mask, val); | ||
| 325 | mutex_unlock(&hw->page_lock); | ||
| 326 | |||
| 327 | return err; | ||
| 328 | } | ||
| 329 | |||
| 330 | static inline int | ||
| 331 | st_lsm6dsx_read_locked(struct st_lsm6dsx_hw *hw, unsigned int addr, | ||
| 332 | void *val, unsigned int len) | ||
| 333 | { | ||
| 334 | int err; | ||
| 335 | |||
| 336 | mutex_lock(&hw->page_lock); | ||
| 337 | err = regmap_bulk_read(hw->regmap, addr, val, len); | ||
| 338 | mutex_unlock(&hw->page_lock); | ||
| 339 | |||
| 340 | return err; | ||
| 341 | } | ||
| 342 | |||
| 343 | static inline int | ||
| 344 | st_lsm6dsx_write_locked(struct st_lsm6dsx_hw *hw, unsigned int addr, | ||
| 345 | unsigned int val) | ||
| 346 | { | ||
| 347 | int err; | ||
| 348 | |||
| 349 | mutex_lock(&hw->page_lock); | ||
| 350 | err = regmap_write(hw->regmap, addr, val); | ||
| 351 | mutex_unlock(&hw->page_lock); | ||
| 352 | |||
| 353 | return err; | ||
| 354 | } | ||
| 194 | 355 | ||
| 195 | #endif /* ST_LSM6DSX_H */ | 356 | #endif /* ST_LSM6DSX_H */ |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index b5263fc522ca..2c0d3763405a 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | |||
| @@ -68,6 +68,9 @@ enum st_lsm6dsx_fifo_tag { | |||
| 68 | ST_LSM6DSX_GYRO_TAG = 0x01, | 68 | ST_LSM6DSX_GYRO_TAG = 0x01, |
| 69 | ST_LSM6DSX_ACC_TAG = 0x02, | 69 | ST_LSM6DSX_ACC_TAG = 0x02, |
| 70 | ST_LSM6DSX_TS_TAG = 0x04, | 70 | ST_LSM6DSX_TS_TAG = 0x04, |
| 71 | ST_LSM6DSX_EXT0_TAG = 0x0f, | ||
| 72 | ST_LSM6DSX_EXT1_TAG = 0x10, | ||
| 73 | ST_LSM6DSX_EXT2_TAG = 0x11, | ||
| 71 | }; | 74 | }; |
| 72 | 75 | ||
| 73 | static const | 76 | static const |
| @@ -102,6 +105,9 @@ static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw, | |||
| 102 | 105 | ||
| 103 | *max_odr = 0, *min_odr = ~0; | 106 | *max_odr = 0, *min_odr = ~0; |
| 104 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { | 107 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
| 108 | if (!hw->iio_devs[i]) | ||
| 109 | continue; | ||
| 110 | |||
| 105 | sensor = iio_priv(hw->iio_devs[i]); | 111 | sensor = iio_priv(hw->iio_devs[i]); |
| 106 | 112 | ||
| 107 | if (!(hw->enable_mask & BIT(sensor->id))) | 113 | if (!(hw->enable_mask & BIT(sensor->id))) |
| @@ -125,6 +131,9 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) | |||
| 125 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { | 131 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
| 126 | const struct st_lsm6dsx_reg *dec_reg; | 132 | const struct st_lsm6dsx_reg *dec_reg; |
| 127 | 133 | ||
| 134 | if (!hw->iio_devs[i]) | ||
| 135 | continue; | ||
| 136 | |||
| 128 | sensor = iio_priv(hw->iio_devs[i]); | 137 | sensor = iio_priv(hw->iio_devs[i]); |
| 129 | /* update fifo decimators and sample in pattern */ | 138 | /* update fifo decimators and sample in pattern */ |
| 130 | if (hw->enable_mask & BIT(sensor->id)) { | 139 | if (hw->enable_mask & BIT(sensor->id)) { |
| @@ -142,8 +151,9 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) | |||
| 142 | if (dec_reg->addr) { | 151 | if (dec_reg->addr) { |
| 143 | int val = ST_LSM6DSX_SHIFT_VAL(data, dec_reg->mask); | 152 | int val = ST_LSM6DSX_SHIFT_VAL(data, dec_reg->mask); |
| 144 | 153 | ||
| 145 | err = regmap_update_bits(hw->regmap, dec_reg->addr, | 154 | err = st_lsm6dsx_update_bits_locked(hw, dec_reg->addr, |
| 146 | dec_reg->mask, val); | 155 | dec_reg->mask, |
| 156 | val); | ||
| 147 | if (err < 0) | 157 | if (err < 0) |
| 148 | return err; | 158 | return err; |
| 149 | } | 159 | } |
| @@ -162,8 +172,8 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) | |||
| 162 | int val, ts_dec = !!hw->ts_sip; | 172 | int val, ts_dec = !!hw->ts_sip; |
| 163 | 173 | ||
| 164 | val = ST_LSM6DSX_SHIFT_VAL(ts_dec, ts_dec_reg->mask); | 174 | val = ST_LSM6DSX_SHIFT_VAL(ts_dec, ts_dec_reg->mask); |
| 165 | err = regmap_update_bits(hw->regmap, ts_dec_reg->addr, | 175 | err = st_lsm6dsx_update_bits_locked(hw, ts_dec_reg->addr, |
| 166 | ts_dec_reg->mask, val); | 176 | ts_dec_reg->mask, val); |
| 167 | } | 177 | } |
| 168 | return err; | 178 | return err; |
| 169 | } | 179 | } |
| @@ -171,12 +181,12 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) | |||
| 171 | int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, | 181 | int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw, |
| 172 | enum st_lsm6dsx_fifo_mode fifo_mode) | 182 | enum st_lsm6dsx_fifo_mode fifo_mode) |
| 173 | { | 183 | { |
| 184 | unsigned int data; | ||
| 174 | int err; | 185 | int err; |
| 175 | 186 | ||
| 176 | err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_FIFO_MODE_ADDR, | 187 | data = FIELD_PREP(ST_LSM6DSX_FIFO_MODE_MASK, fifo_mode); |
| 177 | ST_LSM6DSX_FIFO_MODE_MASK, | 188 | err = st_lsm6dsx_update_bits_locked(hw, ST_LSM6DSX_REG_FIFO_MODE_ADDR, |
| 178 | FIELD_PREP(ST_LSM6DSX_FIFO_MODE_MASK, | 189 | ST_LSM6DSX_FIFO_MODE_MASK, data); |
| 179 | fifo_mode)); | ||
| 180 | if (err < 0) | 190 | if (err < 0) |
| 181 | return err; | 191 | return err; |
| 182 | 192 | ||
| @@ -207,15 +217,15 @@ static int st_lsm6dsx_set_fifo_odr(struct st_lsm6dsx_sensor *sensor, | |||
| 207 | data = 0; | 217 | data = 0; |
| 208 | } | 218 | } |
| 209 | val = ST_LSM6DSX_SHIFT_VAL(data, batch_reg->mask); | 219 | val = ST_LSM6DSX_SHIFT_VAL(data, batch_reg->mask); |
| 210 | return regmap_update_bits(hw->regmap, batch_reg->addr, | 220 | return st_lsm6dsx_update_bits_locked(hw, batch_reg->addr, |
| 211 | batch_reg->mask, val); | 221 | batch_reg->mask, val); |
| 212 | } else { | 222 | } else { |
| 213 | data = hw->enable_mask ? ST_LSM6DSX_MAX_FIFO_ODR_VAL : 0; | 223 | data = hw->enable_mask ? ST_LSM6DSX_MAX_FIFO_ODR_VAL : 0; |
| 214 | return regmap_update_bits(hw->regmap, | 224 | return st_lsm6dsx_update_bits_locked(hw, |
| 215 | ST_LSM6DSX_REG_FIFO_MODE_ADDR, | 225 | ST_LSM6DSX_REG_FIFO_MODE_ADDR, |
| 216 | ST_LSM6DSX_FIFO_ODR_MASK, | 226 | ST_LSM6DSX_FIFO_ODR_MASK, |
| 217 | FIELD_PREP(ST_LSM6DSX_FIFO_ODR_MASK, | 227 | FIELD_PREP(ST_LSM6DSX_FIFO_ODR_MASK, |
| 218 | data)); | 228 | data)); |
| 219 | } | 229 | } |
| 220 | } | 230 | } |
| 221 | 231 | ||
| @@ -231,6 +241,9 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark) | |||
| 231 | return 0; | 241 | return 0; |
| 232 | 242 | ||
| 233 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { | 243 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
| 244 | if (!hw->iio_devs[i]) | ||
| 245 | continue; | ||
| 246 | |||
| 234 | cur_sensor = iio_priv(hw->iio_devs[i]); | 247 | cur_sensor = iio_priv(hw->iio_devs[i]); |
| 235 | 248 | ||
| 236 | if (!(hw->enable_mask & BIT(cur_sensor->id))) | 249 | if (!(hw->enable_mask & BIT(cur_sensor->id))) |
| @@ -246,19 +259,23 @@ int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark) | |||
| 246 | fifo_watermark = (fifo_watermark / hw->sip) * hw->sip; | 259 | fifo_watermark = (fifo_watermark / hw->sip) * hw->sip; |
| 247 | fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl; | 260 | fifo_watermark = fifo_watermark * hw->settings->fifo_ops.th_wl; |
| 248 | 261 | ||
| 262 | mutex_lock(&hw->page_lock); | ||
| 249 | err = regmap_read(hw->regmap, hw->settings->fifo_ops.fifo_th.addr + 1, | 263 | err = regmap_read(hw->regmap, hw->settings->fifo_ops.fifo_th.addr + 1, |
| 250 | &data); | 264 | &data); |
| 251 | if (err < 0) | 265 | if (err < 0) |
| 252 | return err; | 266 | goto out; |
| 253 | 267 | ||
| 254 | fifo_th_mask = hw->settings->fifo_ops.fifo_th.mask; | 268 | fifo_th_mask = hw->settings->fifo_ops.fifo_th.mask; |
| 255 | fifo_watermark = ((data << 8) & ~fifo_th_mask) | | 269 | fifo_watermark = ((data << 8) & ~fifo_th_mask) | |
| 256 | (fifo_watermark & fifo_th_mask); | 270 | (fifo_watermark & fifo_th_mask); |
| 257 | 271 | ||
| 258 | wdata = cpu_to_le16(fifo_watermark); | 272 | wdata = cpu_to_le16(fifo_watermark); |
| 259 | return regmap_bulk_write(hw->regmap, | 273 | err = regmap_bulk_write(hw->regmap, |
| 260 | hw->settings->fifo_ops.fifo_th.addr, | 274 | hw->settings->fifo_ops.fifo_th.addr, |
| 261 | &wdata, sizeof(wdata)); | 275 | &wdata, sizeof(wdata)); |
| 276 | out: | ||
| 277 | mutex_unlock(&hw->page_lock); | ||
| 278 | return err; | ||
| 262 | } | 279 | } |
| 263 | 280 | ||
| 264 | static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw) | 281 | static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw) |
| @@ -267,12 +284,15 @@ static int st_lsm6dsx_reset_hw_ts(struct st_lsm6dsx_hw *hw) | |||
| 267 | int i, err; | 284 | int i, err; |
| 268 | 285 | ||
| 269 | /* reset hw ts counter */ | 286 | /* reset hw ts counter */ |
| 270 | err = regmap_write(hw->regmap, ST_LSM6DSX_REG_TS_RESET_ADDR, | 287 | err = st_lsm6dsx_write_locked(hw, ST_LSM6DSX_REG_TS_RESET_ADDR, |
| 271 | ST_LSM6DSX_TS_RESET_VAL); | 288 | ST_LSM6DSX_TS_RESET_VAL); |
| 272 | if (err < 0) | 289 | if (err < 0) |
| 273 | return err; | 290 | return err; |
| 274 | 291 | ||
| 275 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { | 292 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
| 293 | if (!hw->iio_devs[i]) | ||
| 294 | continue; | ||
| 295 | |||
| 276 | sensor = iio_priv(hw->iio_devs[i]); | 296 | sensor = iio_priv(hw->iio_devs[i]); |
| 277 | /* | 297 | /* |
| 278 | * store enable buffer timestamp as reference for | 298 | * store enable buffer timestamp as reference for |
| @@ -297,8 +317,8 @@ static inline int st_lsm6dsx_read_block(struct st_lsm6dsx_hw *hw, u8 addr, | |||
| 297 | while (read_len < data_len) { | 317 | while (read_len < data_len) { |
| 298 | word_len = min_t(unsigned int, data_len - read_len, | 318 | word_len = min_t(unsigned int, data_len - read_len, |
| 299 | max_word_len); | 319 | max_word_len); |
| 300 | err = regmap_bulk_read(hw->regmap, addr, data + read_len, | 320 | err = st_lsm6dsx_read_locked(hw, addr, data + read_len, |
| 301 | word_len); | 321 | word_len); |
| 302 | if (err < 0) | 322 | if (err < 0) |
| 303 | return err; | 323 | return err; |
| 304 | read_len += word_len; | 324 | read_len += word_len; |
| @@ -328,9 +348,9 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) | |||
| 328 | __le16 fifo_status; | 348 | __le16 fifo_status; |
| 329 | s64 ts = 0; | 349 | s64 ts = 0; |
| 330 | 350 | ||
| 331 | err = regmap_bulk_read(hw->regmap, | 351 | err = st_lsm6dsx_read_locked(hw, |
| 332 | hw->settings->fifo_ops.fifo_diff.addr, | 352 | hw->settings->fifo_ops.fifo_diff.addr, |
| 333 | &fifo_status, sizeof(fifo_status)); | 353 | &fifo_status, sizeof(fifo_status)); |
| 334 | if (err < 0) { | 354 | if (err < 0) { |
| 335 | dev_err(hw->dev, "failed to read fifo status (err=%d)\n", | 355 | dev_err(hw->dev, "failed to read fifo status (err=%d)\n", |
| 336 | err); | 356 | err); |
| @@ -436,6 +456,55 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) | |||
| 436 | return read_len; | 456 | return read_len; |
| 437 | } | 457 | } |
| 438 | 458 | ||
| 459 | static int | ||
| 460 | st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag, | ||
| 461 | u8 *data, s64 ts) | ||
| 462 | { | ||
| 463 | struct st_lsm6dsx_sensor *sensor; | ||
| 464 | struct iio_dev *iio_dev; | ||
| 465 | |||
| 466 | /* | ||
| 467 | * EXT_TAG are managed in FIFO fashion so ST_LSM6DSX_EXT0_TAG | ||
| 468 | * corresponds to the first enabled channel, ST_LSM6DSX_EXT1_TAG | ||
| 469 | * to the second one and ST_LSM6DSX_EXT2_TAG to the last enabled | ||
| 470 | * channel | ||
| 471 | */ | ||
| 472 | switch (tag) { | ||
| 473 | case ST_LSM6DSX_GYRO_TAG: | ||
| 474 | iio_dev = hw->iio_devs[ST_LSM6DSX_ID_GYRO]; | ||
| 475 | break; | ||
| 476 | case ST_LSM6DSX_ACC_TAG: | ||
| 477 | iio_dev = hw->iio_devs[ST_LSM6DSX_ID_ACC]; | ||
| 478 | break; | ||
| 479 | case ST_LSM6DSX_EXT0_TAG: | ||
| 480 | if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0)) | ||
| 481 | iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT0]; | ||
| 482 | else if (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1)) | ||
| 483 | iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1]; | ||
| 484 | else | ||
| 485 | iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2]; | ||
| 486 | break; | ||
| 487 | case ST_LSM6DSX_EXT1_TAG: | ||
| 488 | if ((hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT0)) && | ||
| 489 | (hw->enable_mask & BIT(ST_LSM6DSX_ID_EXT1))) | ||
| 490 | iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT1]; | ||
| 491 | else | ||
| 492 | iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2]; | ||
| 493 | break; | ||
| 494 | case ST_LSM6DSX_EXT2_TAG: | ||
| 495 | iio_dev = hw->iio_devs[ST_LSM6DSX_ID_EXT2]; | ||
| 496 | break; | ||
| 497 | default: | ||
| 498 | return -EINVAL; | ||
| 499 | } | ||
| 500 | |||
| 501 | sensor = iio_priv(iio_dev); | ||
| 502 | iio_push_to_buffers_with_timestamp(iio_dev, data, | ||
| 503 | ts + sensor->ts_ref); | ||
| 504 | |||
| 505 | return 0; | ||
| 506 | } | ||
| 507 | |||
| 439 | /** | 508 | /** |
| 440 | * st_lsm6dsx_read_tagged_fifo() - LSM6DSO read FIFO routine | 509 | * st_lsm6dsx_read_tagged_fifo() - LSM6DSO read FIFO routine |
| 441 | * @hw: Pointer to instance of struct st_lsm6dsx_hw. | 510 | * @hw: Pointer to instance of struct st_lsm6dsx_hw. |
| @@ -455,9 +524,9 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) | |||
| 455 | __le16 fifo_status; | 524 | __le16 fifo_status; |
| 456 | s64 ts = 0; | 525 | s64 ts = 0; |
| 457 | 526 | ||
| 458 | err = regmap_bulk_read(hw->regmap, | 527 | err = st_lsm6dsx_read_locked(hw, |
| 459 | hw->settings->fifo_ops.fifo_diff.addr, | 528 | hw->settings->fifo_ops.fifo_diff.addr, |
| 460 | &fifo_status, sizeof(fifo_status)); | 529 | &fifo_status, sizeof(fifo_status)); |
| 461 | if (err < 0) { | 530 | if (err < 0) { |
| 462 | dev_err(hw->dev, "failed to read fifo status (err=%d)\n", | 531 | dev_err(hw->dev, "failed to read fifo status (err=%d)\n", |
| 463 | err); | 532 | err); |
| @@ -491,8 +560,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) | |||
| 491 | ST_LSM6DSX_SAMPLE_SIZE); | 560 | ST_LSM6DSX_SAMPLE_SIZE); |
| 492 | 561 | ||
| 493 | tag = hw->buff[i] >> 3; | 562 | tag = hw->buff[i] >> 3; |
| 494 | switch (tag) { | 563 | if (tag == ST_LSM6DSX_TS_TAG) { |
| 495 | case ST_LSM6DSX_TS_TAG: | ||
| 496 | /* | 564 | /* |
| 497 | * hw timestamp is 4B long and it is stored | 565 | * hw timestamp is 4B long and it is stored |
| 498 | * in FIFO according to this schema: | 566 | * in FIFO according to this schema: |
| @@ -509,19 +577,9 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) | |||
| 509 | if (!reset_ts && ts >= 0xffff0000) | 577 | if (!reset_ts && ts >= 0xffff0000) |
| 510 | reset_ts = true; | 578 | reset_ts = true; |
| 511 | ts *= ST_LSM6DSX_TS_SENSITIVITY; | 579 | ts *= ST_LSM6DSX_TS_SENSITIVITY; |
| 512 | break; | 580 | } else { |
| 513 | case ST_LSM6DSX_GYRO_TAG: | 581 | st_lsm6dsx_push_tagged_data(hw, tag, iio_buff, |
| 514 | iio_push_to_buffers_with_timestamp( | 582 | ts); |
| 515 | hw->iio_devs[ST_LSM6DSX_ID_GYRO], | ||
| 516 | iio_buff, gyro_sensor->ts_ref + ts); | ||
| 517 | break; | ||
| 518 | case ST_LSM6DSX_ACC_TAG: | ||
| 519 | iio_push_to_buffers_with_timestamp( | ||
| 520 | hw->iio_devs[ST_LSM6DSX_ID_ACC], | ||
| 521 | iio_buff, acc_sensor->ts_ref + ts); | ||
| 522 | break; | ||
| 523 | default: | ||
| 524 | break; | ||
| 525 | } | 583 | } |
| 526 | } | 584 | } |
| 527 | } | 585 | } |
| @@ -562,19 +620,21 @@ static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable) | |||
| 562 | goto out; | 620 | goto out; |
| 563 | } | 621 | } |
| 564 | 622 | ||
| 565 | if (enable) { | 623 | if (sensor->id == ST_LSM6DSX_ID_EXT0 || |
| 566 | err = st_lsm6dsx_sensor_enable(sensor); | 624 | sensor->id == ST_LSM6DSX_ID_EXT1 || |
| 625 | sensor->id == ST_LSM6DSX_ID_EXT2) { | ||
| 626 | err = st_lsm6dsx_shub_set_enable(sensor, enable); | ||
| 567 | if (err < 0) | 627 | if (err < 0) |
| 568 | goto out; | 628 | goto out; |
| 569 | } else { | 629 | } else { |
| 570 | err = st_lsm6dsx_sensor_disable(sensor); | 630 | err = st_lsm6dsx_sensor_set_enable(sensor, enable); |
| 571 | if (err < 0) | 631 | if (err < 0) |
| 572 | goto out; | 632 | goto out; |
| 573 | } | ||
| 574 | 633 | ||
| 575 | err = st_lsm6dsx_set_fifo_odr(sensor, enable); | 634 | err = st_lsm6dsx_set_fifo_odr(sensor, enable); |
| 576 | if (err < 0) | 635 | if (err < 0) |
| 577 | goto out; | 636 | goto out; |
| 637 | } | ||
| 578 | 638 | ||
| 579 | err = st_lsm6dsx_update_decimators(hw); | 639 | err = st_lsm6dsx_update_decimators(hw); |
| 580 | if (err < 0) | 640 | if (err < 0) |
| @@ -690,6 +750,9 @@ int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw) | |||
| 690 | } | 750 | } |
| 691 | 751 | ||
| 692 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { | 752 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
| 753 | if (!hw->iio_devs[i]) | ||
| 754 | continue; | ||
| 755 | |||
| 693 | buffer = devm_iio_kfifo_allocate(hw->dev); | 756 | buffer = devm_iio_kfifo_allocate(hw->dev); |
| 694 | if (!buffer) | 757 | if (!buffer) |
| 695 | return -ENOMEM; | 758 | return -ENOMEM; |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 2ad3c610e4b6..12e29dda9b98 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f | 56 | #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f |
| 57 | #define ST_LSM6DSX_REG_RESET_ADDR 0x12 | 57 | #define ST_LSM6DSX_REG_RESET_ADDR 0x12 |
| 58 | #define ST_LSM6DSX_REG_RESET_MASK BIT(0) | 58 | #define ST_LSM6DSX_REG_RESET_MASK BIT(0) |
| 59 | #define ST_LSM6DSX_REG_BOOT_MASK BIT(7) | ||
| 59 | #define ST_LSM6DSX_REG_BDU_ADDR 0x12 | 60 | #define ST_LSM6DSX_REG_BDU_ADDR 0x12 |
| 60 | #define ST_LSM6DSX_REG_BDU_MASK BIT(6) | 61 | #define ST_LSM6DSX_REG_BDU_MASK BIT(6) |
| 61 | #define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13 | 62 | #define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13 |
| @@ -87,17 +88,6 @@ | |||
| 87 | #define ST_LSM6DSX_GYRO_FS_1000_GAIN IIO_DEGREE_TO_RAD(35000) | 88 | #define ST_LSM6DSX_GYRO_FS_1000_GAIN IIO_DEGREE_TO_RAD(35000) |
| 88 | #define ST_LSM6DSX_GYRO_FS_2000_GAIN IIO_DEGREE_TO_RAD(70000) | 89 | #define ST_LSM6DSX_GYRO_FS_2000_GAIN IIO_DEGREE_TO_RAD(70000) |
| 89 | 90 | ||
| 90 | struct st_lsm6dsx_odr { | ||
| 91 | u16 hz; | ||
| 92 | u8 val; | ||
| 93 | }; | ||
| 94 | |||
| 95 | #define ST_LSM6DSX_ODR_LIST_SIZE 6 | ||
| 96 | struct st_lsm6dsx_odr_table_entry { | ||
| 97 | struct st_lsm6dsx_reg reg; | ||
| 98 | struct st_lsm6dsx_odr odr_avl[ST_LSM6DSX_ODR_LIST_SIZE]; | ||
| 99 | }; | ||
| 100 | |||
| 101 | static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = { | 91 | static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = { |
| 102 | [ST_LSM6DSX_ID_ACC] = { | 92 | [ST_LSM6DSX_ID_ACC] = { |
| 103 | .reg = { | 93 | .reg = { |
| @@ -125,17 +115,6 @@ static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = { | |||
| 125 | } | 115 | } |
| 126 | }; | 116 | }; |
| 127 | 117 | ||
| 128 | struct st_lsm6dsx_fs { | ||
| 129 | u32 gain; | ||
| 130 | u8 val; | ||
| 131 | }; | ||
| 132 | |||
| 133 | #define ST_LSM6DSX_FS_LIST_SIZE 4 | ||
| 134 | struct st_lsm6dsx_fs_table_entry { | ||
| 135 | struct st_lsm6dsx_reg reg; | ||
| 136 | struct st_lsm6dsx_fs fs_avl[ST_LSM6DSX_FS_LIST_SIZE]; | ||
| 137 | }; | ||
| 138 | |||
| 139 | static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = { | 118 | static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = { |
| 140 | [ST_LSM6DSX_ID_ACC] = { | 119 | [ST_LSM6DSX_ID_ACC] = { |
| 141 | .reg = { | 120 | .reg = { |
| @@ -341,27 +320,35 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { | |||
| 341 | .mask = GENMASK(7, 6), | 320 | .mask = GENMASK(7, 6), |
| 342 | }, | 321 | }, |
| 343 | }, | 322 | }, |
| 323 | .shub_settings = { | ||
| 324 | .page_mux = { | ||
| 325 | .addr = 0x01, | ||
| 326 | .mask = BIT(6), | ||
| 327 | }, | ||
| 328 | .master_en = { | ||
| 329 | .addr = 0x14, | ||
| 330 | .mask = BIT(2), | ||
| 331 | }, | ||
| 332 | .pullup_en = { | ||
| 333 | .addr = 0x14, | ||
| 334 | .mask = BIT(3), | ||
| 335 | }, | ||
| 336 | .aux_sens = { | ||
| 337 | .addr = 0x14, | ||
| 338 | .mask = GENMASK(1, 0), | ||
| 339 | }, | ||
| 340 | .wr_once = { | ||
| 341 | .addr = 0x14, | ||
| 342 | .mask = BIT(6), | ||
| 343 | }, | ||
| 344 | .shub_out = 0x02, | ||
| 345 | .slv0_addr = 0x15, | ||
| 346 | .dw_slv0_addr = 0x21, | ||
| 347 | .batch_en = BIT(3), | ||
| 348 | } | ||
| 344 | }, | 349 | }, |
| 345 | }; | 350 | }; |
| 346 | 351 | ||
| 347 | #define ST_LSM6DSX_CHANNEL(chan_type, addr, mod, scan_idx) \ | ||
| 348 | { \ | ||
| 349 | .type = chan_type, \ | ||
| 350 | .address = addr, \ | ||
| 351 | .modified = 1, \ | ||
| 352 | .channel2 = mod, \ | ||
| 353 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | ||
| 354 | BIT(IIO_CHAN_INFO_SCALE), \ | ||
| 355 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ | ||
| 356 | .scan_index = scan_idx, \ | ||
| 357 | .scan_type = { \ | ||
| 358 | .sign = 's', \ | ||
| 359 | .realbits = 16, \ | ||
| 360 | .storagebits = 16, \ | ||
| 361 | .endianness = IIO_LE, \ | ||
| 362 | }, \ | ||
| 363 | } | ||
| 364 | |||
| 365 | static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { | 352 | static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { |
| 366 | ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR, | 353 | ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR, |
| 367 | IIO_MOD_X, 0), | 354 | IIO_MOD_X, 0), |
| @@ -382,6 +369,21 @@ static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = { | |||
| 382 | IIO_CHAN_SOFT_TIMESTAMP(3), | 369 | IIO_CHAN_SOFT_TIMESTAMP(3), |
| 383 | }; | 370 | }; |
| 384 | 371 | ||
| 372 | int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) | ||
| 373 | { | ||
| 374 | const struct st_lsm6dsx_shub_settings *hub_settings; | ||
| 375 | unsigned int data; | ||
| 376 | int err; | ||
| 377 | |||
| 378 | hub_settings = &hw->settings->shub_settings; | ||
| 379 | data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask); | ||
| 380 | err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr, | ||
| 381 | hub_settings->page_mux.mask, data); | ||
| 382 | usleep_range(100, 150); | ||
| 383 | |||
| 384 | return err; | ||
| 385 | } | ||
| 386 | |||
| 385 | static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id) | 387 | static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id) |
| 386 | { | 388 | { |
| 387 | int err, i, j, data; | 389 | int err, i, j, data; |
| @@ -421,6 +423,7 @@ static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, | |||
| 421 | { | 423 | { |
| 422 | struct st_lsm6dsx_hw *hw = sensor->hw; | 424 | struct st_lsm6dsx_hw *hw = sensor->hw; |
| 423 | const struct st_lsm6dsx_reg *reg; | 425 | const struct st_lsm6dsx_reg *reg; |
| 426 | unsigned int data; | ||
| 424 | int i, err; | 427 | int i, err; |
| 425 | u8 val; | 428 | u8 val; |
| 426 | 429 | ||
| @@ -433,8 +436,8 @@ static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, | |||
| 433 | 436 | ||
| 434 | val = st_lsm6dsx_fs_table[sensor->id].fs_avl[i].val; | 437 | val = st_lsm6dsx_fs_table[sensor->id].fs_avl[i].val; |
| 435 | reg = &st_lsm6dsx_fs_table[sensor->id].reg; | 438 | reg = &st_lsm6dsx_fs_table[sensor->id].reg; |
| 436 | err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, | 439 | data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); |
| 437 | ST_LSM6DSX_SHIFT_VAL(val, reg->mask)); | 440 | err = st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data); |
| 438 | if (err < 0) | 441 | if (err < 0) |
| 439 | return err; | 442 | return err; |
| 440 | 443 | ||
| @@ -448,7 +451,11 @@ int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val) | |||
| 448 | int i; | 451 | int i; |
| 449 | 452 | ||
| 450 | for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) | 453 | for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) |
| 451 | if (st_lsm6dsx_odr_table[sensor->id].odr_avl[i].hz == odr) | 454 | /* |
| 455 | * ext devices can run at different odr respect to | ||
| 456 | * accel sensor | ||
| 457 | */ | ||
| 458 | if (st_lsm6dsx_odr_table[sensor->id].odr_avl[i].hz >= odr) | ||
| 452 | break; | 459 | break; |
| 453 | 460 | ||
| 454 | if (i == ST_LSM6DSX_ODR_LIST_SIZE) | 461 | if (i == ST_LSM6DSX_ODR_LIST_SIZE) |
| @@ -459,48 +466,86 @@ int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val) | |||
| 459 | return 0; | 466 | return 0; |
| 460 | } | 467 | } |
| 461 | 468 | ||
| 462 | static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr) | 469 | static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr, |
| 470 | enum st_lsm6dsx_sensor_id id) | ||
| 463 | { | 471 | { |
| 464 | struct st_lsm6dsx_hw *hw = sensor->hw; | 472 | struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]); |
| 465 | const struct st_lsm6dsx_reg *reg; | 473 | |
| 466 | int err; | 474 | if (odr > 0) { |
| 467 | u8 val; | 475 | if (hw->enable_mask & BIT(id)) |
| 468 | 476 | return max_t(u16, ref->odr, odr); | |
| 469 | err = st_lsm6dsx_check_odr(sensor, odr, &val); | 477 | else |
| 470 | if (err < 0) | 478 | return odr; |
| 471 | return err; | 479 | } else { |
| 472 | 480 | return (hw->enable_mask & BIT(id)) ? ref->odr : 0; | |
| 473 | reg = &st_lsm6dsx_odr_table[sensor->id].reg; | 481 | } |
| 474 | return regmap_update_bits(hw->regmap, reg->addr, reg->mask, | ||
| 475 | ST_LSM6DSX_SHIFT_VAL(val, reg->mask)); | ||
| 476 | } | 482 | } |
| 477 | 483 | ||
| 478 | int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor) | 484 | static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr) |
| 479 | { | 485 | { |
| 486 | struct st_lsm6dsx_sensor *ref_sensor = sensor; | ||
| 487 | struct st_lsm6dsx_hw *hw = sensor->hw; | ||
| 488 | const struct st_lsm6dsx_reg *reg; | ||
| 489 | unsigned int data; | ||
| 490 | u8 val = 0; | ||
| 480 | int err; | 491 | int err; |
| 481 | 492 | ||
| 482 | err = st_lsm6dsx_set_odr(sensor, sensor->odr); | 493 | switch (sensor->id) { |
| 483 | if (err < 0) | 494 | case ST_LSM6DSX_ID_EXT0: |
| 484 | return err; | 495 | case ST_LSM6DSX_ID_EXT1: |
| 496 | case ST_LSM6DSX_ID_EXT2: | ||
| 497 | case ST_LSM6DSX_ID_ACC: { | ||
| 498 | u16 odr; | ||
| 499 | int i; | ||
| 500 | |||
| 501 | /* | ||
| 502 | * i2c embedded controller relies on the accelerometer sensor as | ||
| 503 | * bus read/write trigger so we need to enable accel device | ||
| 504 | * at odr = max(accel_odr, ext_odr) in order to properly | ||
| 505 | * communicate with i2c slave devices | ||
| 506 | */ | ||
| 507 | ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); | ||
| 508 | for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) { | ||
| 509 | if (!hw->iio_devs[i] || i == sensor->id) | ||
| 510 | continue; | ||
| 511 | |||
| 512 | odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i); | ||
| 513 | if (odr != req_odr) | ||
| 514 | /* device already configured */ | ||
| 515 | return 0; | ||
| 516 | } | ||
| 517 | break; | ||
| 518 | } | ||
| 519 | default: | ||
| 520 | break; | ||
| 521 | } | ||
| 485 | 522 | ||
| 486 | sensor->hw->enable_mask |= BIT(sensor->id); | 523 | if (req_odr > 0) { |
| 524 | err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val); | ||
| 525 | if (err < 0) | ||
| 526 | return err; | ||
| 527 | } | ||
| 487 | 528 | ||
| 488 | return 0; | 529 | reg = &st_lsm6dsx_odr_table[ref_sensor->id].reg; |
| 530 | data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); | ||
| 531 | return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data); | ||
| 489 | } | 532 | } |
| 490 | 533 | ||
| 491 | int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor) | 534 | int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, |
| 535 | bool enable) | ||
| 492 | { | 536 | { |
| 493 | struct st_lsm6dsx_hw *hw = sensor->hw; | 537 | struct st_lsm6dsx_hw *hw = sensor->hw; |
| 494 | const struct st_lsm6dsx_reg *reg; | 538 | u16 odr = enable ? sensor->odr : 0; |
| 495 | int err; | 539 | int err; |
| 496 | 540 | ||
| 497 | reg = &st_lsm6dsx_odr_table[sensor->id].reg; | 541 | err = st_lsm6dsx_set_odr(sensor, odr); |
| 498 | err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, | ||
| 499 | ST_LSM6DSX_SHIFT_VAL(0, reg->mask)); | ||
| 500 | if (err < 0) | 542 | if (err < 0) |
| 501 | return err; | 543 | return err; |
| 502 | 544 | ||
| 503 | sensor->hw->enable_mask &= ~BIT(sensor->id); | 545 | if (enable) |
| 546 | hw->enable_mask |= BIT(sensor->id); | ||
| 547 | else | ||
| 548 | hw->enable_mask &= ~BIT(sensor->id); | ||
| 504 | 549 | ||
| 505 | return 0; | 550 | return 0; |
| 506 | } | 551 | } |
| @@ -512,18 +557,18 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, | |||
| 512 | int err, delay; | 557 | int err, delay; |
| 513 | __le16 data; | 558 | __le16 data; |
| 514 | 559 | ||
| 515 | err = st_lsm6dsx_sensor_enable(sensor); | 560 | err = st_lsm6dsx_sensor_set_enable(sensor, true); |
| 516 | if (err < 0) | 561 | if (err < 0) |
| 517 | return err; | 562 | return err; |
| 518 | 563 | ||
| 519 | delay = 1000000 / sensor->odr; | 564 | delay = 1000000 / sensor->odr; |
| 520 | usleep_range(delay, 2 * delay); | 565 | usleep_range(delay, 2 * delay); |
| 521 | 566 | ||
| 522 | err = regmap_bulk_read(hw->regmap, addr, &data, sizeof(data)); | 567 | err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data)); |
| 523 | if (err < 0) | 568 | if (err < 0) |
| 524 | return err; | 569 | return err; |
| 525 | 570 | ||
| 526 | st_lsm6dsx_sensor_disable(sensor); | 571 | st_lsm6dsx_sensor_set_enable(sensor, false); |
| 527 | 572 | ||
| 528 | *val = (s16)le16_to_cpu(data); | 573 | *val = (s16)le16_to_cpu(data); |
| 529 | 574 | ||
| @@ -596,7 +641,7 @@ static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, | |||
| 596 | return err; | 641 | return err; |
| 597 | } | 642 | } |
| 598 | 643 | ||
| 599 | static int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) | 644 | int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) |
| 600 | { | 645 | { |
| 601 | struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); | 646 | struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); |
| 602 | struct st_lsm6dsx_hw *hw = sensor->hw; | 647 | struct st_lsm6dsx_hw *hw = sensor->hw; |
| @@ -692,8 +737,6 @@ static const struct iio_info st_lsm6dsx_gyro_info = { | |||
| 692 | .hwfifo_set_watermark = st_lsm6dsx_set_watermark, | 737 | .hwfifo_set_watermark = st_lsm6dsx_set_watermark, |
| 693 | }; | 738 | }; |
| 694 | 739 | ||
| 695 | static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0}; | ||
| 696 | |||
| 697 | static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) | 740 | static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) |
| 698 | { | 741 | { |
| 699 | struct device_node *np = hw->dev->of_node; | 742 | struct device_node *np = hw->dev->of_node; |
| @@ -732,6 +775,51 @@ static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg) | |||
| 732 | return err; | 775 | return err; |
| 733 | } | 776 | } |
| 734 | 777 | ||
| 778 | static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw) | ||
| 779 | { | ||
| 780 | const struct st_lsm6dsx_shub_settings *hub_settings; | ||
| 781 | struct device_node *np = hw->dev->of_node; | ||
| 782 | struct st_sensors_platform_data *pdata; | ||
| 783 | unsigned int data; | ||
| 784 | int err = 0; | ||
| 785 | |||
| 786 | hub_settings = &hw->settings->shub_settings; | ||
| 787 | |||
| 788 | pdata = (struct st_sensors_platform_data *)hw->dev->platform_data; | ||
| 789 | if ((np && of_property_read_bool(np, "st,pullups")) || | ||
| 790 | (pdata && pdata->pullups)) { | ||
| 791 | err = st_lsm6dsx_set_page(hw, true); | ||
| 792 | if (err < 0) | ||
| 793 | return err; | ||
| 794 | |||
| 795 | data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask); | ||
| 796 | err = regmap_update_bits(hw->regmap, | ||
| 797 | hub_settings->pullup_en.addr, | ||
| 798 | hub_settings->pullup_en.mask, data); | ||
| 799 | |||
| 800 | st_lsm6dsx_set_page(hw, false); | ||
| 801 | |||
| 802 | if (err < 0) | ||
| 803 | return err; | ||
| 804 | } | ||
| 805 | |||
| 806 | if (hub_settings->aux_sens.addr) { | ||
| 807 | /* configure aux sensors */ | ||
| 808 | err = st_lsm6dsx_set_page(hw, true); | ||
| 809 | if (err < 0) | ||
| 810 | return err; | ||
| 811 | |||
| 812 | data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask); | ||
| 813 | err = regmap_update_bits(hw->regmap, | ||
| 814 | hub_settings->aux_sens.addr, | ||
| 815 | hub_settings->aux_sens.mask, data); | ||
| 816 | |||
| 817 | st_lsm6dsx_set_page(hw, false); | ||
| 818 | } | ||
| 819 | |||
| 820 | return err; | ||
| 821 | } | ||
| 822 | |||
| 735 | static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw) | 823 | static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw) |
| 736 | { | 824 | { |
| 737 | const struct st_lsm6dsx_hw_ts_settings *ts_settings; | 825 | const struct st_lsm6dsx_hw_ts_settings *ts_settings; |
| @@ -775,12 +863,23 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) | |||
| 775 | u8 drdy_int_reg; | 863 | u8 drdy_int_reg; |
| 776 | int err; | 864 | int err; |
| 777 | 865 | ||
| 778 | err = regmap_write(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR, | 866 | /* device sw reset */ |
| 779 | ST_LSM6DSX_REG_RESET_MASK); | 867 | err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR, |
| 868 | ST_LSM6DSX_REG_RESET_MASK, | ||
| 869 | FIELD_PREP(ST_LSM6DSX_REG_RESET_MASK, 1)); | ||
| 870 | if (err < 0) | ||
| 871 | return err; | ||
| 872 | |||
| 873 | msleep(50); | ||
| 874 | |||
| 875 | /* reload trimming parameter */ | ||
| 876 | err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR, | ||
| 877 | ST_LSM6DSX_REG_BOOT_MASK, | ||
| 878 | FIELD_PREP(ST_LSM6DSX_REG_BOOT_MASK, 1)); | ||
| 780 | if (err < 0) | 879 | if (err < 0) |
| 781 | return err; | 880 | return err; |
| 782 | 881 | ||
| 783 | msleep(200); | 882 | msleep(50); |
| 784 | 883 | ||
| 785 | /* enable Block Data Update */ | 884 | /* enable Block Data Update */ |
| 786 | err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_BDU_ADDR, | 885 | err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_BDU_ADDR, |
| @@ -801,6 +900,10 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) | |||
| 801 | if (err < 0) | 900 | if (err < 0) |
| 802 | return err; | 901 | return err; |
| 803 | 902 | ||
| 903 | err = st_lsm6dsx_init_shub(hw); | ||
| 904 | if (err < 0) | ||
| 905 | return err; | ||
| 906 | |||
| 804 | return st_lsm6dsx_init_hw_timer(hw); | 907 | return st_lsm6dsx_init_hw_timer(hw); |
| 805 | } | 908 | } |
| 806 | 909 | ||
| @@ -854,6 +957,7 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, | |||
| 854 | int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, | 957 | int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, |
| 855 | struct regmap *regmap) | 958 | struct regmap *regmap) |
| 856 | { | 959 | { |
| 960 | const struct st_lsm6dsx_shub_settings *hub_settings; | ||
| 857 | struct st_lsm6dsx_hw *hw; | 961 | struct st_lsm6dsx_hw *hw; |
| 858 | int i, err; | 962 | int i, err; |
| 859 | 963 | ||
| @@ -865,6 +969,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, | |||
| 865 | 969 | ||
| 866 | mutex_init(&hw->fifo_lock); | 970 | mutex_init(&hw->fifo_lock); |
| 867 | mutex_init(&hw->conf_lock); | 971 | mutex_init(&hw->conf_lock); |
| 972 | mutex_init(&hw->page_lock); | ||
| 868 | 973 | ||
| 869 | hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL); | 974 | hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL); |
| 870 | if (!hw->buff) | 975 | if (!hw->buff) |
| @@ -878,7 +983,7 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, | |||
| 878 | if (err < 0) | 983 | if (err < 0) |
| 879 | return err; | 984 | return err; |
| 880 | 985 | ||
| 881 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { | 986 | for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) { |
| 882 | hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name); | 987 | hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name); |
| 883 | if (!hw->iio_devs[i]) | 988 | if (!hw->iio_devs[i]) |
| 884 | return -ENOMEM; | 989 | return -ENOMEM; |
| @@ -888,6 +993,13 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, | |||
| 888 | if (err < 0) | 993 | if (err < 0) |
| 889 | return err; | 994 | return err; |
| 890 | 995 | ||
| 996 | hub_settings = &hw->settings->shub_settings; | ||
| 997 | if (hub_settings->master_en.addr) { | ||
| 998 | err = st_lsm6dsx_shub_probe(hw, name); | ||
| 999 | if (err < 0) | ||
| 1000 | return err; | ||
| 1001 | } | ||
| 1002 | |||
| 891 | if (hw->irq > 0) { | 1003 | if (hw->irq > 0) { |
| 892 | err = st_lsm6dsx_fifo_setup(hw); | 1004 | err = st_lsm6dsx_fifo_setup(hw); |
| 893 | if (err < 0) | 1005 | if (err < 0) |
| @@ -895,6 +1007,9 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name, | |||
| 895 | } | 1007 | } |
| 896 | 1008 | ||
| 897 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { | 1009 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
| 1010 | if (!hw->iio_devs[i]) | ||
| 1011 | continue; | ||
| 1012 | |||
| 898 | err = devm_iio_device_register(hw->dev, hw->iio_devs[i]); | 1013 | err = devm_iio_device_register(hw->dev, hw->iio_devs[i]); |
| 899 | if (err) | 1014 | if (err) |
| 900 | return err; | 1015 | return err; |
| @@ -909,16 +1024,21 @@ static int __maybe_unused st_lsm6dsx_suspend(struct device *dev) | |||
| 909 | struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); | 1024 | struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); |
| 910 | struct st_lsm6dsx_sensor *sensor; | 1025 | struct st_lsm6dsx_sensor *sensor; |
| 911 | const struct st_lsm6dsx_reg *reg; | 1026 | const struct st_lsm6dsx_reg *reg; |
| 1027 | unsigned int data; | ||
| 912 | int i, err = 0; | 1028 | int i, err = 0; |
| 913 | 1029 | ||
| 914 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { | 1030 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
| 1031 | if (!hw->iio_devs[i]) | ||
| 1032 | continue; | ||
| 1033 | |||
| 915 | sensor = iio_priv(hw->iio_devs[i]); | 1034 | sensor = iio_priv(hw->iio_devs[i]); |
| 916 | if (!(hw->enable_mask & BIT(sensor->id))) | 1035 | if (!(hw->enable_mask & BIT(sensor->id))) |
| 917 | continue; | 1036 | continue; |
| 918 | 1037 | ||
| 919 | reg = &st_lsm6dsx_odr_table[sensor->id].reg; | 1038 | reg = &st_lsm6dsx_odr_table[sensor->id].reg; |
| 920 | err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, | 1039 | data = ST_LSM6DSX_SHIFT_VAL(0, reg->mask); |
| 921 | ST_LSM6DSX_SHIFT_VAL(0, reg->mask)); | 1040 | err = st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, |
| 1041 | data); | ||
| 922 | if (err < 0) | 1042 | if (err < 0) |
| 923 | return err; | 1043 | return err; |
| 924 | } | 1044 | } |
| @@ -936,6 +1056,9 @@ static int __maybe_unused st_lsm6dsx_resume(struct device *dev) | |||
| 936 | int i, err = 0; | 1056 | int i, err = 0; |
| 937 | 1057 | ||
| 938 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { | 1058 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
| 1059 | if (!hw->iio_devs[i]) | ||
| 1060 | continue; | ||
| 1061 | |||
| 939 | sensor = iio_priv(hw->iio_devs[i]); | 1062 | sensor = iio_priv(hw->iio_devs[i]); |
| 940 | if (!(hw->enable_mask & BIT(sensor->id))) | 1063 | if (!(hw->enable_mask & BIT(sensor->id))) |
| 941 | continue; | 1064 | continue; |
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c new file mode 100644 index 000000000000..ee59b0cac84f --- /dev/null +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | |||
| @@ -0,0 +1,777 @@ | |||
| 1 | /* | ||
| 2 | * STMicroelectronics st_lsm6dsx i2c controller driver | ||
| 3 | * | ||
| 4 | * i2c controller embedded in lsm6dx series can connect up to four | ||
| 5 | * slave devices using accelerometer sensor as trigger for i2c | ||
| 6 | * read/write operations. Current implementation relies on SLV0 channel | ||
| 7 | * for slave configuration and SLV{1,2,3} to read data and push them into | ||
| 8 | * the hw FIFO | ||
| 9 | * | ||
| 10 | * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> | ||
| 11 | * | ||
| 12 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 13 | * purpose with or without fee is hereby granted, provided that the above | ||
| 14 | * copyright notice and this permission notice appear in all copies. | ||
| 15 | * | ||
| 16 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 17 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 18 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 19 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 20 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 21 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 22 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 23 | * | ||
| 24 | */ | ||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/regmap.h> | ||
| 27 | #include <linux/iio/iio.h> | ||
| 28 | #include <linux/iio/sysfs.h> | ||
| 29 | #include <linux/bitfield.h> | ||
| 30 | |||
| 31 | #include "st_lsm6dsx.h" | ||
| 32 | |||
| 33 | #define ST_LSM6DSX_MAX_SLV_NUM 3 | ||
| 34 | #define ST_LSM6DSX_SLV_ADDR(n, base) ((base) + (n) * 3) | ||
| 35 | #define ST_LSM6DSX_SLV_SUB_ADDR(n, base) ((base) + 1 + (n) * 3) | ||
| 36 | #define ST_LSM6DSX_SLV_CONFIG(n, base) ((base) + 2 + (n) * 3) | ||
| 37 | |||
| 38 | #define ST_LS6DSX_READ_OP_MASK GENMASK(2, 0) | ||
| 39 | |||
| 40 | static const struct st_lsm6dsx_ext_dev_settings st_lsm6dsx_ext_dev_table[] = { | ||
| 41 | /* LIS2MDL */ | ||
| 42 | { | ||
| 43 | .i2c_addr = { 0x1e }, | ||
| 44 | .wai = { | ||
| 45 | .addr = 0x4f, | ||
| 46 | .val = 0x40, | ||
| 47 | }, | ||
| 48 | .id = ST_LSM6DSX_ID_MAGN, | ||
| 49 | .odr_table = { | ||
| 50 | .reg = { | ||
| 51 | .addr = 0x60, | ||
| 52 | .mask = GENMASK(3, 2), | ||
| 53 | }, | ||
| 54 | .odr_avl[0] = { 10, 0x0 }, | ||
| 55 | .odr_avl[1] = { 20, 0x1 }, | ||
| 56 | .odr_avl[2] = { 50, 0x2 }, | ||
| 57 | .odr_avl[3] = { 100, 0x3 }, | ||
| 58 | }, | ||
| 59 | .fs_table = { | ||
| 60 | .fs_avl[0] = { | ||
| 61 | .gain = 1500, | ||
| 62 | .val = 0x0, | ||
| 63 | }, /* 1500 uG/LSB */ | ||
| 64 | }, | ||
| 65 | .temp_comp = { | ||
| 66 | .addr = 0x60, | ||
| 67 | .mask = BIT(7), | ||
| 68 | }, | ||
| 69 | .pwr_table = { | ||
| 70 | .reg = { | ||
| 71 | .addr = 0x60, | ||
| 72 | .mask = GENMASK(1, 0), | ||
| 73 | }, | ||
| 74 | .off_val = 0x2, | ||
| 75 | .on_val = 0x0, | ||
| 76 | }, | ||
| 77 | .off_canc = { | ||
| 78 | .addr = 0x61, | ||
| 79 | .mask = BIT(1), | ||
| 80 | }, | ||
| 81 | .bdu = { | ||
| 82 | .addr = 0x62, | ||
| 83 | .mask = BIT(4), | ||
| 84 | }, | ||
| 85 | .out = { | ||
| 86 | .addr = 0x68, | ||
| 87 | .len = 6, | ||
| 88 | }, | ||
| 89 | }, | ||
| 90 | }; | ||
| 91 | |||
| 92 | static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw) | ||
| 93 | { | ||
| 94 | struct st_lsm6dsx_sensor *sensor; | ||
| 95 | |||
| 96 | sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); | ||
| 97 | msleep((2000U / sensor->odr) + 1); | ||
| 98 | } | ||
| 99 | |||
| 100 | /** | ||
| 101 | * st_lsm6dsx_shub_read_reg - read i2c controller register | ||
| 102 | * | ||
| 103 | * Read st_lsm6dsx i2c controller register | ||
| 104 | */ | ||
| 105 | static int st_lsm6dsx_shub_read_reg(struct st_lsm6dsx_hw *hw, u8 addr, | ||
| 106 | u8 *data, int len) | ||
| 107 | { | ||
| 108 | const struct st_lsm6dsx_shub_settings *hub_settings; | ||
| 109 | int err; | ||
| 110 | |||
| 111 | mutex_lock(&hw->page_lock); | ||
| 112 | |||
| 113 | hub_settings = &hw->settings->shub_settings; | ||
| 114 | err = st_lsm6dsx_set_page(hw, true); | ||
| 115 | if (err < 0) | ||
| 116 | goto out; | ||
| 117 | |||
| 118 | err = regmap_bulk_read(hw->regmap, addr, data, len); | ||
| 119 | |||
| 120 | st_lsm6dsx_set_page(hw, false); | ||
| 121 | out: | ||
| 122 | mutex_unlock(&hw->page_lock); | ||
| 123 | |||
| 124 | return err; | ||
| 125 | } | ||
| 126 | |||
| 127 | /** | ||
| 128 | * st_lsm6dsx_shub_write_reg - write i2c controller register | ||
| 129 | * | ||
| 130 | * Write st_lsm6dsx i2c controller register | ||
| 131 | */ | ||
| 132 | static int st_lsm6dsx_shub_write_reg(struct st_lsm6dsx_hw *hw, u8 addr, | ||
| 133 | u8 *data, int len) | ||
| 134 | { | ||
| 135 | int err; | ||
| 136 | |||
| 137 | mutex_lock(&hw->page_lock); | ||
| 138 | err = st_lsm6dsx_set_page(hw, true); | ||
| 139 | if (err < 0) | ||
| 140 | goto out; | ||
| 141 | |||
| 142 | err = regmap_bulk_write(hw->regmap, addr, data, len); | ||
| 143 | |||
| 144 | st_lsm6dsx_set_page(hw, false); | ||
| 145 | out: | ||
| 146 | mutex_unlock(&hw->page_lock); | ||
| 147 | |||
| 148 | return err; | ||
| 149 | } | ||
| 150 | |||
| 151 | static int | ||
| 152 | st_lsm6dsx_shub_write_reg_with_mask(struct st_lsm6dsx_hw *hw, u8 addr, | ||
| 153 | u8 mask, u8 val) | ||
| 154 | { | ||
| 155 | int err; | ||
| 156 | |||
| 157 | mutex_lock(&hw->page_lock); | ||
| 158 | err = st_lsm6dsx_set_page(hw, true); | ||
| 159 | if (err < 0) | ||
| 160 | goto out; | ||
| 161 | |||
| 162 | err = regmap_update_bits(hw->regmap, addr, mask, val); | ||
| 163 | |||
| 164 | st_lsm6dsx_set_page(hw, false); | ||
| 165 | out: | ||
| 166 | mutex_unlock(&hw->page_lock); | ||
| 167 | |||
| 168 | return err; | ||
| 169 | } | ||
| 170 | |||
| 171 | static int st_lsm6dsx_shub_master_enable(struct st_lsm6dsx_sensor *sensor, | ||
| 172 | bool enable) | ||
| 173 | { | ||
| 174 | const struct st_lsm6dsx_shub_settings *hub_settings; | ||
| 175 | struct st_lsm6dsx_hw *hw = sensor->hw; | ||
| 176 | unsigned int data; | ||
| 177 | int err; | ||
| 178 | |||
| 179 | /* enable acc sensor as trigger */ | ||
| 180 | err = st_lsm6dsx_sensor_set_enable(sensor, enable); | ||
| 181 | if (err < 0) | ||
| 182 | return err; | ||
| 183 | |||
| 184 | mutex_lock(&hw->page_lock); | ||
| 185 | |||
| 186 | hub_settings = &hw->settings->shub_settings; | ||
| 187 | err = st_lsm6dsx_set_page(hw, true); | ||
| 188 | if (err < 0) | ||
| 189 | goto out; | ||
| 190 | |||
| 191 | data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->master_en.mask); | ||
| 192 | err = regmap_update_bits(hw->regmap, hub_settings->master_en.addr, | ||
| 193 | hub_settings->master_en.mask, data); | ||
| 194 | |||
| 195 | st_lsm6dsx_set_page(hw, false); | ||
| 196 | out: | ||
| 197 | mutex_unlock(&hw->page_lock); | ||
| 198 | |||
| 199 | return err; | ||
| 200 | } | ||
| 201 | |||
| 202 | /** | ||
| 203 | * st_lsm6dsx_shub_read - read data from slave device register | ||
| 204 | * | ||
| 205 | * Read data from slave device register. SLV0 is used for | ||
| 206 | * one-shot read operation | ||
| 207 | */ | ||
| 208 | static int | ||
| 209 | st_lsm6dsx_shub_read(struct st_lsm6dsx_sensor *sensor, u8 addr, | ||
| 210 | u8 *data, int len) | ||
| 211 | { | ||
| 212 | const struct st_lsm6dsx_shub_settings *hub_settings; | ||
| 213 | struct st_lsm6dsx_hw *hw = sensor->hw; | ||
| 214 | u8 config[3], slv_addr; | ||
| 215 | int err; | ||
| 216 | |||
| 217 | hub_settings = &hw->settings->shub_settings; | ||
| 218 | slv_addr = ST_LSM6DSX_SLV_ADDR(0, hub_settings->slv0_addr); | ||
| 219 | |||
| 220 | config[0] = (sensor->ext_info.addr << 1) | 1; | ||
| 221 | config[1] = addr; | ||
| 222 | config[2] = len & ST_LS6DSX_READ_OP_MASK; | ||
| 223 | |||
| 224 | err = st_lsm6dsx_shub_write_reg(hw, slv_addr, config, | ||
| 225 | sizeof(config)); | ||
| 226 | if (err < 0) | ||
| 227 | return err; | ||
| 228 | |||
| 229 | err = st_lsm6dsx_shub_master_enable(sensor, true); | ||
| 230 | if (err < 0) | ||
| 231 | return err; | ||
| 232 | |||
| 233 | st_lsm6dsx_shub_wait_complete(hw); | ||
| 234 | |||
| 235 | err = st_lsm6dsx_shub_read_reg(hw, hub_settings->shub_out, data, | ||
| 236 | len & ST_LS6DSX_READ_OP_MASK); | ||
| 237 | |||
| 238 | st_lsm6dsx_shub_master_enable(sensor, false); | ||
| 239 | |||
| 240 | memset(config, 0, sizeof(config)); | ||
| 241 | return st_lsm6dsx_shub_write_reg(hw, slv_addr, config, | ||
| 242 | sizeof(config)); | ||
| 243 | } | ||
| 244 | |||
| 245 | /** | ||
| 246 | * st_lsm6dsx_shub_write - write data to slave device register | ||
| 247 | * | ||
| 248 | * Write data from slave device register. SLV0 is used for | ||
| 249 | * one-shot write operation | ||
| 250 | */ | ||
| 251 | static int | ||
| 252 | st_lsm6dsx_shub_write(struct st_lsm6dsx_sensor *sensor, u8 addr, | ||
| 253 | u8 *data, int len) | ||
| 254 | { | ||
| 255 | const struct st_lsm6dsx_shub_settings *hub_settings; | ||
| 256 | struct st_lsm6dsx_hw *hw = sensor->hw; | ||
| 257 | u8 config[2], slv_addr; | ||
| 258 | int err, i; | ||
| 259 | |||
| 260 | hub_settings = &hw->settings->shub_settings; | ||
| 261 | if (hub_settings->wr_once.addr) { | ||
| 262 | unsigned int data; | ||
| 263 | |||
| 264 | data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->wr_once.mask); | ||
| 265 | err = st_lsm6dsx_shub_write_reg_with_mask(hw, | ||
| 266 | hub_settings->wr_once.addr, | ||
| 267 | hub_settings->wr_once.mask, | ||
| 268 | data); | ||
| 269 | if (err < 0) | ||
| 270 | return err; | ||
| 271 | } | ||
| 272 | |||
| 273 | slv_addr = ST_LSM6DSX_SLV_ADDR(0, hub_settings->slv0_addr); | ||
| 274 | config[0] = sensor->ext_info.addr << 1; | ||
| 275 | for (i = 0 ; i < len; i++) { | ||
| 276 | config[1] = addr + i; | ||
| 277 | |||
| 278 | err = st_lsm6dsx_shub_write_reg(hw, slv_addr, config, | ||
| 279 | sizeof(config)); | ||
| 280 | if (err < 0) | ||
| 281 | return err; | ||
| 282 | |||
| 283 | err = st_lsm6dsx_shub_write_reg(hw, hub_settings->dw_slv0_addr, | ||
| 284 | &data[i], 1); | ||
| 285 | if (err < 0) | ||
| 286 | return err; | ||
| 287 | |||
| 288 | err = st_lsm6dsx_shub_master_enable(sensor, true); | ||
| 289 | if (err < 0) | ||
| 290 | return err; | ||
| 291 | |||
| 292 | st_lsm6dsx_shub_wait_complete(hw); | ||
| 293 | |||
| 294 | st_lsm6dsx_shub_master_enable(sensor, false); | ||
| 295 | } | ||
| 296 | |||
| 297 | memset(config, 0, sizeof(config)); | ||
| 298 | return st_lsm6dsx_shub_write_reg(hw, slv_addr, config, sizeof(config)); | ||
| 299 | } | ||
| 300 | |||
| 301 | static int | ||
| 302 | st_lsm6dsx_shub_write_with_mask(struct st_lsm6dsx_sensor *sensor, | ||
| 303 | u8 addr, u8 mask, u8 val) | ||
| 304 | { | ||
| 305 | int err; | ||
| 306 | u8 data; | ||
| 307 | |||
| 308 | err = st_lsm6dsx_shub_read(sensor, addr, &data, sizeof(data)); | ||
| 309 | if (err < 0) | ||
| 310 | return err; | ||
| 311 | |||
| 312 | data = ((data & ~mask) | (val << __ffs(mask) & mask)); | ||
| 313 | |||
| 314 | return st_lsm6dsx_shub_write(sensor, addr, &data, sizeof(data)); | ||
| 315 | } | ||
| 316 | |||
| 317 | static int | ||
| 318 | st_lsm6dsx_shub_get_odr_val(struct st_lsm6dsx_sensor *sensor, | ||
| 319 | u16 odr, u16 *val) | ||
| 320 | { | ||
| 321 | const struct st_lsm6dsx_ext_dev_settings *settings; | ||
| 322 | int i; | ||
| 323 | |||
| 324 | settings = sensor->ext_info.settings; | ||
| 325 | for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) | ||
| 326 | if (settings->odr_table.odr_avl[i].hz == odr) | ||
| 327 | break; | ||
| 328 | |||
| 329 | if (i == ST_LSM6DSX_ODR_LIST_SIZE) | ||
| 330 | return -EINVAL; | ||
| 331 | |||
| 332 | *val = settings->odr_table.odr_avl[i].val; | ||
| 333 | return 0; | ||
| 334 | } | ||
| 335 | |||
| 336 | static int | ||
| 337 | st_lsm6dsx_shub_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr) | ||
| 338 | { | ||
| 339 | const struct st_lsm6dsx_ext_dev_settings *settings; | ||
| 340 | u16 val; | ||
| 341 | int err; | ||
| 342 | |||
| 343 | err = st_lsm6dsx_shub_get_odr_val(sensor, odr, &val); | ||
| 344 | if (err < 0) | ||
| 345 | return err; | ||
| 346 | |||
| 347 | settings = sensor->ext_info.settings; | ||
| 348 | return st_lsm6dsx_shub_write_with_mask(sensor, | ||
| 349 | settings->odr_table.reg.addr, | ||
| 350 | settings->odr_table.reg.mask, | ||
| 351 | val); | ||
| 352 | } | ||
| 353 | |||
| 354 | /* use SLV{1,2,3} for FIFO read operations */ | ||
| 355 | static int | ||
| 356 | st_lsm6dsx_shub_config_channels(struct st_lsm6dsx_sensor *sensor, | ||
| 357 | bool enable) | ||
| 358 | { | ||
| 359 | const struct st_lsm6dsx_shub_settings *hub_settings; | ||
| 360 | const struct st_lsm6dsx_ext_dev_settings *settings; | ||
| 361 | u8 config[9] = {}, enable_mask, slv_addr; | ||
| 362 | struct st_lsm6dsx_hw *hw = sensor->hw; | ||
| 363 | struct st_lsm6dsx_sensor *cur_sensor; | ||
| 364 | int i, j = 0; | ||
| 365 | |||
| 366 | hub_settings = &hw->settings->shub_settings; | ||
| 367 | if (enable) | ||
| 368 | enable_mask = hw->enable_mask | BIT(sensor->id); | ||
| 369 | else | ||
| 370 | enable_mask = hw->enable_mask & ~BIT(sensor->id); | ||
| 371 | |||
| 372 | for (i = ST_LSM6DSX_ID_EXT0; i <= ST_LSM6DSX_ID_EXT2; i++) { | ||
| 373 | if (!hw->iio_devs[i]) | ||
| 374 | continue; | ||
| 375 | |||
| 376 | cur_sensor = iio_priv(hw->iio_devs[i]); | ||
| 377 | if (!(enable_mask & BIT(cur_sensor->id))) | ||
| 378 | continue; | ||
| 379 | |||
| 380 | settings = cur_sensor->ext_info.settings; | ||
| 381 | config[j] = (sensor->ext_info.addr << 1) | 1; | ||
| 382 | config[j + 1] = settings->out.addr; | ||
| 383 | config[j + 2] = (settings->out.len & ST_LS6DSX_READ_OP_MASK) | | ||
| 384 | hub_settings->batch_en; | ||
| 385 | j += 3; | ||
| 386 | } | ||
| 387 | |||
| 388 | slv_addr = ST_LSM6DSX_SLV_ADDR(1, hub_settings->slv0_addr); | ||
| 389 | return st_lsm6dsx_shub_write_reg(hw, slv_addr, config, | ||
| 390 | sizeof(config)); | ||
| 391 | } | ||
| 392 | |||
| 393 | int st_lsm6dsx_shub_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable) | ||
| 394 | { | ||
| 395 | const struct st_lsm6dsx_ext_dev_settings *settings; | ||
| 396 | int err; | ||
| 397 | |||
| 398 | err = st_lsm6dsx_shub_config_channels(sensor, enable); | ||
| 399 | if (err < 0) | ||
| 400 | return err; | ||
| 401 | |||
| 402 | settings = sensor->ext_info.settings; | ||
| 403 | if (enable) { | ||
| 404 | err = st_lsm6dsx_shub_set_odr(sensor, sensor->odr); | ||
| 405 | if (err < 0) | ||
| 406 | return err; | ||
| 407 | } else { | ||
| 408 | err = st_lsm6dsx_shub_write_with_mask(sensor, | ||
| 409 | settings->odr_table.reg.addr, | ||
| 410 | settings->odr_table.reg.mask, 0); | ||
| 411 | if (err < 0) | ||
| 412 | return err; | ||
| 413 | } | ||
| 414 | |||
| 415 | if (settings->pwr_table.reg.addr) { | ||
| 416 | u8 val; | ||
| 417 | |||
| 418 | val = enable ? settings->pwr_table.on_val | ||
| 419 | : settings->pwr_table.off_val; | ||
| 420 | err = st_lsm6dsx_shub_write_with_mask(sensor, | ||
| 421 | settings->pwr_table.reg.addr, | ||
| 422 | settings->pwr_table.reg.mask, val); | ||
| 423 | if (err < 0) | ||
| 424 | return err; | ||
| 425 | } | ||
| 426 | |||
| 427 | return st_lsm6dsx_shub_master_enable(sensor, enable); | ||
| 428 | } | ||
| 429 | |||
| 430 | static int | ||
| 431 | st_lsm6dsx_shub_read_oneshot(struct st_lsm6dsx_sensor *sensor, | ||
| 432 | struct iio_chan_spec const *ch, | ||
| 433 | int *val) | ||
| 434 | { | ||
| 435 | int err, delay, len = ch->scan_type.realbits >> 3; | ||
| 436 | __le16 data; | ||
| 437 | |||
| 438 | err = st_lsm6dsx_shub_set_enable(sensor, true); | ||
| 439 | if (err < 0) | ||
| 440 | return err; | ||
| 441 | |||
| 442 | delay = 1000000 / sensor->odr; | ||
| 443 | usleep_range(delay, 2 * delay); | ||
| 444 | |||
| 445 | err = st_lsm6dsx_shub_read(sensor, ch->address, (u8 *)&data, len); | ||
| 446 | if (err < 0) | ||
| 447 | return err; | ||
| 448 | |||
| 449 | st_lsm6dsx_shub_set_enable(sensor, false); | ||
| 450 | |||
| 451 | switch (len) { | ||
| 452 | case 2: | ||
| 453 | *val = (s16)le16_to_cpu(data); | ||
| 454 | break; | ||
| 455 | default: | ||
| 456 | return -EINVAL; | ||
| 457 | } | ||
| 458 | |||
| 459 | return IIO_VAL_INT; | ||
| 460 | } | ||
| 461 | |||
| 462 | static int | ||
| 463 | st_lsm6dsx_shub_read_raw(struct iio_dev *iio_dev, | ||
| 464 | struct iio_chan_spec const *ch, | ||
| 465 | int *val, int *val2, long mask) | ||
| 466 | { | ||
| 467 | struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); | ||
| 468 | int ret; | ||
| 469 | |||
| 470 | switch (mask) { | ||
| 471 | case IIO_CHAN_INFO_RAW: | ||
| 472 | ret = iio_device_claim_direct_mode(iio_dev); | ||
| 473 | if (ret) | ||
| 474 | break; | ||
| 475 | |||
| 476 | ret = st_lsm6dsx_shub_read_oneshot(sensor, ch, val); | ||
| 477 | iio_device_release_direct_mode(iio_dev); | ||
| 478 | break; | ||
| 479 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
| 480 | *val = sensor->odr; | ||
| 481 | ret = IIO_VAL_INT; | ||
| 482 | break; | ||
| 483 | case IIO_CHAN_INFO_SCALE: | ||
| 484 | *val = 0; | ||
| 485 | *val2 = sensor->gain; | ||
| 486 | ret = IIO_VAL_INT_PLUS_MICRO; | ||
| 487 | break; | ||
| 488 | default: | ||
| 489 | ret = -EINVAL; | ||
| 490 | break; | ||
| 491 | } | ||
| 492 | |||
| 493 | return ret; | ||
| 494 | } | ||
| 495 | |||
| 496 | static int | ||
| 497 | st_lsm6dsx_shub_write_raw(struct iio_dev *iio_dev, | ||
| 498 | struct iio_chan_spec const *chan, | ||
| 499 | int val, int val2, long mask) | ||
| 500 | { | ||
| 501 | struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); | ||
| 502 | int err; | ||
| 503 | |||
| 504 | err = iio_device_claim_direct_mode(iio_dev); | ||
| 505 | if (err) | ||
| 506 | return err; | ||
| 507 | |||
| 508 | switch (mask) { | ||
| 509 | case IIO_CHAN_INFO_SAMP_FREQ: { | ||
| 510 | u16 data; | ||
| 511 | |||
| 512 | err = st_lsm6dsx_shub_get_odr_val(sensor, val, &data); | ||
| 513 | if (!err) | ||
| 514 | sensor->odr = val; | ||
| 515 | break; | ||
| 516 | } | ||
| 517 | default: | ||
| 518 | err = -EINVAL; | ||
| 519 | break; | ||
| 520 | } | ||
| 521 | |||
| 522 | iio_device_release_direct_mode(iio_dev); | ||
| 523 | |||
| 524 | return err; | ||
| 525 | } | ||
| 526 | |||
| 527 | static ssize_t | ||
| 528 | st_lsm6dsx_shub_sampling_freq_avail(struct device *dev, | ||
| 529 | struct device_attribute *attr, | ||
| 530 | char *buf) | ||
| 531 | { | ||
| 532 | struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); | ||
| 533 | const struct st_lsm6dsx_ext_dev_settings *settings; | ||
| 534 | int i, len = 0; | ||
| 535 | |||
| 536 | settings = sensor->ext_info.settings; | ||
| 537 | for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) { | ||
| 538 | u16 val = settings->odr_table.odr_avl[i].hz; | ||
| 539 | |||
| 540 | if (val > 0) | ||
| 541 | len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", | ||
| 542 | val); | ||
| 543 | } | ||
| 544 | buf[len - 1] = '\n'; | ||
| 545 | |||
| 546 | return len; | ||
| 547 | } | ||
| 548 | |||
| 549 | static ssize_t st_lsm6dsx_shub_scale_avail(struct device *dev, | ||
| 550 | struct device_attribute *attr, | ||
| 551 | char *buf) | ||
| 552 | { | ||
| 553 | struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); | ||
| 554 | const struct st_lsm6dsx_ext_dev_settings *settings; | ||
| 555 | int i, len = 0; | ||
| 556 | |||
| 557 | settings = sensor->ext_info.settings; | ||
| 558 | for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) { | ||
| 559 | u16 val = settings->fs_table.fs_avl[i].gain; | ||
| 560 | |||
| 561 | if (val > 0) | ||
| 562 | len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", | ||
| 563 | val); | ||
| 564 | } | ||
| 565 | buf[len - 1] = '\n'; | ||
| 566 | |||
| 567 | return len; | ||
| 568 | } | ||
| 569 | |||
| 570 | static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_shub_sampling_freq_avail); | ||
| 571 | static IIO_DEVICE_ATTR(in_scale_available, 0444, | ||
| 572 | st_lsm6dsx_shub_scale_avail, NULL, 0); | ||
| 573 | static struct attribute *st_lsm6dsx_ext_attributes[] = { | ||
| 574 | &iio_dev_attr_sampling_frequency_available.dev_attr.attr, | ||
| 575 | &iio_dev_attr_in_scale_available.dev_attr.attr, | ||
| 576 | NULL, | ||
| 577 | }; | ||
| 578 | |||
| 579 | static const struct attribute_group st_lsm6dsx_ext_attribute_group = { | ||
| 580 | .attrs = st_lsm6dsx_ext_attributes, | ||
| 581 | }; | ||
| 582 | |||
| 583 | static const struct iio_info st_lsm6dsx_ext_info = { | ||
| 584 | .attrs = &st_lsm6dsx_ext_attribute_group, | ||
| 585 | .read_raw = st_lsm6dsx_shub_read_raw, | ||
| 586 | .write_raw = st_lsm6dsx_shub_write_raw, | ||
| 587 | .hwfifo_set_watermark = st_lsm6dsx_set_watermark, | ||
| 588 | }; | ||
| 589 | |||
| 590 | static struct iio_dev * | ||
| 591 | st_lsm6dsx_shub_alloc_iiodev(struct st_lsm6dsx_hw *hw, | ||
| 592 | enum st_lsm6dsx_sensor_id id, | ||
| 593 | const struct st_lsm6dsx_ext_dev_settings *info, | ||
| 594 | u8 i2c_addr, const char *name) | ||
| 595 | { | ||
| 596 | struct iio_chan_spec *ext_channels; | ||
| 597 | struct st_lsm6dsx_sensor *sensor; | ||
| 598 | struct iio_dev *iio_dev; | ||
| 599 | |||
| 600 | iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor)); | ||
| 601 | if (!iio_dev) | ||
| 602 | return NULL; | ||
| 603 | |||
| 604 | iio_dev->modes = INDIO_DIRECT_MODE; | ||
| 605 | iio_dev->dev.parent = hw->dev; | ||
| 606 | iio_dev->info = &st_lsm6dsx_ext_info; | ||
| 607 | |||
| 608 | sensor = iio_priv(iio_dev); | ||
| 609 | sensor->id = id; | ||
| 610 | sensor->hw = hw; | ||
| 611 | sensor->odr = info->odr_table.odr_avl[0].hz; | ||
| 612 | sensor->gain = info->fs_table.fs_avl[0].gain; | ||
| 613 | sensor->ext_info.settings = info; | ||
| 614 | sensor->ext_info.addr = i2c_addr; | ||
| 615 | sensor->watermark = 1; | ||
| 616 | |||
| 617 | switch (info->id) { | ||
| 618 | case ST_LSM6DSX_ID_MAGN: { | ||
| 619 | const struct iio_chan_spec magn_channels[] = { | ||
| 620 | ST_LSM6DSX_CHANNEL(IIO_MAGN, info->out.addr, | ||
| 621 | IIO_MOD_X, 0), | ||
| 622 | ST_LSM6DSX_CHANNEL(IIO_MAGN, info->out.addr + 2, | ||
| 623 | IIO_MOD_Y, 1), | ||
| 624 | ST_LSM6DSX_CHANNEL(IIO_MAGN, info->out.addr + 4, | ||
| 625 | IIO_MOD_Z, 2), | ||
| 626 | IIO_CHAN_SOFT_TIMESTAMP(3), | ||
| 627 | }; | ||
| 628 | |||
| 629 | ext_channels = devm_kzalloc(hw->dev, sizeof(magn_channels), | ||
| 630 | GFP_KERNEL); | ||
| 631 | if (!ext_channels) | ||
| 632 | return NULL; | ||
| 633 | |||
| 634 | memcpy(ext_channels, magn_channels, sizeof(magn_channels)); | ||
| 635 | iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks; | ||
| 636 | iio_dev->channels = ext_channels; | ||
| 637 | iio_dev->num_channels = ARRAY_SIZE(magn_channels); | ||
| 638 | |||
| 639 | scnprintf(sensor->name, sizeof(sensor->name), "%s_magn", | ||
| 640 | name); | ||
| 641 | break; | ||
| 642 | } | ||
| 643 | default: | ||
| 644 | return NULL; | ||
| 645 | } | ||
| 646 | iio_dev->name = sensor->name; | ||
| 647 | |||
| 648 | return iio_dev; | ||
| 649 | } | ||
| 650 | |||
| 651 | static int st_lsm6dsx_shub_init_device(struct st_lsm6dsx_sensor *sensor) | ||
| 652 | { | ||
| 653 | const struct st_lsm6dsx_ext_dev_settings *settings; | ||
| 654 | int err; | ||
| 655 | |||
| 656 | settings = sensor->ext_info.settings; | ||
| 657 | if (settings->bdu.addr) { | ||
| 658 | err = st_lsm6dsx_shub_write_with_mask(sensor, | ||
| 659 | settings->bdu.addr, | ||
| 660 | settings->bdu.mask, 1); | ||
| 661 | if (err < 0) | ||
| 662 | return err; | ||
| 663 | } | ||
| 664 | |||
| 665 | if (settings->temp_comp.addr) { | ||
| 666 | err = st_lsm6dsx_shub_write_with_mask(sensor, | ||
| 667 | settings->temp_comp.addr, | ||
| 668 | settings->temp_comp.mask, 1); | ||
| 669 | if (err < 0) | ||
| 670 | return err; | ||
| 671 | } | ||
| 672 | |||
| 673 | if (settings->off_canc.addr) { | ||
| 674 | err = st_lsm6dsx_shub_write_with_mask(sensor, | ||
| 675 | settings->off_canc.addr, | ||
| 676 | settings->off_canc.mask, 1); | ||
| 677 | if (err < 0) | ||
| 678 | return err; | ||
| 679 | } | ||
| 680 | |||
| 681 | return 0; | ||
| 682 | } | ||
| 683 | |||
| 684 | static int | ||
| 685 | st_lsm6dsx_shub_check_wai(struct st_lsm6dsx_hw *hw, u8 *i2c_addr, | ||
| 686 | const struct st_lsm6dsx_ext_dev_settings *settings) | ||
| 687 | { | ||
| 688 | const struct st_lsm6dsx_shub_settings *hub_settings; | ||
| 689 | struct st_lsm6dsx_sensor *sensor; | ||
| 690 | u8 config[3], data, slv_addr; | ||
| 691 | bool found = false; | ||
| 692 | int i, err; | ||
| 693 | |||
| 694 | hub_settings = &hw->settings->shub_settings; | ||
| 695 | slv_addr = ST_LSM6DSX_SLV_ADDR(0, hub_settings->slv0_addr); | ||
| 696 | sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); | ||
| 697 | |||
| 698 | for (i = 0; i < ARRAY_SIZE(settings->i2c_addr); i++) { | ||
| 699 | if (!settings->i2c_addr[i]) | ||
| 700 | continue; | ||
| 701 | |||
| 702 | /* read wai slave register */ | ||
| 703 | config[0] = (settings->i2c_addr[i] << 1) | 0x1; | ||
| 704 | config[1] = settings->wai.addr; | ||
| 705 | config[2] = 0x1; | ||
| 706 | |||
| 707 | err = st_lsm6dsx_shub_write_reg(hw, slv_addr, config, | ||
| 708 | sizeof(config)); | ||
| 709 | if (err < 0) | ||
| 710 | return err; | ||
| 711 | |||
| 712 | err = st_lsm6dsx_shub_master_enable(sensor, true); | ||
| 713 | if (err < 0) | ||
| 714 | return err; | ||
| 715 | |||
| 716 | st_lsm6dsx_shub_wait_complete(hw); | ||
| 717 | |||
| 718 | err = st_lsm6dsx_shub_read_reg(hw, | ||
| 719 | hub_settings->shub_out, | ||
| 720 | &data, sizeof(data)); | ||
| 721 | |||
| 722 | st_lsm6dsx_shub_master_enable(sensor, false); | ||
| 723 | |||
| 724 | if (err < 0) | ||
| 725 | return err; | ||
| 726 | |||
| 727 | if (data != settings->wai.val) | ||
| 728 | continue; | ||
| 729 | |||
| 730 | *i2c_addr = settings->i2c_addr[i]; | ||
| 731 | found = true; | ||
| 732 | break; | ||
| 733 | } | ||
| 734 | |||
| 735 | /* reset SLV0 channel */ | ||
| 736 | memset(config, 0, sizeof(config)); | ||
| 737 | err = st_lsm6dsx_shub_write_reg(hw, slv_addr, config, | ||
| 738 | sizeof(config)); | ||
| 739 | if (err < 0) | ||
| 740 | return err; | ||
| 741 | |||
| 742 | return found ? 0 : -ENODEV; | ||
| 743 | } | ||
| 744 | |||
| 745 | int st_lsm6dsx_shub_probe(struct st_lsm6dsx_hw *hw, const char *name) | ||
| 746 | { | ||
| 747 | enum st_lsm6dsx_sensor_id id = ST_LSM6DSX_ID_EXT0; | ||
| 748 | struct st_lsm6dsx_sensor *sensor; | ||
| 749 | int err, i, num_ext_dev = 0; | ||
| 750 | u8 i2c_addr = 0; | ||
| 751 | |||
| 752 | for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_ext_dev_table); i++) { | ||
| 753 | err = st_lsm6dsx_shub_check_wai(hw, &i2c_addr, | ||
| 754 | &st_lsm6dsx_ext_dev_table[i]); | ||
| 755 | if (err == -ENODEV) | ||
| 756 | continue; | ||
| 757 | else if (err < 0) | ||
| 758 | return err; | ||
| 759 | |||
| 760 | hw->iio_devs[id] = st_lsm6dsx_shub_alloc_iiodev(hw, id, | ||
| 761 | &st_lsm6dsx_ext_dev_table[i], | ||
| 762 | i2c_addr, name); | ||
| 763 | if (!hw->iio_devs[id]) | ||
| 764 | return -ENOMEM; | ||
| 765 | |||
| 766 | sensor = iio_priv(hw->iio_devs[id]); | ||
| 767 | err = st_lsm6dsx_shub_init_device(sensor); | ||
| 768 | if (err < 0) | ||
| 769 | return err; | ||
| 770 | |||
| 771 | if (++num_ext_dev >= ST_LSM6DSX_MAX_SLV_NUM) | ||
| 772 | break; | ||
| 773 | id++; | ||
| 774 | } | ||
| 775 | |||
| 776 | return 0; | ||
| 777 | } | ||
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index d66ea754ffff..36f458433480 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig | |||
| @@ -460,6 +460,19 @@ config VCNL4000 | |||
| 460 | To compile this driver as a module, choose M here: the | 460 | To compile this driver as a module, choose M here: the |
| 461 | module will be called vcnl4000. | 461 | module will be called vcnl4000. |
| 462 | 462 | ||
| 463 | config VCNL4035 | ||
| 464 | tristate "VCNL4035 combined ALS and proximity sensor" | ||
| 465 | select IIO_TRIGGERED_BUFFER | ||
| 466 | select REGMAP_I2C | ||
| 467 | depends on I2C | ||
| 468 | help | ||
| 469 | Say Y here if you want to build a driver for the Vishay VCNL4035, | ||
| 470 | combined ambient light (ALS) and proximity sensor. Currently only ALS | ||
| 471 | function is available. | ||
| 472 | |||
| 473 | To compile this driver as a module, choose M here: the | ||
| 474 | module will be called vcnl4035. | ||
| 475 | |||
| 463 | config VEML6070 | 476 | config VEML6070 |
| 464 | tristate "VEML6070 UV A light sensor" | 477 | tristate "VEML6070 UV A light sensor" |
| 465 | depends on I2C | 478 | depends on I2C |
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index 86337b114bc4..286bf3975372 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile | |||
| @@ -45,6 +45,7 @@ obj-$(CONFIG_TSL2772) += tsl2772.o | |||
| 45 | obj-$(CONFIG_TSL4531) += tsl4531.o | 45 | obj-$(CONFIG_TSL4531) += tsl4531.o |
| 46 | obj-$(CONFIG_US5182D) += us5182d.o | 46 | obj-$(CONFIG_US5182D) += us5182d.o |
| 47 | obj-$(CONFIG_VCNL4000) += vcnl4000.o | 47 | obj-$(CONFIG_VCNL4000) += vcnl4000.o |
| 48 | obj-$(CONFIG_VCNL4035) += vcnl4035.o | ||
| 48 | obj-$(CONFIG_VEML6070) += veml6070.o | 49 | obj-$(CONFIG_VEML6070) += veml6070.o |
| 49 | obj-$(CONFIG_VL6180) += vl6180.o | 50 | obj-$(CONFIG_VL6180) += vl6180.o |
| 50 | obj-$(CONFIG_ZOPT2201) += zopt2201.o | 51 | obj-$(CONFIG_ZOPT2201) += zopt2201.o |
diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c new file mode 100644 index 000000000000..cca4db312bd3 --- /dev/null +++ b/drivers/iio/light/vcnl4035.c | |||
| @@ -0,0 +1,676 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * VCNL4035 Ambient Light and Proximity Sensor - 7-bit I2C slave address 0x60 | ||
| 4 | * | ||
| 5 | * Copyright (c) 2018, DENX Software Engineering GmbH | ||
| 6 | * Author: Parthiban Nallathambi <pn@denx.de> | ||
| 7 | * | ||
| 8 | * TODO: Proximity | ||
| 9 | */ | ||
| 10 | #include <linux/bitops.h> | ||
| 11 | #include <linux/i2c.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/pm_runtime.h> | ||
| 14 | #include <linux/regmap.h> | ||
| 15 | |||
| 16 | #include <linux/iio/buffer.h> | ||
| 17 | #include <linux/iio/events.h> | ||
| 18 | #include <linux/iio/iio.h> | ||
| 19 | #include <linux/iio/sysfs.h> | ||
| 20 | #include <linux/iio/trigger.h> | ||
| 21 | #include <linux/iio/trigger_consumer.h> | ||
| 22 | #include <linux/iio/triggered_buffer.h> | ||
| 23 | |||
| 24 | #define VCNL4035_DRV_NAME "vcnl4035" | ||
| 25 | #define VCNL4035_IRQ_NAME "vcnl4035_event" | ||
| 26 | #define VCNL4035_REGMAP_NAME "vcnl4035_regmap" | ||
| 27 | |||
| 28 | /* Device registers */ | ||
| 29 | #define VCNL4035_ALS_CONF 0x00 | ||
| 30 | #define VCNL4035_ALS_THDH 0x01 | ||
| 31 | #define VCNL4035_ALS_THDL 0x02 | ||
| 32 | #define VCNL4035_ALS_DATA 0x0B | ||
| 33 | #define VCNL4035_WHITE_DATA 0x0C | ||
| 34 | #define VCNL4035_INT_FLAG 0x0D | ||
| 35 | #define VCNL4035_DEV_ID 0x0E | ||
| 36 | |||
| 37 | /* Register masks */ | ||
| 38 | #define VCNL4035_MODE_ALS_MASK BIT(0) | ||
| 39 | #define VCNL4035_MODE_ALS_WHITE_CHAN BIT(8) | ||
| 40 | #define VCNL4035_MODE_ALS_INT_MASK BIT(1) | ||
| 41 | #define VCNL4035_ALS_IT_MASK GENMASK(7, 5) | ||
| 42 | #define VCNL4035_ALS_PERS_MASK GENMASK(3, 2) | ||
| 43 | #define VCNL4035_INT_ALS_IF_H_MASK BIT(12) | ||
| 44 | #define VCNL4035_INT_ALS_IF_L_MASK BIT(13) | ||
| 45 | |||
| 46 | /* Default values */ | ||
| 47 | #define VCNL4035_MODE_ALS_ENABLE BIT(0) | ||
| 48 | #define VCNL4035_MODE_ALS_DISABLE 0x00 | ||
| 49 | #define VCNL4035_MODE_ALS_INT_ENABLE BIT(1) | ||
| 50 | #define VCNL4035_MODE_ALS_INT_DISABLE 0 | ||
| 51 | #define VCNL4035_DEV_ID_VAL 0x80 | ||
| 52 | #define VCNL4035_ALS_IT_DEFAULT 0x01 | ||
| 53 | #define VCNL4035_ALS_PERS_DEFAULT 0x00 | ||
| 54 | #define VCNL4035_ALS_THDH_DEFAULT 5000 | ||
| 55 | #define VCNL4035_ALS_THDL_DEFAULT 100 | ||
| 56 | #define VCNL4035_SLEEP_DELAY_MS 2000 | ||
| 57 | |||
| 58 | struct vcnl4035_data { | ||
| 59 | struct i2c_client *client; | ||
| 60 | struct regmap *regmap; | ||
| 61 | unsigned int als_it_val; | ||
| 62 | unsigned int als_persistence; | ||
| 63 | unsigned int als_thresh_low; | ||
| 64 | unsigned int als_thresh_high; | ||
| 65 | struct iio_trigger *drdy_trigger0; | ||
| 66 | }; | ||
| 67 | |||
| 68 | static inline bool vcnl4035_is_triggered(struct vcnl4035_data *data) | ||
| 69 | { | ||
| 70 | int ret; | ||
| 71 | int reg; | ||
| 72 | |||
| 73 | ret = regmap_read(data->regmap, VCNL4035_INT_FLAG, ®); | ||
| 74 | if (ret < 0) | ||
| 75 | return false; | ||
| 76 | |||
| 77 | return !!(reg & | ||
| 78 | (VCNL4035_INT_ALS_IF_H_MASK | VCNL4035_INT_ALS_IF_L_MASK)); | ||
| 79 | } | ||
| 80 | |||
| 81 | static irqreturn_t vcnl4035_drdy_irq_thread(int irq, void *private) | ||
| 82 | { | ||
| 83 | struct iio_dev *indio_dev = private; | ||
| 84 | struct vcnl4035_data *data = iio_priv(indio_dev); | ||
| 85 | |||
| 86 | if (vcnl4035_is_triggered(data)) { | ||
| 87 | iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_LIGHT, | ||
| 88 | 0, | ||
| 89 | IIO_EV_TYPE_THRESH, | ||
| 90 | IIO_EV_DIR_EITHER), | ||
| 91 | iio_get_time_ns(indio_dev)); | ||
| 92 | iio_trigger_poll_chained(data->drdy_trigger0); | ||
| 93 | return IRQ_HANDLED; | ||
| 94 | } | ||
| 95 | |||
| 96 | return IRQ_NONE; | ||
| 97 | } | ||
| 98 | |||
| 99 | /* Triggered buffer */ | ||
| 100 | static irqreturn_t vcnl4035_trigger_consumer_handler(int irq, void *p) | ||
| 101 | { | ||
| 102 | struct iio_poll_func *pf = p; | ||
| 103 | struct iio_dev *indio_dev = pf->indio_dev; | ||
| 104 | struct vcnl4035_data *data = iio_priv(indio_dev); | ||
| 105 | u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)]; | ||
| 106 | int ret; | ||
| 107 | |||
| 108 | ret = regmap_read(data->regmap, VCNL4035_ALS_DATA, (int *)buffer); | ||
| 109 | if (ret < 0) { | ||
| 110 | dev_err(&data->client->dev, | ||
| 111 | "Trigger consumer can't read from sensor.\n"); | ||
| 112 | goto fail_read; | ||
| 113 | } | ||
| 114 | iio_push_to_buffers_with_timestamp(indio_dev, buffer, | ||
| 115 | iio_get_time_ns(indio_dev)); | ||
| 116 | |||
| 117 | fail_read: | ||
| 118 | iio_trigger_notify_done(indio_dev->trig); | ||
| 119 | |||
| 120 | return IRQ_HANDLED; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int vcnl4035_als_drdy_set_state(struct iio_trigger *trigger, | ||
| 124 | bool enable_drdy) | ||
| 125 | { | ||
| 126 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trigger); | ||
| 127 | struct vcnl4035_data *data = iio_priv(indio_dev); | ||
| 128 | int val = enable_drdy ? VCNL4035_MODE_ALS_INT_ENABLE : | ||
| 129 | VCNL4035_MODE_ALS_INT_DISABLE; | ||
| 130 | |||
| 131 | return regmap_update_bits(data->regmap, VCNL4035_ALS_CONF, | ||
| 132 | VCNL4035_MODE_ALS_INT_MASK, | ||
| 133 | val); | ||
| 134 | } | ||
| 135 | |||
| 136 | static const struct iio_trigger_ops vcnl4035_trigger_ops = { | ||
| 137 | .validate_device = iio_trigger_validate_own_device, | ||
| 138 | .set_trigger_state = vcnl4035_als_drdy_set_state, | ||
| 139 | }; | ||
| 140 | |||
| 141 | static int vcnl4035_set_pm_runtime_state(struct vcnl4035_data *data, bool on) | ||
| 142 | { | ||
| 143 | int ret; | ||
| 144 | struct device *dev = &data->client->dev; | ||
| 145 | |||
| 146 | if (on) { | ||
| 147 | ret = pm_runtime_get_sync(dev); | ||
| 148 | if (ret < 0) | ||
| 149 | pm_runtime_put_noidle(dev); | ||
| 150 | } else { | ||
| 151 | pm_runtime_mark_last_busy(dev); | ||
| 152 | ret = pm_runtime_put_autosuspend(dev); | ||
| 153 | } | ||
| 154 | |||
| 155 | return ret; | ||
| 156 | } | ||
| 157 | |||
| 158 | /* | ||
| 159 | * Device IT INT Time (ms) Scale (lux/step) | ||
| 160 | * 000 50 0.064 | ||
| 161 | * 001 100 0.032 | ||
| 162 | * 010 200 0.016 | ||
| 163 | * 100 400 0.008 | ||
| 164 | * 101 - 111 800 0.004 | ||
| 165 | * Values are proportional, so ALS INT is selected for input due to | ||
| 166 | * simplicity reason. Integration time value and scaling is | ||
| 167 | * calculated based on device INT value | ||
| 168 | * | ||
| 169 | * Raw value needs to be scaled using ALS steps | ||
| 170 | */ | ||
| 171 | static int vcnl4035_read_raw(struct iio_dev *indio_dev, | ||
| 172 | struct iio_chan_spec const *chan, int *val, | ||
| 173 | int *val2, long mask) | ||
| 174 | { | ||
| 175 | struct vcnl4035_data *data = iio_priv(indio_dev); | ||
| 176 | int ret; | ||
| 177 | int raw_data; | ||
| 178 | unsigned int reg; | ||
| 179 | |||
| 180 | switch (mask) { | ||
| 181 | case IIO_CHAN_INFO_RAW: | ||
| 182 | ret = vcnl4035_set_pm_runtime_state(data, true); | ||
| 183 | if (ret < 0) | ||
| 184 | return ret; | ||
| 185 | |||
| 186 | ret = iio_device_claim_direct_mode(indio_dev); | ||
| 187 | if (!ret) { | ||
| 188 | if (chan->channel) | ||
| 189 | reg = VCNL4035_ALS_DATA; | ||
| 190 | else | ||
| 191 | reg = VCNL4035_WHITE_DATA; | ||
| 192 | ret = regmap_read(data->regmap, reg, &raw_data); | ||
| 193 | iio_device_release_direct_mode(indio_dev); | ||
| 194 | if (!ret) { | ||
| 195 | *val = raw_data; | ||
| 196 | ret = IIO_VAL_INT; | ||
| 197 | } | ||
| 198 | } | ||
| 199 | vcnl4035_set_pm_runtime_state(data, false); | ||
| 200 | return ret; | ||
| 201 | case IIO_CHAN_INFO_INT_TIME: | ||
| 202 | *val = 50; | ||
| 203 | if (data->als_it_val) | ||
| 204 | *val = data->als_it_val * 100; | ||
| 205 | return IIO_VAL_INT; | ||
| 206 | case IIO_CHAN_INFO_SCALE: | ||
| 207 | *val = 64; | ||
| 208 | if (!data->als_it_val) | ||
| 209 | *val2 = 1000; | ||
| 210 | else | ||
| 211 | *val2 = data->als_it_val * 2 * 1000; | ||
| 212 | return IIO_VAL_FRACTIONAL; | ||
| 213 | default: | ||
| 214 | return -EINVAL; | ||
| 215 | } | ||
| 216 | } | ||
| 217 | |||
| 218 | static int vcnl4035_write_raw(struct iio_dev *indio_dev, | ||
| 219 | struct iio_chan_spec const *chan, | ||
| 220 | int val, int val2, long mask) | ||
| 221 | { | ||
| 222 | int ret; | ||
| 223 | struct vcnl4035_data *data = iio_priv(indio_dev); | ||
| 224 | |||
| 225 | switch (mask) { | ||
| 226 | case IIO_CHAN_INFO_INT_TIME: | ||
| 227 | if (val <= 0 || val > 800) | ||
| 228 | return -EINVAL; | ||
| 229 | |||
| 230 | ret = vcnl4035_set_pm_runtime_state(data, true); | ||
| 231 | if (ret < 0) | ||
| 232 | return ret; | ||
| 233 | |||
| 234 | ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF, | ||
| 235 | VCNL4035_ALS_IT_MASK, | ||
| 236 | val / 100); | ||
| 237 | if (!ret) | ||
| 238 | data->als_it_val = val / 100; | ||
| 239 | |||
| 240 | vcnl4035_set_pm_runtime_state(data, false); | ||
| 241 | return ret; | ||
| 242 | default: | ||
| 243 | return -EINVAL; | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | /* No direct ABI for persistence and threshold, so eventing */ | ||
| 248 | static int vcnl4035_read_thresh(struct iio_dev *indio_dev, | ||
| 249 | const struct iio_chan_spec *chan, enum iio_event_type type, | ||
| 250 | enum iio_event_direction dir, enum iio_event_info info, | ||
| 251 | int *val, int *val2) | ||
| 252 | { | ||
| 253 | struct vcnl4035_data *data = iio_priv(indio_dev); | ||
| 254 | |||
| 255 | switch (info) { | ||
| 256 | case IIO_EV_INFO_VALUE: | ||
| 257 | switch (dir) { | ||
| 258 | case IIO_EV_DIR_RISING: | ||
| 259 | *val = data->als_thresh_high; | ||
| 260 | return IIO_VAL_INT; | ||
| 261 | case IIO_EV_DIR_FALLING: | ||
| 262 | *val = data->als_thresh_low; | ||
| 263 | return IIO_VAL_INT; | ||
| 264 | default: | ||
| 265 | return -EINVAL; | ||
| 266 | } | ||
| 267 | break; | ||
| 268 | case IIO_EV_INFO_PERIOD: | ||
| 269 | *val = data->als_persistence; | ||
| 270 | return IIO_VAL_INT; | ||
| 271 | default: | ||
| 272 | return -EINVAL; | ||
| 273 | } | ||
| 274 | |||
| 275 | } | ||
| 276 | |||
| 277 | static int vcnl4035_write_thresh(struct iio_dev *indio_dev, | ||
| 278 | const struct iio_chan_spec *chan, enum iio_event_type type, | ||
| 279 | enum iio_event_direction dir, enum iio_event_info info, int val, | ||
| 280 | int val2) | ||
| 281 | { | ||
| 282 | struct vcnl4035_data *data = iio_priv(indio_dev); | ||
| 283 | int ret; | ||
| 284 | |||
| 285 | switch (info) { | ||
| 286 | case IIO_EV_INFO_VALUE: | ||
| 287 | /* 16 bit threshold range 0 - 65535 */ | ||
| 288 | if (val < 0 || val > 65535) | ||
| 289 | return -EINVAL; | ||
| 290 | if (dir == IIO_EV_DIR_RISING) { | ||
| 291 | if (val < data->als_thresh_low) | ||
| 292 | return -EINVAL; | ||
| 293 | ret = regmap_write(data->regmap, VCNL4035_ALS_THDH, | ||
| 294 | val); | ||
| 295 | if (ret) | ||
| 296 | return ret; | ||
| 297 | data->als_thresh_high = val; | ||
| 298 | } else { | ||
| 299 | if (val > data->als_thresh_high) | ||
| 300 | return -EINVAL; | ||
| 301 | ret = regmap_write(data->regmap, VCNL4035_ALS_THDL, | ||
| 302 | val); | ||
| 303 | if (ret) | ||
| 304 | return ret; | ||
| 305 | data->als_thresh_low = val; | ||
| 306 | } | ||
| 307 | return ret; | ||
| 308 | case IIO_EV_INFO_PERIOD: | ||
| 309 | /* allow only 1 2 4 8 as persistence value */ | ||
| 310 | if (val < 0 || val > 8 || hweight8(val) != 1) | ||
| 311 | return -EINVAL; | ||
| 312 | ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF, | ||
| 313 | VCNL4035_ALS_PERS_MASK, val); | ||
| 314 | if (!ret) | ||
| 315 | data->als_persistence = val; | ||
| 316 | return ret; | ||
| 317 | default: | ||
| 318 | return -EINVAL; | ||
| 319 | } | ||
| 320 | } | ||
| 321 | |||
| 322 | static IIO_CONST_ATTR_INT_TIME_AVAIL("50 100 200 400 800"); | ||
| 323 | |||
| 324 | static struct attribute *vcnl4035_attributes[] = { | ||
| 325 | &iio_const_attr_integration_time_available.dev_attr.attr, | ||
| 326 | NULL, | ||
| 327 | }; | ||
| 328 | |||
| 329 | static const struct attribute_group vcnl4035_attribute_group = { | ||
| 330 | .attrs = vcnl4035_attributes, | ||
| 331 | }; | ||
| 332 | |||
| 333 | static const struct iio_info vcnl4035_info = { | ||
| 334 | .read_raw = vcnl4035_read_raw, | ||
| 335 | .write_raw = vcnl4035_write_raw, | ||
| 336 | .read_event_value = vcnl4035_read_thresh, | ||
| 337 | .write_event_value = vcnl4035_write_thresh, | ||
| 338 | .attrs = &vcnl4035_attribute_group, | ||
| 339 | }; | ||
| 340 | |||
| 341 | static const struct iio_event_spec vcnl4035_event_spec[] = { | ||
| 342 | { | ||
| 343 | .type = IIO_EV_TYPE_THRESH, | ||
| 344 | .dir = IIO_EV_DIR_RISING, | ||
| 345 | .mask_separate = BIT(IIO_EV_INFO_VALUE), | ||
| 346 | }, { | ||
| 347 | .type = IIO_EV_TYPE_THRESH, | ||
| 348 | .dir = IIO_EV_DIR_FALLING, | ||
| 349 | .mask_separate = BIT(IIO_EV_INFO_VALUE), | ||
| 350 | }, { | ||
| 351 | .type = IIO_EV_TYPE_THRESH, | ||
| 352 | .dir = IIO_EV_DIR_EITHER, | ||
| 353 | .mask_separate = BIT(IIO_EV_INFO_PERIOD), | ||
| 354 | }, | ||
| 355 | }; | ||
| 356 | |||
| 357 | enum vcnl4035_scan_index_order { | ||
| 358 | VCNL4035_CHAN_INDEX_LIGHT, | ||
| 359 | VCNL4035_CHAN_INDEX_WHITE_LED, | ||
| 360 | }; | ||
| 361 | |||
| 362 | static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { | ||
| 363 | .validate_scan_mask = &iio_validate_scan_mask_onehot, | ||
| 364 | }; | ||
| 365 | |||
| 366 | static const struct iio_chan_spec vcnl4035_channels[] = { | ||
| 367 | { | ||
| 368 | .type = IIO_LIGHT, | ||
| 369 | .channel = 0, | ||
| 370 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | | ||
| 371 | BIT(IIO_CHAN_INFO_INT_TIME) | | ||
| 372 | BIT(IIO_CHAN_INFO_SCALE), | ||
| 373 | .event_spec = vcnl4035_event_spec, | ||
| 374 | .num_event_specs = ARRAY_SIZE(vcnl4035_event_spec), | ||
| 375 | .scan_index = VCNL4035_CHAN_INDEX_LIGHT, | ||
| 376 | .scan_type = { | ||
| 377 | .sign = 'u', | ||
| 378 | .realbits = 16, | ||
| 379 | .storagebits = 16, | ||
| 380 | .endianness = IIO_LE, | ||
| 381 | }, | ||
| 382 | }, | ||
| 383 | { | ||
| 384 | .type = IIO_INTENSITY, | ||
| 385 | .channel = 1, | ||
| 386 | .modified = 1, | ||
| 387 | .channel2 = IIO_MOD_LIGHT_BOTH, | ||
| 388 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | ||
| 389 | .scan_index = VCNL4035_CHAN_INDEX_WHITE_LED, | ||
| 390 | .scan_type = { | ||
| 391 | .sign = 'u', | ||
| 392 | .realbits = 16, | ||
| 393 | .storagebits = 16, | ||
| 394 | .endianness = IIO_LE, | ||
| 395 | }, | ||
| 396 | }, | ||
| 397 | }; | ||
| 398 | |||
| 399 | static int vcnl4035_set_als_power_state(struct vcnl4035_data *data, u8 status) | ||
| 400 | { | ||
| 401 | return regmap_update_bits(data->regmap, VCNL4035_ALS_CONF, | ||
| 402 | VCNL4035_MODE_ALS_MASK, | ||
| 403 | status); | ||
| 404 | } | ||
| 405 | |||
| 406 | static int vcnl4035_init(struct vcnl4035_data *data) | ||
| 407 | { | ||
| 408 | int ret; | ||
| 409 | int id; | ||
| 410 | |||
| 411 | ret = regmap_read(data->regmap, VCNL4035_DEV_ID, &id); | ||
| 412 | if (ret < 0) { | ||
| 413 | dev_err(&data->client->dev, "Failed to read DEV_ID register\n"); | ||
| 414 | return ret; | ||
| 415 | } | ||
| 416 | |||
| 417 | if (id != VCNL4035_DEV_ID_VAL) { | ||
| 418 | dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n", | ||
| 419 | id, VCNL4035_DEV_ID_VAL); | ||
| 420 | return -ENODEV; | ||
| 421 | } | ||
| 422 | |||
| 423 | ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_ENABLE); | ||
| 424 | if (ret < 0) | ||
| 425 | return ret; | ||
| 426 | |||
| 427 | /* ALS white channel enable */ | ||
| 428 | ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF, | ||
| 429 | VCNL4035_MODE_ALS_WHITE_CHAN, | ||
| 430 | 1); | ||
| 431 | if (ret) { | ||
| 432 | dev_err(&data->client->dev, "set white channel enable %d\n", | ||
| 433 | ret); | ||
| 434 | return ret; | ||
| 435 | } | ||
| 436 | |||
| 437 | /* set default integration time - 100 ms for ALS */ | ||
| 438 | ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF, | ||
| 439 | VCNL4035_ALS_IT_MASK, | ||
| 440 | VCNL4035_ALS_IT_DEFAULT); | ||
| 441 | if (ret) { | ||
| 442 | dev_err(&data->client->dev, "set default ALS IT returned %d\n", | ||
| 443 | ret); | ||
| 444 | return ret; | ||
| 445 | } | ||
| 446 | data->als_it_val = VCNL4035_ALS_IT_DEFAULT; | ||
| 447 | |||
| 448 | /* set default persistence time - 1 for ALS */ | ||
| 449 | ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF, | ||
| 450 | VCNL4035_ALS_PERS_MASK, | ||
| 451 | VCNL4035_ALS_PERS_DEFAULT); | ||
| 452 | if (ret) { | ||
| 453 | dev_err(&data->client->dev, "set default PERS returned %d\n", | ||
| 454 | ret); | ||
| 455 | return ret; | ||
| 456 | } | ||
| 457 | data->als_persistence = VCNL4035_ALS_PERS_DEFAULT; | ||
| 458 | |||
| 459 | /* set default HIGH threshold for ALS */ | ||
| 460 | ret = regmap_write(data->regmap, VCNL4035_ALS_THDH, | ||
| 461 | VCNL4035_ALS_THDH_DEFAULT); | ||
| 462 | if (ret) { | ||
| 463 | dev_err(&data->client->dev, "set default THDH returned %d\n", | ||
| 464 | ret); | ||
| 465 | return ret; | ||
| 466 | } | ||
| 467 | data->als_thresh_high = VCNL4035_ALS_THDH_DEFAULT; | ||
| 468 | |||
| 469 | /* set default LOW threshold for ALS */ | ||
| 470 | ret = regmap_write(data->regmap, VCNL4035_ALS_THDL, | ||
| 471 | VCNL4035_ALS_THDL_DEFAULT); | ||
| 472 | if (ret) { | ||
| 473 | dev_err(&data->client->dev, "set default THDL returned %d\n", | ||
| 474 | ret); | ||
| 475 | return ret; | ||
| 476 | } | ||
| 477 | data->als_thresh_low = VCNL4035_ALS_THDL_DEFAULT; | ||
| 478 | |||
| 479 | return 0; | ||
| 480 | } | ||
| 481 | |||
| 482 | static bool vcnl4035_is_volatile_reg(struct device *dev, unsigned int reg) | ||
| 483 | { | ||
| 484 | switch (reg) { | ||
| 485 | case VCNL4035_ALS_CONF: | ||
| 486 | case VCNL4035_DEV_ID: | ||
| 487 | return false; | ||
| 488 | default: | ||
| 489 | return true; | ||
| 490 | } | ||
| 491 | } | ||
| 492 | |||
| 493 | static const struct regmap_config vcnl4035_regmap_config = { | ||
| 494 | .name = VCNL4035_REGMAP_NAME, | ||
| 495 | .reg_bits = 8, | ||
| 496 | .val_bits = 16, | ||
| 497 | .max_register = VCNL4035_DEV_ID, | ||
| 498 | .cache_type = REGCACHE_RBTREE, | ||
| 499 | .volatile_reg = vcnl4035_is_volatile_reg, | ||
| 500 | .val_format_endian = REGMAP_ENDIAN_LITTLE, | ||
| 501 | }; | ||
| 502 | |||
| 503 | static int vcnl4035_probe_trigger(struct iio_dev *indio_dev) | ||
| 504 | { | ||
| 505 | int ret; | ||
| 506 | struct vcnl4035_data *data = iio_priv(indio_dev); | ||
| 507 | |||
| 508 | data->drdy_trigger0 = devm_iio_trigger_alloc( | ||
| 509 | indio_dev->dev.parent, | ||
| 510 | "%s-dev%d", indio_dev->name, indio_dev->id); | ||
| 511 | if (!data->drdy_trigger0) | ||
| 512 | return -ENOMEM; | ||
| 513 | |||
| 514 | data->drdy_trigger0->dev.parent = indio_dev->dev.parent; | ||
| 515 | data->drdy_trigger0->ops = &vcnl4035_trigger_ops; | ||
| 516 | iio_trigger_set_drvdata(data->drdy_trigger0, indio_dev); | ||
| 517 | ret = devm_iio_trigger_register(indio_dev->dev.parent, | ||
| 518 | data->drdy_trigger0); | ||
| 519 | if (ret) { | ||
| 520 | dev_err(&data->client->dev, "iio trigger register failed\n"); | ||
| 521 | return ret; | ||
| 522 | } | ||
| 523 | |||
| 524 | /* Trigger setup */ | ||
| 525 | ret = devm_iio_triggered_buffer_setup(indio_dev->dev.parent, indio_dev, | ||
| 526 | NULL, vcnl4035_trigger_consumer_handler, | ||
| 527 | &iio_triggered_buffer_setup_ops); | ||
| 528 | if (ret < 0) { | ||
| 529 | dev_err(&data->client->dev, "iio triggered buffer setup failed\n"); | ||
| 530 | return ret; | ||
| 531 | } | ||
| 532 | |||
| 533 | /* IRQ to trigger mapping */ | ||
| 534 | ret = devm_request_threaded_irq(&data->client->dev, data->client->irq, | ||
| 535 | NULL, vcnl4035_drdy_irq_thread, | ||
| 536 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
| 537 | VCNL4035_IRQ_NAME, indio_dev); | ||
| 538 | if (ret < 0) | ||
| 539 | dev_err(&data->client->dev, "request irq %d for trigger0 failed\n", | ||
| 540 | data->client->irq); | ||
| 541 | return ret; | ||
| 542 | } | ||
| 543 | |||
| 544 | static int vcnl4035_probe(struct i2c_client *client, | ||
| 545 | const struct i2c_device_id *id) | ||
| 546 | { | ||
| 547 | struct vcnl4035_data *data; | ||
| 548 | struct iio_dev *indio_dev; | ||
| 549 | struct regmap *regmap; | ||
| 550 | int ret; | ||
| 551 | |||
| 552 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); | ||
| 553 | if (!indio_dev) | ||
| 554 | return -ENOMEM; | ||
| 555 | |||
| 556 | regmap = devm_regmap_init_i2c(client, &vcnl4035_regmap_config); | ||
| 557 | if (IS_ERR(regmap)) { | ||
| 558 | dev_err(&client->dev, "regmap_init failed!\n"); | ||
| 559 | return PTR_ERR(regmap); | ||
| 560 | } | ||
| 561 | |||
| 562 | data = iio_priv(indio_dev); | ||
| 563 | i2c_set_clientdata(client, indio_dev); | ||
| 564 | data->client = client; | ||
| 565 | data->regmap = regmap; | ||
| 566 | |||
| 567 | indio_dev->dev.parent = &client->dev; | ||
| 568 | indio_dev->info = &vcnl4035_info; | ||
| 569 | indio_dev->name = VCNL4035_DRV_NAME; | ||
| 570 | indio_dev->channels = vcnl4035_channels; | ||
| 571 | indio_dev->num_channels = ARRAY_SIZE(vcnl4035_channels); | ||
| 572 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
| 573 | |||
| 574 | ret = vcnl4035_init(data); | ||
| 575 | if (ret < 0) { | ||
| 576 | dev_err(&client->dev, "vcnl4035 chip init failed\n"); | ||
| 577 | return ret; | ||
| 578 | } | ||
| 579 | |||
| 580 | if (client->irq > 0) { | ||
| 581 | ret = vcnl4035_probe_trigger(indio_dev); | ||
| 582 | if (ret < 0) { | ||
| 583 | dev_err(&client->dev, "vcnl4035 unable init trigger\n"); | ||
| 584 | goto fail_poweroff; | ||
| 585 | } | ||
| 586 | } | ||
| 587 | |||
| 588 | ret = pm_runtime_set_active(&client->dev); | ||
| 589 | if (ret < 0) | ||
| 590 | goto fail_poweroff; | ||
| 591 | |||
| 592 | ret = iio_device_register(indio_dev); | ||
| 593 | if (ret < 0) | ||
| 594 | goto fail_poweroff; | ||
| 595 | |||
| 596 | pm_runtime_enable(&client->dev); | ||
| 597 | pm_runtime_set_autosuspend_delay(&client->dev, VCNL4035_SLEEP_DELAY_MS); | ||
| 598 | pm_runtime_use_autosuspend(&client->dev); | ||
| 599 | |||
| 600 | return 0; | ||
| 601 | |||
| 602 | fail_poweroff: | ||
| 603 | vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_DISABLE); | ||
| 604 | return ret; | ||
| 605 | } | ||
| 606 | |||
| 607 | static int vcnl4035_remove(struct i2c_client *client) | ||
| 608 | { | ||
| 609 | struct iio_dev *indio_dev = i2c_get_clientdata(client); | ||
| 610 | |||
| 611 | pm_runtime_dont_use_autosuspend(&client->dev); | ||
| 612 | pm_runtime_disable(&client->dev); | ||
| 613 | iio_device_unregister(indio_dev); | ||
| 614 | pm_runtime_set_suspended(&client->dev); | ||
| 615 | |||
| 616 | return vcnl4035_set_als_power_state(iio_priv(indio_dev), | ||
| 617 | VCNL4035_MODE_ALS_DISABLE); | ||
| 618 | } | ||
| 619 | |||
| 620 | static int __maybe_unused vcnl4035_runtime_suspend(struct device *dev) | ||
| 621 | { | ||
| 622 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | ||
| 623 | struct vcnl4035_data *data = iio_priv(indio_dev); | ||
| 624 | int ret; | ||
| 625 | |||
| 626 | ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_DISABLE); | ||
| 627 | regcache_mark_dirty(data->regmap); | ||
| 628 | |||
| 629 | return ret; | ||
| 630 | } | ||
| 631 | |||
| 632 | static int __maybe_unused vcnl4035_runtime_resume(struct device *dev) | ||
| 633 | { | ||
| 634 | struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | ||
| 635 | struct vcnl4035_data *data = iio_priv(indio_dev); | ||
| 636 | int ret; | ||
| 637 | |||
| 638 | regcache_sync(data->regmap); | ||
| 639 | ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_ENABLE); | ||
| 640 | if (ret < 0) | ||
| 641 | return ret; | ||
| 642 | |||
| 643 | /* wait for 1 ALS integration cycle */ | ||
| 644 | msleep(data->als_it_val * 100); | ||
| 645 | |||
| 646 | return 0; | ||
| 647 | } | ||
| 648 | |||
| 649 | static const struct dev_pm_ops vcnl4035_pm_ops = { | ||
| 650 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | ||
| 651 | pm_runtime_force_resume) | ||
| 652 | SET_RUNTIME_PM_OPS(vcnl4035_runtime_suspend, | ||
| 653 | vcnl4035_runtime_resume, NULL) | ||
| 654 | }; | ||
| 655 | |||
| 656 | static const struct of_device_id vcnl4035_of_match[] = { | ||
| 657 | { .compatible = "vishay,vcnl4035", }, | ||
| 658 | { } | ||
| 659 | }; | ||
| 660 | MODULE_DEVICE_TABLE(of, vcnl4035_of_match); | ||
| 661 | |||
| 662 | static struct i2c_driver vcnl4035_driver = { | ||
| 663 | .driver = { | ||
| 664 | .name = VCNL4035_DRV_NAME, | ||
| 665 | .pm = &vcnl4035_pm_ops, | ||
| 666 | .of_match_table = vcnl4035_of_match, | ||
| 667 | }, | ||
| 668 | .probe = vcnl4035_probe, | ||
| 669 | .remove = vcnl4035_remove, | ||
| 670 | }; | ||
| 671 | |||
| 672 | module_i2c_driver(vcnl4035_driver); | ||
| 673 | |||
| 674 | MODULE_AUTHOR("Parthiban Nallathambi <pn@denx.de>"); | ||
| 675 | MODULE_DESCRIPTION("VCNL4035 Ambient Light Sensor driver"); | ||
| 676 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig index ed9d776d01af..8a63cbbca4b7 100644 --- a/drivers/iio/magnetometer/Kconfig +++ b/drivers/iio/magnetometer/Kconfig | |||
| @@ -175,4 +175,33 @@ config SENSORS_HMC5843_SPI | |||
| 175 | - hmc5843_core (core functions) | 175 | - hmc5843_core (core functions) |
| 176 | - hmc5843_spi (support for HMC5983) | 176 | - hmc5843_spi (support for HMC5983) |
| 177 | 177 | ||
| 178 | config SENSORS_RM3100 | ||
| 179 | tristate | ||
| 180 | select IIO_BUFFER | ||
| 181 | select IIO_TRIGGERED_BUFFER | ||
| 182 | |||
| 183 | config SENSORS_RM3100_I2C | ||
| 184 | tristate "PNI RM3100 3-Axis Magnetometer (I2C)" | ||
| 185 | depends on I2C | ||
| 186 | select SENSORS_RM3100 | ||
| 187 | select REGMAP_I2C | ||
| 188 | help | ||
| 189 | Say Y here to add support for the PNI RM3100 3-Axis Magnetometer. | ||
| 190 | |||
| 191 | This driver can also be compiled as a module. | ||
| 192 | To compile this driver as a module, choose M here: the module | ||
| 193 | will be called rm3100-i2c. | ||
| 194 | |||
| 195 | config SENSORS_RM3100_SPI | ||
| 196 | tristate "PNI RM3100 3-Axis Magnetometer (SPI)" | ||
| 197 | depends on SPI_MASTER | ||
| 198 | select SENSORS_RM3100 | ||
| 199 | select REGMAP_SPI | ||
| 200 | help | ||
| 201 | Say Y here to add support for the PNI RM3100 3-Axis Magnetometer. | ||
| 202 | |||
| 203 | This driver can also be compiled as a module. | ||
| 204 | To compile this driver as a module, choose M here: the module | ||
| 205 | will be called rm3100-spi. | ||
| 206 | |||
| 178 | endmenu | 207 | endmenu |
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile index 664b2f866472..ba1bc34b82fa 100644 --- a/drivers/iio/magnetometer/Makefile +++ b/drivers/iio/magnetometer/Makefile | |||
| @@ -24,3 +24,7 @@ obj-$(CONFIG_IIO_ST_MAGN_SPI_3AXIS) += st_magn_spi.o | |||
| 24 | obj-$(CONFIG_SENSORS_HMC5843) += hmc5843_core.o | 24 | obj-$(CONFIG_SENSORS_HMC5843) += hmc5843_core.o |
| 25 | obj-$(CONFIG_SENSORS_HMC5843_I2C) += hmc5843_i2c.o | 25 | obj-$(CONFIG_SENSORS_HMC5843_I2C) += hmc5843_i2c.o |
| 26 | obj-$(CONFIG_SENSORS_HMC5843_SPI) += hmc5843_spi.o | 26 | obj-$(CONFIG_SENSORS_HMC5843_SPI) += hmc5843_spi.o |
| 27 | |||
| 28 | obj-$(CONFIG_SENSORS_RM3100) += rm3100-core.o | ||
| 29 | obj-$(CONFIG_SENSORS_RM3100_I2C) += rm3100-i2c.o | ||
| 30 | obj-$(CONFIG_SENSORS_RM3100_SPI) += rm3100-spi.o | ||
diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c new file mode 100644 index 000000000000..7c20918d8108 --- /dev/null +++ b/drivers/iio/magnetometer/rm3100-core.c | |||
| @@ -0,0 +1,616 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * PNI RM3100 3-axis geomagnetic sensor driver core. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2018 Song Qiang <songqiang1304521@gmail.com> | ||
| 6 | * | ||
| 7 | * User Manual available at | ||
| 8 | * <https://www.pnicorp.com/download/rm3100-user-manual/> | ||
| 9 | * | ||
| 10 | * TODO: event generation, pm. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/delay.h> | ||
| 14 | #include <linux/interrupt.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/slab.h> | ||
| 17 | |||
| 18 | #include <linux/iio/buffer.h> | ||
| 19 | #include <linux/iio/iio.h> | ||
| 20 | #include <linux/iio/sysfs.h> | ||
| 21 | #include <linux/iio/trigger.h> | ||
| 22 | #include <linux/iio/triggered_buffer.h> | ||
| 23 | #include <linux/iio/trigger_consumer.h> | ||
| 24 | |||
| 25 | #include "rm3100.h" | ||
| 26 | |||
| 27 | /* Cycle Count Registers. */ | ||
| 28 | #define RM3100_REG_CC_X 0x05 | ||
| 29 | #define RM3100_REG_CC_Y 0x07 | ||
| 30 | #define RM3100_REG_CC_Z 0x09 | ||
| 31 | |||
| 32 | /* Poll Measurement Mode register. */ | ||
| 33 | #define RM3100_REG_POLL 0x00 | ||
| 34 | #define RM3100_POLL_X BIT(4) | ||
| 35 | #define RM3100_POLL_Y BIT(5) | ||
| 36 | #define RM3100_POLL_Z BIT(6) | ||
| 37 | |||
| 38 | /* Continuous Measurement Mode register. */ | ||
| 39 | #define RM3100_REG_CMM 0x01 | ||
| 40 | #define RM3100_CMM_START BIT(0) | ||
| 41 | #define RM3100_CMM_X BIT(4) | ||
| 42 | #define RM3100_CMM_Y BIT(5) | ||
| 43 | #define RM3100_CMM_Z BIT(6) | ||
| 44 | |||
| 45 | /* TiMe Rate Configuration register. */ | ||
| 46 | #define RM3100_REG_TMRC 0x0B | ||
| 47 | #define RM3100_TMRC_OFFSET 0x92 | ||
| 48 | |||
| 49 | /* Result Status register. */ | ||
| 50 | #define RM3100_REG_STATUS 0x34 | ||
| 51 | #define RM3100_STATUS_DRDY BIT(7) | ||
| 52 | |||
| 53 | /* Measurement result registers. */ | ||
| 54 | #define RM3100_REG_MX2 0x24 | ||
| 55 | #define RM3100_REG_MY2 0x27 | ||
| 56 | #define RM3100_REG_MZ2 0x2a | ||
| 57 | |||
| 58 | #define RM3100_W_REG_START RM3100_REG_POLL | ||
| 59 | #define RM3100_W_REG_END RM3100_REG_TMRC | ||
| 60 | #define RM3100_R_REG_START RM3100_REG_POLL | ||
| 61 | #define RM3100_R_REG_END RM3100_REG_STATUS | ||
| 62 | #define RM3100_V_REG_START RM3100_REG_POLL | ||
| 63 | #define RM3100_V_REG_END RM3100_REG_STATUS | ||
| 64 | |||
| 65 | /* | ||
| 66 | * This is computed by hand, is the sum of channel storage bits and padding | ||
| 67 | * bits, which is 4+4+4+12=24 in here. | ||
| 68 | */ | ||
| 69 | #define RM3100_SCAN_BYTES 24 | ||
| 70 | |||
| 71 | #define RM3100_CMM_AXIS_SHIFT 4 | ||
| 72 | |||
| 73 | struct rm3100_data { | ||
| 74 | struct regmap *regmap; | ||
| 75 | struct completion measuring_done; | ||
| 76 | bool use_interrupt; | ||
| 77 | int conversion_time; | ||
| 78 | int scale; | ||
| 79 | u8 buffer[RM3100_SCAN_BYTES]; | ||
| 80 | struct iio_trigger *drdy_trig; | ||
| 81 | |||
| 82 | /* | ||
| 83 | * This lock is for protecting the consistency of series of i2c | ||
| 84 | * operations, that is, to make sure a measurement process will | ||
| 85 | * not be interrupted by a set frequency operation, which should | ||
| 86 | * be taken where a series of i2c operation starts, released where | ||
| 87 | * the operation ends. | ||
| 88 | */ | ||
| 89 | struct mutex lock; | ||
| 90 | }; | ||
| 91 | |||
| 92 | static const struct regmap_range rm3100_readable_ranges[] = { | ||
| 93 | regmap_reg_range(RM3100_R_REG_START, RM3100_R_REG_END), | ||
| 94 | }; | ||
| 95 | |||
| 96 | const struct regmap_access_table rm3100_readable_table = { | ||
| 97 | .yes_ranges = rm3100_readable_ranges, | ||
| 98 | .n_yes_ranges = ARRAY_SIZE(rm3100_readable_ranges), | ||
| 99 | }; | ||
| 100 | EXPORT_SYMBOL_GPL(rm3100_readable_table); | ||
| 101 | |||
| 102 | static const struct regmap_range rm3100_writable_ranges[] = { | ||
| 103 | regmap_reg_range(RM3100_W_REG_START, RM3100_W_REG_END), | ||
| 104 | }; | ||
| 105 | |||
| 106 | const struct regmap_access_table rm3100_writable_table = { | ||
| 107 | .yes_ranges = rm3100_writable_ranges, | ||
| 108 | .n_yes_ranges = ARRAY_SIZE(rm3100_writable_ranges), | ||
| 109 | }; | ||
| 110 | EXPORT_SYMBOL_GPL(rm3100_writable_table); | ||
| 111 | |||
| 112 | static const struct regmap_range rm3100_volatile_ranges[] = { | ||
| 113 | regmap_reg_range(RM3100_V_REG_START, RM3100_V_REG_END), | ||
| 114 | }; | ||
| 115 | |||
| 116 | const struct regmap_access_table rm3100_volatile_table = { | ||
| 117 | .yes_ranges = rm3100_volatile_ranges, | ||
| 118 | .n_yes_ranges = ARRAY_SIZE(rm3100_volatile_ranges), | ||
| 119 | }; | ||
| 120 | EXPORT_SYMBOL_GPL(rm3100_volatile_table); | ||
| 121 | |||
| 122 | static irqreturn_t rm3100_thread_fn(int irq, void *d) | ||
| 123 | { | ||
| 124 | struct iio_dev *indio_dev = d; | ||
| 125 | struct rm3100_data *data = iio_priv(indio_dev); | ||
| 126 | |||
| 127 | /* | ||
| 128 | * Write operation to any register or read operation | ||
| 129 | * to first byte of results will clear the interrupt. | ||
| 130 | */ | ||
| 131 | regmap_write(data->regmap, RM3100_REG_POLL, 0); | ||
| 132 | |||
| 133 | return IRQ_HANDLED; | ||
| 134 | } | ||
| 135 | |||
| 136 | static irqreturn_t rm3100_irq_handler(int irq, void *d) | ||
| 137 | { | ||
| 138 | struct iio_dev *indio_dev = d; | ||
| 139 | struct rm3100_data *data = iio_priv(indio_dev); | ||
| 140 | |||
| 141 | switch (indio_dev->currentmode) { | ||
| 142 | case INDIO_DIRECT_MODE: | ||
| 143 | complete(&data->measuring_done); | ||
| 144 | break; | ||
| 145 | case INDIO_BUFFER_TRIGGERED: | ||
| 146 | iio_trigger_poll(data->drdy_trig); | ||
| 147 | break; | ||
| 148 | default: | ||
| 149 | dev_err(indio_dev->dev.parent, | ||
| 150 | "device mode out of control, current mode: %d", | ||
| 151 | indio_dev->currentmode); | ||
| 152 | } | ||
| 153 | |||
| 154 | return IRQ_WAKE_THREAD; | ||
| 155 | } | ||
| 156 | |||
| 157 | static int rm3100_wait_measurement(struct rm3100_data *data) | ||
| 158 | { | ||
| 159 | struct regmap *regmap = data->regmap; | ||
| 160 | unsigned int val; | ||
| 161 | int tries = 20; | ||
| 162 | int ret; | ||
| 163 | |||
| 164 | /* | ||
| 165 | * A read cycle of 400kbits i2c bus is about 20us, plus the time | ||
| 166 | * used for scheduling, a read cycle of fast mode of this device | ||
| 167 | * can reach 1.7ms, it may be possible for data to arrive just | ||
| 168 | * after we check the RM3100_REG_STATUS. In this case, irq_handler is | ||
| 169 | * called before measuring_done is reinitialized, it will wait | ||
| 170 | * forever for data that has already been ready. | ||
| 171 | * Reinitialize measuring_done before looking up makes sure we | ||
| 172 | * will always capture interrupt no matter when it happens. | ||
| 173 | */ | ||
| 174 | if (data->use_interrupt) | ||
| 175 | reinit_completion(&data->measuring_done); | ||
| 176 | |||
| 177 | ret = regmap_read(regmap, RM3100_REG_STATUS, &val); | ||
| 178 | if (ret < 0) | ||
| 179 | return ret; | ||
| 180 | |||
| 181 | if ((val & RM3100_STATUS_DRDY) != RM3100_STATUS_DRDY) { | ||
| 182 | if (data->use_interrupt) { | ||
| 183 | ret = wait_for_completion_timeout(&data->measuring_done, | ||
| 184 | msecs_to_jiffies(data->conversion_time)); | ||
| 185 | if (!ret) | ||
| 186 | return -ETIMEDOUT; | ||
| 187 | } else { | ||
| 188 | do { | ||
| 189 | usleep_range(1000, 5000); | ||
| 190 | |||
| 191 | ret = regmap_read(regmap, RM3100_REG_STATUS, | ||
| 192 | &val); | ||
| 193 | if (ret < 0) | ||
| 194 | return ret; | ||
| 195 | |||
| 196 | if (val & RM3100_STATUS_DRDY) | ||
| 197 | break; | ||
| 198 | } while (--tries); | ||
| 199 | if (!tries) | ||
| 200 | return -ETIMEDOUT; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | return 0; | ||
| 204 | } | ||
| 205 | |||
| 206 | static int rm3100_read_mag(struct rm3100_data *data, int idx, int *val) | ||
| 207 | { | ||
| 208 | struct regmap *regmap = data->regmap; | ||
| 209 | u8 buffer[3]; | ||
| 210 | int ret; | ||
| 211 | |||
| 212 | mutex_lock(&data->lock); | ||
| 213 | ret = regmap_write(regmap, RM3100_REG_POLL, BIT(4 + idx)); | ||
| 214 | if (ret < 0) | ||
| 215 | goto unlock_return; | ||
| 216 | |||
| 217 | ret = rm3100_wait_measurement(data); | ||
| 218 | if (ret < 0) | ||
| 219 | goto unlock_return; | ||
| 220 | |||
| 221 | ret = regmap_bulk_read(regmap, RM3100_REG_MX2 + 3 * idx, buffer, 3); | ||
| 222 | if (ret < 0) | ||
| 223 | goto unlock_return; | ||
| 224 | mutex_unlock(&data->lock); | ||
| 225 | |||
| 226 | *val = sign_extend32((buffer[0] << 16) | (buffer[1] << 8) | buffer[2], | ||
| 227 | 23); | ||
| 228 | |||
| 229 | return IIO_VAL_INT; | ||
| 230 | |||
| 231 | unlock_return: | ||
| 232 | mutex_unlock(&data->lock); | ||
| 233 | return ret; | ||
| 234 | } | ||
| 235 | |||
| 236 | #define RM3100_CHANNEL(axis, idx) \ | ||
| 237 | { \ | ||
| 238 | .type = IIO_MAGN, \ | ||
| 239 | .modified = 1, \ | ||
| 240 | .channel2 = IIO_MOD_##axis, \ | ||
| 241 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ | ||
| 242 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ | ||
| 243 | BIT(IIO_CHAN_INFO_SAMP_FREQ), \ | ||
| 244 | .scan_index = idx, \ | ||
| 245 | .scan_type = { \ | ||
| 246 | .sign = 's', \ | ||
| 247 | .realbits = 24, \ | ||
| 248 | .storagebits = 32, \ | ||
| 249 | .shift = 8, \ | ||
| 250 | .endianness = IIO_BE, \ | ||
| 251 | }, \ | ||
| 252 | } | ||
| 253 | |||
| 254 | static const struct iio_chan_spec rm3100_channels[] = { | ||
| 255 | RM3100_CHANNEL(X, 0), | ||
| 256 | RM3100_CHANNEL(Y, 1), | ||
| 257 | RM3100_CHANNEL(Z, 2), | ||
| 258 | IIO_CHAN_SOFT_TIMESTAMP(3), | ||
| 259 | }; | ||
| 260 | |||
| 261 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( | ||
| 262 | "600 300 150 75 37 18 9 4.5 2.3 1.2 0.6 0.3 0.015 0.075" | ||
| 263 | ); | ||
| 264 | |||
| 265 | static struct attribute *rm3100_attributes[] = { | ||
| 266 | &iio_const_attr_sampling_frequency_available.dev_attr.attr, | ||
| 267 | NULL, | ||
| 268 | }; | ||
| 269 | |||
| 270 | static const struct attribute_group rm3100_attribute_group = { | ||
| 271 | .attrs = rm3100_attributes, | ||
| 272 | }; | ||
| 273 | |||
| 274 | #define RM3100_SAMP_NUM 14 | ||
| 275 | |||
| 276 | /* | ||
| 277 | * Frequency : rm3100_samp_rates[][0].rm3100_samp_rates[][1]Hz. | ||
| 278 | * Time between reading: rm3100_sam_rates[][2]ms. | ||
| 279 | * The first one is actually 1.7ms. | ||
| 280 | */ | ||
| 281 | static const int rm3100_samp_rates[RM3100_SAMP_NUM][3] = { | ||
| 282 | {600, 0, 2}, {300, 0, 3}, {150, 0, 7}, {75, 0, 13}, {37, 0, 27}, | ||
| 283 | {18, 0, 55}, {9, 0, 110}, {4, 500000, 220}, {2, 300000, 440}, | ||
| 284 | {1, 200000, 800}, {0, 600000, 1600}, {0, 300000, 3300}, | ||
| 285 | {0, 15000, 6700}, {0, 75000, 13000} | ||
| 286 | }; | ||
| 287 | |||
| 288 | static int rm3100_get_samp_freq(struct rm3100_data *data, int *val, int *val2) | ||
| 289 | { | ||
| 290 | unsigned int tmp; | ||
| 291 | int ret; | ||
| 292 | |||
| 293 | mutex_lock(&data->lock); | ||
| 294 | ret = regmap_read(data->regmap, RM3100_REG_TMRC, &tmp); | ||
| 295 | mutex_unlock(&data->lock); | ||
| 296 | if (ret < 0) | ||
| 297 | return ret; | ||
| 298 | *val = rm3100_samp_rates[tmp - RM3100_TMRC_OFFSET][0]; | ||
| 299 | *val2 = rm3100_samp_rates[tmp - RM3100_TMRC_OFFSET][1]; | ||
| 300 | |||
| 301 | return IIO_VAL_INT_PLUS_MICRO; | ||
| 302 | } | ||
| 303 | |||
| 304 | static int rm3100_set_cycle_count(struct rm3100_data *data, int val) | ||
| 305 | { | ||
| 306 | int ret; | ||
| 307 | u8 i; | ||
| 308 | |||
| 309 | for (i = 0; i < 3; i++) { | ||
| 310 | ret = regmap_write(data->regmap, RM3100_REG_CC_X + 2 * i, val); | ||
| 311 | if (ret < 0) | ||
| 312 | return ret; | ||
| 313 | } | ||
| 314 | |||
| 315 | /* | ||
| 316 | * The scale of this sensor depends on the cycle count value, these | ||
| 317 | * three values are corresponding to the cycle count value 50, 100, | ||
| 318 | * 200. scale = output / gain * 10^4. | ||
| 319 | */ | ||
| 320 | switch (val) { | ||
| 321 | case 50: | ||
| 322 | data->scale = 500; | ||
| 323 | break; | ||
| 324 | case 100: | ||
| 325 | data->scale = 263; | ||
| 326 | break; | ||
| 327 | /* | ||
| 328 | * case 200: | ||
| 329 | * This function will never be called by users' code, so here we | ||
| 330 | * assume that it will never get a wrong parameter. | ||
| 331 | */ | ||
| 332 | default: | ||
| 333 | data->scale = 133; | ||
| 334 | } | ||
| 335 | |||
| 336 | return 0; | ||
| 337 | } | ||
| 338 | |||
| 339 | static int rm3100_set_samp_freq(struct iio_dev *indio_dev, int val, int val2) | ||
| 340 | { | ||
| 341 | struct rm3100_data *data = iio_priv(indio_dev); | ||
| 342 | struct regmap *regmap = data->regmap; | ||
| 343 | unsigned int cycle_count; | ||
| 344 | int ret; | ||
| 345 | int i; | ||
| 346 | |||
| 347 | mutex_lock(&data->lock); | ||
| 348 | /* All cycle count registers use the same value. */ | ||
| 349 | ret = regmap_read(regmap, RM3100_REG_CC_X, &cycle_count); | ||
| 350 | if (ret < 0) | ||
| 351 | goto unlock_return; | ||
| 352 | |||
| 353 | for (i = 0; i < RM3100_SAMP_NUM; i++) { | ||
| 354 | if (val == rm3100_samp_rates[i][0] && | ||
| 355 | val2 == rm3100_samp_rates[i][1]) | ||
| 356 | break; | ||
| 357 | } | ||
| 358 | if (i == RM3100_SAMP_NUM) { | ||
| 359 | ret = -EINVAL; | ||
| 360 | goto unlock_return; | ||
| 361 | } | ||
| 362 | |||
| 363 | ret = regmap_write(regmap, RM3100_REG_TMRC, i + RM3100_TMRC_OFFSET); | ||
| 364 | if (ret < 0) | ||
| 365 | goto unlock_return; | ||
| 366 | |||
| 367 | /* Checking if cycle count registers need changing. */ | ||
| 368 | if (val == 600 && cycle_count == 200) { | ||
| 369 | ret = rm3100_set_cycle_count(data, 100); | ||
| 370 | if (ret < 0) | ||
| 371 | goto unlock_return; | ||
| 372 | } else if (val != 600 && cycle_count == 100) { | ||
| 373 | ret = rm3100_set_cycle_count(data, 200); | ||
| 374 | if (ret < 0) | ||
| 375 | goto unlock_return; | ||
| 376 | } | ||
| 377 | |||
| 378 | if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { | ||
| 379 | /* Writing TMRC registers requires CMM reset. */ | ||
| 380 | ret = regmap_write(regmap, RM3100_REG_CMM, 0); | ||
| 381 | if (ret < 0) | ||
| 382 | goto unlock_return; | ||
| 383 | ret = regmap_write(data->regmap, RM3100_REG_CMM, | ||
| 384 | (*indio_dev->active_scan_mask & 0x7) << | ||
| 385 | RM3100_CMM_AXIS_SHIFT | RM3100_CMM_START); | ||
| 386 | if (ret < 0) | ||
| 387 | goto unlock_return; | ||
| 388 | } | ||
| 389 | mutex_unlock(&data->lock); | ||
| 390 | |||
| 391 | data->conversion_time = rm3100_samp_rates[i][2] * 2; | ||
| 392 | return 0; | ||
| 393 | |||
| 394 | unlock_return: | ||
| 395 | mutex_unlock(&data->lock); | ||
| 396 | return ret; | ||
| 397 | } | ||
| 398 | |||
| 399 | static int rm3100_read_raw(struct iio_dev *indio_dev, | ||
| 400 | const struct iio_chan_spec *chan, | ||
| 401 | int *val, int *val2, long mask) | ||
| 402 | { | ||
| 403 | struct rm3100_data *data = iio_priv(indio_dev); | ||
| 404 | int ret; | ||
| 405 | |||
| 406 | switch (mask) { | ||
| 407 | case IIO_CHAN_INFO_RAW: | ||
| 408 | ret = iio_device_claim_direct_mode(indio_dev); | ||
| 409 | if (ret < 0) | ||
| 410 | return ret; | ||
| 411 | |||
| 412 | ret = rm3100_read_mag(data, chan->scan_index, val); | ||
| 413 | iio_device_release_direct_mode(indio_dev); | ||
| 414 | |||
| 415 | return ret; | ||
| 416 | case IIO_CHAN_INFO_SCALE: | ||
| 417 | *val = 0; | ||
| 418 | *val2 = data->scale; | ||
| 419 | |||
| 420 | return IIO_VAL_INT_PLUS_MICRO; | ||
| 421 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
| 422 | return rm3100_get_samp_freq(data, val, val2); | ||
| 423 | default: | ||
| 424 | return -EINVAL; | ||
| 425 | } | ||
| 426 | } | ||
| 427 | |||
| 428 | static int rm3100_write_raw(struct iio_dev *indio_dev, | ||
| 429 | struct iio_chan_spec const *chan, | ||
| 430 | int val, int val2, long mask) | ||
| 431 | { | ||
| 432 | switch (mask) { | ||
| 433 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
| 434 | return rm3100_set_samp_freq(indio_dev, val, val2); | ||
| 435 | default: | ||
| 436 | return -EINVAL; | ||
| 437 | } | ||
| 438 | } | ||
| 439 | |||
| 440 | static const struct iio_info rm3100_info = { | ||
| 441 | .attrs = &rm3100_attribute_group, | ||
| 442 | .read_raw = rm3100_read_raw, | ||
| 443 | .write_raw = rm3100_write_raw, | ||
| 444 | }; | ||
| 445 | |||
| 446 | static int rm3100_buffer_preenable(struct iio_dev *indio_dev) | ||
| 447 | { | ||
| 448 | struct rm3100_data *data = iio_priv(indio_dev); | ||
| 449 | |||
| 450 | /* Starting channels enabled. */ | ||
| 451 | return regmap_write(data->regmap, RM3100_REG_CMM, | ||
| 452 | (*indio_dev->active_scan_mask & 0x7) << RM3100_CMM_AXIS_SHIFT | | ||
| 453 | RM3100_CMM_START); | ||
| 454 | } | ||
| 455 | |||
| 456 | static int rm3100_buffer_postdisable(struct iio_dev *indio_dev) | ||
| 457 | { | ||
| 458 | struct rm3100_data *data = iio_priv(indio_dev); | ||
| 459 | |||
| 460 | return regmap_write(data->regmap, RM3100_REG_CMM, 0); | ||
| 461 | } | ||
| 462 | |||
| 463 | static const struct iio_buffer_setup_ops rm3100_buffer_ops = { | ||
| 464 | .preenable = rm3100_buffer_preenable, | ||
| 465 | .postenable = iio_triggered_buffer_postenable, | ||
| 466 | .predisable = iio_triggered_buffer_predisable, | ||
| 467 | .postdisable = rm3100_buffer_postdisable, | ||
| 468 | }; | ||
| 469 | |||
| 470 | static irqreturn_t rm3100_trigger_handler(int irq, void *p) | ||
| 471 | { | ||
| 472 | struct iio_poll_func *pf = p; | ||
| 473 | struct iio_dev *indio_dev = pf->indio_dev; | ||
| 474 | unsigned long scan_mask = *indio_dev->active_scan_mask; | ||
| 475 | unsigned int mask_len = indio_dev->masklength; | ||
| 476 | struct rm3100_data *data = iio_priv(indio_dev); | ||
| 477 | struct regmap *regmap = data->regmap; | ||
| 478 | int ret, i, bit; | ||
| 479 | |||
| 480 | mutex_lock(&data->lock); | ||
| 481 | switch (scan_mask) { | ||
| 482 | case BIT(0) | BIT(1) | BIT(2): | ||
| 483 | ret = regmap_bulk_read(regmap, RM3100_REG_MX2, data->buffer, 9); | ||
| 484 | mutex_unlock(&data->lock); | ||
| 485 | if (ret < 0) | ||
| 486 | goto done; | ||
| 487 | /* Convert XXXYYYZZZxxx to XXXxYYYxZZZx. x for paddings. */ | ||
| 488 | for (i = 2; i > 0; i--) | ||
| 489 | memmove(data->buffer + i * 4, data->buffer + i * 3, 3); | ||
| 490 | break; | ||
| 491 | case BIT(0) | BIT(1): | ||
| 492 | ret = regmap_bulk_read(regmap, RM3100_REG_MX2, data->buffer, 6); | ||
| 493 | mutex_unlock(&data->lock); | ||
| 494 | if (ret < 0) | ||
| 495 | goto done; | ||
| 496 | memmove(data->buffer + 4, data->buffer + 3, 3); | ||
| 497 | break; | ||
| 498 | case BIT(1) | BIT(2): | ||
| 499 | ret = regmap_bulk_read(regmap, RM3100_REG_MY2, data->buffer, 6); | ||
| 500 | mutex_unlock(&data->lock); | ||
| 501 | if (ret < 0) | ||
| 502 | goto done; | ||
| 503 | memmove(data->buffer + 4, data->buffer + 3, 3); | ||
| 504 | break; | ||
| 505 | case BIT(0) | BIT(2): | ||
| 506 | ret = regmap_bulk_read(regmap, RM3100_REG_MX2, data->buffer, 9); | ||
| 507 | mutex_unlock(&data->lock); | ||
| 508 | if (ret < 0) | ||
| 509 | goto done; | ||
| 510 | memmove(data->buffer + 4, data->buffer + 6, 3); | ||
| 511 | break; | ||
| 512 | default: | ||
| 513 | for_each_set_bit(bit, &scan_mask, mask_len) { | ||
| 514 | ret = regmap_bulk_read(regmap, RM3100_REG_MX2 + 3 * bit, | ||
| 515 | data->buffer, 3); | ||
| 516 | if (ret < 0) { | ||
| 517 | mutex_unlock(&data->lock); | ||
| 518 | goto done; | ||
| 519 | } | ||
| 520 | } | ||
| 521 | mutex_unlock(&data->lock); | ||
| 522 | } | ||
| 523 | /* | ||
| 524 | * Always using the same buffer so that we wouldn't need to set the | ||
| 525 | * paddings to 0 in case of leaking any data. | ||
| 526 | */ | ||
| 527 | iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, | ||
| 528 | pf->timestamp); | ||
| 529 | done: | ||
| 530 | iio_trigger_notify_done(indio_dev->trig); | ||
| 531 | |||
| 532 | return IRQ_HANDLED; | ||
| 533 | } | ||
| 534 | |||
| 535 | int rm3100_common_probe(struct device *dev, struct regmap *regmap, int irq) | ||
| 536 | { | ||
| 537 | struct iio_dev *indio_dev; | ||
| 538 | struct rm3100_data *data; | ||
| 539 | unsigned int tmp; | ||
| 540 | int ret; | ||
| 541 | |||
| 542 | indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); | ||
| 543 | if (!indio_dev) | ||
| 544 | return -ENOMEM; | ||
| 545 | |||
| 546 | data = iio_priv(indio_dev); | ||
| 547 | data->regmap = regmap; | ||
| 548 | |||
| 549 | mutex_init(&data->lock); | ||
| 550 | |||
| 551 | indio_dev->dev.parent = dev; | ||
| 552 | indio_dev->name = "rm3100"; | ||
| 553 | indio_dev->info = &rm3100_info; | ||
| 554 | indio_dev->channels = rm3100_channels; | ||
| 555 | indio_dev->num_channels = ARRAY_SIZE(rm3100_channels); | ||
| 556 | indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED; | ||
| 557 | indio_dev->currentmode = INDIO_DIRECT_MODE; | ||
| 558 | |||
| 559 | if (!irq) | ||
| 560 | data->use_interrupt = false; | ||
| 561 | else { | ||
| 562 | data->use_interrupt = true; | ||
| 563 | |||
| 564 | init_completion(&data->measuring_done); | ||
| 565 | ret = devm_request_threaded_irq(dev, | ||
| 566 | irq, | ||
| 567 | rm3100_irq_handler, | ||
| 568 | rm3100_thread_fn, | ||
| 569 | IRQF_TRIGGER_HIGH | | ||
| 570 | IRQF_ONESHOT, | ||
| 571 | indio_dev->name, | ||
| 572 | indio_dev); | ||
| 573 | if (ret < 0) { | ||
| 574 | dev_err(dev, "request irq line failed.\n"); | ||
| 575 | return ret; | ||
| 576 | } | ||
| 577 | |||
| 578 | data->drdy_trig = devm_iio_trigger_alloc(dev, "%s-drdy%d", | ||
| 579 | indio_dev->name, | ||
| 580 | indio_dev->id); | ||
| 581 | if (!data->drdy_trig) | ||
| 582 | return -ENOMEM; | ||
| 583 | |||
| 584 | data->drdy_trig->dev.parent = dev; | ||
| 585 | ret = devm_iio_trigger_register(dev, data->drdy_trig); | ||
| 586 | if (ret < 0) | ||
| 587 | return ret; | ||
| 588 | } | ||
| 589 | |||
| 590 | ret = devm_iio_triggered_buffer_setup(dev, indio_dev, | ||
| 591 | &iio_pollfunc_store_time, | ||
| 592 | rm3100_trigger_handler, | ||
| 593 | &rm3100_buffer_ops); | ||
| 594 | if (ret < 0) | ||
| 595 | return ret; | ||
| 596 | |||
| 597 | ret = regmap_read(regmap, RM3100_REG_TMRC, &tmp); | ||
| 598 | if (ret < 0) | ||
| 599 | return ret; | ||
| 600 | /* Initializing max wait time, which is double conversion time. */ | ||
| 601 | data->conversion_time = rm3100_samp_rates[tmp - RM3100_TMRC_OFFSET][2] | ||
| 602 | * 2; | ||
| 603 | |||
| 604 | /* Cycle count values may not be what we want. */ | ||
| 605 | if ((tmp - RM3100_TMRC_OFFSET) == 0) | ||
| 606 | rm3100_set_cycle_count(data, 100); | ||
| 607 | else | ||
| 608 | rm3100_set_cycle_count(data, 200); | ||
| 609 | |||
| 610 | return devm_iio_device_register(dev, indio_dev); | ||
| 611 | } | ||
| 612 | EXPORT_SYMBOL_GPL(rm3100_common_probe); | ||
| 613 | |||
| 614 | MODULE_AUTHOR("Song Qiang <songqiang1304521@gmail.com>"); | ||
| 615 | MODULE_DESCRIPTION("PNI RM3100 3-axis magnetometer i2c driver"); | ||
| 616 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/magnetometer/rm3100-i2c.c b/drivers/iio/magnetometer/rm3100-i2c.c new file mode 100644 index 000000000000..1ac622c6d6c9 --- /dev/null +++ b/drivers/iio/magnetometer/rm3100-i2c.c | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Support for PNI RM3100 3-axis geomagnetic sensor on a i2c bus. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2018 Song Qiang <songqiang1304521@gmail.com> | ||
| 6 | * | ||
| 7 | * i2c slave address: 0x20 + SA1 << 1 + SA0. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/i2c.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | |||
| 13 | #include "rm3100.h" | ||
| 14 | |||
| 15 | static const struct regmap_config rm3100_regmap_config = { | ||
| 16 | .reg_bits = 8, | ||
| 17 | .val_bits = 8, | ||
| 18 | |||
| 19 | .rd_table = &rm3100_readable_table, | ||
| 20 | .wr_table = &rm3100_writable_table, | ||
| 21 | .volatile_table = &rm3100_volatile_table, | ||
| 22 | |||
| 23 | .cache_type = REGCACHE_RBTREE, | ||
| 24 | }; | ||
| 25 | |||
| 26 | static int rm3100_probe(struct i2c_client *client) | ||
| 27 | { | ||
| 28 | struct regmap *regmap; | ||
| 29 | |||
| 30 | regmap = devm_regmap_init_i2c(client, &rm3100_regmap_config); | ||
| 31 | if (IS_ERR(regmap)) | ||
| 32 | return PTR_ERR(regmap); | ||
| 33 | |||
| 34 | return rm3100_common_probe(&client->dev, regmap, client->irq); | ||
| 35 | } | ||
| 36 | |||
| 37 | static const struct of_device_id rm3100_dt_match[] = { | ||
| 38 | { .compatible = "pni,rm3100", }, | ||
| 39 | { } | ||
| 40 | }; | ||
| 41 | MODULE_DEVICE_TABLE(of, rm3100_dt_match); | ||
| 42 | |||
| 43 | static struct i2c_driver rm3100_driver = { | ||
| 44 | .driver = { | ||
| 45 | .name = "rm3100-i2c", | ||
| 46 | .of_match_table = rm3100_dt_match, | ||
| 47 | }, | ||
| 48 | .probe_new = rm3100_probe, | ||
| 49 | }; | ||
| 50 | module_i2c_driver(rm3100_driver); | ||
| 51 | |||
| 52 | MODULE_AUTHOR("Song Qiang <songqiang1304521@gmail.com>"); | ||
| 53 | MODULE_DESCRIPTION("PNI RM3100 3-axis magnetometer i2c driver"); | ||
| 54 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/magnetometer/rm3100-spi.c b/drivers/iio/magnetometer/rm3100-spi.c new file mode 100644 index 000000000000..65d5eb9e4f5e --- /dev/null +++ b/drivers/iio/magnetometer/rm3100-spi.c | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Support for PNI RM3100 3-axis geomagnetic sensor on a spi bus. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2018 Song Qiang <songqiang1304521@gmail.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/module.h> | ||
| 9 | #include <linux/spi/spi.h> | ||
| 10 | |||
| 11 | #include "rm3100.h" | ||
| 12 | |||
| 13 | static const struct regmap_config rm3100_regmap_config = { | ||
| 14 | .reg_bits = 8, | ||
| 15 | .val_bits = 8, | ||
| 16 | |||
| 17 | .rd_table = &rm3100_readable_table, | ||
| 18 | .wr_table = &rm3100_writable_table, | ||
| 19 | .volatile_table = &rm3100_volatile_table, | ||
| 20 | |||
| 21 | .read_flag_mask = 0x80, | ||
| 22 | |||
| 23 | .cache_type = REGCACHE_RBTREE, | ||
| 24 | }; | ||
| 25 | |||
| 26 | static int rm3100_probe(struct spi_device *spi) | ||
| 27 | { | ||
| 28 | struct regmap *regmap; | ||
| 29 | int ret; | ||
| 30 | |||
| 31 | /* Actually this device supports both mode 0 and mode 3. */ | ||
| 32 | spi->mode = SPI_MODE_0; | ||
| 33 | /* Data rates cannot exceed 1Mbits. */ | ||
| 34 | spi->max_speed_hz = 1000000; | ||
| 35 | spi->bits_per_word = 8; | ||
| 36 | ret = spi_setup(spi); | ||
| 37 | if (ret) | ||
| 38 | return ret; | ||
| 39 | |||
| 40 | regmap = devm_regmap_init_spi(spi, &rm3100_regmap_config); | ||
| 41 | if (IS_ERR(regmap)) | ||
| 42 | return PTR_ERR(regmap); | ||
| 43 | |||
| 44 | return rm3100_common_probe(&spi->dev, regmap, spi->irq); | ||
| 45 | } | ||
| 46 | |||
| 47 | static const struct of_device_id rm3100_dt_match[] = { | ||
| 48 | { .compatible = "pni,rm3100", }, | ||
| 49 | { } | ||
| 50 | }; | ||
| 51 | MODULE_DEVICE_TABLE(of, rm3100_dt_match); | ||
| 52 | |||
| 53 | static struct spi_driver rm3100_driver = { | ||
| 54 | .driver = { | ||
| 55 | .name = "rm3100-spi", | ||
| 56 | .of_match_table = rm3100_dt_match, | ||
| 57 | }, | ||
| 58 | .probe = rm3100_probe, | ||
| 59 | }; | ||
| 60 | module_spi_driver(rm3100_driver); | ||
| 61 | |||
| 62 | MODULE_AUTHOR("Song Qiang <songqiang1304521@gmail.com>"); | ||
| 63 | MODULE_DESCRIPTION("PNI RM3100 3-axis magnetometer spi driver"); | ||
| 64 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/magnetometer/rm3100.h b/drivers/iio/magnetometer/rm3100.h new file mode 100644 index 000000000000..c3508218bc77 --- /dev/null +++ b/drivers/iio/magnetometer/rm3100.h | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2018 Song Qiang <songqiang1304521@gmail.com> | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef RM3100_CORE_H | ||
| 7 | #define RM3100_CORE_H | ||
| 8 | |||
| 9 | #include <linux/regmap.h> | ||
| 10 | |||
| 11 | extern const struct regmap_access_table rm3100_readable_table; | ||
| 12 | extern const struct regmap_access_table rm3100_writable_table; | ||
| 13 | extern const struct regmap_access_table rm3100_volatile_table; | ||
| 14 | |||
| 15 | int rm3100_common_probe(struct device *dev, struct regmap *regmap, int irq); | ||
| 16 | |||
| 17 | #endif /* RM3100_CORE_H */ | ||
diff --git a/drivers/iio/magnetometer/st_magn.h b/drivers/iio/magnetometer/st_magn.h index 8fe51ce427bd..bc14ad4f1b26 100644 --- a/drivers/iio/magnetometer/st_magn.h +++ b/drivers/iio/magnetometer/st_magn.h | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #define LIS3MDL_MAGN_DEV_NAME "lis3mdl" | 20 | #define LIS3MDL_MAGN_DEV_NAME "lis3mdl" |
| 21 | #define LSM303AGR_MAGN_DEV_NAME "lsm303agr_magn" | 21 | #define LSM303AGR_MAGN_DEV_NAME "lsm303agr_magn" |
| 22 | #define LIS2MDL_MAGN_DEV_NAME "lis2mdl" | 22 | #define LIS2MDL_MAGN_DEV_NAME "lis2mdl" |
| 23 | #define LSM9DS1_MAGN_DEV_NAME "lsm9ds1_magn" | ||
| 23 | 24 | ||
| 24 | int st_magn_common_probe(struct iio_dev *indio_dev); | 25 | int st_magn_common_probe(struct iio_dev *indio_dev); |
| 25 | void st_magn_common_remove(struct iio_dev *indio_dev); | 26 | void st_magn_common_remove(struct iio_dev *indio_dev); |
diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index 72f6d1335a04..5d056bdb3b37 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c | |||
| @@ -29,9 +29,9 @@ | |||
| 29 | #define ST_MAGN_NUMBER_DATA_CHANNELS 3 | 29 | #define ST_MAGN_NUMBER_DATA_CHANNELS 3 |
| 30 | 30 | ||
| 31 | /* DEFAULT VALUE FOR SENSORS */ | 31 | /* DEFAULT VALUE FOR SENSORS */ |
| 32 | #define ST_MAGN_DEFAULT_OUT_X_H_ADDR 0X03 | 32 | #define ST_MAGN_DEFAULT_OUT_X_H_ADDR 0x03 |
| 33 | #define ST_MAGN_DEFAULT_OUT_Y_H_ADDR 0X07 | 33 | #define ST_MAGN_DEFAULT_OUT_Y_H_ADDR 0x07 |
| 34 | #define ST_MAGN_DEFAULT_OUT_Z_H_ADDR 0X05 | 34 | #define ST_MAGN_DEFAULT_OUT_Z_H_ADDR 0x05 |
| 35 | 35 | ||
| 36 | /* FULLSCALE */ | 36 | /* FULLSCALE */ |
| 37 | #define ST_MAGN_FS_AVL_1300MG 1300 | 37 | #define ST_MAGN_FS_AVL_1300MG 1300 |
| @@ -267,6 +267,7 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = { | |||
| 267 | .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, | 267 | .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, |
| 268 | .sensors_supported = { | 268 | .sensors_supported = { |
| 269 | [0] = LIS3MDL_MAGN_DEV_NAME, | 269 | [0] = LIS3MDL_MAGN_DEV_NAME, |
| 270 | [1] = LSM9DS1_MAGN_DEV_NAME, | ||
| 270 | }, | 271 | }, |
| 271 | .ch = (struct iio_chan_spec *)st_magn_2_16bit_channels, | 272 | .ch = (struct iio_chan_spec *)st_magn_2_16bit_channels, |
| 272 | .odr = { | 273 | .odr = { |
| @@ -315,6 +316,10 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = { | |||
| 315 | }, | 316 | }, |
| 316 | }, | 317 | }, |
| 317 | }, | 318 | }, |
| 319 | .bdu = { | ||
| 320 | .addr = 0x24, | ||
| 321 | .mask = 0x40, | ||
| 322 | }, | ||
| 318 | .drdy_irq = { | 323 | .drdy_irq = { |
| 319 | /* drdy line is routed drdy pin */ | 324 | /* drdy line is routed drdy pin */ |
| 320 | .stat_drdy = { | 325 | .stat_drdy = { |
diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c index feaa28cf6a77..68650f5f5c19 100644 --- a/drivers/iio/magnetometer/st_magn_i2c.c +++ b/drivers/iio/magnetometer/st_magn_i2c.c | |||
| @@ -44,6 +44,10 @@ static const struct of_device_id st_magn_of_match[] = { | |||
| 44 | .compatible = "st,lis2mdl", | 44 | .compatible = "st,lis2mdl", |
| 45 | .data = LIS2MDL_MAGN_DEV_NAME, | 45 | .data = LIS2MDL_MAGN_DEV_NAME, |
| 46 | }, | 46 | }, |
| 47 | { | ||
| 48 | .compatible = "st,lsm9ds1-magn", | ||
| 49 | .data = LSM9DS1_MAGN_DEV_NAME, | ||
| 50 | }, | ||
| 47 | {}, | 51 | {}, |
| 48 | }; | 52 | }; |
| 49 | MODULE_DEVICE_TABLE(of, st_magn_of_match); | 53 | MODULE_DEVICE_TABLE(of, st_magn_of_match); |
| @@ -90,6 +94,7 @@ static const struct i2c_device_id st_magn_id_table[] = { | |||
| 90 | { LIS3MDL_MAGN_DEV_NAME }, | 94 | { LIS3MDL_MAGN_DEV_NAME }, |
| 91 | { LSM303AGR_MAGN_DEV_NAME }, | 95 | { LSM303AGR_MAGN_DEV_NAME }, |
| 92 | { LIS2MDL_MAGN_DEV_NAME }, | 96 | { LIS2MDL_MAGN_DEV_NAME }, |
| 97 | { LSM9DS1_MAGN_DEV_NAME }, | ||
| 93 | {}, | 98 | {}, |
| 94 | }; | 99 | }; |
| 95 | MODULE_DEVICE_TABLE(i2c, st_magn_id_table); | 100 | MODULE_DEVICE_TABLE(i2c, st_magn_id_table); |
diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c index 7b7cd08fcc32..cb05fcd9ddfe 100644 --- a/drivers/iio/magnetometer/st_magn_spi.c +++ b/drivers/iio/magnetometer/st_magn_spi.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | * For new single-chip sensors use <device_name> as compatible string. | 23 | * For new single-chip sensors use <device_name> as compatible string. |
| 24 | * For old single-chip devices keep <device_name>-magn to maintain | 24 | * For old single-chip devices keep <device_name>-magn to maintain |
| 25 | * compatibility | 25 | * compatibility |
| 26 | * For multi-chip devices, use <device_name>-magn to distinguish which | ||
| 27 | * capability is being used | ||
| 26 | */ | 28 | */ |
| 27 | static const struct of_device_id st_magn_of_match[] = { | 29 | static const struct of_device_id st_magn_of_match[] = { |
| 28 | { | 30 | { |
| @@ -37,6 +39,10 @@ static const struct of_device_id st_magn_of_match[] = { | |||
| 37 | .compatible = "st,lis2mdl", | 39 | .compatible = "st,lis2mdl", |
| 38 | .data = LIS2MDL_MAGN_DEV_NAME, | 40 | .data = LIS2MDL_MAGN_DEV_NAME, |
| 39 | }, | 41 | }, |
| 42 | { | ||
| 43 | .compatible = "st,lsm9ds1-magn", | ||
| 44 | .data = LSM9DS1_MAGN_DEV_NAME, | ||
| 45 | }, | ||
| 40 | {} | 46 | {} |
| 41 | }; | 47 | }; |
| 42 | MODULE_DEVICE_TABLE(of, st_magn_of_match); | 48 | MODULE_DEVICE_TABLE(of, st_magn_of_match); |
| @@ -79,6 +85,7 @@ static const struct spi_device_id st_magn_id_table[] = { | |||
| 79 | { LIS3MDL_MAGN_DEV_NAME }, | 85 | { LIS3MDL_MAGN_DEV_NAME }, |
| 80 | { LSM303AGR_MAGN_DEV_NAME }, | 86 | { LSM303AGR_MAGN_DEV_NAME }, |
| 81 | { LIS2MDL_MAGN_DEV_NAME }, | 87 | { LIS2MDL_MAGN_DEV_NAME }, |
| 88 | { LSM9DS1_MAGN_DEV_NAME }, | ||
| 82 | {}, | 89 | {}, |
| 83 | }; | 90 | }; |
| 84 | MODULE_DEVICE_TABLE(spi, st_magn_id_table); | 91 | MODULE_DEVICE_TABLE(spi, st_magn_id_table); |
diff --git a/drivers/iio/potentiometer/mcp4131.c b/drivers/iio/potentiometer/mcp4131.c index b3e30db246cc..efe035ce010d 100644 --- a/drivers/iio/potentiometer/mcp4131.c +++ b/drivers/iio/potentiometer/mcp4131.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
| 43 | #include <linux/mutex.h> | 43 | #include <linux/mutex.h> |
| 44 | #include <linux/of.h> | 44 | #include <linux/of.h> |
| 45 | #include <linux/of_device.h> | ||
| 45 | #include <linux/spi/spi.h> | 46 | #include <linux/spi/spi.h> |
| 46 | 47 | ||
| 47 | #define MCP4131_WRITE (0x00 << 2) | 48 | #define MCP4131_WRITE (0x00 << 2) |
| @@ -243,7 +244,7 @@ static int mcp4131_probe(struct spi_device *spi) | |||
| 243 | { | 244 | { |
| 244 | int err; | 245 | int err; |
| 245 | struct device *dev = &spi->dev; | 246 | struct device *dev = &spi->dev; |
| 246 | unsigned long devid = spi_get_device_id(spi)->driver_data; | 247 | unsigned long devid; |
| 247 | struct mcp4131_data *data; | 248 | struct mcp4131_data *data; |
| 248 | struct iio_dev *indio_dev; | 249 | struct iio_dev *indio_dev; |
| 249 | 250 | ||
| @@ -254,7 +255,11 @@ static int mcp4131_probe(struct spi_device *spi) | |||
| 254 | data = iio_priv(indio_dev); | 255 | data = iio_priv(indio_dev); |
| 255 | spi_set_drvdata(spi, indio_dev); | 256 | spi_set_drvdata(spi, indio_dev); |
| 256 | data->spi = spi; | 257 | data->spi = spi; |
| 257 | data->cfg = &mcp4131_cfg[devid]; | 258 | data->cfg = of_device_get_match_data(&spi->dev); |
| 259 | if (!data->cfg) { | ||
| 260 | devid = spi_get_device_id(spi)->driver_data; | ||
| 261 | data->cfg = &mcp4131_cfg[devid]; | ||
| 262 | } | ||
| 258 | 263 | ||
| 259 | mutex_init(&data->lock); | 264 | mutex_init(&data->lock); |
| 260 | 265 | ||
| @@ -273,7 +278,6 @@ static int mcp4131_probe(struct spi_device *spi) | |||
| 273 | return 0; | 278 | return 0; |
| 274 | } | 279 | } |
| 275 | 280 | ||
| 276 | #if defined(CONFIG_OF) | ||
| 277 | static const struct of_device_id mcp4131_dt_ids[] = { | 281 | static const struct of_device_id mcp4131_dt_ids[] = { |
| 278 | { .compatible = "microchip,mcp4131-502", | 282 | { .compatible = "microchip,mcp4131-502", |
| 279 | .data = &mcp4131_cfg[MCP413x_502] }, | 283 | .data = &mcp4131_cfg[MCP413x_502] }, |
| @@ -406,7 +410,6 @@ static const struct of_device_id mcp4131_dt_ids[] = { | |||
| 406 | {} | 410 | {} |
| 407 | }; | 411 | }; |
| 408 | MODULE_DEVICE_TABLE(of, mcp4131_dt_ids); | 412 | MODULE_DEVICE_TABLE(of, mcp4131_dt_ids); |
| 409 | #endif /* CONFIG_OF */ | ||
| 410 | 413 | ||
| 411 | static const struct spi_device_id mcp4131_id[] = { | 414 | static const struct spi_device_id mcp4131_id[] = { |
| 412 | { "mcp4131-502", MCP413x_502 }, | 415 | { "mcp4131-502", MCP413x_502 }, |
diff --git a/drivers/iio/potentiometer/tpl0102.c b/drivers/iio/potentiometer/tpl0102.c index ca1cce58fe20..a0a07e47f13f 100644 --- a/drivers/iio/potentiometer/tpl0102.c +++ b/drivers/iio/potentiometer/tpl0102.c | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | struct tpl0102_cfg { | 16 | struct tpl0102_cfg { |
| 17 | int wipers; | 17 | int wipers; |
| 18 | int max_pos; | 18 | int avail[3]; |
| 19 | int kohms; | 19 | int kohms; |
| 20 | }; | 20 | }; |
| 21 | 21 | ||
| @@ -28,16 +28,16 @@ enum tpl0102_type { | |||
| 28 | 28 | ||
| 29 | static const struct tpl0102_cfg tpl0102_cfg[] = { | 29 | static const struct tpl0102_cfg tpl0102_cfg[] = { |
| 30 | /* on-semiconductor parts */ | 30 | /* on-semiconductor parts */ |
| 31 | [CAT5140_503] = { .wipers = 1, .max_pos = 256, .kohms = 50, }, | 31 | [CAT5140_503] = { .wipers = 1, .avail = { 0, 1, 255 }, .kohms = 50, }, |
| 32 | [CAT5140_104] = { .wipers = 1, .max_pos = 256, .kohms = 100, }, | 32 | [CAT5140_104] = { .wipers = 1, .avail = { 0, 1, 255 }, .kohms = 100, }, |
| 33 | /* ti parts */ | 33 | /* ti parts */ |
| 34 | [TPL0102_104] = { .wipers = 2, .max_pos = 256, .kohms = 100 }, | 34 | [TPL0102_104] = { .wipers = 2, .avail = { 0, 1, 255 }, .kohms = 100 }, |
| 35 | [TPL0401_103] = { .wipers = 1, .max_pos = 128, .kohms = 10, }, | 35 | [TPL0401_103] = { .wipers = 1, .avail = { 0, 1, 127 }, .kohms = 10, }, |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | struct tpl0102_data { | 38 | struct tpl0102_data { |
| 39 | struct regmap *regmap; | 39 | struct regmap *regmap; |
| 40 | unsigned long devid; | 40 | const struct tpl0102_cfg *cfg; |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | static const struct regmap_config tpl0102_regmap_config = { | 43 | static const struct regmap_config tpl0102_regmap_config = { |
| @@ -52,6 +52,7 @@ static const struct regmap_config tpl0102_regmap_config = { | |||
| 52 | .channel = (ch), \ | 52 | .channel = (ch), \ |
| 53 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ | 53 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
| 54 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ | 54 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
| 55 | .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW), \ | ||
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | static const struct iio_chan_spec tpl0102_channels[] = { | 58 | static const struct iio_chan_spec tpl0102_channels[] = { |
| @@ -72,14 +73,32 @@ static int tpl0102_read_raw(struct iio_dev *indio_dev, | |||
| 72 | return ret ? ret : IIO_VAL_INT; | 73 | return ret ? ret : IIO_VAL_INT; |
| 73 | } | 74 | } |
| 74 | case IIO_CHAN_INFO_SCALE: | 75 | case IIO_CHAN_INFO_SCALE: |
| 75 | *val = 1000 * tpl0102_cfg[data->devid].kohms; | 76 | *val = 1000 * data->cfg->kohms; |
| 76 | *val2 = tpl0102_cfg[data->devid].max_pos; | 77 | *val2 = data->cfg->avail[2] + 1; |
| 77 | return IIO_VAL_FRACTIONAL; | 78 | return IIO_VAL_FRACTIONAL; |
| 78 | } | 79 | } |
| 79 | 80 | ||
| 80 | return -EINVAL; | 81 | return -EINVAL; |
| 81 | } | 82 | } |
| 82 | 83 | ||
| 84 | static int tpl0102_read_avail(struct iio_dev *indio_dev, | ||
| 85 | struct iio_chan_spec const *chan, | ||
| 86 | const int **vals, int *type, int *length, | ||
| 87 | long mask) | ||
| 88 | { | ||
| 89 | struct tpl0102_data *data = iio_priv(indio_dev); | ||
| 90 | |||
| 91 | switch (mask) { | ||
| 92 | case IIO_CHAN_INFO_RAW: | ||
| 93 | *length = ARRAY_SIZE(data->cfg->avail); | ||
| 94 | *vals = data->cfg->avail; | ||
| 95 | *type = IIO_VAL_INT; | ||
| 96 | return IIO_AVAIL_RANGE; | ||
| 97 | } | ||
| 98 | |||
| 99 | return -EINVAL; | ||
| 100 | } | ||
| 101 | |||
| 83 | static int tpl0102_write_raw(struct iio_dev *indio_dev, | 102 | static int tpl0102_write_raw(struct iio_dev *indio_dev, |
| 84 | struct iio_chan_spec const *chan, | 103 | struct iio_chan_spec const *chan, |
| 85 | int val, int val2, long mask) | 104 | int val, int val2, long mask) |
| @@ -89,7 +108,7 @@ static int tpl0102_write_raw(struct iio_dev *indio_dev, | |||
| 89 | if (mask != IIO_CHAN_INFO_RAW) | 108 | if (mask != IIO_CHAN_INFO_RAW) |
| 90 | return -EINVAL; | 109 | return -EINVAL; |
| 91 | 110 | ||
| 92 | if (val >= tpl0102_cfg[data->devid].max_pos || val < 0) | 111 | if (val > data->cfg->avail[2] || val < 0) |
| 93 | return -EINVAL; | 112 | return -EINVAL; |
| 94 | 113 | ||
| 95 | return regmap_write(data->regmap, chan->channel, val); | 114 | return regmap_write(data->regmap, chan->channel, val); |
| @@ -97,6 +116,7 @@ static int tpl0102_write_raw(struct iio_dev *indio_dev, | |||
| 97 | 116 | ||
| 98 | static const struct iio_info tpl0102_info = { | 117 | static const struct iio_info tpl0102_info = { |
| 99 | .read_raw = tpl0102_read_raw, | 118 | .read_raw = tpl0102_read_raw, |
| 119 | .read_avail = tpl0102_read_avail, | ||
| 100 | .write_raw = tpl0102_write_raw, | 120 | .write_raw = tpl0102_write_raw, |
| 101 | }; | 121 | }; |
| 102 | 122 | ||
| @@ -113,7 +133,7 @@ static int tpl0102_probe(struct i2c_client *client, | |||
| 113 | data = iio_priv(indio_dev); | 133 | data = iio_priv(indio_dev); |
| 114 | i2c_set_clientdata(client, indio_dev); | 134 | i2c_set_clientdata(client, indio_dev); |
| 115 | 135 | ||
| 116 | data->devid = id->driver_data; | 136 | data->cfg = &tpl0102_cfg[id->driver_data]; |
| 117 | data->regmap = devm_regmap_init_i2c(client, &tpl0102_regmap_config); | 137 | data->regmap = devm_regmap_init_i2c(client, &tpl0102_regmap_config); |
| 118 | if (IS_ERR(data->regmap)) { | 138 | if (IS_ERR(data->regmap)) { |
| 119 | dev_err(dev, "regmap initialization failed\n"); | 139 | dev_err(dev, "regmap initialization failed\n"); |
| @@ -123,7 +143,7 @@ static int tpl0102_probe(struct i2c_client *client, | |||
| 123 | indio_dev->dev.parent = dev; | 143 | indio_dev->dev.parent = dev; |
| 124 | indio_dev->info = &tpl0102_info; | 144 | indio_dev->info = &tpl0102_info; |
| 125 | indio_dev->channels = tpl0102_channels; | 145 | indio_dev->channels = tpl0102_channels; |
| 126 | indio_dev->num_channels = tpl0102_cfg[data->devid].wipers; | 146 | indio_dev->num_channels = data->cfg->wipers; |
| 127 | indio_dev->name = client->name; | 147 | indio_dev->name = client->name; |
| 128 | 148 | ||
| 129 | return devm_iio_device_register(dev, indio_dev); | 149 | return devm_iio_device_register(dev, indio_dev); |
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 9d3062a07460..fc23059f1673 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig | |||
| @@ -73,6 +73,7 @@ config AD7192 | |||
| 73 | config AD7280 | 73 | config AD7280 |
| 74 | tristate "Analog Devices AD7280A Lithium Ion Battery Monitoring System" | 74 | tristate "Analog Devices AD7280A Lithium Ion Battery Monitoring System" |
| 75 | depends on SPI | 75 | depends on SPI |
| 76 | select CRC8 | ||
| 76 | help | 77 | help |
| 77 | Say yes here to build support for Analog Devices AD7280A | 78 | Say yes here to build support for Analog Devices AD7280A |
| 78 | Lithium Ion Battery Monitoring System. | 79 | Lithium Ion Battery Monitoring System. |
diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index 58420dcb406d..0bb9ab174f2a 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * Licensed under the GPL-2. | 6 | * Licensed under the GPL-2. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/crc8.h> | ||
| 9 | #include <linux/device.h> | 10 | #include <linux/device.h> |
| 10 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 11 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
| @@ -121,8 +122,6 @@ static unsigned int ad7280a_devaddr(unsigned int addr) | |||
| 121 | * P(x) = x^8 + x^5 + x^3 + x^2 + x^1 + x^0 = 0b100101111 => 0x2F | 122 | * P(x) = x^8 + x^5 + x^3 + x^2 + x^1 + x^0 = 0b100101111 => 0x2F |
| 122 | */ | 123 | */ |
| 123 | #define POLYNOM 0x2F | 124 | #define POLYNOM 0x2F |
| 124 | #define POLYNOM_ORDER 8 | ||
| 125 | #define HIGHBIT (1 << (POLYNOM_ORDER - 1)) | ||
| 126 | 125 | ||
| 127 | struct ad7280_state { | 126 | struct ad7280_state { |
| 128 | struct spi_device *spi; | 127 | struct spi_device *spi; |
| @@ -131,7 +130,7 @@ struct ad7280_state { | |||
| 131 | int slave_num; | 130 | int slave_num; |
| 132 | int scan_cnt; | 131 | int scan_cnt; |
| 133 | int readback_delay_us; | 132 | int readback_delay_us; |
| 134 | unsigned char crc_tab[256]; | 133 | unsigned char crc_tab[CRC8_TABLE_SIZE]; |
| 135 | unsigned char ctrl_hb; | 134 | unsigned char ctrl_hb; |
| 136 | unsigned char ctrl_lb; | 135 | unsigned char ctrl_lb; |
| 137 | unsigned char cell_threshhigh; | 136 | unsigned char cell_threshhigh; |
| @@ -144,23 +143,6 @@ struct ad7280_state { | |||
| 144 | __be32 buf[2] ____cacheline_aligned; | 143 | __be32 buf[2] ____cacheline_aligned; |
| 145 | }; | 144 | }; |
| 146 | 145 | ||
| 147 | static void ad7280_crc8_build_table(unsigned char *crc_tab) | ||
| 148 | { | ||
| 149 | unsigned char bit, crc; | ||
| 150 | int cnt, i; | ||
| 151 | |||
| 152 | for (cnt = 0; cnt < 256; cnt++) { | ||
| 153 | crc = cnt; | ||
| 154 | for (i = 0; i < 8; i++) { | ||
| 155 | bit = crc & HIGHBIT; | ||
| 156 | crc <<= 1; | ||
| 157 | if (bit) | ||
| 158 | crc ^= POLYNOM; | ||
| 159 | } | ||
| 160 | crc_tab[cnt] = crc; | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | static unsigned char ad7280_calc_crc8(unsigned char *crc_tab, unsigned int val) | 146 | static unsigned char ad7280_calc_crc8(unsigned char *crc_tab, unsigned int val) |
| 165 | { | 147 | { |
| 166 | unsigned char crc; | 148 | unsigned char crc; |
| @@ -256,7 +238,9 @@ static int ad7280_read(struct ad7280_state *st, unsigned int devaddr, | |||
| 256 | if (ret) | 238 | if (ret) |
| 257 | return ret; | 239 | return ret; |
| 258 | 240 | ||
| 259 | __ad7280_read32(st, &tmp); | 241 | ret = __ad7280_read32(st, &tmp); |
| 242 | if (ret) | ||
| 243 | return ret; | ||
| 260 | 244 | ||
| 261 | if (ad7280_check_crc(st, tmp)) | 245 | if (ad7280_check_crc(st, tmp)) |
| 262 | return -EIO; | 246 | return -EIO; |
| @@ -294,7 +278,9 @@ static int ad7280_read_channel(struct ad7280_state *st, unsigned int devaddr, | |||
| 294 | 278 | ||
| 295 | ad7280_delay(st); | 279 | ad7280_delay(st); |
| 296 | 280 | ||
| 297 | __ad7280_read32(st, &tmp); | 281 | ret = __ad7280_read32(st, &tmp); |
| 282 | if (ret) | ||
| 283 | return ret; | ||
| 298 | 284 | ||
| 299 | if (ad7280_check_crc(st, tmp)) | 285 | if (ad7280_check_crc(st, tmp)) |
| 300 | return -EIO; | 286 | return -EIO; |
| @@ -327,7 +313,9 @@ static int ad7280_read_all_channels(struct ad7280_state *st, unsigned int cnt, | |||
| 327 | ad7280_delay(st); | 313 | ad7280_delay(st); |
| 328 | 314 | ||
| 329 | for (i = 0; i < cnt; i++) { | 315 | for (i = 0; i < cnt; i++) { |
| 330 | __ad7280_read32(st, &tmp); | 316 | ret = __ad7280_read32(st, &tmp); |
| 317 | if (ret) | ||
| 318 | return ret; | ||
| 331 | 319 | ||
| 332 | if (ad7280_check_crc(st, tmp)) | 320 | if (ad7280_check_crc(st, tmp)) |
| 333 | return -EIO; | 321 | return -EIO; |
| @@ -342,6 +330,14 @@ static int ad7280_read_all_channels(struct ad7280_state *st, unsigned int cnt, | |||
| 342 | return sum; | 330 | return sum; |
| 343 | } | 331 | } |
| 344 | 332 | ||
| 333 | static void ad7280_sw_power_down(void *data) | ||
| 334 | { | ||
| 335 | struct ad7280_state *st = data; | ||
| 336 | |||
| 337 | ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_HB, 1, | ||
| 338 | AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb); | ||
| 339 | } | ||
| 340 | |||
| 345 | static int ad7280_chain_setup(struct ad7280_state *st) | 341 | static int ad7280_chain_setup(struct ad7280_state *st) |
| 346 | { | 342 | { |
| 347 | unsigned int val, n; | 343 | unsigned int val, n; |
| @@ -362,26 +358,38 @@ static int ad7280_chain_setup(struct ad7280_state *st) | |||
| 362 | AD7280A_CTRL_LB_MUST_SET | | 358 | AD7280A_CTRL_LB_MUST_SET | |
| 363 | st->ctrl_lb); | 359 | st->ctrl_lb); |
| 364 | if (ret) | 360 | if (ret) |
| 365 | return ret; | 361 | goto error_power_down; |
| 366 | 362 | ||
| 367 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_READ, 1, | 363 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_READ, 1, |
| 368 | AD7280A_CONTROL_LB << 2); | 364 | AD7280A_CONTROL_LB << 2); |
| 369 | if (ret) | 365 | if (ret) |
| 370 | return ret; | 366 | goto error_power_down; |
| 371 | 367 | ||
| 372 | for (n = 0; n <= AD7280A_MAX_CHAIN; n++) { | 368 | for (n = 0; n <= AD7280A_MAX_CHAIN; n++) { |
| 373 | __ad7280_read32(st, &val); | 369 | ret = __ad7280_read32(st, &val); |
| 370 | if (ret) | ||
| 371 | goto error_power_down; | ||
| 372 | |||
| 374 | if (val == 0) | 373 | if (val == 0) |
| 375 | return n - 1; | 374 | return n - 1; |
| 376 | 375 | ||
| 377 | if (ad7280_check_crc(st, val)) | 376 | if (ad7280_check_crc(st, val)) { |
| 378 | return -EIO; | 377 | ret = -EIO; |
| 378 | goto error_power_down; | ||
| 379 | } | ||
| 379 | 380 | ||
| 380 | if (n != ad7280a_devaddr(val >> 27)) | 381 | if (n != ad7280a_devaddr(val >> 27)) { |
| 381 | return -EIO; | 382 | ret = -EIO; |
| 383 | goto error_power_down; | ||
| 384 | } | ||
| 382 | } | 385 | } |
| 386 | ret = -EFAULT; | ||
| 383 | 387 | ||
| 384 | return -EFAULT; | 388 | error_power_down: |
| 389 | ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_HB, 1, | ||
| 390 | AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb); | ||
| 391 | |||
| 392 | return ret; | ||
| 385 | } | 393 | } |
| 386 | 394 | ||
| 387 | static ssize_t ad7280_show_balance_sw(struct device *dev, | 395 | static ssize_t ad7280_show_balance_sw(struct device *dev, |
| @@ -492,8 +500,8 @@ static int ad7280_channel_init(struct ad7280_state *st) | |||
| 492 | { | 500 | { |
| 493 | int dev, ch, cnt; | 501 | int dev, ch, cnt; |
| 494 | 502 | ||
| 495 | st->channels = kcalloc((st->slave_num + 1) * 12 + 2, | 503 | st->channels = devm_kcalloc(&st->spi->dev, (st->slave_num + 1) * 12 + 2, |
| 496 | sizeof(*st->channels), GFP_KERNEL); | 504 | sizeof(*st->channels), GFP_KERNEL); |
| 497 | if (!st->channels) | 505 | if (!st->channels) |
| 498 | return -ENOMEM; | 506 | return -ENOMEM; |
| 499 | 507 | ||
| @@ -552,16 +560,18 @@ static int ad7280_channel_init(struct ad7280_state *st) | |||
| 552 | static int ad7280_attr_init(struct ad7280_state *st) | 560 | static int ad7280_attr_init(struct ad7280_state *st) |
| 553 | { | 561 | { |
| 554 | int dev, ch, cnt; | 562 | int dev, ch, cnt; |
| 563 | unsigned int index; | ||
| 555 | 564 | ||
| 556 | st->iio_attr = kcalloc(2, sizeof(*st->iio_attr) * | 565 | st->iio_attr = devm_kcalloc(&st->spi->dev, 2, sizeof(*st->iio_attr) * |
| 557 | (st->slave_num + 1) * AD7280A_CELLS_PER_DEV, | 566 | (st->slave_num + 1) * AD7280A_CELLS_PER_DEV, |
| 558 | GFP_KERNEL); | 567 | GFP_KERNEL); |
| 559 | if (!st->iio_attr) | 568 | if (!st->iio_attr) |
| 560 | return -ENOMEM; | 569 | return -ENOMEM; |
| 561 | 570 | ||
| 562 | for (dev = 0, cnt = 0; dev <= st->slave_num; dev++) | 571 | for (dev = 0, cnt = 0; dev <= st->slave_num; dev++) |
| 563 | for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_CELL_VOLTAGE_6; | 572 | for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_CELL_VOLTAGE_6; |
| 564 | ch++, cnt++) { | 573 | ch++, cnt++) { |
| 574 | index = dev * AD7280A_CELLS_PER_DEV + ch; | ||
| 565 | st->iio_attr[cnt].address = | 575 | st->iio_attr[cnt].address = |
| 566 | ad7280a_devaddr(dev) << 8 | ch; | 576 | ad7280a_devaddr(dev) << 8 | ch; |
| 567 | st->iio_attr[cnt].dev_attr.attr.mode = | 577 | st->iio_attr[cnt].dev_attr.attr.mode = |
| @@ -571,10 +581,9 @@ static int ad7280_attr_init(struct ad7280_state *st) | |||
| 571 | st->iio_attr[cnt].dev_attr.store = | 581 | st->iio_attr[cnt].dev_attr.store = |
| 572 | ad7280_store_balance_sw; | 582 | ad7280_store_balance_sw; |
| 573 | st->iio_attr[cnt].dev_attr.attr.name = | 583 | st->iio_attr[cnt].dev_attr.attr.name = |
| 574 | kasprintf(GFP_KERNEL, | 584 | devm_kasprintf(&st->spi->dev, GFP_KERNEL, |
| 575 | "in%d-in%d_balance_switch_en", | 585 | "in%d-in%d_balance_switch_en", |
| 576 | dev * AD7280A_CELLS_PER_DEV + ch, | 586 | index, index + 1); |
| 577 | dev * AD7280A_CELLS_PER_DEV + ch + 1); | ||
| 578 | ad7280_attributes[cnt] = | 587 | ad7280_attributes[cnt] = |
| 579 | &st->iio_attr[cnt].dev_attr.attr; | 588 | &st->iio_attr[cnt].dev_attr.attr; |
| 580 | cnt++; | 589 | cnt++; |
| @@ -588,10 +597,9 @@ static int ad7280_attr_init(struct ad7280_state *st) | |||
| 588 | st->iio_attr[cnt].dev_attr.store = | 597 | st->iio_attr[cnt].dev_attr.store = |
| 589 | ad7280_store_balance_timer; | 598 | ad7280_store_balance_timer; |
| 590 | st->iio_attr[cnt].dev_attr.attr.name = | 599 | st->iio_attr[cnt].dev_attr.attr.name = |
| 591 | kasprintf(GFP_KERNEL, | 600 | devm_kasprintf(&st->spi->dev, GFP_KERNEL, |
| 592 | "in%d-in%d_balance_timer", | 601 | "in%d-in%d_balance_timer", |
| 593 | dev * AD7280A_CELLS_PER_DEV + ch, | 602 | index, index + 1); |
| 594 | dev * AD7280A_CELLS_PER_DEV + ch + 1); | ||
| 595 | ad7280_attributes[cnt] = | 603 | ad7280_attributes[cnt] = |
| 596 | &st->iio_attr[cnt].dev_attr.attr; | 604 | &st->iio_attr[cnt].dev_attr.attr; |
| 597 | } | 605 | } |
| @@ -610,7 +618,7 @@ static ssize_t ad7280_read_channel_config(struct device *dev, | |||
| 610 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | 618 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
| 611 | unsigned int val; | 619 | unsigned int val; |
| 612 | 620 | ||
| 613 | switch ((u32)this_attr->address) { | 621 | switch (this_attr->address) { |
| 614 | case AD7280A_CELL_OVERVOLTAGE: | 622 | case AD7280A_CELL_OVERVOLTAGE: |
| 615 | val = 1000 + (st->cell_threshhigh * 1568) / 100; | 623 | val = 1000 + (st->cell_threshhigh * 1568) / 100; |
| 616 | break; | 624 | break; |
| @@ -646,7 +654,7 @@ static ssize_t ad7280_write_channel_config(struct device *dev, | |||
| 646 | if (ret) | 654 | if (ret) |
| 647 | return ret; | 655 | return ret; |
| 648 | 656 | ||
| 649 | switch ((u32)this_attr->address) { | 657 | switch (this_attr->address) { |
| 650 | case AD7280A_CELL_OVERVOLTAGE: | 658 | case AD7280A_CELL_OVERVOLTAGE: |
| 651 | case AD7280A_CELL_UNDERVOLTAGE: | 659 | case AD7280A_CELL_UNDERVOLTAGE: |
| 652 | val = ((val - 1000) * 100) / 1568; /* LSB 15.68mV */ | 660 | val = ((val - 1000) * 100) / 1568; /* LSB 15.68mV */ |
| @@ -662,7 +670,7 @@ static ssize_t ad7280_write_channel_config(struct device *dev, | |||
| 662 | val = clamp(val, 0L, 0xFFL); | 670 | val = clamp(val, 0L, 0xFFL); |
| 663 | 671 | ||
| 664 | mutex_lock(&st->lock); | 672 | mutex_lock(&st->lock); |
| 665 | switch ((u32)this_attr->address) { | 673 | switch (this_attr->address) { |
| 666 | case AD7280A_CELL_OVERVOLTAGE: | 674 | case AD7280A_CELL_OVERVOLTAGE: |
| 667 | st->cell_threshhigh = val; | 675 | st->cell_threshhigh = val; |
| 668 | break; | 676 | break; |
| @@ -857,7 +865,7 @@ static int ad7280_probe(struct spi_device *spi) | |||
| 857 | if (!pdata) | 865 | if (!pdata) |
| 858 | pdata = &ad7793_default_pdata; | 866 | pdata = &ad7793_default_pdata; |
| 859 | 867 | ||
| 860 | ad7280_crc8_build_table(st->crc_tab); | 868 | crc8_populate_msb(st->crc_tab, POLYNOM); |
| 861 | 869 | ||
| 862 | st->spi->max_speed_hz = AD7280A_MAX_SPI_CLK_HZ; | 870 | st->spi->max_speed_hz = AD7280A_MAX_SPI_CLK_HZ; |
| 863 | st->spi->mode = SPI_MODE_1; | 871 | st->spi->mode = SPI_MODE_1; |
| @@ -872,6 +880,10 @@ static int ad7280_probe(struct spi_device *spi) | |||
| 872 | if (ret < 0) | 880 | if (ret < 0) |
| 873 | return ret; | 881 | return ret; |
| 874 | 882 | ||
| 883 | ret = devm_add_action_or_reset(&spi->dev, ad7280_sw_power_down, st); | ||
| 884 | if (ret) | ||
| 885 | return ret; | ||
| 886 | |||
| 875 | st->slave_num = ret; | 887 | st->slave_num = ret; |
| 876 | st->scan_cnt = (st->slave_num + 1) * AD7280A_NUM_CH; | 888 | st->scan_cnt = (st->slave_num + 1) * AD7280A_NUM_CH; |
| 877 | st->cell_threshhigh = 0xFF; | 889 | st->cell_threshhigh = 0xFF; |
| @@ -909,66 +921,38 @@ static int ad7280_probe(struct spi_device *spi) | |||
| 909 | 921 | ||
| 910 | ret = ad7280_attr_init(st); | 922 | ret = ad7280_attr_init(st); |
| 911 | if (ret < 0) | 923 | if (ret < 0) |
| 912 | goto error_free_channels; | 924 | return ret; |
| 913 | 925 | ||
| 914 | ret = iio_device_register(indio_dev); | 926 | ret = devm_iio_device_register(&spi->dev, indio_dev); |
| 915 | if (ret) | 927 | if (ret) |
| 916 | goto error_free_attr; | 928 | return ret; |
| 917 | 929 | ||
| 918 | if (spi->irq > 0) { | 930 | if (spi->irq > 0) { |
| 919 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, | 931 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, |
| 920 | AD7280A_ALERT, 1, | 932 | AD7280A_ALERT, 1, |
| 921 | AD7280A_ALERT_RELAY_SIG_CHAIN_DOWN); | 933 | AD7280A_ALERT_RELAY_SIG_CHAIN_DOWN); |
| 922 | if (ret) | 934 | if (ret) |
| 923 | goto error_unregister; | 935 | return ret; |
| 924 | 936 | ||
| 925 | ret = ad7280_write(st, ad7280a_devaddr(st->slave_num), | 937 | ret = ad7280_write(st, ad7280a_devaddr(st->slave_num), |
| 926 | AD7280A_ALERT, 0, | 938 | AD7280A_ALERT, 0, |
| 927 | AD7280A_ALERT_GEN_STATIC_HIGH | | 939 | AD7280A_ALERT_GEN_STATIC_HIGH | |
| 928 | (pdata->chain_last_alert_ignore & 0xF)); | 940 | (pdata->chain_last_alert_ignore & 0xF)); |
| 929 | if (ret) | 941 | if (ret) |
| 930 | goto error_unregister; | 942 | return ret; |
| 931 | 943 | ||
| 932 | ret = request_threaded_irq(spi->irq, | 944 | ret = devm_request_threaded_irq(&spi->dev, spi->irq, |
| 933 | NULL, | 945 | NULL, |
| 934 | ad7280_event_handler, | 946 | ad7280_event_handler, |
| 935 | IRQF_TRIGGER_FALLING | | 947 | IRQF_TRIGGER_FALLING | |
| 936 | IRQF_ONESHOT, | 948 | IRQF_ONESHOT, |
| 937 | indio_dev->name, | 949 | indio_dev->name, |
| 938 | indio_dev); | 950 | indio_dev); |
| 939 | if (ret) | 951 | if (ret) |
| 940 | goto error_unregister; | 952 | return ret; |
| 941 | } | 953 | } |
| 942 | 954 | ||
| 943 | return 0; | 955 | return 0; |
| 944 | error_unregister: | ||
| 945 | iio_device_unregister(indio_dev); | ||
| 946 | |||
| 947 | error_free_attr: | ||
| 948 | kfree(st->iio_attr); | ||
| 949 | |||
| 950 | error_free_channels: | ||
| 951 | kfree(st->channels); | ||
| 952 | |||
| 953 | return ret; | ||
| 954 | } | ||
| 955 | |||
| 956 | static int ad7280_remove(struct spi_device *spi) | ||
| 957 | { | ||
| 958 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | ||
| 959 | struct ad7280_state *st = iio_priv(indio_dev); | ||
| 960 | |||
| 961 | if (spi->irq > 0) | ||
| 962 | free_irq(spi->irq, indio_dev); | ||
| 963 | iio_device_unregister(indio_dev); | ||
| 964 | |||
| 965 | ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_HB, 1, | ||
| 966 | AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb); | ||
| 967 | |||
| 968 | kfree(st->channels); | ||
| 969 | kfree(st->iio_attr); | ||
| 970 | |||
| 971 | return 0; | ||
| 972 | } | 956 | } |
| 973 | 957 | ||
| 974 | static const struct spi_device_id ad7280_id[] = { | 958 | static const struct spi_device_id ad7280_id[] = { |
| @@ -982,7 +966,6 @@ static struct spi_driver ad7280_driver = { | |||
| 982 | .name = "ad7280", | 966 | .name = "ad7280", |
| 983 | }, | 967 | }, |
| 984 | .probe = ad7280_probe, | 968 | .probe = ad7280_probe, |
| 985 | .remove = ad7280_remove, | ||
| 986 | .id_table = ad7280_id, | 969 | .id_table = ad7280_id, |
| 987 | }; | 970 | }; |
| 988 | module_spi_driver(ad7280_driver); | 971 | module_spi_driver(ad7280_driver); |
diff --git a/drivers/staging/iio/adc/ad7606.c b/drivers/staging/iio/adc/ad7606.c index 048c205b979e..7308fa8fbb4c 100644 --- a/drivers/staging/iio/adc/ad7606.c +++ b/drivers/staging/iio/adc/ad7606.c | |||
| @@ -374,7 +374,7 @@ static int ad7606_request_gpios(struct ad7606_state *st) | |||
| 374 | return 0; | 374 | return 0; |
| 375 | 375 | ||
| 376 | st->gpio_os = devm_gpiod_get_array_optional(dev, "oversampling-ratio", | 376 | st->gpio_os = devm_gpiod_get_array_optional(dev, "oversampling-ratio", |
| 377 | GPIOD_OUT_LOW); | 377 | GPIOD_OUT_LOW); |
| 378 | return PTR_ERR_OR_ZERO(st->gpio_os); | 378 | return PTR_ERR_OR_ZERO(st->gpio_os); |
| 379 | } | 379 | } |
| 380 | 380 | ||
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index b67412db0318..c4a85789c2db 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c | |||
| @@ -22,19 +22,28 @@ | |||
| 22 | #include <linux/iio/sysfs.h> | 22 | #include <linux/iio/sysfs.h> |
| 23 | #include <linux/iio/adc/ad_sigma_delta.h> | 23 | #include <linux/iio/adc/ad_sigma_delta.h> |
| 24 | 24 | ||
| 25 | #define AD7780_RDY BIT(7) | 25 | #define AD7780_RDY BIT(7) |
| 26 | #define AD7780_FILTER BIT(6) | 26 | #define AD7780_FILTER BIT(6) |
| 27 | #define AD7780_ERR BIT(5) | 27 | #define AD7780_ERR BIT(5) |
| 28 | #define AD7780_ID1 BIT(4) | 28 | #define AD7780_ID1 BIT(4) |
| 29 | #define AD7780_ID0 BIT(3) | 29 | #define AD7780_ID0 BIT(3) |
| 30 | #define AD7780_GAIN BIT(2) | 30 | #define AD7780_GAIN BIT(2) |
| 31 | #define AD7780_PAT1 BIT(1) | 31 | #define AD7780_PAT1 BIT(1) |
| 32 | #define AD7780_PAT0 BIT(0) | 32 | #define AD7780_PAT0 BIT(0) |
| 33 | |||
| 34 | #define AD7780_PATTERN (AD7780_PAT0) | ||
| 35 | #define AD7780_PATTERN_MASK (AD7780_PAT0 | AD7780_PAT1) | ||
| 36 | |||
| 37 | #define AD7170_PAT2 BIT(2) | ||
| 38 | |||
| 39 | #define AD7170_PATTERN (AD7780_PAT0 | AD7170_PAT2) | ||
| 40 | #define AD7170_PATTERN_MASK (AD7780_PAT0 | AD7780_PAT1 | AD7170_PAT2) | ||
| 33 | 41 | ||
| 34 | struct ad7780_chip_info { | 42 | struct ad7780_chip_info { |
| 35 | struct iio_chan_spec channel; | 43 | struct iio_chan_spec channel; |
| 36 | unsigned int pattern_mask; | 44 | unsigned int pattern_mask; |
| 37 | unsigned int pattern; | 45 | unsigned int pattern; |
| 46 | bool is_ad778x; | ||
| 38 | }; | 47 | }; |
| 39 | 48 | ||
| 40 | struct ad7780_state { | 49 | struct ad7780_state { |
| @@ -42,7 +51,6 @@ struct ad7780_state { | |||
| 42 | struct regulator *reg; | 51 | struct regulator *reg; |
| 43 | struct gpio_desc *powerdown_gpio; | 52 | struct gpio_desc *powerdown_gpio; |
| 44 | unsigned int gain; | 53 | unsigned int gain; |
| 45 | u16 int_vref_mv; | ||
| 46 | 54 | ||
| 47 | struct ad_sigma_delta sd; | 55 | struct ad_sigma_delta sd; |
| 48 | }; | 56 | }; |
| @@ -87,16 +95,20 @@ static int ad7780_read_raw(struct iio_dev *indio_dev, | |||
| 87 | long m) | 95 | long m) |
| 88 | { | 96 | { |
| 89 | struct ad7780_state *st = iio_priv(indio_dev); | 97 | struct ad7780_state *st = iio_priv(indio_dev); |
| 98 | int voltage_uv; | ||
| 90 | 99 | ||
| 91 | switch (m) { | 100 | switch (m) { |
| 92 | case IIO_CHAN_INFO_RAW: | 101 | case IIO_CHAN_INFO_RAW: |
| 93 | return ad_sigma_delta_single_conversion(indio_dev, chan, val); | 102 | return ad_sigma_delta_single_conversion(indio_dev, chan, val); |
| 94 | case IIO_CHAN_INFO_SCALE: | 103 | case IIO_CHAN_INFO_SCALE: |
| 95 | *val = st->int_vref_mv * st->gain; | 104 | voltage_uv = regulator_get_voltage(st->reg); |
| 105 | if (voltage_uv < 0) | ||
| 106 | return voltage_uv; | ||
| 107 | *val = (voltage_uv / 1000) * st->gain; | ||
| 96 | *val2 = chan->scan_type.realbits - 1; | 108 | *val2 = chan->scan_type.realbits - 1; |
| 97 | return IIO_VAL_FRACTIONAL_LOG2; | 109 | return IIO_VAL_FRACTIONAL_LOG2; |
| 98 | case IIO_CHAN_INFO_OFFSET: | 110 | case IIO_CHAN_INFO_OFFSET: |
| 99 | *val -= (1 << (chan->scan_type.realbits - 1)); | 111 | *val = -(1 << (chan->scan_type.realbits - 1)); |
| 100 | return IIO_VAL_INT; | 112 | return IIO_VAL_INT; |
| 101 | } | 113 | } |
| 102 | 114 | ||
| @@ -113,10 +125,12 @@ static int ad7780_postprocess_sample(struct ad_sigma_delta *sigma_delta, | |||
| 113 | ((raw_sample & chip_info->pattern_mask) != chip_info->pattern)) | 125 | ((raw_sample & chip_info->pattern_mask) != chip_info->pattern)) |
| 114 | return -EIO; | 126 | return -EIO; |
| 115 | 127 | ||
| 116 | if (raw_sample & AD7780_GAIN) | 128 | if (chip_info->is_ad778x) { |
| 117 | st->gain = 1; | 129 | if (raw_sample & AD7780_GAIN) |
| 118 | else | 130 | st->gain = 1; |
| 119 | st->gain = 128; | 131 | else |
| 132 | st->gain = 128; | ||
| 133 | } | ||
| 120 | 134 | ||
| 121 | return 0; | 135 | return 0; |
| 122 | } | 136 | } |
| @@ -133,23 +147,27 @@ static const struct ad_sigma_delta_info ad7780_sigma_delta_info = { | |||
| 133 | static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { | 147 | static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { |
| 134 | [ID_AD7170] = { | 148 | [ID_AD7170] = { |
| 135 | .channel = AD7780_CHANNEL(12, 24), | 149 | .channel = AD7780_CHANNEL(12, 24), |
| 136 | .pattern = 0x5, | 150 | .pattern = AD7170_PATTERN, |
| 137 | .pattern_mask = 0x7, | 151 | .pattern_mask = AD7170_PATTERN_MASK, |
| 152 | .is_ad778x = false, | ||
| 138 | }, | 153 | }, |
| 139 | [ID_AD7171] = { | 154 | [ID_AD7171] = { |
| 140 | .channel = AD7780_CHANNEL(16, 24), | 155 | .channel = AD7780_CHANNEL(16, 24), |
| 141 | .pattern = 0x5, | 156 | .pattern = AD7170_PATTERN, |
| 142 | .pattern_mask = 0x7, | 157 | .pattern_mask = AD7170_PATTERN_MASK, |
| 158 | .is_ad778x = false, | ||
| 143 | }, | 159 | }, |
| 144 | [ID_AD7780] = { | 160 | [ID_AD7780] = { |
| 145 | .channel = AD7780_CHANNEL(24, 32), | 161 | .channel = AD7780_CHANNEL(24, 32), |
| 146 | .pattern = 0x1, | 162 | .pattern = AD7780_PATTERN, |
| 147 | .pattern_mask = 0x3, | 163 | .pattern_mask = AD7780_PATTERN_MASK, |
| 164 | .is_ad778x = true, | ||
| 148 | }, | 165 | }, |
| 149 | [ID_AD7781] = { | 166 | [ID_AD7781] = { |
| 150 | .channel = AD7780_CHANNEL(20, 32), | 167 | .channel = AD7780_CHANNEL(20, 32), |
| 151 | .pattern = 0x1, | 168 | .pattern = AD7780_PATTERN, |
| 152 | .pattern_mask = 0x3, | 169 | .pattern_mask = AD7780_PATTERN_MASK, |
| 170 | .is_ad778x = true, | ||
| 153 | }, | 171 | }, |
| 154 | }; | 172 | }; |
| 155 | 173 | ||
| @@ -161,7 +179,7 @@ static int ad7780_probe(struct spi_device *spi) | |||
| 161 | { | 179 | { |
| 162 | struct ad7780_state *st; | 180 | struct ad7780_state *st; |
| 163 | struct iio_dev *indio_dev; | 181 | struct iio_dev *indio_dev; |
| 164 | int ret, voltage_uv = 0; | 182 | int ret; |
| 165 | 183 | ||
| 166 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | 184 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); |
| 167 | if (!indio_dev) | 185 | if (!indio_dev) |
| @@ -181,16 +199,10 @@ static int ad7780_probe(struct spi_device *spi) | |||
| 181 | dev_err(&spi->dev, "Failed to enable specified AVdd supply\n"); | 199 | dev_err(&spi->dev, "Failed to enable specified AVdd supply\n"); |
| 182 | return ret; | 200 | return ret; |
| 183 | } | 201 | } |
| 184 | voltage_uv = regulator_get_voltage(st->reg); | ||
| 185 | 202 | ||
| 186 | st->chip_info = | 203 | st->chip_info = |
| 187 | &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data]; | 204 | &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data]; |
| 188 | 205 | ||
| 189 | if (voltage_uv) | ||
| 190 | st->int_vref_mv = voltage_uv / 1000; | ||
| 191 | else | ||
| 192 | dev_warn(&spi->dev, "Reference voltage unspecified\n"); | ||
| 193 | |||
| 194 | spi_set_drvdata(spi, indio_dev); | 206 | spi_set_drvdata(spi, indio_dev); |
| 195 | 207 | ||
| 196 | indio_dev->dev.parent = &spi->dev; | 208 | indio_dev->dev.parent = &spi->dev; |
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index bf76a8620bdb..5209651a1b25 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
| 10 | #include <linux/gpio.h> | 10 | #include <linux/gpio/consumer.h> |
| 11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
| 12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| 13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| @@ -43,15 +43,22 @@ | |||
| 43 | */ | 43 | */ |
| 44 | 44 | ||
| 45 | struct ad7816_chip_info { | 45 | struct ad7816_chip_info { |
| 46 | kernel_ulong_t id; | ||
| 46 | struct spi_device *spi_dev; | 47 | struct spi_device *spi_dev; |
| 47 | u16 rdwr_pin; | 48 | struct gpio_desc *rdwr_pin; |
| 48 | u16 convert_pin; | 49 | struct gpio_desc *convert_pin; |
| 49 | u16 busy_pin; | 50 | struct gpio_desc *busy_pin; |
| 50 | u8 oti_data[AD7816_CS_MAX + 1]; | 51 | u8 oti_data[AD7816_CS_MAX + 1]; |
| 51 | u8 channel_id; /* 0 always be temperature */ | 52 | u8 channel_id; /* 0 always be temperature */ |
| 52 | u8 mode; | 53 | u8 mode; |
| 53 | }; | 54 | }; |
| 54 | 55 | ||
| 56 | enum ad7816_type { | ||
| 57 | ID_AD7816, | ||
| 58 | ID_AD7817, | ||
| 59 | ID_AD7818, | ||
| 60 | }; | ||
| 61 | |||
| 55 | /* | 62 | /* |
| 56 | * ad7816 data access by SPI | 63 | * ad7816 data access by SPI |
| 57 | */ | 64 | */ |
| @@ -61,28 +68,30 @@ static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data) | |||
| 61 | int ret = 0; | 68 | int ret = 0; |
| 62 | __be16 buf; | 69 | __be16 buf; |
| 63 | 70 | ||
| 64 | gpio_set_value(chip->rdwr_pin, 1); | 71 | gpiod_set_value(chip->rdwr_pin, 1); |
| 65 | gpio_set_value(chip->rdwr_pin, 0); | 72 | gpiod_set_value(chip->rdwr_pin, 0); |
| 66 | ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id)); | 73 | ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id)); |
| 67 | if (ret < 0) { | 74 | if (ret < 0) { |
| 68 | dev_err(&spi_dev->dev, "SPI channel setting error\n"); | 75 | dev_err(&spi_dev->dev, "SPI channel setting error\n"); |
| 69 | return ret; | 76 | return ret; |
| 70 | } | 77 | } |
| 71 | gpio_set_value(chip->rdwr_pin, 1); | 78 | gpiod_set_value(chip->rdwr_pin, 1); |
| 72 | 79 | ||
| 73 | if (chip->mode == AD7816_PD) { /* operating mode 2 */ | 80 | if (chip->mode == AD7816_PD) { /* operating mode 2 */ |
| 74 | gpio_set_value(chip->convert_pin, 1); | 81 | gpiod_set_value(chip->convert_pin, 1); |
| 75 | gpio_set_value(chip->convert_pin, 0); | 82 | gpiod_set_value(chip->convert_pin, 0); |
| 76 | } else { /* operating mode 1 */ | 83 | } else { /* operating mode 1 */ |
| 77 | gpio_set_value(chip->convert_pin, 0); | 84 | gpiod_set_value(chip->convert_pin, 0); |
| 78 | gpio_set_value(chip->convert_pin, 1); | 85 | gpiod_set_value(chip->convert_pin, 1); |
| 79 | } | 86 | } |
| 80 | 87 | ||
| 81 | while (gpio_get_value(chip->busy_pin)) | 88 | if (chip->id == ID_AD7816 || chip->id == ID_AD7817) { |
| 82 | cpu_relax(); | 89 | while (gpiod_get_value(chip->busy_pin)) |
| 90 | cpu_relax(); | ||
| 91 | } | ||
| 83 | 92 | ||
| 84 | gpio_set_value(chip->rdwr_pin, 0); | 93 | gpiod_set_value(chip->rdwr_pin, 0); |
| 85 | gpio_set_value(chip->rdwr_pin, 1); | 94 | gpiod_set_value(chip->rdwr_pin, 1); |
| 86 | ret = spi_read(spi_dev, &buf, sizeof(*data)); | 95 | ret = spi_read(spi_dev, &buf, sizeof(*data)); |
| 87 | if (ret < 0) { | 96 | if (ret < 0) { |
| 88 | dev_err(&spi_dev->dev, "SPI data read error\n"); | 97 | dev_err(&spi_dev->dev, "SPI data read error\n"); |
| @@ -99,8 +108,8 @@ static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data) | |||
| 99 | struct spi_device *spi_dev = chip->spi_dev; | 108 | struct spi_device *spi_dev = chip->spi_dev; |
| 100 | int ret = 0; | 109 | int ret = 0; |
| 101 | 110 | ||
| 102 | gpio_set_value(chip->rdwr_pin, 1); | 111 | gpiod_set_value(chip->rdwr_pin, 1); |
| 103 | gpio_set_value(chip->rdwr_pin, 0); | 112 | gpiod_set_value(chip->rdwr_pin, 0); |
| 104 | ret = spi_write(spi_dev, &data, sizeof(data)); | 113 | ret = spi_write(spi_dev, &data, sizeof(data)); |
| 105 | if (ret < 0) | 114 | if (ret < 0) |
| 106 | dev_err(&spi_dev->dev, "SPI oti data write error\n"); | 115 | dev_err(&spi_dev->dev, "SPI oti data write error\n"); |
| @@ -129,10 +138,10 @@ static ssize_t ad7816_store_mode(struct device *dev, | |||
| 129 | struct ad7816_chip_info *chip = iio_priv(indio_dev); | 138 | struct ad7816_chip_info *chip = iio_priv(indio_dev); |
| 130 | 139 | ||
| 131 | if (strcmp(buf, "full")) { | 140 | if (strcmp(buf, "full")) { |
| 132 | gpio_set_value(chip->rdwr_pin, 1); | 141 | gpiod_set_value(chip->rdwr_pin, 1); |
| 133 | chip->mode = AD7816_FULL; | 142 | chip->mode = AD7816_FULL; |
| 134 | } else { | 143 | } else { |
| 135 | gpio_set_value(chip->rdwr_pin, 0); | 144 | gpiod_set_value(chip->rdwr_pin, 0); |
| 136 | chip->mode = AD7816_PD; | 145 | chip->mode = AD7816_PD; |
| 137 | } | 146 | } |
| 138 | 147 | ||
| @@ -345,15 +354,9 @@ static int ad7816_probe(struct spi_device *spi_dev) | |||
| 345 | { | 354 | { |
| 346 | struct ad7816_chip_info *chip; | 355 | struct ad7816_chip_info *chip; |
| 347 | struct iio_dev *indio_dev; | 356 | struct iio_dev *indio_dev; |
| 348 | unsigned short *pins = dev_get_platdata(&spi_dev->dev); | ||
| 349 | int ret = 0; | 357 | int ret = 0; |
| 350 | int i; | 358 | int i; |
| 351 | 359 | ||
| 352 | if (!pins) { | ||
| 353 | dev_err(&spi_dev->dev, "No necessary GPIO platform data.\n"); | ||
| 354 | return -EINVAL; | ||
| 355 | } | ||
| 356 | |||
| 357 | indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip)); | 360 | indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip)); |
| 358 | if (!indio_dev) | 361 | if (!indio_dev) |
| 359 | return -ENOMEM; | 362 | return -ENOMEM; |
| @@ -364,34 +367,33 @@ static int ad7816_probe(struct spi_device *spi_dev) | |||
| 364 | chip->spi_dev = spi_dev; | 367 | chip->spi_dev = spi_dev; |
| 365 | for (i = 0; i <= AD7816_CS_MAX; i++) | 368 | for (i = 0; i <= AD7816_CS_MAX; i++) |
| 366 | chip->oti_data[i] = 203; | 369 | chip->oti_data[i] = 203; |
| 367 | chip->rdwr_pin = pins[0]; | 370 | |
| 368 | chip->convert_pin = pins[1]; | 371 | chip->id = spi_get_device_id(spi_dev)->driver_data; |
| 369 | chip->busy_pin = pins[2]; | 372 | chip->rdwr_pin = devm_gpiod_get(&spi_dev->dev, "rdwr", GPIOD_OUT_HIGH); |
| 370 | 373 | if (IS_ERR(chip->rdwr_pin)) { | |
| 371 | ret = devm_gpio_request(&spi_dev->dev, chip->rdwr_pin, | 374 | ret = PTR_ERR(chip->rdwr_pin); |
| 372 | spi_get_device_id(spi_dev)->name); | 375 | dev_err(&spi_dev->dev, "Failed to request rdwr GPIO: %d\n", |
| 373 | if (ret) { | 376 | ret); |
| 374 | dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n", | ||
| 375 | chip->rdwr_pin); | ||
| 376 | return ret; | 377 | return ret; |
| 377 | } | 378 | } |
| 378 | gpio_direction_input(chip->rdwr_pin); | 379 | chip->convert_pin = devm_gpiod_get(&spi_dev->dev, "convert", |
| 379 | ret = devm_gpio_request(&spi_dev->dev, chip->convert_pin, | 380 | GPIOD_OUT_HIGH); |
| 380 | spi_get_device_id(spi_dev)->name); | 381 | if (IS_ERR(chip->convert_pin)) { |
| 381 | if (ret) { | 382 | ret = PTR_ERR(chip->convert_pin); |
| 382 | dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n", | 383 | dev_err(&spi_dev->dev, "Failed to request convert GPIO: %d\n", |
| 383 | chip->convert_pin); | 384 | ret); |
| 384 | return ret; | 385 | return ret; |
| 385 | } | 386 | } |
| 386 | gpio_direction_input(chip->convert_pin); | 387 | if (chip->id == ID_AD7816 || chip->id == ID_AD7817) { |
| 387 | ret = devm_gpio_request(&spi_dev->dev, chip->busy_pin, | 388 | chip->busy_pin = devm_gpiod_get(&spi_dev->dev, "busy", |
| 388 | spi_get_device_id(spi_dev)->name); | 389 | GPIOD_IN); |
| 389 | if (ret) { | 390 | if (IS_ERR(chip->busy_pin)) { |
| 390 | dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n", | 391 | ret = PTR_ERR(chip->busy_pin); |
| 391 | chip->busy_pin); | 392 | dev_err(&spi_dev->dev, "Failed to request busy GPIO: %d\n", |
| 392 | return ret; | 393 | ret); |
| 394 | return ret; | ||
| 395 | } | ||
| 393 | } | 396 | } |
| 394 | gpio_direction_input(chip->busy_pin); | ||
| 395 | 397 | ||
| 396 | indio_dev->name = spi_get_device_id(spi_dev)->name; | 398 | indio_dev->name = spi_get_device_id(spi_dev)->name; |
| 397 | indio_dev->dev.parent = &spi_dev->dev; | 399 | indio_dev->dev.parent = &spi_dev->dev; |
| @@ -420,10 +422,18 @@ static int ad7816_probe(struct spi_device *spi_dev) | |||
| 420 | return 0; | 422 | return 0; |
| 421 | } | 423 | } |
| 422 | 424 | ||
| 425 | static const struct of_device_id ad7816_of_match[] = { | ||
| 426 | { .compatible = "adi,ad7816", }, | ||
| 427 | { .compatible = "adi,ad7817", }, | ||
| 428 | { .compatible = "adi,ad7818", }, | ||
| 429 | { } | ||
| 430 | }; | ||
| 431 | MODULE_DEVICE_TABLE(of, ad7816_of_match); | ||
| 432 | |||
| 423 | static const struct spi_device_id ad7816_id[] = { | 433 | static const struct spi_device_id ad7816_id[] = { |
| 424 | { "ad7816", 0 }, | 434 | { "ad7816", ID_AD7816 }, |
| 425 | { "ad7817", 0 }, | 435 | { "ad7817", ID_AD7817 }, |
| 426 | { "ad7818", 0 }, | 436 | { "ad7818", ID_AD7818 }, |
| 427 | {} | 437 | {} |
| 428 | }; | 438 | }; |
| 429 | 439 | ||
| @@ -432,6 +442,7 @@ MODULE_DEVICE_TABLE(spi, ad7816_id); | |||
| 432 | static struct spi_driver ad7816_driver = { | 442 | static struct spi_driver ad7816_driver = { |
| 433 | .driver = { | 443 | .driver = { |
| 434 | .name = "ad7816", | 444 | .name = "ad7816", |
| 445 | .of_match_table = ad7816_of_match, | ||
| 435 | }, | 446 | }, |
| 436 | .probe = ad7816_probe, | 447 | .probe = ad7816_probe, |
| 437 | .id_table = ad7816_id, | 448 | .id_table = ad7816_id, |
diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c index f66dd3ebbab1..473e5e34ec00 100644 --- a/drivers/staging/iio/addac/adt7316-i2c.c +++ b/drivers/staging/iio/addac/adt7316-i2c.c | |||
| @@ -30,11 +30,17 @@ static int adt7316_i2c_read(void *client, u8 reg, u8 *data) | |||
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | ret = i2c_smbus_read_byte(client); | 32 | ret = i2c_smbus_read_byte(client); |
| 33 | |||
| 34 | if (!ret) | ||
| 35 | return -EIO; | ||
| 36 | |||
| 33 | if (ret < 0) { | 37 | if (ret < 0) { |
| 34 | dev_err(&cl->dev, "I2C read error\n"); | 38 | dev_err(&cl->dev, "I2C read error\n"); |
| 35 | return ret; | 39 | return ret; |
| 36 | } | 40 | } |
| 37 | 41 | ||
| 42 | *data = ret; | ||
| 43 | |||
| 38 | return 0; | 44 | return 0; |
| 39 | } | 45 | } |
| 40 | 46 | ||
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index 3f22d1088713..2f8a122f475d 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c | |||
| @@ -217,8 +217,8 @@ struct adt7316_limit_regs { | |||
| 217 | }; | 217 | }; |
| 218 | 218 | ||
| 219 | static ssize_t adt7316_show_enabled(struct device *dev, | 219 | static ssize_t adt7316_show_enabled(struct device *dev, |
| 220 | struct device_attribute *attr, | 220 | struct device_attribute *attr, |
| 221 | char *buf) | 221 | char *buf) |
| 222 | { | 222 | { |
| 223 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 223 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 224 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 224 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -227,7 +227,7 @@ static ssize_t adt7316_show_enabled(struct device *dev, | |||
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | static ssize_t _adt7316_store_enabled(struct adt7316_chip_info *chip, | 229 | static ssize_t _adt7316_store_enabled(struct adt7316_chip_info *chip, |
| 230 | int enable) | 230 | int enable) |
| 231 | { | 231 | { |
| 232 | u8 config1; | 232 | u8 config1; |
| 233 | int ret; | 233 | int ret; |
| @@ -247,9 +247,9 @@ static ssize_t _adt7316_store_enabled(struct adt7316_chip_info *chip, | |||
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | static ssize_t adt7316_store_enabled(struct device *dev, | 249 | static ssize_t adt7316_store_enabled(struct device *dev, |
| 250 | struct device_attribute *attr, | 250 | struct device_attribute *attr, |
| 251 | const char *buf, | 251 | const char *buf, |
| 252 | size_t len) | 252 | size_t len) |
| 253 | { | 253 | { |
| 254 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 254 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 255 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 255 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -272,8 +272,8 @@ static IIO_DEVICE_ATTR(enabled, 0644, | |||
| 272 | 0); | 272 | 0); |
| 273 | 273 | ||
| 274 | static ssize_t adt7316_show_select_ex_temp(struct device *dev, | 274 | static ssize_t adt7316_show_select_ex_temp(struct device *dev, |
| 275 | struct device_attribute *attr, | 275 | struct device_attribute *attr, |
| 276 | char *buf) | 276 | char *buf) |
| 277 | { | 277 | { |
| 278 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 278 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 279 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 279 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -285,9 +285,9 @@ static ssize_t adt7316_show_select_ex_temp(struct device *dev, | |||
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | static ssize_t adt7316_store_select_ex_temp(struct device *dev, | 287 | static ssize_t adt7316_store_select_ex_temp(struct device *dev, |
| 288 | struct device_attribute *attr, | 288 | struct device_attribute *attr, |
| 289 | const char *buf, | 289 | const char *buf, |
| 290 | size_t len) | 290 | size_t len) |
| 291 | { | 291 | { |
| 292 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 292 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 293 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 293 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -316,8 +316,8 @@ static IIO_DEVICE_ATTR(select_ex_temp, 0644, | |||
| 316 | 0); | 316 | 0); |
| 317 | 317 | ||
| 318 | static ssize_t adt7316_show_mode(struct device *dev, | 318 | static ssize_t adt7316_show_mode(struct device *dev, |
| 319 | struct device_attribute *attr, | 319 | struct device_attribute *attr, |
| 320 | char *buf) | 320 | char *buf) |
| 321 | { | 321 | { |
| 322 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 322 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 323 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 323 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -329,9 +329,9 @@ static ssize_t adt7316_show_mode(struct device *dev, | |||
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | static ssize_t adt7316_store_mode(struct device *dev, | 331 | static ssize_t adt7316_store_mode(struct device *dev, |
| 332 | struct device_attribute *attr, | 332 | struct device_attribute *attr, |
| 333 | const char *buf, | 333 | const char *buf, |
| 334 | size_t len) | 334 | size_t len) |
| 335 | { | 335 | { |
| 336 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 336 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 337 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 337 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -357,8 +357,8 @@ static IIO_DEVICE_ATTR(mode, 0644, | |||
| 357 | 0); | 357 | 0); |
| 358 | 358 | ||
| 359 | static ssize_t adt7316_show_all_modes(struct device *dev, | 359 | static ssize_t adt7316_show_all_modes(struct device *dev, |
| 360 | struct device_attribute *attr, | 360 | struct device_attribute *attr, |
| 361 | char *buf) | 361 | char *buf) |
| 362 | { | 362 | { |
| 363 | return sprintf(buf, "single_channel\nround_robin\n"); | 363 | return sprintf(buf, "single_channel\nround_robin\n"); |
| 364 | } | 364 | } |
| @@ -366,8 +366,8 @@ static ssize_t adt7316_show_all_modes(struct device *dev, | |||
| 366 | static IIO_DEVICE_ATTR(all_modes, 0444, adt7316_show_all_modes, NULL, 0); | 366 | static IIO_DEVICE_ATTR(all_modes, 0444, adt7316_show_all_modes, NULL, 0); |
| 367 | 367 | ||
| 368 | static ssize_t adt7316_show_ad_channel(struct device *dev, | 368 | static ssize_t adt7316_show_ad_channel(struct device *dev, |
| 369 | struct device_attribute *attr, | 369 | struct device_attribute *attr, |
| 370 | char *buf) | 370 | char *buf) |
| 371 | { | 371 | { |
| 372 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 372 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 373 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 373 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -382,7 +382,7 @@ static ssize_t adt7316_show_ad_channel(struct device *dev, | |||
| 382 | return sprintf(buf, "1 - Internal Temperature\n"); | 382 | return sprintf(buf, "1 - Internal Temperature\n"); |
| 383 | case ADT7316_AD_SINGLE_CH_EX: | 383 | case ADT7316_AD_SINGLE_CH_EX: |
| 384 | if (((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) && | 384 | if (((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) && |
| 385 | (chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) | 385 | (chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) |
| 386 | return sprintf(buf, "2 - AIN1\n"); | 386 | return sprintf(buf, "2 - AIN1\n"); |
| 387 | 387 | ||
| 388 | return sprintf(buf, "2 - External Temperature\n"); | 388 | return sprintf(buf, "2 - External Temperature\n"); |
| @@ -404,9 +404,9 @@ static ssize_t adt7316_show_ad_channel(struct device *dev, | |||
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | static ssize_t adt7316_store_ad_channel(struct device *dev, | 406 | static ssize_t adt7316_store_ad_channel(struct device *dev, |
| 407 | struct device_attribute *attr, | 407 | struct device_attribute *attr, |
| 408 | const char *buf, | 408 | const char *buf, |
| 409 | size_t len) | 409 | size_t len) |
| 410 | { | 410 | { |
| 411 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 411 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 412 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 412 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -450,8 +450,8 @@ static IIO_DEVICE_ATTR(ad_channel, 0644, | |||
| 450 | 0); | 450 | 0); |
| 451 | 451 | ||
| 452 | static ssize_t adt7316_show_all_ad_channels(struct device *dev, | 452 | static ssize_t adt7316_show_all_ad_channels(struct device *dev, |
| 453 | struct device_attribute *attr, | 453 | struct device_attribute *attr, |
| 454 | char *buf) | 454 | char *buf) |
| 455 | { | 455 | { |
| 456 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 456 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 457 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 457 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -471,8 +471,8 @@ static IIO_DEVICE_ATTR(all_ad_channels, 0444, | |||
| 471 | adt7316_show_all_ad_channels, NULL, 0); | 471 | adt7316_show_all_ad_channels, NULL, 0); |
| 472 | 472 | ||
| 473 | static ssize_t adt7316_show_disable_averaging(struct device *dev, | 473 | static ssize_t adt7316_show_disable_averaging(struct device *dev, |
| 474 | struct device_attribute *attr, | 474 | struct device_attribute *attr, |
| 475 | char *buf) | 475 | char *buf) |
| 476 | { | 476 | { |
| 477 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 477 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 478 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 478 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -482,9 +482,9 @@ static ssize_t adt7316_show_disable_averaging(struct device *dev, | |||
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | static ssize_t adt7316_store_disable_averaging(struct device *dev, | 484 | static ssize_t adt7316_store_disable_averaging(struct device *dev, |
| 485 | struct device_attribute *attr, | 485 | struct device_attribute *attr, |
| 486 | const char *buf, | 486 | const char *buf, |
| 487 | size_t len) | 487 | size_t len) |
| 488 | { | 488 | { |
| 489 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 489 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 490 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 490 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -510,8 +510,8 @@ static IIO_DEVICE_ATTR(disable_averaging, 0644, | |||
| 510 | 0); | 510 | 0); |
| 511 | 511 | ||
| 512 | static ssize_t adt7316_show_enable_smbus_timeout(struct device *dev, | 512 | static ssize_t adt7316_show_enable_smbus_timeout(struct device *dev, |
| 513 | struct device_attribute *attr, | 513 | struct device_attribute *attr, |
| 514 | char *buf) | 514 | char *buf) |
| 515 | { | 515 | { |
| 516 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 516 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 517 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 517 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -521,9 +521,9 @@ static ssize_t adt7316_show_enable_smbus_timeout(struct device *dev, | |||
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | static ssize_t adt7316_store_enable_smbus_timeout(struct device *dev, | 523 | static ssize_t adt7316_store_enable_smbus_timeout(struct device *dev, |
| 524 | struct device_attribute *attr, | 524 | struct device_attribute *attr, |
| 525 | const char *buf, | 525 | const char *buf, |
| 526 | size_t len) | 526 | size_t len) |
| 527 | { | 527 | { |
| 528 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 528 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 529 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 529 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -549,8 +549,8 @@ static IIO_DEVICE_ATTR(enable_smbus_timeout, 0644, | |||
| 549 | 0); | 549 | 0); |
| 550 | 550 | ||
| 551 | static ssize_t adt7316_show_powerdown(struct device *dev, | 551 | static ssize_t adt7316_show_powerdown(struct device *dev, |
| 552 | struct device_attribute *attr, | 552 | struct device_attribute *attr, |
| 553 | char *buf) | 553 | char *buf) |
| 554 | { | 554 | { |
| 555 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 555 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 556 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 556 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -559,9 +559,9 @@ static ssize_t adt7316_show_powerdown(struct device *dev, | |||
| 559 | } | 559 | } |
| 560 | 560 | ||
| 561 | static ssize_t adt7316_store_powerdown(struct device *dev, | 561 | static ssize_t adt7316_store_powerdown(struct device *dev, |
| 562 | struct device_attribute *attr, | 562 | struct device_attribute *attr, |
| 563 | const char *buf, | 563 | const char *buf, |
| 564 | size_t len) | 564 | size_t len) |
| 565 | { | 565 | { |
| 566 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 566 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 567 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 567 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -587,8 +587,8 @@ static IIO_DEVICE_ATTR(powerdown, 0644, | |||
| 587 | 0); | 587 | 0); |
| 588 | 588 | ||
| 589 | static ssize_t adt7316_show_fast_ad_clock(struct device *dev, | 589 | static ssize_t adt7316_show_fast_ad_clock(struct device *dev, |
| 590 | struct device_attribute *attr, | 590 | struct device_attribute *attr, |
| 591 | char *buf) | 591 | char *buf) |
| 592 | { | 592 | { |
| 593 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 593 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 594 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 594 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -597,9 +597,9 @@ static ssize_t adt7316_show_fast_ad_clock(struct device *dev, | |||
| 597 | } | 597 | } |
| 598 | 598 | ||
| 599 | static ssize_t adt7316_store_fast_ad_clock(struct device *dev, | 599 | static ssize_t adt7316_store_fast_ad_clock(struct device *dev, |
| 600 | struct device_attribute *attr, | 600 | struct device_attribute *attr, |
| 601 | const char *buf, | 601 | const char *buf, |
| 602 | size_t len) | 602 | size_t len) |
| 603 | { | 603 | { |
| 604 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 604 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 605 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 605 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -625,8 +625,8 @@ static IIO_DEVICE_ATTR(fast_ad_clock, 0644, | |||
| 625 | 0); | 625 | 0); |
| 626 | 626 | ||
| 627 | static ssize_t adt7316_show_da_high_resolution(struct device *dev, | 627 | static ssize_t adt7316_show_da_high_resolution(struct device *dev, |
| 628 | struct device_attribute *attr, | 628 | struct device_attribute *attr, |
| 629 | char *buf) | 629 | char *buf) |
| 630 | { | 630 | { |
| 631 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 631 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 632 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 632 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -642,9 +642,9 @@ static ssize_t adt7316_show_da_high_resolution(struct device *dev, | |||
| 642 | } | 642 | } |
| 643 | 643 | ||
| 644 | static ssize_t adt7316_store_da_high_resolution(struct device *dev, | 644 | static ssize_t adt7316_store_da_high_resolution(struct device *dev, |
| 645 | struct device_attribute *attr, | 645 | struct device_attribute *attr, |
| 646 | const char *buf, | 646 | const char *buf, |
| 647 | size_t len) | 647 | size_t len) |
| 648 | { | 648 | { |
| 649 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 649 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 650 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 650 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -678,8 +678,8 @@ static IIO_DEVICE_ATTR(da_high_resolution, 0644, | |||
| 678 | 0); | 678 | 0); |
| 679 | 679 | ||
| 680 | static ssize_t adt7316_show_AIN_internal_Vref(struct device *dev, | 680 | static ssize_t adt7316_show_AIN_internal_Vref(struct device *dev, |
| 681 | struct device_attribute *attr, | 681 | struct device_attribute *attr, |
| 682 | char *buf) | 682 | char *buf) |
| 683 | { | 683 | { |
| 684 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 684 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 685 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 685 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -692,9 +692,9 @@ static ssize_t adt7316_show_AIN_internal_Vref(struct device *dev, | |||
| 692 | } | 692 | } |
| 693 | 693 | ||
| 694 | static ssize_t adt7316_store_AIN_internal_Vref(struct device *dev, | 694 | static ssize_t adt7316_store_AIN_internal_Vref(struct device *dev, |
| 695 | struct device_attribute *attr, | 695 | struct device_attribute *attr, |
| 696 | const char *buf, | 696 | const char *buf, |
| 697 | size_t len) | 697 | size_t len) |
| 698 | { | 698 | { |
| 699 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 699 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 700 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 700 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -724,8 +724,8 @@ static IIO_DEVICE_ATTR(AIN_internal_Vref, 0644, | |||
| 724 | 0); | 724 | 0); |
| 725 | 725 | ||
| 726 | static ssize_t adt7316_show_enable_prop_DACA(struct device *dev, | 726 | static ssize_t adt7316_show_enable_prop_DACA(struct device *dev, |
| 727 | struct device_attribute *attr, | 727 | struct device_attribute *attr, |
| 728 | char *buf) | 728 | char *buf) |
| 729 | { | 729 | { |
| 730 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 730 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 731 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 731 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -735,9 +735,9 @@ static ssize_t adt7316_show_enable_prop_DACA(struct device *dev, | |||
| 735 | } | 735 | } |
| 736 | 736 | ||
| 737 | static ssize_t adt7316_store_enable_prop_DACA(struct device *dev, | 737 | static ssize_t adt7316_store_enable_prop_DACA(struct device *dev, |
| 738 | struct device_attribute *attr, | 738 | struct device_attribute *attr, |
| 739 | const char *buf, | 739 | const char *buf, |
| 740 | size_t len) | 740 | size_t len) |
| 741 | { | 741 | { |
| 742 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 742 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 743 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 743 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -758,13 +758,13 @@ static ssize_t adt7316_store_enable_prop_DACA(struct device *dev, | |||
| 758 | } | 758 | } |
| 759 | 759 | ||
| 760 | static IIO_DEVICE_ATTR(enable_proportion_DACA, 0644, | 760 | static IIO_DEVICE_ATTR(enable_proportion_DACA, 0644, |
| 761 | adt7316_show_enable_prop_DACA, | 761 | adt7316_show_enable_prop_DACA, |
| 762 | adt7316_store_enable_prop_DACA, | 762 | adt7316_store_enable_prop_DACA, |
| 763 | 0); | 763 | 0); |
| 764 | 764 | ||
| 765 | static ssize_t adt7316_show_enable_prop_DACB(struct device *dev, | 765 | static ssize_t adt7316_show_enable_prop_DACB(struct device *dev, |
| 766 | struct device_attribute *attr, | 766 | struct device_attribute *attr, |
| 767 | char *buf) | 767 | char *buf) |
| 768 | { | 768 | { |
| 769 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 769 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 770 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 770 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -774,9 +774,9 @@ static ssize_t adt7316_show_enable_prop_DACB(struct device *dev, | |||
| 774 | } | 774 | } |
| 775 | 775 | ||
| 776 | static ssize_t adt7316_store_enable_prop_DACB(struct device *dev, | 776 | static ssize_t adt7316_store_enable_prop_DACB(struct device *dev, |
| 777 | struct device_attribute *attr, | 777 | struct device_attribute *attr, |
| 778 | const char *buf, | 778 | const char *buf, |
| 779 | size_t len) | 779 | size_t len) |
| 780 | { | 780 | { |
| 781 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 781 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 782 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 782 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -797,13 +797,13 @@ static ssize_t adt7316_store_enable_prop_DACB(struct device *dev, | |||
| 797 | } | 797 | } |
| 798 | 798 | ||
| 799 | static IIO_DEVICE_ATTR(enable_proportion_DACB, 0644, | 799 | static IIO_DEVICE_ATTR(enable_proportion_DACB, 0644, |
| 800 | adt7316_show_enable_prop_DACB, | 800 | adt7316_show_enable_prop_DACB, |
| 801 | adt7316_store_enable_prop_DACB, | 801 | adt7316_store_enable_prop_DACB, |
| 802 | 0); | 802 | 0); |
| 803 | 803 | ||
| 804 | static ssize_t adt7316_show_DAC_2Vref_ch_mask(struct device *dev, | 804 | static ssize_t adt7316_show_DAC_2Vref_ch_mask(struct device *dev, |
| 805 | struct device_attribute *attr, | 805 | struct device_attribute *attr, |
| 806 | char *buf) | 806 | char *buf) |
| 807 | { | 807 | { |
| 808 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 808 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 809 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 809 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -813,9 +813,9 @@ static ssize_t adt7316_show_DAC_2Vref_ch_mask(struct device *dev, | |||
| 813 | } | 813 | } |
| 814 | 814 | ||
| 815 | static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev, | 815 | static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev, |
| 816 | struct device_attribute *attr, | 816 | struct device_attribute *attr, |
| 817 | const char *buf, | 817 | const char *buf, |
| 818 | size_t len) | 818 | size_t len) |
| 819 | { | 819 | { |
| 820 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 820 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 821 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 821 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -840,13 +840,13 @@ static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev, | |||
| 840 | } | 840 | } |
| 841 | 841 | ||
| 842 | static IIO_DEVICE_ATTR(DAC_2Vref_channels_mask, 0644, | 842 | static IIO_DEVICE_ATTR(DAC_2Vref_channels_mask, 0644, |
| 843 | adt7316_show_DAC_2Vref_ch_mask, | 843 | adt7316_show_DAC_2Vref_ch_mask, |
| 844 | adt7316_store_DAC_2Vref_ch_mask, | 844 | adt7316_store_DAC_2Vref_ch_mask, |
| 845 | 0); | 845 | 0); |
| 846 | 846 | ||
| 847 | static ssize_t adt7316_show_DAC_update_mode(struct device *dev, | 847 | static ssize_t adt7316_show_DAC_update_mode(struct device *dev, |
| 848 | struct device_attribute *attr, | 848 | struct device_attribute *attr, |
| 849 | char *buf) | 849 | char *buf) |
| 850 | { | 850 | { |
| 851 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 851 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 852 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 852 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -870,9 +870,9 @@ static ssize_t adt7316_show_DAC_update_mode(struct device *dev, | |||
| 870 | } | 870 | } |
| 871 | 871 | ||
| 872 | static ssize_t adt7316_store_DAC_update_mode(struct device *dev, | 872 | static ssize_t adt7316_store_DAC_update_mode(struct device *dev, |
| 873 | struct device_attribute *attr, | 873 | struct device_attribute *attr, |
| 874 | const char *buf, | 874 | const char *buf, |
| 875 | size_t len) | 875 | size_t len) |
| 876 | { | 876 | { |
| 877 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 877 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 878 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 878 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -900,13 +900,13 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev, | |||
| 900 | } | 900 | } |
| 901 | 901 | ||
| 902 | static IIO_DEVICE_ATTR(DAC_update_mode, 0644, | 902 | static IIO_DEVICE_ATTR(DAC_update_mode, 0644, |
| 903 | adt7316_show_DAC_update_mode, | 903 | adt7316_show_DAC_update_mode, |
| 904 | adt7316_store_DAC_update_mode, | 904 | adt7316_store_DAC_update_mode, |
| 905 | 0); | 905 | 0); |
| 906 | 906 | ||
| 907 | static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev, | 907 | static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev, |
| 908 | struct device_attribute *attr, | 908 | struct device_attribute *attr, |
| 909 | char *buf) | 909 | char *buf) |
| 910 | { | 910 | { |
| 911 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 911 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 912 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 912 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -920,12 +920,12 @@ static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev, | |||
| 920 | } | 920 | } |
| 921 | 921 | ||
| 922 | static IIO_DEVICE_ATTR(all_DAC_update_modes, 0444, | 922 | static IIO_DEVICE_ATTR(all_DAC_update_modes, 0444, |
| 923 | adt7316_show_all_DAC_update_modes, NULL, 0); | 923 | adt7316_show_all_DAC_update_modes, NULL, 0); |
| 924 | 924 | ||
| 925 | static ssize_t adt7316_store_update_DAC(struct device *dev, | 925 | static ssize_t adt7316_store_update_DAC(struct device *dev, |
| 926 | struct device_attribute *attr, | 926 | struct device_attribute *attr, |
| 927 | const char *buf, | 927 | const char *buf, |
| 928 | size_t len) | 928 | size_t len) |
| 929 | { | 929 | { |
| 930 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 930 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 931 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 931 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -958,13 +958,13 @@ static ssize_t adt7316_store_update_DAC(struct device *dev, | |||
| 958 | } | 958 | } |
| 959 | 959 | ||
| 960 | static IIO_DEVICE_ATTR(update_DAC, 0644, | 960 | static IIO_DEVICE_ATTR(update_DAC, 0644, |
| 961 | NULL, | 961 | NULL, |
| 962 | adt7316_store_update_DAC, | 962 | adt7316_store_update_DAC, |
| 963 | 0); | 963 | 0); |
| 964 | 964 | ||
| 965 | static ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev, | 965 | static ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev, |
| 966 | struct device_attribute *attr, | 966 | struct device_attribute *attr, |
| 967 | char *buf) | 967 | char *buf) |
| 968 | { | 968 | { |
| 969 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 969 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 970 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 970 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -977,9 +977,9 @@ static ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev, | |||
| 977 | } | 977 | } |
| 978 | 978 | ||
| 979 | static ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev, | 979 | static ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev, |
| 980 | struct device_attribute *attr, | 980 | struct device_attribute *attr, |
| 981 | const char *buf, | 981 | const char *buf, |
| 982 | size_t len) | 982 | size_t len) |
| 983 | { | 983 | { |
| 984 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 984 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 985 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 985 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1003,13 +1003,13 @@ static ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev, | |||
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | static IIO_DEVICE_ATTR(DA_AB_Vref_bypass, 0644, | 1005 | static IIO_DEVICE_ATTR(DA_AB_Vref_bypass, 0644, |
| 1006 | adt7316_show_DA_AB_Vref_bypass, | 1006 | adt7316_show_DA_AB_Vref_bypass, |
| 1007 | adt7316_store_DA_AB_Vref_bypass, | 1007 | adt7316_store_DA_AB_Vref_bypass, |
| 1008 | 0); | 1008 | 0); |
| 1009 | 1009 | ||
| 1010 | static ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev, | 1010 | static ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev, |
| 1011 | struct device_attribute *attr, | 1011 | struct device_attribute *attr, |
| 1012 | char *buf) | 1012 | char *buf) |
| 1013 | { | 1013 | { |
| 1014 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1014 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1015 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1015 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1022,9 +1022,9 @@ static ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev, | |||
| 1022 | } | 1022 | } |
| 1023 | 1023 | ||
| 1024 | static ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev, | 1024 | static ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev, |
| 1025 | struct device_attribute *attr, | 1025 | struct device_attribute *attr, |
| 1026 | const char *buf, | 1026 | const char *buf, |
| 1027 | size_t len) | 1027 | size_t len) |
| 1028 | { | 1028 | { |
| 1029 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1029 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1030 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1030 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1048,13 +1048,13 @@ static ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev, | |||
| 1048 | } | 1048 | } |
| 1049 | 1049 | ||
| 1050 | static IIO_DEVICE_ATTR(DA_CD_Vref_bypass, 0644, | 1050 | static IIO_DEVICE_ATTR(DA_CD_Vref_bypass, 0644, |
| 1051 | adt7316_show_DA_CD_Vref_bypass, | 1051 | adt7316_show_DA_CD_Vref_bypass, |
| 1052 | adt7316_store_DA_CD_Vref_bypass, | 1052 | adt7316_store_DA_CD_Vref_bypass, |
| 1053 | 0); | 1053 | 0); |
| 1054 | 1054 | ||
| 1055 | static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev, | 1055 | static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev, |
| 1056 | struct device_attribute *attr, | 1056 | struct device_attribute *attr, |
| 1057 | char *buf) | 1057 | char *buf) |
| 1058 | { | 1058 | { |
| 1059 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1059 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1060 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1060 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1068,9 +1068,9 @@ static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev, | |||
| 1068 | } | 1068 | } |
| 1069 | 1069 | ||
| 1070 | static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, | 1070 | static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, |
| 1071 | struct device_attribute *attr, | 1071 | struct device_attribute *attr, |
| 1072 | const char *buf, | 1072 | const char *buf, |
| 1073 | size_t len) | 1073 | size_t len) |
| 1074 | { | 1074 | { |
| 1075 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1075 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1076 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1076 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1109,12 +1109,12 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, | |||
| 1109 | } | 1109 | } |
| 1110 | 1110 | ||
| 1111 | static IIO_DEVICE_ATTR(DAC_internal_Vref, 0644, | 1111 | static IIO_DEVICE_ATTR(DAC_internal_Vref, 0644, |
| 1112 | adt7316_show_DAC_internal_Vref, | 1112 | adt7316_show_DAC_internal_Vref, |
| 1113 | adt7316_store_DAC_internal_Vref, | 1113 | adt7316_store_DAC_internal_Vref, |
| 1114 | 0); | 1114 | 0); |
| 1115 | 1115 | ||
| 1116 | static ssize_t adt7316_show_ad(struct adt7316_chip_info *chip, | 1116 | static ssize_t adt7316_show_ad(struct adt7316_chip_info *chip, |
| 1117 | int channel, char *buf) | 1117 | int channel, char *buf) |
| 1118 | { | 1118 | { |
| 1119 | u16 data; | 1119 | u16 data; |
| 1120 | u8 msb, lsb; | 1120 | u8 msb, lsb; |
| @@ -1122,7 +1122,7 @@ static ssize_t adt7316_show_ad(struct adt7316_chip_info *chip, | |||
| 1122 | int ret; | 1122 | int ret; |
| 1123 | 1123 | ||
| 1124 | if ((chip->config2 & ADT7316_AD_SINGLE_CH_MODE) && | 1124 | if ((chip->config2 & ADT7316_AD_SINGLE_CH_MODE) && |
| 1125 | channel != (chip->config2 & ADT7516_AD_SINGLE_CH_MASK)) | 1125 | channel != (chip->config2 & ADT7516_AD_SINGLE_CH_MASK)) |
| 1126 | return -EPERM; | 1126 | return -EPERM; |
| 1127 | 1127 | ||
| 1128 | switch (channel) { | 1128 | switch (channel) { |
| @@ -1189,8 +1189,8 @@ static ssize_t adt7316_show_ad(struct adt7316_chip_info *chip, | |||
| 1189 | } | 1189 | } |
| 1190 | 1190 | ||
| 1191 | static ssize_t adt7316_show_VDD(struct device *dev, | 1191 | static ssize_t adt7316_show_VDD(struct device *dev, |
| 1192 | struct device_attribute *attr, | 1192 | struct device_attribute *attr, |
| 1193 | char *buf) | 1193 | char *buf) |
| 1194 | { | 1194 | { |
| 1195 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1195 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1196 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1196 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1200,8 +1200,8 @@ static ssize_t adt7316_show_VDD(struct device *dev, | |||
| 1200 | static IIO_DEVICE_ATTR(VDD, 0444, adt7316_show_VDD, NULL, 0); | 1200 | static IIO_DEVICE_ATTR(VDD, 0444, adt7316_show_VDD, NULL, 0); |
| 1201 | 1201 | ||
| 1202 | static ssize_t adt7316_show_in_temp(struct device *dev, | 1202 | static ssize_t adt7316_show_in_temp(struct device *dev, |
| 1203 | struct device_attribute *attr, | 1203 | struct device_attribute *attr, |
| 1204 | char *buf) | 1204 | char *buf) |
| 1205 | { | 1205 | { |
| 1206 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1206 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1207 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1207 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1212,8 +1212,8 @@ static ssize_t adt7316_show_in_temp(struct device *dev, | |||
| 1212 | static IIO_DEVICE_ATTR(in_temp, 0444, adt7316_show_in_temp, NULL, 0); | 1212 | static IIO_DEVICE_ATTR(in_temp, 0444, adt7316_show_in_temp, NULL, 0); |
| 1213 | 1213 | ||
| 1214 | static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev, | 1214 | static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev, |
| 1215 | struct device_attribute *attr, | 1215 | struct device_attribute *attr, |
| 1216 | char *buf) | 1216 | char *buf) |
| 1217 | { | 1217 | { |
| 1218 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1218 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1219 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1219 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1222,12 +1222,12 @@ static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev, | |||
| 1222 | } | 1222 | } |
| 1223 | 1223 | ||
| 1224 | static IIO_DEVICE_ATTR(ex_temp_AIN1, 0444, adt7316_show_ex_temp_AIN1, | 1224 | static IIO_DEVICE_ATTR(ex_temp_AIN1, 0444, adt7316_show_ex_temp_AIN1, |
| 1225 | NULL, 0); | 1225 | NULL, 0); |
| 1226 | static IIO_DEVICE_ATTR(ex_temp, 0444, adt7316_show_ex_temp_AIN1, NULL, 0); | 1226 | static IIO_DEVICE_ATTR(ex_temp, 0444, adt7316_show_ex_temp_AIN1, NULL, 0); |
| 1227 | 1227 | ||
| 1228 | static ssize_t adt7316_show_AIN2(struct device *dev, | 1228 | static ssize_t adt7316_show_AIN2(struct device *dev, |
| 1229 | struct device_attribute *attr, | 1229 | struct device_attribute *attr, |
| 1230 | char *buf) | 1230 | char *buf) |
| 1231 | { | 1231 | { |
| 1232 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1232 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1233 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1233 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1237,8 +1237,8 @@ static ssize_t adt7316_show_AIN2(struct device *dev, | |||
| 1237 | static IIO_DEVICE_ATTR(AIN2, 0444, adt7316_show_AIN2, NULL, 0); | 1237 | static IIO_DEVICE_ATTR(AIN2, 0444, adt7316_show_AIN2, NULL, 0); |
| 1238 | 1238 | ||
| 1239 | static ssize_t adt7316_show_AIN3(struct device *dev, | 1239 | static ssize_t adt7316_show_AIN3(struct device *dev, |
| 1240 | struct device_attribute *attr, | 1240 | struct device_attribute *attr, |
| 1241 | char *buf) | 1241 | char *buf) |
| 1242 | { | 1242 | { |
| 1243 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1243 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1244 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1244 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1248,8 +1248,8 @@ static ssize_t adt7316_show_AIN3(struct device *dev, | |||
| 1248 | static IIO_DEVICE_ATTR(AIN3, 0444, adt7316_show_AIN3, NULL, 0); | 1248 | static IIO_DEVICE_ATTR(AIN3, 0444, adt7316_show_AIN3, NULL, 0); |
| 1249 | 1249 | ||
| 1250 | static ssize_t adt7316_show_AIN4(struct device *dev, | 1250 | static ssize_t adt7316_show_AIN4(struct device *dev, |
| 1251 | struct device_attribute *attr, | 1251 | struct device_attribute *attr, |
| 1252 | char *buf) | 1252 | char *buf) |
| 1253 | { | 1253 | { |
| 1254 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1254 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1255 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1255 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1259,7 +1259,7 @@ static ssize_t adt7316_show_AIN4(struct device *dev, | |||
| 1259 | static IIO_DEVICE_ATTR(AIN4, 0444, adt7316_show_AIN4, NULL, 0); | 1259 | static IIO_DEVICE_ATTR(AIN4, 0444, adt7316_show_AIN4, NULL, 0); |
| 1260 | 1260 | ||
| 1261 | static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip, | 1261 | static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip, |
| 1262 | int offset_addr, char *buf) | 1262 | int offset_addr, char *buf) |
| 1263 | { | 1263 | { |
| 1264 | int data; | 1264 | int data; |
| 1265 | u8 val; | 1265 | u8 val; |
| @@ -1277,7 +1277,9 @@ static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip, | |||
| 1277 | } | 1277 | } |
| 1278 | 1278 | ||
| 1279 | static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip, | 1279 | static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip, |
| 1280 | int offset_addr, const char *buf, size_t len) | 1280 | int offset_addr, |
| 1281 | const char *buf, | ||
| 1282 | size_t len) | ||
| 1281 | { | 1283 | { |
| 1282 | int data; | 1284 | int data; |
| 1283 | u8 val; | 1285 | u8 val; |
| @@ -1300,8 +1302,8 @@ static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip, | |||
| 1300 | } | 1302 | } |
| 1301 | 1303 | ||
| 1302 | static ssize_t adt7316_show_in_temp_offset(struct device *dev, | 1304 | static ssize_t adt7316_show_in_temp_offset(struct device *dev, |
| 1303 | struct device_attribute *attr, | 1305 | struct device_attribute *attr, |
| 1304 | char *buf) | 1306 | char *buf) |
| 1305 | { | 1307 | { |
| 1306 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1308 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1307 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1309 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1310,9 +1312,9 @@ static ssize_t adt7316_show_in_temp_offset(struct device *dev, | |||
| 1310 | } | 1312 | } |
| 1311 | 1313 | ||
| 1312 | static ssize_t adt7316_store_in_temp_offset(struct device *dev, | 1314 | static ssize_t adt7316_store_in_temp_offset(struct device *dev, |
| 1313 | struct device_attribute *attr, | 1315 | struct device_attribute *attr, |
| 1314 | const char *buf, | 1316 | const char *buf, |
| 1315 | size_t len) | 1317 | size_t len) |
| 1316 | { | 1318 | { |
| 1317 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1319 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1318 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1320 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1322,12 +1324,12 @@ static ssize_t adt7316_store_in_temp_offset(struct device *dev, | |||
| 1322 | } | 1324 | } |
| 1323 | 1325 | ||
| 1324 | static IIO_DEVICE_ATTR(in_temp_offset, 0644, | 1326 | static IIO_DEVICE_ATTR(in_temp_offset, 0644, |
| 1325 | adt7316_show_in_temp_offset, | 1327 | adt7316_show_in_temp_offset, |
| 1326 | adt7316_store_in_temp_offset, 0); | 1328 | adt7316_store_in_temp_offset, 0); |
| 1327 | 1329 | ||
| 1328 | static ssize_t adt7316_show_ex_temp_offset(struct device *dev, | 1330 | static ssize_t adt7316_show_ex_temp_offset(struct device *dev, |
| 1329 | struct device_attribute *attr, | 1331 | struct device_attribute *attr, |
| 1330 | char *buf) | 1332 | char *buf) |
| 1331 | { | 1333 | { |
| 1332 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1334 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1333 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1335 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1336,9 +1338,9 @@ static ssize_t adt7316_show_ex_temp_offset(struct device *dev, | |||
| 1336 | } | 1338 | } |
| 1337 | 1339 | ||
| 1338 | static ssize_t adt7316_store_ex_temp_offset(struct device *dev, | 1340 | static ssize_t adt7316_store_ex_temp_offset(struct device *dev, |
| 1339 | struct device_attribute *attr, | 1341 | struct device_attribute *attr, |
| 1340 | const char *buf, | 1342 | const char *buf, |
| 1341 | size_t len) | 1343 | size_t len) |
| 1342 | { | 1344 | { |
| 1343 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1345 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1344 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1346 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1348,12 +1350,12 @@ static ssize_t adt7316_store_ex_temp_offset(struct device *dev, | |||
| 1348 | } | 1350 | } |
| 1349 | 1351 | ||
| 1350 | static IIO_DEVICE_ATTR(ex_temp_offset, 0644, | 1352 | static IIO_DEVICE_ATTR(ex_temp_offset, 0644, |
| 1351 | adt7316_show_ex_temp_offset, | 1353 | adt7316_show_ex_temp_offset, |
| 1352 | adt7316_store_ex_temp_offset, 0); | 1354 | adt7316_store_ex_temp_offset, 0); |
| 1353 | 1355 | ||
| 1354 | static ssize_t adt7316_show_in_analog_temp_offset(struct device *dev, | 1356 | static ssize_t adt7316_show_in_analog_temp_offset(struct device *dev, |
| 1355 | struct device_attribute *attr, | 1357 | struct device_attribute *attr, |
| 1356 | char *buf) | 1358 | char *buf) |
| 1357 | { | 1359 | { |
| 1358 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1360 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1359 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1361 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1363,9 +1365,9 @@ static ssize_t adt7316_show_in_analog_temp_offset(struct device *dev, | |||
| 1363 | } | 1365 | } |
| 1364 | 1366 | ||
| 1365 | static ssize_t adt7316_store_in_analog_temp_offset(struct device *dev, | 1367 | static ssize_t adt7316_store_in_analog_temp_offset(struct device *dev, |
| 1366 | struct device_attribute *attr, | 1368 | struct device_attribute *attr, |
| 1367 | const char *buf, | 1369 | const char *buf, |
| 1368 | size_t len) | 1370 | size_t len) |
| 1369 | { | 1371 | { |
| 1370 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1372 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1371 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1373 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1375,12 +1377,12 @@ static ssize_t adt7316_store_in_analog_temp_offset(struct device *dev, | |||
| 1375 | } | 1377 | } |
| 1376 | 1378 | ||
| 1377 | static IIO_DEVICE_ATTR(in_analog_temp_offset, 0644, | 1379 | static IIO_DEVICE_ATTR(in_analog_temp_offset, 0644, |
| 1378 | adt7316_show_in_analog_temp_offset, | 1380 | adt7316_show_in_analog_temp_offset, |
| 1379 | adt7316_store_in_analog_temp_offset, 0); | 1381 | adt7316_store_in_analog_temp_offset, 0); |
| 1380 | 1382 | ||
| 1381 | static ssize_t adt7316_show_ex_analog_temp_offset(struct device *dev, | 1383 | static ssize_t adt7316_show_ex_analog_temp_offset(struct device *dev, |
| 1382 | struct device_attribute *attr, | 1384 | struct device_attribute *attr, |
| 1383 | char *buf) | 1385 | char *buf) |
| 1384 | { | 1386 | { |
| 1385 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1387 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1386 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1388 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1390,9 +1392,9 @@ static ssize_t adt7316_show_ex_analog_temp_offset(struct device *dev, | |||
| 1390 | } | 1392 | } |
| 1391 | 1393 | ||
| 1392 | static ssize_t adt7316_store_ex_analog_temp_offset(struct device *dev, | 1394 | static ssize_t adt7316_store_ex_analog_temp_offset(struct device *dev, |
| 1393 | struct device_attribute *attr, | 1395 | struct device_attribute *attr, |
| 1394 | const char *buf, | 1396 | const char *buf, |
| 1395 | size_t len) | 1397 | size_t len) |
| 1396 | { | 1398 | { |
| 1397 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1399 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1398 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1400 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1402,21 +1404,21 @@ static ssize_t adt7316_store_ex_analog_temp_offset(struct device *dev, | |||
| 1402 | } | 1404 | } |
| 1403 | 1405 | ||
| 1404 | static IIO_DEVICE_ATTR(ex_analog_temp_offset, 0644, | 1406 | static IIO_DEVICE_ATTR(ex_analog_temp_offset, 0644, |
| 1405 | adt7316_show_ex_analog_temp_offset, | 1407 | adt7316_show_ex_analog_temp_offset, |
| 1406 | adt7316_store_ex_analog_temp_offset, 0); | 1408 | adt7316_store_ex_analog_temp_offset, 0); |
| 1407 | 1409 | ||
| 1408 | static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, | 1410 | static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, |
| 1409 | int channel, char *buf) | 1411 | int channel, char *buf) |
| 1410 | { | 1412 | { |
| 1411 | u16 data; | 1413 | u16 data; |
| 1412 | u8 msb, lsb, offset; | 1414 | u8 msb, lsb, offset; |
| 1413 | int ret; | 1415 | int ret; |
| 1414 | 1416 | ||
| 1415 | if (channel >= ADT7316_DA_MSB_DATA_REGS || | 1417 | if (channel >= ADT7316_DA_MSB_DATA_REGS || |
| 1416 | (channel == 0 && | 1418 | (channel == 0 && |
| 1417 | (chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) || | 1419 | (chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) || |
| 1418 | (channel == 1 && | 1420 | (channel == 1 && |
| 1419 | (chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB))) | 1421 | (chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB))) |
| 1420 | return -EPERM; | 1422 | return -EPERM; |
| 1421 | 1423 | ||
| 1422 | offset = chip->dac_bits - 8; | 1424 | offset = chip->dac_bits - 8; |
| @@ -1439,17 +1441,17 @@ static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, | |||
| 1439 | } | 1441 | } |
| 1440 | 1442 | ||
| 1441 | static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, | 1443 | static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, |
| 1442 | int channel, const char *buf, size_t len) | 1444 | int channel, const char *buf, size_t len) |
| 1443 | { | 1445 | { |
| 1444 | u8 msb, lsb, offset; | 1446 | u8 msb, lsb, offset; |
| 1445 | u16 data; | 1447 | u16 data; |
| 1446 | int ret; | 1448 | int ret; |
| 1447 | 1449 | ||
| 1448 | if (channel >= ADT7316_DA_MSB_DATA_REGS || | 1450 | if (channel >= ADT7316_DA_MSB_DATA_REGS || |
| 1449 | (channel == 0 && | 1451 | (channel == 0 && |
| 1450 | (chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) || | 1452 | (chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) || |
| 1451 | (channel == 1 && | 1453 | (channel == 1 && |
| 1452 | (chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB))) | 1454 | (chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB))) |
| 1453 | return -EPERM; | 1455 | return -EPERM; |
| 1454 | 1456 | ||
| 1455 | offset = chip->dac_bits - 8; | 1457 | offset = chip->dac_bits - 8; |
| @@ -1476,8 +1478,8 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, | |||
| 1476 | } | 1478 | } |
| 1477 | 1479 | ||
| 1478 | static ssize_t adt7316_show_DAC_A(struct device *dev, | 1480 | static ssize_t adt7316_show_DAC_A(struct device *dev, |
| 1479 | struct device_attribute *attr, | 1481 | struct device_attribute *attr, |
| 1480 | char *buf) | 1482 | char *buf) |
| 1481 | { | 1483 | { |
| 1482 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1484 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1483 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1485 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1486,9 +1488,9 @@ static ssize_t adt7316_show_DAC_A(struct device *dev, | |||
| 1486 | } | 1488 | } |
| 1487 | 1489 | ||
| 1488 | static ssize_t adt7316_store_DAC_A(struct device *dev, | 1490 | static ssize_t adt7316_store_DAC_A(struct device *dev, |
| 1489 | struct device_attribute *attr, | 1491 | struct device_attribute *attr, |
| 1490 | const char *buf, | 1492 | const char *buf, |
| 1491 | size_t len) | 1493 | size_t len) |
| 1492 | { | 1494 | { |
| 1493 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1495 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1494 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1496 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1497,11 +1499,11 @@ static ssize_t adt7316_store_DAC_A(struct device *dev, | |||
| 1497 | } | 1499 | } |
| 1498 | 1500 | ||
| 1499 | static IIO_DEVICE_ATTR(DAC_A, 0644, adt7316_show_DAC_A, | 1501 | static IIO_DEVICE_ATTR(DAC_A, 0644, adt7316_show_DAC_A, |
| 1500 | adt7316_store_DAC_A, 0); | 1502 | adt7316_store_DAC_A, 0); |
| 1501 | 1503 | ||
| 1502 | static ssize_t adt7316_show_DAC_B(struct device *dev, | 1504 | static ssize_t adt7316_show_DAC_B(struct device *dev, |
| 1503 | struct device_attribute *attr, | 1505 | struct device_attribute *attr, |
| 1504 | char *buf) | 1506 | char *buf) |
| 1505 | { | 1507 | { |
| 1506 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1508 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1507 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1509 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1510,9 +1512,9 @@ static ssize_t adt7316_show_DAC_B(struct device *dev, | |||
| 1510 | } | 1512 | } |
| 1511 | 1513 | ||
| 1512 | static ssize_t adt7316_store_DAC_B(struct device *dev, | 1514 | static ssize_t adt7316_store_DAC_B(struct device *dev, |
| 1513 | struct device_attribute *attr, | 1515 | struct device_attribute *attr, |
| 1514 | const char *buf, | 1516 | const char *buf, |
| 1515 | size_t len) | 1517 | size_t len) |
| 1516 | { | 1518 | { |
| 1517 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1519 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1518 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1520 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1521,11 +1523,11 @@ static ssize_t adt7316_store_DAC_B(struct device *dev, | |||
| 1521 | } | 1523 | } |
| 1522 | 1524 | ||
| 1523 | static IIO_DEVICE_ATTR(DAC_B, 0644, adt7316_show_DAC_B, | 1525 | static IIO_DEVICE_ATTR(DAC_B, 0644, adt7316_show_DAC_B, |
| 1524 | adt7316_store_DAC_B, 0); | 1526 | adt7316_store_DAC_B, 0); |
| 1525 | 1527 | ||
| 1526 | static ssize_t adt7316_show_DAC_C(struct device *dev, | 1528 | static ssize_t adt7316_show_DAC_C(struct device *dev, |
| 1527 | struct device_attribute *attr, | 1529 | struct device_attribute *attr, |
| 1528 | char *buf) | 1530 | char *buf) |
| 1529 | { | 1531 | { |
| 1530 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1532 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1531 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1533 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1534,9 +1536,9 @@ static ssize_t adt7316_show_DAC_C(struct device *dev, | |||
| 1534 | } | 1536 | } |
| 1535 | 1537 | ||
| 1536 | static ssize_t adt7316_store_DAC_C(struct device *dev, | 1538 | static ssize_t adt7316_store_DAC_C(struct device *dev, |
| 1537 | struct device_attribute *attr, | 1539 | struct device_attribute *attr, |
| 1538 | const char *buf, | 1540 | const char *buf, |
| 1539 | size_t len) | 1541 | size_t len) |
| 1540 | { | 1542 | { |
| 1541 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1543 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1542 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1544 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1545,11 +1547,11 @@ static ssize_t adt7316_store_DAC_C(struct device *dev, | |||
| 1545 | } | 1547 | } |
| 1546 | 1548 | ||
| 1547 | static IIO_DEVICE_ATTR(DAC_C, 0644, adt7316_show_DAC_C, | 1549 | static IIO_DEVICE_ATTR(DAC_C, 0644, adt7316_show_DAC_C, |
| 1548 | adt7316_store_DAC_C, 0); | 1550 | adt7316_store_DAC_C, 0); |
| 1549 | 1551 | ||
| 1550 | static ssize_t adt7316_show_DAC_D(struct device *dev, | 1552 | static ssize_t adt7316_show_DAC_D(struct device *dev, |
| 1551 | struct device_attribute *attr, | 1553 | struct device_attribute *attr, |
| 1552 | char *buf) | 1554 | char *buf) |
| 1553 | { | 1555 | { |
| 1554 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1556 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1555 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1557 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1558,9 +1560,9 @@ static ssize_t adt7316_show_DAC_D(struct device *dev, | |||
| 1558 | } | 1560 | } |
| 1559 | 1561 | ||
| 1560 | static ssize_t adt7316_store_DAC_D(struct device *dev, | 1562 | static ssize_t adt7316_store_DAC_D(struct device *dev, |
| 1561 | struct device_attribute *attr, | 1563 | struct device_attribute *attr, |
| 1562 | const char *buf, | 1564 | const char *buf, |
| 1563 | size_t len) | 1565 | size_t len) |
| 1564 | { | 1566 | { |
| 1565 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1567 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1566 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1568 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1569,11 +1571,11 @@ static ssize_t adt7316_store_DAC_D(struct device *dev, | |||
| 1569 | } | 1571 | } |
| 1570 | 1572 | ||
| 1571 | static IIO_DEVICE_ATTR(DAC_D, 0644, adt7316_show_DAC_D, | 1573 | static IIO_DEVICE_ATTR(DAC_D, 0644, adt7316_show_DAC_D, |
| 1572 | adt7316_store_DAC_D, 0); | 1574 | adt7316_store_DAC_D, 0); |
| 1573 | 1575 | ||
| 1574 | static ssize_t adt7316_show_device_id(struct device *dev, | 1576 | static ssize_t adt7316_show_device_id(struct device *dev, |
| 1575 | struct device_attribute *attr, | 1577 | struct device_attribute *attr, |
| 1576 | char *buf) | 1578 | char *buf) |
| 1577 | { | 1579 | { |
| 1578 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1580 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1579 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1581 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1590,8 +1592,8 @@ static ssize_t adt7316_show_device_id(struct device *dev, | |||
| 1590 | static IIO_DEVICE_ATTR(device_id, 0444, adt7316_show_device_id, NULL, 0); | 1592 | static IIO_DEVICE_ATTR(device_id, 0444, adt7316_show_device_id, NULL, 0); |
| 1591 | 1593 | ||
| 1592 | static ssize_t adt7316_show_manufactorer_id(struct device *dev, | 1594 | static ssize_t adt7316_show_manufactorer_id(struct device *dev, |
| 1593 | struct device_attribute *attr, | 1595 | struct device_attribute *attr, |
| 1594 | char *buf) | 1596 | char *buf) |
| 1595 | { | 1597 | { |
| 1596 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1598 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1597 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1599 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1606,11 +1608,11 @@ static ssize_t adt7316_show_manufactorer_id(struct device *dev, | |||
| 1606 | } | 1608 | } |
| 1607 | 1609 | ||
| 1608 | static IIO_DEVICE_ATTR(manufactorer_id, 0444, | 1610 | static IIO_DEVICE_ATTR(manufactorer_id, 0444, |
| 1609 | adt7316_show_manufactorer_id, NULL, 0); | 1611 | adt7316_show_manufactorer_id, NULL, 0); |
| 1610 | 1612 | ||
| 1611 | static ssize_t adt7316_show_device_rev(struct device *dev, | 1613 | static ssize_t adt7316_show_device_rev(struct device *dev, |
| 1612 | struct device_attribute *attr, | 1614 | struct device_attribute *attr, |
| 1613 | char *buf) | 1615 | char *buf) |
| 1614 | { | 1616 | { |
| 1615 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1617 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1616 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1618 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1627,8 +1629,8 @@ static ssize_t adt7316_show_device_rev(struct device *dev, | |||
| 1627 | static IIO_DEVICE_ATTR(device_rev, 0444, adt7316_show_device_rev, NULL, 0); | 1629 | static IIO_DEVICE_ATTR(device_rev, 0444, adt7316_show_device_rev, NULL, 0); |
| 1628 | 1630 | ||
| 1629 | static ssize_t adt7316_show_bus_type(struct device *dev, | 1631 | static ssize_t adt7316_show_bus_type(struct device *dev, |
| 1630 | struct device_attribute *attr, | 1632 | struct device_attribute *attr, |
| 1631 | char *buf) | 1633 | char *buf) |
| 1632 | { | 1634 | { |
| 1633 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1635 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1634 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1636 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1811,8 +1813,8 @@ static irqreturn_t adt7316_event_handler(int irq, void *private) | |||
| 1811 | * Show mask of enabled interrupts in Hex. | 1813 | * Show mask of enabled interrupts in Hex. |
| 1812 | */ | 1814 | */ |
| 1813 | static ssize_t adt7316_show_int_mask(struct device *dev, | 1815 | static ssize_t adt7316_show_int_mask(struct device *dev, |
| 1814 | struct device_attribute *attr, | 1816 | struct device_attribute *attr, |
| 1815 | char *buf) | 1817 | char *buf) |
| 1816 | { | 1818 | { |
| 1817 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1819 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1818 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1820 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1824,9 +1826,9 @@ static ssize_t adt7316_show_int_mask(struct device *dev, | |||
| 1824 | * Set 1 to the mask in Hex to enabled interrupts. | 1826 | * Set 1 to the mask in Hex to enabled interrupts. |
| 1825 | */ | 1827 | */ |
| 1826 | static ssize_t adt7316_set_int_mask(struct device *dev, | 1828 | static ssize_t adt7316_set_int_mask(struct device *dev, |
| 1827 | struct device_attribute *attr, | 1829 | struct device_attribute *attr, |
| 1828 | const char *buf, | 1830 | const char *buf, |
| 1829 | size_t len) | 1831 | size_t len) |
| 1830 | { | 1832 | { |
| 1831 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1833 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1832 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1834 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1865,8 +1867,8 @@ static ssize_t adt7316_set_int_mask(struct device *dev, | |||
| 1865 | } | 1867 | } |
| 1866 | 1868 | ||
| 1867 | static inline ssize_t adt7316_show_ad_bound(struct device *dev, | 1869 | static inline ssize_t adt7316_show_ad_bound(struct device *dev, |
| 1868 | struct device_attribute *attr, | 1870 | struct device_attribute *attr, |
| 1869 | char *buf) | 1871 | char *buf) |
| 1870 | { | 1872 | { |
| 1871 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | 1873 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
| 1872 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1874 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| @@ -1876,7 +1878,7 @@ static inline ssize_t adt7316_show_ad_bound(struct device *dev, | |||
| 1876 | int ret; | 1878 | int ret; |
| 1877 | 1879 | ||
| 1878 | if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX && | 1880 | if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX && |
| 1879 | this_attr->address > ADT7316_EX_TEMP_LOW) | 1881 | this_attr->address > ADT7316_EX_TEMP_LOW) |
| 1880 | return -EPERM; | 1882 | return -EPERM; |
| 1881 | 1883 | ||
| 1882 | ret = chip->bus.read(chip->bus.client, this_attr->address, &val); | 1884 | ret = chip->bus.read(chip->bus.client, this_attr->address, &val); |
| @@ -1886,7 +1888,7 @@ static inline ssize_t adt7316_show_ad_bound(struct device *dev, | |||
| 1886 | data = (int)val; | 1888 | data = (int)val; |
| 1887 | 1889 | ||
| 1888 | if (!((chip->id & ID_FAMILY_MASK) == ID_ADT75XX && | 1890 | if (!((chip->id & ID_FAMILY_MASK) == ID_ADT75XX && |
| 1889 | (chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)) { | 1891 | (chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)) { |
| 1890 | if (data & 0x80) | 1892 | if (data & 0x80) |
| 1891 | data -= 256; | 1893 | data -= 256; |
| 1892 | } | 1894 | } |
| @@ -1895,9 +1897,9 @@ static inline ssize_t adt7316_show_ad_bound(struct device *dev, | |||
| 1895 | } | 1897 | } |
| 1896 | 1898 | ||
| 1897 | static inline ssize_t adt7316_set_ad_bound(struct device *dev, | 1899 | static inline ssize_t adt7316_set_ad_bound(struct device *dev, |
| 1898 | struct device_attribute *attr, | 1900 | struct device_attribute *attr, |
| 1899 | const char *buf, | 1901 | const char *buf, |
| 1900 | size_t len) | 1902 | size_t len) |
| 1901 | { | 1903 | { |
| 1902 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | 1904 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); |
| 1903 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1905 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| @@ -1907,7 +1909,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev, | |||
| 1907 | int ret; | 1909 | int ret; |
| 1908 | 1910 | ||
| 1909 | if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX && | 1911 | if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX && |
| 1910 | this_attr->address > ADT7316_EX_TEMP_LOW) | 1912 | this_attr->address > ADT7316_EX_TEMP_LOW) |
| 1911 | return -EPERM; | 1913 | return -EPERM; |
| 1912 | 1914 | ||
| 1913 | ret = kstrtoint(buf, 10, &data); | 1915 | ret = kstrtoint(buf, 10, &data); |
| @@ -1915,7 +1917,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev, | |||
| 1915 | return -EINVAL; | 1917 | return -EINVAL; |
| 1916 | 1918 | ||
| 1917 | if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX && | 1919 | if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX && |
| 1918 | (chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) { | 1920 | (chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) { |
| 1919 | if (data > 255 || data < 0) | 1921 | if (data > 255 || data < 0) |
| 1920 | return -EINVAL; | 1922 | return -EINVAL; |
| 1921 | } else { | 1923 | } else { |
| @@ -1936,8 +1938,8 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev, | |||
| 1936 | } | 1938 | } |
| 1937 | 1939 | ||
| 1938 | static ssize_t adt7316_show_int_enabled(struct device *dev, | 1940 | static ssize_t adt7316_show_int_enabled(struct device *dev, |
| 1939 | struct device_attribute *attr, | 1941 | struct device_attribute *attr, |
| 1940 | char *buf) | 1942 | char *buf) |
| 1941 | { | 1943 | { |
| 1942 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1944 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1943 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1945 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -1946,9 +1948,9 @@ static ssize_t adt7316_show_int_enabled(struct device *dev, | |||
| 1946 | } | 1948 | } |
| 1947 | 1949 | ||
| 1948 | static ssize_t adt7316_set_int_enabled(struct device *dev, | 1950 | static ssize_t adt7316_set_int_enabled(struct device *dev, |
| 1949 | struct device_attribute *attr, | 1951 | struct device_attribute *attr, |
| 1950 | const char *buf, | 1952 | const char *buf, |
| 1951 | size_t len) | 1953 | size_t len) |
| 1952 | { | 1954 | { |
| 1953 | struct iio_dev *dev_info = dev_to_iio_dev(dev); | 1955 | struct iio_dev *dev_info = dev_to_iio_dev(dev); |
| 1954 | struct adt7316_chip_info *chip = iio_priv(dev_info); | 1956 | struct adt7316_chip_info *chip = iio_priv(dev_info); |
| @@ -2097,7 +2099,7 @@ static const struct iio_info adt7516_info = { | |||
| 2097 | * device probe and remove | 2099 | * device probe and remove |
| 2098 | */ | 2100 | */ |
| 2099 | int adt7316_probe(struct device *dev, struct adt7316_bus *bus, | 2101 | int adt7316_probe(struct device *dev, struct adt7316_bus *bus, |
| 2100 | const char *name) | 2102 | const char *name) |
| 2101 | { | 2103 | { |
| 2102 | struct adt7316_chip_info *chip; | 2104 | struct adt7316_chip_info *chip; |
| 2103 | struct iio_dev *indio_dev; | 2105 | struct iio_dev *indio_dev; |
| @@ -2169,7 +2171,7 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, | |||
| 2169 | return ret; | 2171 | return ret; |
| 2170 | 2172 | ||
| 2171 | dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n", | 2173 | dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n", |
| 2172 | indio_dev->name); | 2174 | indio_dev->name); |
| 2173 | 2175 | ||
| 2174 | return 0; | 2176 | return 0; |
| 2175 | } | 2177 | } |
diff --git a/drivers/staging/iio/addac/adt7316.h b/drivers/staging/iio/addac/adt7316.h index ec40fbb698a6..b954dcbc92db 100644 --- a/drivers/staging/iio/addac/adt7316.h +++ b/drivers/staging/iio/addac/adt7316.h | |||
| @@ -31,6 +31,6 @@ extern const struct dev_pm_ops adt7316_pm_ops; | |||
| 31 | #define ADT7316_PM_OPS NULL | 31 | #define ADT7316_PM_OPS NULL |
| 32 | #endif | 32 | #endif |
| 33 | int adt7316_probe(struct device *dev, struct adt7316_bus *bus, | 33 | int adt7316_probe(struct device *dev, struct adt7316_bus *bus, |
| 34 | const char *name); | 34 | const char *name); |
| 35 | 35 | ||
| 36 | #endif | 36 | #endif |
diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index d16084d7068c..24f74ce60f80 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c | |||
| @@ -102,18 +102,19 @@ static int ad7150_read_raw(struct iio_dev *indio_dev, | |||
| 102 | { | 102 | { |
| 103 | int ret; | 103 | int ret; |
| 104 | struct ad7150_chip_info *chip = iio_priv(indio_dev); | 104 | struct ad7150_chip_info *chip = iio_priv(indio_dev); |
| 105 | int channel = chan->channel; | ||
| 105 | 106 | ||
| 106 | switch (mask) { | 107 | switch (mask) { |
| 107 | case IIO_CHAN_INFO_RAW: | 108 | case IIO_CHAN_INFO_RAW: |
| 108 | ret = i2c_smbus_read_word_data(chip->client, | 109 | ret = i2c_smbus_read_word_data(chip->client, |
| 109 | ad7150_addresses[chan->channel][0]); | 110 | ad7150_addresses[channel][0]); |
| 110 | if (ret < 0) | 111 | if (ret < 0) |
| 111 | return ret; | 112 | return ret; |
| 112 | *val = swab16(ret); | 113 | *val = swab16(ret); |
| 113 | return IIO_VAL_INT; | 114 | return IIO_VAL_INT; |
| 114 | case IIO_CHAN_INFO_AVERAGE_RAW: | 115 | case IIO_CHAN_INFO_AVERAGE_RAW: |
| 115 | ret = i2c_smbus_read_word_data(chip->client, | 116 | ret = i2c_smbus_read_word_data(chip->client, |
| 116 | ad7150_addresses[chan->channel][1]); | 117 | ad7150_addresses[channel][1]); |
| 117 | if (ret < 0) | 118 | if (ret < 0) |
| 118 | return ret; | 119 | return ret; |
| 119 | *val = swab16(ret); | 120 | *val = swab16(ret); |
| @@ -182,8 +183,8 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev, | |||
| 182 | case IIO_EV_TYPE_THRESH: | 183 | case IIO_EV_TYPE_THRESH: |
| 183 | value = chip->threshold[rising][chan]; | 184 | value = chip->threshold[rising][chan]; |
| 184 | return i2c_smbus_write_word_data(chip->client, | 185 | return i2c_smbus_write_word_data(chip->client, |
| 185 | ad7150_addresses[chan][3], | 186 | ad7150_addresses[chan][3], |
| 186 | swab16(value)); | 187 | swab16(value)); |
| 187 | case IIO_EV_TYPE_MAG_ADAPTIVE: | 188 | case IIO_EV_TYPE_MAG_ADAPTIVE: |
| 188 | sens = chip->mag_sensitivity[rising][chan]; | 189 | sens = chip->mag_sensitivity[rising][chan]; |
| 189 | timeout = chip->mag_timeout[rising][chan]; | 190 | timeout = chip->mag_timeout[rising][chan]; |
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index a2370dd1e1a8..f9bcb8310e21 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c | |||
| @@ -84,13 +84,13 @@ | |||
| 84 | 84 | ||
| 85 | /** | 85 | /** |
| 86 | * struct ad5933_platform_data - platform specific data | 86 | * struct ad5933_platform_data - platform specific data |
| 87 | * @ext_clk_Hz: the external clock frequency in Hz, if not set | 87 | * @ext_clk_hz: the external clock frequency in Hz, if not set |
| 88 | * the driver uses the internal clock (16.776 MHz) | 88 | * the driver uses the internal clock (16.776 MHz) |
| 89 | * @vref_mv: the external reference voltage in millivolt | 89 | * @vref_mv: the external reference voltage in millivolt |
| 90 | */ | 90 | */ |
| 91 | 91 | ||
| 92 | struct ad5933_platform_data { | 92 | struct ad5933_platform_data { |
| 93 | unsigned long ext_clk_Hz; | 93 | unsigned long ext_clk_hz; |
| 94 | unsigned short vref_mv; | 94 | unsigned short vref_mv; |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| @@ -210,7 +210,7 @@ static int ad5933_set_freq(struct ad5933_state *st, | |||
| 210 | u8 d8[4]; | 210 | u8 d8[4]; |
| 211 | } dat; | 211 | } dat; |
| 212 | 212 | ||
| 213 | freqreg = (u64) freq * (u64) (1 << 27); | 213 | freqreg = (u64)freq * (u64)(1 << 27); |
| 214 | do_div(freqreg, st->mclk_hz / 4); | 214 | do_div(freqreg, st->mclk_hz / 4); |
| 215 | 215 | ||
| 216 | switch (reg) { | 216 | switch (reg) { |
| @@ -267,7 +267,6 @@ static void ad5933_calc_out_ranges(struct ad5933_state *st) | |||
| 267 | 267 | ||
| 268 | for (i = 0; i < 4; i++) | 268 | for (i = 0; i < 4; i++) |
| 269 | st->range_avail[i] = normalized_3v3[i] * st->vref_mv / 3300; | 269 | st->range_avail[i] = normalized_3v3[i] * st->vref_mv / 3300; |
| 270 | |||
| 271 | } | 270 | } |
| 272 | 271 | ||
| 273 | /* | 272 | /* |
| @@ -726,8 +725,8 @@ static int ad5933_probe(struct i2c_client *client, | |||
| 726 | else | 725 | else |
| 727 | st->vref_mv = pdata->vref_mv; | 726 | st->vref_mv = pdata->vref_mv; |
| 728 | 727 | ||
| 729 | if (pdata->ext_clk_Hz) { | 728 | if (pdata->ext_clk_hz) { |
| 730 | st->mclk_hz = pdata->ext_clk_Hz; | 729 | st->mclk_hz = pdata->ext_clk_hz; |
| 731 | st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK; | 730 | st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK; |
| 732 | } else { | 731 | } else { |
| 733 | st->mclk_hz = AD5933_INT_OSC_FREQ_Hz; | 732 | st->mclk_hz = AD5933_INT_OSC_FREQ_Hz; |
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index ac13b99bd9cb..cec9d995b3df 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c | |||
| @@ -15,12 +15,11 @@ | |||
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | #include <linux/sysfs.h> | 16 | #include <linux/sysfs.h> |
| 17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
| 18 | #include <linux/gpio.h> | 18 | #include <linux/gpio/consumer.h> |
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | 20 | ||
| 21 | #include <linux/iio/iio.h> | 21 | #include <linux/iio/iio.h> |
| 22 | #include <linux/iio/sysfs.h> | 22 | #include <linux/iio/sysfs.h> |
| 23 | #include "ad2s1210.h" | ||
| 24 | 23 | ||
| 25 | #define DRV_NAME "ad2s1210" | 24 | #define DRV_NAME "ad2s1210" |
| 26 | 25 | ||
| @@ -67,12 +66,33 @@ enum ad2s1210_mode { | |||
| 67 | MOD_RESERVED, | 66 | MOD_RESERVED, |
| 68 | }; | 67 | }; |
| 69 | 68 | ||
| 69 | enum ad2s1210_gpios { | ||
| 70 | AD2S1210_SAMPLE, | ||
| 71 | AD2S1210_A0, | ||
| 72 | AD2S1210_A1, | ||
| 73 | AD2S1210_RES0, | ||
| 74 | AD2S1210_RES1, | ||
| 75 | }; | ||
| 76 | |||
| 77 | struct ad2s1210_gpio { | ||
| 78 | const char *name; | ||
| 79 | unsigned long flags; | ||
| 80 | }; | ||
| 81 | |||
| 82 | static const struct ad2s1210_gpio gpios[] = { | ||
| 83 | [AD2S1210_SAMPLE] = { .name = "adi,sample", .flags = GPIOD_OUT_LOW }, | ||
| 84 | [AD2S1210_A0] = { .name = "adi,a0", .flags = GPIOD_OUT_LOW }, | ||
| 85 | [AD2S1210_A1] = { .name = "adi,a1", .flags = GPIOD_OUT_LOW }, | ||
| 86 | [AD2S1210_RES0] = { .name = "adi,res0", .flags = GPIOD_OUT_LOW }, | ||
| 87 | [AD2S1210_RES1] = { .name = "adi,res1", .flags = GPIOD_OUT_LOW }, | ||
| 88 | }; | ||
| 89 | |||
| 70 | static const unsigned int ad2s1210_resolution_value[] = { 10, 12, 14, 16 }; | 90 | static const unsigned int ad2s1210_resolution_value[] = { 10, 12, 14, 16 }; |
| 71 | 91 | ||
| 72 | struct ad2s1210_state { | 92 | struct ad2s1210_state { |
| 73 | const struct ad2s1210_platform_data *pdata; | ||
| 74 | struct mutex lock; | 93 | struct mutex lock; |
| 75 | struct spi_device *sdev; | 94 | struct spi_device *sdev; |
| 95 | struct gpio_desc *gpios[5]; | ||
| 76 | unsigned int fclkin; | 96 | unsigned int fclkin; |
| 77 | unsigned int fexcit; | 97 | unsigned int fexcit; |
| 78 | bool hysteresis; | 98 | bool hysteresis; |
| @@ -91,8 +111,8 @@ static const int ad2s1210_mode_vals[4][2] = { | |||
| 91 | static inline void ad2s1210_set_mode(enum ad2s1210_mode mode, | 111 | static inline void ad2s1210_set_mode(enum ad2s1210_mode mode, |
| 92 | struct ad2s1210_state *st) | 112 | struct ad2s1210_state *st) |
| 93 | { | 113 | { |
| 94 | gpio_set_value(st->pdata->a[0], ad2s1210_mode_vals[mode][0]); | 114 | gpiod_set_value(st->gpios[AD2S1210_A0], ad2s1210_mode_vals[mode][0]); |
| 95 | gpio_set_value(st->pdata->a[1], ad2s1210_mode_vals[mode][1]); | 115 | gpiod_set_value(st->gpios[AD2S1210_A1], ad2s1210_mode_vals[mode][1]); |
| 96 | st->mode = mode; | 116 | st->mode = mode; |
| 97 | } | 117 | } |
| 98 | 118 | ||
| @@ -150,24 +170,16 @@ int ad2s1210_update_frequency_control_word(struct ad2s1210_state *st) | |||
| 150 | return ad2s1210_config_write(st, fcw); | 170 | return ad2s1210_config_write(st, fcw); |
| 151 | } | 171 | } |
| 152 | 172 | ||
| 153 | static unsigned char ad2s1210_read_resolution_pin(struct ad2s1210_state *st) | ||
| 154 | { | ||
| 155 | int resolution = (gpio_get_value(st->pdata->res[0]) << 1) | | ||
| 156 | gpio_get_value(st->pdata->res[1]); | ||
| 157 | |||
| 158 | return ad2s1210_resolution_value[resolution]; | ||
| 159 | } | ||
| 160 | |||
| 161 | static const int ad2s1210_res_pins[4][2] = { | 173 | static const int ad2s1210_res_pins[4][2] = { |
| 162 | { 0, 0 }, {0, 1}, {1, 0}, {1, 1} | 174 | { 0, 0 }, {0, 1}, {1, 0}, {1, 1} |
| 163 | }; | 175 | }; |
| 164 | 176 | ||
| 165 | static inline void ad2s1210_set_resolution_pin(struct ad2s1210_state *st) | 177 | static inline void ad2s1210_set_resolution_pin(struct ad2s1210_state *st) |
| 166 | { | 178 | { |
| 167 | gpio_set_value(st->pdata->res[0], | 179 | gpiod_set_value(st->gpios[AD2S1210_RES0], |
| 168 | ad2s1210_res_pins[(st->resolution - 10) / 2][0]); | 180 | ad2s1210_res_pins[(st->resolution - 10) / 2][0]); |
| 169 | gpio_set_value(st->pdata->res[1], | 181 | gpiod_set_value(st->gpios[AD2S1210_RES1], |
| 170 | ad2s1210_res_pins[(st->resolution - 10) / 2][1]); | 182 | ad2s1210_res_pins[(st->resolution - 10) / 2][1]); |
| 171 | } | 183 | } |
| 172 | 184 | ||
| 173 | static inline int ad2s1210_soft_reset(struct ad2s1210_state *st) | 185 | static inline int ad2s1210_soft_reset(struct ad2s1210_state *st) |
| @@ -301,15 +313,9 @@ static ssize_t ad2s1210_store_control(struct device *dev, | |||
| 301 | "ad2s1210: write control register fail\n"); | 313 | "ad2s1210: write control register fail\n"); |
| 302 | goto error_ret; | 314 | goto error_ret; |
| 303 | } | 315 | } |
| 304 | st->resolution | 316 | st->resolution = |
| 305 | = ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION]; | 317 | ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION]; |
| 306 | if (st->pdata->gpioin) { | 318 | ad2s1210_set_resolution_pin(st); |
| 307 | data = ad2s1210_read_resolution_pin(st); | ||
| 308 | if (data != st->resolution) | ||
| 309 | dev_warn(dev, "ad2s1210: resolution settings not match\n"); | ||
| 310 | } else { | ||
| 311 | ad2s1210_set_resolution_pin(st); | ||
| 312 | } | ||
| 313 | ret = len; | 319 | ret = len; |
| 314 | st->hysteresis = !!(data & AD2S1210_ENABLE_HYSTERESIS); | 320 | st->hysteresis = !!(data & AD2S1210_ENABLE_HYSTERESIS); |
| 315 | 321 | ||
| @@ -363,15 +369,9 @@ static ssize_t ad2s1210_store_resolution(struct device *dev, | |||
| 363 | dev_err(dev, "ad2s1210: setting resolution fail\n"); | 369 | dev_err(dev, "ad2s1210: setting resolution fail\n"); |
| 364 | goto error_ret; | 370 | goto error_ret; |
| 365 | } | 371 | } |
| 366 | st->resolution | 372 | st->resolution = |
| 367 | = ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION]; | 373 | ad2s1210_resolution_value[data & AD2S1210_SET_RESOLUTION]; |
| 368 | if (st->pdata->gpioin) { | 374 | ad2s1210_set_resolution_pin(st); |
| 369 | data = ad2s1210_read_resolution_pin(st); | ||
| 370 | if (data != st->resolution) | ||
| 371 | dev_warn(dev, "ad2s1210: resolution settings not match\n"); | ||
| 372 | } else { | ||
| 373 | ad2s1210_set_resolution_pin(st); | ||
| 374 | } | ||
| 375 | ret = len; | 375 | ret = len; |
| 376 | error_ret: | 376 | error_ret: |
| 377 | mutex_unlock(&st->lock); | 377 | mutex_unlock(&st->lock); |
| @@ -401,15 +401,15 @@ static ssize_t ad2s1210_clear_fault(struct device *dev, | |||
| 401 | int ret; | 401 | int ret; |
| 402 | 402 | ||
| 403 | mutex_lock(&st->lock); | 403 | mutex_lock(&st->lock); |
| 404 | gpio_set_value(st->pdata->sample, 0); | 404 | gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0); |
| 405 | /* delay (2 * tck + 20) nano seconds */ | 405 | /* delay (2 * tck + 20) nano seconds */ |
| 406 | udelay(1); | 406 | udelay(1); |
| 407 | gpio_set_value(st->pdata->sample, 1); | 407 | gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1); |
| 408 | ret = ad2s1210_config_read(st, AD2S1210_REG_FAULT); | 408 | ret = ad2s1210_config_read(st, AD2S1210_REG_FAULT); |
| 409 | if (ret < 0) | 409 | if (ret < 0) |
| 410 | goto error_ret; | 410 | goto error_ret; |
| 411 | gpio_set_value(st->pdata->sample, 0); | 411 | gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0); |
| 412 | gpio_set_value(st->pdata->sample, 1); | 412 | gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1); |
| 413 | error_ret: | 413 | error_ret: |
| 414 | mutex_unlock(&st->lock); | 414 | mutex_unlock(&st->lock); |
| 415 | 415 | ||
| @@ -466,7 +466,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev, | |||
| 466 | s16 vel; | 466 | s16 vel; |
| 467 | 467 | ||
| 468 | mutex_lock(&st->lock); | 468 | mutex_lock(&st->lock); |
| 469 | gpio_set_value(st->pdata->sample, 0); | 469 | gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 0); |
| 470 | /* delay (6 * tck + 20) nano seconds */ | 470 | /* delay (6 * tck + 20) nano seconds */ |
| 471 | udelay(1); | 471 | udelay(1); |
| 472 | 472 | ||
| @@ -512,7 +512,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev, | |||
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | error_ret: | 514 | error_ret: |
| 515 | gpio_set_value(st->pdata->sample, 1); | 515 | gpiod_set_value(st->gpios[AD2S1210_SAMPLE], 1); |
| 516 | /* delay (2 * tck + 20) nano seconds */ | 516 | /* delay (2 * tck + 20) nano seconds */ |
| 517 | udelay(1); | 517 | udelay(1); |
| 518 | mutex_unlock(&st->lock); | 518 | mutex_unlock(&st->lock); |
| @@ -592,10 +592,7 @@ static int ad2s1210_initial(struct ad2s1210_state *st) | |||
| 592 | int ret; | 592 | int ret; |
| 593 | 593 | ||
| 594 | mutex_lock(&st->lock); | 594 | mutex_lock(&st->lock); |
| 595 | if (st->pdata->gpioin) | 595 | ad2s1210_set_resolution_pin(st); |
| 596 | st->resolution = ad2s1210_read_resolution_pin(st); | ||
| 597 | else | ||
| 598 | ad2s1210_set_resolution_pin(st); | ||
| 599 | 596 | ||
| 600 | ret = ad2s1210_config_write(st, AD2S1210_REG_CONTROL); | 597 | ret = ad2s1210_config_write(st, AD2S1210_REG_CONTROL); |
| 601 | if (ret < 0) | 598 | if (ret < 0) |
| @@ -630,30 +627,22 @@ static const struct iio_info ad2s1210_info = { | |||
| 630 | 627 | ||
| 631 | static int ad2s1210_setup_gpios(struct ad2s1210_state *st) | 628 | static int ad2s1210_setup_gpios(struct ad2s1210_state *st) |
| 632 | { | 629 | { |
| 633 | unsigned long flags = st->pdata->gpioin ? GPIOF_DIR_IN : GPIOF_DIR_OUT; | 630 | struct spi_device *spi = st->sdev; |
| 634 | struct gpio ad2s1210_gpios[] = { | 631 | int i, ret; |
| 635 | { st->pdata->sample, GPIOF_DIR_IN, "sample" }, | 632 | |
| 636 | { st->pdata->a[0], flags, "a0" }, | 633 | for (i = 0; i < ARRAY_SIZE(gpios); i++) { |
| 637 | { st->pdata->a[1], flags, "a1" }, | 634 | st->gpios[i] = devm_gpiod_get(&spi->dev, gpios[i].name, |
| 638 | { st->pdata->res[0], flags, "res0" }, | 635 | gpios[i].flags); |
| 639 | { st->pdata->res[0], flags, "res1" }, | 636 | if (IS_ERR(st->gpios[i])) { |
| 640 | }; | 637 | ret = PTR_ERR(st->gpios[i]); |
| 641 | 638 | dev_err(&spi->dev, | |
| 642 | return gpio_request_array(ad2s1210_gpios, ARRAY_SIZE(ad2s1210_gpios)); | 639 | "ad2s1210: failed to request %s GPIO: %d\n", |
| 643 | } | 640 | gpios[i].name, ret); |
| 644 | 641 | return ret; | |
| 645 | static void ad2s1210_free_gpios(struct ad2s1210_state *st) | 642 | } |
| 646 | { | 643 | } |
| 647 | unsigned long flags = st->pdata->gpioin ? GPIOF_DIR_IN : GPIOF_DIR_OUT; | ||
| 648 | struct gpio ad2s1210_gpios[] = { | ||
| 649 | { st->pdata->sample, GPIOF_DIR_IN, "sample" }, | ||
| 650 | { st->pdata->a[0], flags, "a0" }, | ||
| 651 | { st->pdata->a[1], flags, "a1" }, | ||
| 652 | { st->pdata->res[0], flags, "res0" }, | ||
| 653 | { st->pdata->res[0], flags, "res1" }, | ||
| 654 | }; | ||
| 655 | 644 | ||
| 656 | gpio_free_array(ad2s1210_gpios, ARRAY_SIZE(ad2s1210_gpios)); | 645 | return 0; |
| 657 | } | 646 | } |
| 658 | 647 | ||
| 659 | static int ad2s1210_probe(struct spi_device *spi) | 648 | static int ad2s1210_probe(struct spi_device *spi) |
| @@ -669,7 +658,6 @@ static int ad2s1210_probe(struct spi_device *spi) | |||
| 669 | if (!indio_dev) | 658 | if (!indio_dev) |
| 670 | return -ENOMEM; | 659 | return -ENOMEM; |
| 671 | st = iio_priv(indio_dev); | 660 | st = iio_priv(indio_dev); |
| 672 | st->pdata = spi->dev.platform_data; | ||
| 673 | ret = ad2s1210_setup_gpios(st); | 661 | ret = ad2s1210_setup_gpios(st); |
| 674 | if (ret < 0) | 662 | if (ret < 0) |
| 675 | return ret; | 663 | return ret; |
| @@ -692,7 +680,7 @@ static int ad2s1210_probe(struct spi_device *spi) | |||
| 692 | 680 | ||
| 693 | ret = iio_device_register(indio_dev); | 681 | ret = iio_device_register(indio_dev); |
| 694 | if (ret) | 682 | if (ret) |
| 695 | goto error_free_gpios; | 683 | return ret; |
| 696 | 684 | ||
| 697 | st->fclkin = spi->max_speed_hz; | 685 | st->fclkin = spi->max_speed_hz; |
| 698 | spi->mode = SPI_MODE_3; | 686 | spi->mode = SPI_MODE_3; |
| @@ -700,10 +688,6 @@ static int ad2s1210_probe(struct spi_device *spi) | |||
| 700 | ad2s1210_initial(st); | 688 | ad2s1210_initial(st); |
| 701 | 689 | ||
| 702 | return 0; | 690 | return 0; |
| 703 | |||
| 704 | error_free_gpios: | ||
| 705 | ad2s1210_free_gpios(st); | ||
| 706 | return ret; | ||
| 707 | } | 691 | } |
| 708 | 692 | ||
| 709 | static int ad2s1210_remove(struct spi_device *spi) | 693 | static int ad2s1210_remove(struct spi_device *spi) |
| @@ -711,11 +695,16 @@ static int ad2s1210_remove(struct spi_device *spi) | |||
| 711 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | 695 | struct iio_dev *indio_dev = spi_get_drvdata(spi); |
| 712 | 696 | ||
| 713 | iio_device_unregister(indio_dev); | 697 | iio_device_unregister(indio_dev); |
| 714 | ad2s1210_free_gpios(iio_priv(indio_dev)); | ||
| 715 | 698 | ||
| 716 | return 0; | 699 | return 0; |
| 717 | } | 700 | } |
| 718 | 701 | ||
| 702 | static const struct of_device_id ad2s1210_of_match[] = { | ||
| 703 | { .compatible = "adi,ad2s1210", }, | ||
| 704 | { } | ||
| 705 | }; | ||
| 706 | MODULE_DEVICE_TABLE(of, ad2s1210_of_match); | ||
| 707 | |||
| 719 | static const struct spi_device_id ad2s1210_id[] = { | 708 | static const struct spi_device_id ad2s1210_id[] = { |
| 720 | { "ad2s1210" }, | 709 | { "ad2s1210" }, |
| 721 | {} | 710 | {} |
| @@ -725,6 +714,7 @@ MODULE_DEVICE_TABLE(spi, ad2s1210_id); | |||
| 725 | static struct spi_driver ad2s1210_driver = { | 714 | static struct spi_driver ad2s1210_driver = { |
| 726 | .driver = { | 715 | .driver = { |
| 727 | .name = DRV_NAME, | 716 | .name = DRV_NAME, |
| 717 | .of_match_table = of_match_ptr(ad2s1210_of_match), | ||
| 728 | }, | 718 | }, |
| 729 | .probe = ad2s1210_probe, | 719 | .probe = ad2s1210_probe, |
| 730 | .remove = ad2s1210_remove, | 720 | .remove = ad2s1210_remove, |
diff --git a/drivers/staging/iio/resolver/ad2s1210.h b/drivers/staging/iio/resolver/ad2s1210.h deleted file mode 100644 index e9b2147701fc..000000000000 --- a/drivers/staging/iio/resolver/ad2s1210.h +++ /dev/null | |||
| @@ -1,20 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * ad2s1210.h plaform data for the ADI Resolver to Digital Converters: | ||
| 3 | * AD2S1210 | ||
| 4 | * | ||
| 5 | * Copyright (c) 2010-2010 Analog Devices Inc. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | #ifndef _AD2S1210_H | ||
| 12 | #define _AD2S1210_H | ||
| 13 | |||
| 14 | struct ad2s1210_platform_data { | ||
| 15 | unsigned int sample; | ||
| 16 | unsigned int a[2]; | ||
| 17 | unsigned int res[2]; | ||
| 18 | bool gpioin; | ||
| 19 | }; | ||
| 20 | #endif /* _AD2S1210_H */ | ||
diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c index 59586947a936..3e257ac46f7a 100644 --- a/drivers/staging/iio/resolver/ad2s90.c +++ b/drivers/staging/iio/resolver/ad2s90.c | |||
| @@ -34,16 +34,32 @@ static int ad2s90_read_raw(struct iio_dev *indio_dev, | |||
| 34 | int ret; | 34 | int ret; |
| 35 | struct ad2s90_state *st = iio_priv(indio_dev); | 35 | struct ad2s90_state *st = iio_priv(indio_dev); |
| 36 | 36 | ||
| 37 | mutex_lock(&st->lock); | 37 | if (chan->type != IIO_ANGL) |
| 38 | ret = spi_read(st->sdev, st->rx, 2); | 38 | return -EINVAL; |
| 39 | if (ret) | 39 | |
| 40 | goto error_ret; | 40 | switch (m) { |
| 41 | *val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); | 41 | case IIO_CHAN_INFO_SCALE: |
| 42 | 42 | /* 2 * Pi / 2^12 */ | |
| 43 | error_ret: | 43 | *val = 6283; /* mV */ |
| 44 | mutex_unlock(&st->lock); | 44 | *val2 = 12; |
| 45 | 45 | return IIO_VAL_FRACTIONAL_LOG2; | |
| 46 | return IIO_VAL_INT; | 46 | case IIO_CHAN_INFO_RAW: |
| 47 | mutex_lock(&st->lock); | ||
| 48 | ret = spi_read(st->sdev, st->rx, 2); | ||
| 49 | if (ret < 0) { | ||
| 50 | mutex_unlock(&st->lock); | ||
| 51 | return ret; | ||
| 52 | } | ||
| 53 | *val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); | ||
| 54 | |||
| 55 | mutex_unlock(&st->lock); | ||
| 56 | |||
| 57 | return IIO_VAL_INT; | ||
| 58 | default: | ||
| 59 | break; | ||
| 60 | } | ||
| 61 | |||
| 62 | return -EINVAL; | ||
| 47 | } | 63 | } |
| 48 | 64 | ||
| 49 | static const struct iio_info ad2s90_info = { | 65 | static const struct iio_info ad2s90_info = { |
| @@ -54,14 +70,14 @@ static const struct iio_chan_spec ad2s90_chan = { | |||
| 54 | .type = IIO_ANGL, | 70 | .type = IIO_ANGL, |
| 55 | .indexed = 1, | 71 | .indexed = 1, |
| 56 | .channel = 0, | 72 | .channel = 0, |
| 57 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | 73 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), |
| 58 | }; | 74 | }; |
| 59 | 75 | ||
| 60 | static int ad2s90_probe(struct spi_device *spi) | 76 | static int ad2s90_probe(struct spi_device *spi) |
| 61 | { | 77 | { |
| 62 | struct iio_dev *indio_dev; | 78 | struct iio_dev *indio_dev; |
| 63 | struct ad2s90_state *st; | 79 | struct ad2s90_state *st; |
| 64 | int ret = 0; | 80 | int ret; |
| 65 | 81 | ||
| 66 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | 82 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); |
| 67 | if (!indio_dev) | 83 | if (!indio_dev) |
| @@ -78,16 +94,17 @@ static int ad2s90_probe(struct spi_device *spi) | |||
| 78 | indio_dev->num_channels = 1; | 94 | indio_dev->num_channels = 1; |
| 79 | indio_dev->name = spi_get_device_id(spi)->name; | 95 | indio_dev->name = spi_get_device_id(spi)->name; |
| 80 | 96 | ||
| 81 | ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); | ||
| 82 | if (ret) | ||
| 83 | return ret; | ||
| 84 | |||
| 85 | /* need 600ns between CS and the first falling edge of SCLK */ | 97 | /* need 600ns between CS and the first falling edge of SCLK */ |
| 86 | spi->max_speed_hz = 830000; | 98 | spi->max_speed_hz = 830000; |
| 87 | spi->mode = SPI_MODE_3; | 99 | spi->mode = SPI_MODE_3; |
| 88 | spi_setup(spi); | 100 | ret = spi_setup(spi); |
| 101 | |||
| 102 | if (ret < 0) { | ||
| 103 | dev_err(&spi->dev, "spi_setup failed!\n"); | ||
| 104 | return ret; | ||
| 105 | } | ||
| 89 | 106 | ||
| 90 | return 0; | 107 | return devm_iio_device_register(indio_dev->dev.parent, indio_dev); |
| 91 | } | 108 | } |
| 92 | 109 | ||
| 93 | static const struct spi_device_id ad2s90_id[] = { | 110 | static const struct spi_device_id ad2s90_id[] = { |
diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h index 730ead1a46df..7e84351fa2c0 100644 --- a/include/linux/iio/adc/ad_sigma_delta.h +++ b/include/linux/iio/adc/ad_sigma_delta.h | |||
| @@ -39,6 +39,8 @@ struct iio_dev; | |||
| 39 | * if there is just one read-only sample data shift register. | 39 | * if there is just one read-only sample data shift register. |
| 40 | * @addr_shift: Shift of the register address in the communications register. | 40 | * @addr_shift: Shift of the register address in the communications register. |
| 41 | * @read_mask: Mask for the communications register having the read bit set. | 41 | * @read_mask: Mask for the communications register having the read bit set. |
| 42 | * @data_reg: Address of the data register, if 0 the default address of 0x3 will | ||
| 43 | * be used. | ||
| 42 | */ | 44 | */ |
| 43 | struct ad_sigma_delta_info { | 45 | struct ad_sigma_delta_info { |
| 44 | int (*set_channel)(struct ad_sigma_delta *, unsigned int channel); | 46 | int (*set_channel)(struct ad_sigma_delta *, unsigned int channel); |
| @@ -47,6 +49,7 @@ struct ad_sigma_delta_info { | |||
| 47 | bool has_registers; | 49 | bool has_registers; |
| 48 | unsigned int addr_shift; | 50 | unsigned int addr_shift; |
| 49 | unsigned int read_mask; | 51 | unsigned int read_mask; |
| 52 | unsigned int data_reg; | ||
| 50 | }; | 53 | }; |
| 51 | 54 | ||
| 52 | /** | 55 | /** |
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h index f9bd6e8ab138..8092b8e7f37e 100644 --- a/include/linux/iio/common/st_sensors.h +++ b/include/linux/iio/common/st_sensors.h | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | #define ST_SENSORS_DEFAULT_STAT_ADDR 0x27 | 40 | #define ST_SENSORS_DEFAULT_STAT_ADDR 0x27 |
| 41 | 41 | ||
| 42 | #define ST_SENSORS_MAX_NAME 17 | 42 | #define ST_SENSORS_MAX_NAME 17 |
| 43 | #define ST_SENSORS_MAX_4WAI 7 | 43 | #define ST_SENSORS_MAX_4WAI 8 |
| 44 | 44 | ||
| 45 | #define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \ | 45 | #define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \ |
| 46 | ch2, s, endian, rbits, sbits, addr) \ | 46 | ch2, s, endian, rbits, sbits, addr) \ |
diff --git a/include/linux/platform_data/st_sensors_pdata.h b/include/linux/platform_data/st_sensors_pdata.h index f8274b0c6888..728193111c2f 100644 --- a/include/linux/platform_data/st_sensors_pdata.h +++ b/include/linux/platform_data/st_sensors_pdata.h | |||
| @@ -18,11 +18,13 @@ | |||
| 18 | * Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet). | 18 | * Accelerometer DRDY on LSM330 available only on pin 1 (see datasheet). |
| 19 | * @open_drain: set the interrupt line to be open drain if possible. | 19 | * @open_drain: set the interrupt line to be open drain if possible. |
| 20 | * @spi_3wire: enable spi-3wire mode. | 20 | * @spi_3wire: enable spi-3wire mode. |
| 21 | * @pullups: enable/disable i2c controller pullup resistors. | ||
| 21 | */ | 22 | */ |
| 22 | struct st_sensors_platform_data { | 23 | struct st_sensors_platform_data { |
| 23 | u8 drdy_int_pin; | 24 | u8 drdy_int_pin; |
| 24 | bool open_drain; | 25 | bool open_drain; |
| 25 | bool spi_3wire; | 26 | bool spi_3wire; |
| 27 | bool pullups; | ||
| 26 | }; | 28 | }; |
| 27 | 29 | ||
| 28 | #endif /* ST_SENSORS_PDATA_H */ | 30 | #endif /* ST_SENSORS_PDATA_H */ |
diff --git a/tools/iio/Makefile b/tools/iio/Makefile index 332ed2f6c2c2..e22378dba244 100644 --- a/tools/iio/Makefile +++ b/tools/iio/Makefile | |||
| @@ -12,7 +12,7 @@ endif | |||
| 12 | # (this improves performance and avoids hard-to-debug behaviour); | 12 | # (this improves performance and avoids hard-to-debug behaviour); |
| 13 | MAKEFLAGS += -r | 13 | MAKEFLAGS += -r |
| 14 | 14 | ||
| 15 | CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include | 15 | override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include |
| 16 | 16 | ||
| 17 | ALL_TARGETS := iio_event_monitor lsiio iio_generic_buffer | 17 | ALL_TARGETS := iio_event_monitor lsiio iio_generic_buffer |
| 18 | ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) | 18 | ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) |
