mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
1st set of IIO new device support, feature and cleanup for 6.2 (take2)
We have finally managed to take the mlock mutex entirely private so as to avoid it being used for multiple purposes. Now it is just used to protect device mode transitions (typically to and from buffered capture). Includes merge of an immutable i2c branch to get the new i2c_client_get_device_id() (thanks to Wolfram for providing the branch). Based on rc3 to pick up some precursor fixes from early in the cycle and avoid an unnecessarily messy history. New device support * adi,ad4310 - New driver to support this very flexible measurement device including a 24 bit ADC. Later fix for documentation build issue. * adi,adxl355 - Add support of the ADXL359 accelerometer. * adi,ltc2983 - Support additional variants of the temperatures sensor: LTC2984 with an EEPROM LTC2985, LTC2986 with only 10 channels. * invensense,icm42600 - Add support for icm42631 (needed only ID and WHOAMI) * kionix,kx022a - New driver for this 3 axis accelerometer. * maxim,max11401 - New driver to support this 24-bit 10 channel ADC. Includes some new ABI to support configuration of notch filters. * mediatek,mt6370 - Add new driver to support the ADC part of the mt6370. * st,lsm6dsx - Add support for LSM6DSV accelerometer and gyroscope. Simple additional of chip specific data and IDs. - Add support for LSM6DSV16X accelerometer and gyroscope. Compatible with features currently implemented for the LSM6DSV. * st,stm32-adc - Add support for stm32pm13x SoCs. core / subsystem wide: - Add new IIO_STATIC_CONST_DEVICE_ATTR() which is a dance necessary to allow for the wrapping of attributes in the code that duplicates them for multiple buffers. - Harden against future issues with expectation that all buffer attributes are iio_dev_attrs by changing the code to take an array of pointers of the correct type. - Last transitions of drivers to local locks rather than missuses of mlock. - Add an iio_device_claim_buffer_mode() callback to avoid a race in the max30100 driver without directly using mlock. - Move mlock to the opaque IIO device structure to prevent misuse. - Add missing spi_device_id tables to support auto loading of modules. - Update some ADI maintainers in DT bindings. - A few more moves of bus drivers and core module sets to export name spaces. - Extensive use of new devm_regulator_get_enable() and friends. - Switch a bunch of i2c drivers to probe_new() including the bmp280 which makes use of the new i2c_client_get_device_id() helper to simplify this change. dt-bindings: - More use of spi-peripheral-props.yaml. Features * freescale,mpl115 - Use runtime PM to implement shutdown GPIO support. * melexis,mlx90632 - More sophisticated runtime power management - Provide access to sampling frequency. - Trivial follow up fixes. * microchip,mcp3911 - Support control of PGA. * st,lsm6dsx - Add support for software triggers for cases where the IRQ lines are not wired up. * vishay,vcnl4000 - Add control of integration time. Minor cleanups and fixes * adi,ad4130 - Improve ABI documentation formatting. - Kconfig dependency fixup. * adi,ad5758 - Minor dt binding fix. * adi,ad9834 - Tidy up line breaks. * adi,ade7854 - Minor improvement in code clarity by replacing a ternary. * adi,admv8818 - Harden code against hardware returning wrong values. * adi,adxl355 - Warn only if unknown device ID detected to allow for fall back device tree compatibles on future devices. * adi,ltc2983 - dt-bindings clarifications and general improvements. - Ensure DMA safe buffer for bulk writes without relying on current regmap implementation choices. * avago,adps9960 - Fix up a disconnect between event enable attributes and what was enabled. * bosch,bma400 - Switch to dev_err_probe() from open coded EPROBE_DEFER handling. * cosmic,cc10001 - Fully devm managed probe() and related tidying up. * meas,ms5611 - Add an example of spi-max-frequency. * meleixs,mlx90632 - Tidy up confusing error return value. - Style improvements. * multiplexer - Switch to dev_err_probe() from open coded EPROBE_DEFER handling. * qcom,spmi-vadc - Minor dt binding improvements. * rockchip,saradc - Add ID for rv1126. * semtech,sx9360 - Add SAMM0208 ACPI ID. Doesn't appear to be a valid vendor prefix but is in the wild. * st,lsm6dsx - Factor out common code as _device_set_enable(). - Fix up wrong docs after LSM6DSV addition. * st,stm32-adc - Manage the min sampling time on all internal channels. * trig,sysfs - Improve error labels. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmN+fI4RHGppYzIzQGtl cm5lbC5vcmcACgkQVIU0mcT0FogY1Q/7BTdKLbRuFoE4aK9AABv+m4w91s+RlBg6 eXRw3Gt4IHHht7gIUVZByYztyoKkmW3RzsPafIlfJJkWAsiBpv6gXTW2h6UvjHg8 SW3k91oVk5iLEeTaUSfJqxHCXX+VRYanyeti53MkpUvR2QUgAengP11N6bWmNXav D6OFGSTn9QpJ0XRmEmfxXt3pt/Miuz7GT2sN5ut1ZvTgN0wZ2aMMdEa8w3UQvxoN +Iu0Z3kRtltbw5zqTTdJfXPHS3K1I+361zTT6E4KDVun2939C3Tzw6ziy6MIsng+ nysaMbZTc5MmdIDPYtSlIV+i4S4DyqvAKsv5PBqqbD3oQfo8AkmnyY6Hdygbv23O vK23x19GYcpgLQ42C0g+LFUYxJOJMnMiOocISq8V7Df9+CQRNnk4e7s8MvmhAXmu VrOT1VDEL8bJFeukiMRtVTsDo/KRHOWUjEi+1dxJ7aOqry8FGrlR4L+ZtjbMTnmw V+7CN0euOdpiDV6jJwmXHQvLWlG3wgq7ZHHj6toaFtq8FI4OaQiA7Ko5WuBLTBxw V0jtK/Fru77P0aR7dAd5ck6Rwek8N2rSuOvpucLmImt9asZP3uzoM/LRmtv4Gzjq Dp8koqSwx6YMtMAHmXgB/2GkSoOV7eByvIkYCoFCxEp2tst+mIOKSQPDKP8PKuRd VBSmvuEilis= =Fo38 -----END PGP SIGNATURE----- Merge tag 'iio-for-6.2a-take2' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-next Jonathan writes: 1st set of IIO new device support, feature and cleanup for 6.2 (take2) We have finally managed to take the mlock mutex entirely private so as to avoid it being used for multiple purposes. Now it is just used to protect device mode transitions (typically to and from buffered capture). Includes merge of an immutable i2c branch to get the new i2c_client_get_device_id() (thanks to Wolfram for providing the branch). Based on rc3 to pick up some precursor fixes from early in the cycle and avoid an unnecessarily messy history. New device support * adi,ad4310 - New driver to support this very flexible measurement device including a 24 bit ADC. Later fix for documentation build issue. * adi,adxl355 - Add support of the ADXL359 accelerometer. * adi,ltc2983 - Support additional variants of the temperatures sensor: LTC2984 with an EEPROM LTC2985, LTC2986 with only 10 channels. * invensense,icm42600 - Add support for icm42631 (needed only ID and WHOAMI) * kionix,kx022a - New driver for this 3 axis accelerometer. * maxim,max11401 - New driver to support this 24-bit 10 channel ADC. Includes some new ABI to support configuration of notch filters. * mediatek,mt6370 - Add new driver to support the ADC part of the mt6370. * st,lsm6dsx - Add support for LSM6DSV accelerometer and gyroscope. Simple additional of chip specific data and IDs. - Add support for LSM6DSV16X accelerometer and gyroscope. Compatible with features currently implemented for the LSM6DSV. * st,stm32-adc - Add support for stm32pm13x SoCs. core / subsystem wide: - Add new IIO_STATIC_CONST_DEVICE_ATTR() which is a dance necessary to allow for the wrapping of attributes in the code that duplicates them for multiple buffers. - Harden against future issues with expectation that all buffer attributes are iio_dev_attrs by changing the code to take an array of pointers of the correct type. - Last transitions of drivers to local locks rather than missuses of mlock. - Add an iio_device_claim_buffer_mode() callback to avoid a race in the max30100 driver without directly using mlock. - Move mlock to the opaque IIO device structure to prevent misuse. - Add missing spi_device_id tables to support auto loading of modules. - Update some ADI maintainers in DT bindings. - A few more moves of bus drivers and core module sets to export name spaces. - Extensive use of new devm_regulator_get_enable() and friends. - Switch a bunch of i2c drivers to probe_new() including the bmp280 which makes use of the new i2c_client_get_device_id() helper to simplify this change. dt-bindings: - More use of spi-peripheral-props.yaml. Features * freescale,mpl115 - Use runtime PM to implement shutdown GPIO support. * melexis,mlx90632 - More sophisticated runtime power management - Provide access to sampling frequency. - Trivial follow up fixes. * microchip,mcp3911 - Support control of PGA. * st,lsm6dsx - Add support for software triggers for cases where the IRQ lines are not wired up. * vishay,vcnl4000 - Add control of integration time. Minor cleanups and fixes * adi,ad4130 - Improve ABI documentation formatting. - Kconfig dependency fixup. * adi,ad5758 - Minor dt binding fix. * adi,ad9834 - Tidy up line breaks. * adi,ade7854 - Minor improvement in code clarity by replacing a ternary. * adi,admv8818 - Harden code against hardware returning wrong values. * adi,adxl355 - Warn only if unknown device ID detected to allow for fall back device tree compatibles on future devices. * adi,ltc2983 - dt-bindings clarifications and general improvements. - Ensure DMA safe buffer for bulk writes without relying on current regmap implementation choices. * avago,adps9960 - Fix up a disconnect between event enable attributes and what was enabled. * bosch,bma400 - Switch to dev_err_probe() from open coded EPROBE_DEFER handling. * cosmic,cc10001 - Fully devm managed probe() and related tidying up. * meas,ms5611 - Add an example of spi-max-frequency. * meleixs,mlx90632 - Tidy up confusing error return value. - Style improvements. * multiplexer - Switch to dev_err_probe() from open coded EPROBE_DEFER handling. * qcom,spmi-vadc - Minor dt binding improvements. * rockchip,saradc - Add ID for rv1126. * semtech,sx9360 - Add SAMM0208 ACPI ID. Doesn't appear to be a valid vendor prefix but is in the wild. * st,lsm6dsx - Factor out common code as _device_set_enable(). - Fix up wrong docs after LSM6DSV addition. * st,stm32-adc - Manage the min sampling time on all internal channels. * trig,sysfs - Improve error labels. * tag 'iio-for-6.2a-take2' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (146 commits) iio: pressure: bmp280: convert to i2c's .probe_new() iio: imu: st_lsm6dsx: fix LSM6DSV sensor description iio: adc: ad4130: depend on GPIOLIB staging: iio: meter: replace ternary operator by if condition iio: light: apds9960: Fix iio_event_spec structures dt-bindings: iio: imu: Add inv_icm42600 documentation iio: imu: inv_icm42600: Add support for icm42631 dt-bindings: iio: adc: rockchip-saradc: Add saradc for rv1126 dt-bindings: iio: dac: adi,ad5758: Drop 'contains' from 'adi,dc-dc-mode' dt-bindings: iio: imu: st_lsm6dsx: add lsm6dsv16x iio: imu: st_lsm6dsx: add support to LSM6DSV16X iio: proximity: sx9360: Add a new ACPI hardware ID iio: temperature: mlx90632: Add missing static marking on devm_pm_ops iio: temperature: mlx90632: Add error handling for devm_pm_runtime_enable() iio: temperature: ltc2983: support more parts dt-bindings: iio: temperature: ltc2983: support more parts dt-bindings: iio: temperature: ltc2983: use generic node name in example dt-bindings: iio: temperature: ltc2983: describe broken mux delay property dt-bindings: iio: temperature: ltc2983: refine descriptions dt-bindings: iio: temperature: ltc2983: change default excitation for custom thermistors ...
This commit is contained in:
commit
56d784d177
46
Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130
Normal file
46
Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130
Normal file
@ -0,0 +1,46 @@
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_filter_mode_available
|
||||
KernelVersion: 6.2
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Reading returns a list with the possible filter modes.
|
||||
|
||||
* "sinc4" - Sinc 4. Excellent noise performance. Long
|
||||
1st conversion time. No natural 50/60Hz rejection.
|
||||
|
||||
* "sinc4+sinc1" - Sinc4 + averaging by 8. Low 1st conversion
|
||||
time.
|
||||
|
||||
* "sinc3" - Sinc3. Moderate 1st conversion time.
|
||||
Good noise performance.
|
||||
|
||||
* "sinc3+rej60" - Sinc3 + 60Hz rejection. At a sampling
|
||||
frequency of 50Hz, achieves simultaneous 50Hz and 60Hz
|
||||
rejection.
|
||||
|
||||
* "sinc3+sinc1" - Sinc3 + averaging by 8. Low 1st conversion
|
||||
time. Best used with a sampling frequency of at least
|
||||
216.19Hz.
|
||||
|
||||
* "sinc3+pf1" - Sinc3 + Post Filter 1. 53dB rejection @
|
||||
50Hz, 58dB rejection @ 60Hz.
|
||||
|
||||
* "sinc3+pf2" - Sinc3 + Post Filter 2. 70dB rejection @
|
||||
50Hz, 70dB rejection @ 60Hz.
|
||||
|
||||
* "sinc3+pf3" - Sinc3 + Post Filter 3. 99dB rejection @
|
||||
50Hz, 103dB rejection @ 60Hz.
|
||||
|
||||
* "sinc3+pf4" - Sinc3 + Post Filter 4. 103dB rejection @
|
||||
50Hz, 109dB rejection @ 60Hz.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_filter_mode
|
||||
KernelVersion: 6.2
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Set the filter mode of the differential channel. When the filter
|
||||
mode changes, the in_voltageY-voltageZ_sampling_frequency and
|
||||
in_voltageY-voltageZ_sampling_frequency_available attributes
|
||||
might also change to accommodate the new filter mode.
|
||||
If the current sampling frequency is out of range for the new
|
||||
filter mode, the sampling frequency will be changed to the
|
||||
closest valid one.
|
13
Documentation/ABI/testing/sysfs-bus-iio-adc-max11410
Normal file
13
Documentation/ABI/testing/sysfs-bus-iio-adc-max11410
Normal file
@ -0,0 +1,13 @@
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_voltage_filterY_notch_en
|
||||
Date: September 2022
|
||||
KernelVersion: 6.0
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Enable or disable a notch filter.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_voltage_filterY_notch_center
|
||||
Date: September 2022
|
||||
KernelVersion: 6.0
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Center frequency of the notch filter in Hz.
|
@ -4,20 +4,22 @@
|
||||
$id: http://devicetree.org/schemas/iio/accel/adi,adxl355.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices ADXL355 3-Axis, Low noise MEMS Accelerometer
|
||||
title: Analog Devices ADXL355 and ADXL359 3-Axis, Low noise MEMS Accelerometers
|
||||
|
||||
maintainers:
|
||||
- Puranjay Mohan <puranjay12@gmail.com>
|
||||
|
||||
description: |
|
||||
Analog Devices ADXL355 3-Axis, Low noise MEMS Accelerometer that supports
|
||||
both I2C & SPI interfaces
|
||||
Analog Devices ADXL355 and ADXL359 3-Axis, Low noise MEMS Accelerometers that
|
||||
support both I2C & SPI interfaces
|
||||
https://www.analog.com/en/products/adxl355.html
|
||||
https://www.analog.com/en/products/adxl359.html
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,adxl355
|
||||
- adi,adxl359
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -0,0 +1,65 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/accel/kionix,kx022a.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ROHM/Kionix KX022A Accelerometer
|
||||
|
||||
maintainers:
|
||||
- Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
|
||||
description: |
|
||||
KX022A is a 3-axis accelerometer supporting +/- 2G, 4G, 8G and 16G ranges,
|
||||
output data-rates from 0.78Hz to 1600Hz and a hardware-fifo buffering.
|
||||
KX022A can be accessed either via I2C or SPI.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: kionix,kx022a
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- enum: [INT1, INT2]
|
||||
- const: INT2
|
||||
|
||||
vdd-supply: true
|
||||
io-vdd-supply: true
|
||||
|
||||
mount-matrix:
|
||||
description: |
|
||||
an optional 3x3 mounting rotation matrix.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
accel@1f {
|
||||
compatible = "kionix,kx022a";
|
||||
reg = <0x1f>;
|
||||
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "INT1";
|
||||
|
||||
io-vdd-supply = <&iovdd>;
|
||||
vdd-supply = <&vdd>;
|
||||
};
|
||||
};
|
259
Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml
Normal file
259
Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml
Normal file
@ -0,0 +1,259 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
# Copyright 2022 Analog Devices Inc.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/adi,ad4130.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices AD4130 ADC device driver
|
||||
|
||||
maintainers:
|
||||
- Cosmin Tanislav <cosmin.tanislav@analog.com>
|
||||
|
||||
description: |
|
||||
Bindings for the Analog Devices AD4130 ADC. Datasheet can be found here:
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/AD4130-8.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ad4130
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description: phandle to the master clock (mclk)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: mclk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
description: |
|
||||
Specify which interrupt pin should be configured as Data Ready / FIFO
|
||||
interrupt.
|
||||
Default if not supplied is int.
|
||||
enum:
|
||||
- int
|
||||
- clk
|
||||
- p2
|
||||
- dout
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
refin1-supply:
|
||||
description: refin1 supply. Can be used as reference for conversion.
|
||||
|
||||
refin2-supply:
|
||||
description: refin2 supply. Can be used as reference for conversion.
|
||||
|
||||
avdd-supply:
|
||||
description: AVDD voltage supply. Can be used as reference for conversion.
|
||||
|
||||
iovdd-supply:
|
||||
description: IOVDD voltage supply. Used for the chip interface.
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 5000000
|
||||
|
||||
adi,ext-clk-freq-hz:
|
||||
description: Specify the frequency of the external clock.
|
||||
enum: [76800, 153600]
|
||||
default: 76800
|
||||
|
||||
adi,bipolar:
|
||||
description: Specify if the device should be used in bipolar mode.
|
||||
type: boolean
|
||||
|
||||
adi,vbias-pins:
|
||||
description: Analog inputs to apply a voltage bias of (AVDD − AVSS) / 2 to.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 16
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
patternProperties:
|
||||
"^channel@([0-9a-f])$":
|
||||
type: object
|
||||
$ref: adc.yaml
|
||||
unevaluatedProperties: false
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: The channel number.
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
|
||||
diff-channels:
|
||||
description: |
|
||||
Besides the analog inputs available, internal inputs can be used.
|
||||
16: Internal temperature sensor.
|
||||
17: AVSS
|
||||
18: Internal reference
|
||||
19: DGND
|
||||
20: (AVDD − AVSS)/6+
|
||||
21: (AVDD − AVSS)/6-
|
||||
22: (IOVDD − DGND)/6+
|
||||
23: (IOVDD − DGND)/6-
|
||||
24: (ALDO − AVSS)/6+
|
||||
25: (ALDO − AVSS)/6-
|
||||
26: (DLDO − DGND)/6+
|
||||
27: (DLDO − DGND)/6-
|
||||
28: V_MV_P
|
||||
29: V_MV_M
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 29
|
||||
|
||||
adi,reference-select:
|
||||
description: |
|
||||
Select the reference source to use when converting on the
|
||||
specific channel. Valid values are:
|
||||
0: REFIN1(+)/REFIN1(−)
|
||||
1: REFIN2(+)/REFIN2(−)
|
||||
2: REFOUT/AVSS (Internal reference)
|
||||
3: AVDD/AVSS
|
||||
If not specified, REFIN1 is used.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2, 3]
|
||||
default: 0
|
||||
|
||||
adi,excitation-pin-0:
|
||||
description: |
|
||||
Analog input to apply excitation current to while the channel
|
||||
is active.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
default: 0
|
||||
|
||||
adi,excitation-pin-1:
|
||||
description: |
|
||||
Analog input to apply excitation current to while this channel
|
||||
is active.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
default: 0
|
||||
|
||||
adi,excitation-current-0-nanoamp:
|
||||
description: |
|
||||
Excitation current in nanoamps to be applied to pin specified in
|
||||
adi,excitation-pin-0 while this channel is active.
|
||||
enum: [0, 100, 10000, 20000, 50000, 100000, 150000, 200000]
|
||||
default: 0
|
||||
|
||||
adi,excitation-current-1-nanoamp:
|
||||
description: |
|
||||
Excitation current in nanoamps to be applied to pin specified in
|
||||
adi,excitation-pin-1 while this channel is active.
|
||||
enum: [0, 100, 10000, 20000, 50000, 100000, 150000, 200000]
|
||||
default: 0
|
||||
|
||||
adi,burnout-current-nanoamp:
|
||||
description: |
|
||||
Burnout current in nanoamps to be applied for this channel.
|
||||
enum: [0, 500, 2000, 4000]
|
||||
default: 0
|
||||
|
||||
adi,buffered-positive:
|
||||
description: Enable buffered mode for positive input.
|
||||
type: boolean
|
||||
|
||||
adi,buffered-negative:
|
||||
description: Enable buffered mode for negative input.
|
||||
type: boolean
|
||||
|
||||
required:
|
||||
- reg
|
||||
- diff-channels
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0 {
|
||||
compatible = "adi,ad4130";
|
||||
reg = <0>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
spi-max-frequency = <5000000>;
|
||||
interrupts = <27 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-parent = <&gpio>;
|
||||
|
||||
channel@0 {
|
||||
reg = <0>;
|
||||
|
||||
adi,reference-select = <2>;
|
||||
|
||||
/* AIN8, AIN9 */
|
||||
diff-channels = <8 9>;
|
||||
};
|
||||
|
||||
channel@1 {
|
||||
reg = <1>;
|
||||
|
||||
adi,reference-select = <2>;
|
||||
|
||||
/* AIN10, AIN11 */
|
||||
diff-channels = <10 11>;
|
||||
};
|
||||
|
||||
channel@2 {
|
||||
reg = <2>;
|
||||
|
||||
adi,reference-select = <2>;
|
||||
|
||||
/* Temperature Sensor, DGND */
|
||||
diff-channels = <16 19>;
|
||||
};
|
||||
|
||||
channel@3 {
|
||||
reg = <3>;
|
||||
|
||||
adi,reference-select = <2>;
|
||||
|
||||
/* Internal reference, DGND */
|
||||
diff-channels = <18 19>;
|
||||
};
|
||||
|
||||
channel@4 {
|
||||
reg = <4>;
|
||||
|
||||
adi,reference-select = <2>;
|
||||
|
||||
/* DGND, DGND */
|
||||
diff-channels = <19 19>;
|
||||
};
|
||||
};
|
||||
};
|
177
Documentation/devicetree/bindings/iio/adc/adi,max11410.yaml
Normal file
177
Documentation/devicetree/bindings/iio/adc/adi,max11410.yaml
Normal file
@ -0,0 +1,177 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
# Copyright 2022 Analog Devices Inc.
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/adc/adi,max11410.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices MAX11410 ADC device driver
|
||||
|
||||
maintainers:
|
||||
- Ibrahim Tilki <Ibrahim.Tilki@analog.com>
|
||||
|
||||
description: |
|
||||
Bindings for the Analog Devices MAX11410 ADC device. Datasheet can be
|
||||
found here:
|
||||
https://datasheets.maximintegrated.com/en/ds/MAX11410.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,max11410
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
description: Name of the gpio pin of max11410 used for IRQ
|
||||
minItems: 1
|
||||
items:
|
||||
- enum: [gpio0, gpio1]
|
||||
- const: gpio1
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
avdd-supply:
|
||||
description: Optional avdd supply. Used as reference when no explicit reference supplied.
|
||||
|
||||
vref0p-supply:
|
||||
description: vref0p supply can be used as reference for conversion.
|
||||
|
||||
vref1p-supply:
|
||||
description: vref1p supply can be used as reference for conversion.
|
||||
|
||||
vref2p-supply:
|
||||
description: vref2p supply can be used as reference for conversion.
|
||||
|
||||
vref0n-supply:
|
||||
description: vref0n supply can be used as reference for conversion.
|
||||
|
||||
vref1n-supply:
|
||||
description: vref1n supply can be used as reference for conversion.
|
||||
|
||||
vref2n-supply:
|
||||
description: vref2n supply can be used as reference for conversion.
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 8000000
|
||||
|
||||
patternProperties:
|
||||
"^channel(@[0-9])?$":
|
||||
$ref: adc.yaml
|
||||
type: object
|
||||
description: Represents the external channels which are connected to the ADC.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description: The channel number in single-ended mode.
|
||||
minimum: 0
|
||||
maximum: 9
|
||||
|
||||
adi,reference:
|
||||
description: |
|
||||
Select the reference source to use when converting on
|
||||
the specific channel. Valid values are:
|
||||
0: VREF0P/VREF0N
|
||||
1: VREF1P/VREF1N
|
||||
2: VREF2P/VREF2N
|
||||
3: AVDD/AGND
|
||||
4: VREF0P/AGND
|
||||
5: VREF1P/AGND
|
||||
6: VREF2P/AGND
|
||||
If this field is left empty, AVDD/AGND is selected.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2, 3, 4, 5, 6]
|
||||
default: 3
|
||||
|
||||
adi,input-mode:
|
||||
description: |
|
||||
Select signal path of input channels. Valid values are:
|
||||
0: Buffered, low-power, unity-gain path (default)
|
||||
1: Bypass path
|
||||
2: PGA path
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 1, 2]
|
||||
default: 0
|
||||
|
||||
diff-channels: true
|
||||
|
||||
bipolar: true
|
||||
|
||||
settling-time-us: true
|
||||
|
||||
adi,buffered-vrefp:
|
||||
description: Enable buffered mode for positive reference.
|
||||
type: boolean
|
||||
|
||||
adi,buffered-vrefn:
|
||||
description: Enable buffered mode for negative reference.
|
||||
type: boolean
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0 {
|
||||
reg = <0>;
|
||||
compatible = "adi,max11410";
|
||||
spi-max-frequency = <8000000>;
|
||||
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupt-names = "gpio1";
|
||||
|
||||
avdd-supply = <&adc_avdd>;
|
||||
|
||||
vref1p-supply = <&adc_vref1p>;
|
||||
vref1n-supply = <&adc_vref1n>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
channel@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
channel@1 {
|
||||
reg = <1>;
|
||||
diff-channels = <2 3>;
|
||||
adi,reference = <1>;
|
||||
bipolar;
|
||||
settling-time-us = <100000>;
|
||||
};
|
||||
|
||||
channel@2 {
|
||||
reg = <2>;
|
||||
diff-channels = <7 9>;
|
||||
adi,reference = <5>;
|
||||
adi,input-mode = <2>;
|
||||
settling-time-us = <50000>;
|
||||
};
|
||||
};
|
||||
};
|
@ -22,13 +22,11 @@ properties:
|
||||
- items:
|
||||
- const: qcom,pms405-adc
|
||||
- const: qcom,spmi-adc-rev2
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,spmi-vadc
|
||||
- qcom,spmi-adc5
|
||||
- qcom,spmi-adc-rev2
|
||||
- qcom,spmi-adc7
|
||||
- enum:
|
||||
- qcom,spmi-vadc
|
||||
- qcom,spmi-adc5
|
||||
- qcom,spmi-adc-rev2
|
||||
- qcom,spmi-adc7
|
||||
|
||||
reg:
|
||||
description: VADC base address in the SPMI PMIC register map
|
||||
@ -238,42 +236,72 @@ additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spmi_bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
/* VADC node */
|
||||
pmic_vadc: adc@3100 {
|
||||
compatible = "qcom,spmi-vadc";
|
||||
reg = <0x3100>;
|
||||
interrupts = <0x0 0x31 0x0 0x1>;
|
||||
spmi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#io-channel-cells = <1>;
|
||||
/* VADC node */
|
||||
pmic_vadc: adc@3100 {
|
||||
compatible = "qcom,spmi-vadc";
|
||||
reg = <0x3100>;
|
||||
interrupts = <0x0 0x31 0x0 0x1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#io-channel-cells = <1>;
|
||||
|
||||
/* Channel node */
|
||||
adc-chan@39 {
|
||||
reg = <0x39>;
|
||||
qcom,decimation = <512>;
|
||||
qcom,ratiometric;
|
||||
qcom,hw-settle-time = <200>;
|
||||
qcom,avg-samples = <1>;
|
||||
qcom,pre-scaling = <1 3>;
|
||||
};
|
||||
/* Channel node */
|
||||
adc-chan@39 {
|
||||
reg = <0x39>;
|
||||
qcom,decimation = <512>;
|
||||
qcom,ratiometric;
|
||||
qcom,hw-settle-time = <200>;
|
||||
qcom,avg-samples = <1>;
|
||||
qcom,pre-scaling = <1 3>;
|
||||
};
|
||||
|
||||
adc-chan@9 {
|
||||
reg = <0x9>;
|
||||
};
|
||||
adc-chan@9 {
|
||||
reg = <0x9>;
|
||||
};
|
||||
|
||||
adc-chan@a {
|
||||
reg = <0xa>;
|
||||
};
|
||||
adc-chan@a {
|
||||
reg = <0xa>;
|
||||
};
|
||||
|
||||
adc-chan@e {
|
||||
reg = <0xe>;
|
||||
};
|
||||
adc-chan@e {
|
||||
reg = <0xe>;
|
||||
};
|
||||
|
||||
adc-chan@f {
|
||||
reg = <0xf>;
|
||||
adc-chan@f {
|
||||
reg = <0xf>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
|
||||
#include <dt-bindings/iio/qcom,spmi-adc7-pm8350.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
spmi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
adc@3100 {
|
||||
reg = <0x3100>;
|
||||
compatible = "qcom,spmi-adc7";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
#io-channel-cells = <1>;
|
||||
|
||||
/* Other properties are omitted */
|
||||
xo-therm@44 {
|
||||
reg = <PMK8350_ADC7_AMUX_THM1_100K_PU>;
|
||||
qcom,ratiometric;
|
||||
qcom,hw-settle-time = <200>;
|
||||
};
|
||||
|
||||
conn-therm@47 {
|
||||
reg = <PM8350_ADC7_AMUX_THM4_100K_PU>;
|
||||
qcom,ratiometric;
|
||||
qcom,hw-settle-time = <200>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -22,6 +22,7 @@ properties:
|
||||
- rockchip,rk3328-saradc
|
||||
- rockchip,rk3568-saradc
|
||||
- rockchip,rv1108-saradc
|
||||
- rockchip,rv1126-saradc
|
||||
- const: rockchip,rk3399-saradc
|
||||
|
||||
reg:
|
||||
|
@ -27,6 +27,7 @@ properties:
|
||||
- st,stm32f4-adc-core
|
||||
- st,stm32h7-adc-core
|
||||
- st,stm32mp1-adc-core
|
||||
- st,stm32mp13-adc-core
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -37,6 +38,7 @@ properties:
|
||||
- stm32f4 and stm32h7 share a common ADC interrupt line.
|
||||
- stm32mp1 has two separate interrupt lines, one for each ADC within
|
||||
ADC block.
|
||||
- stm32mp13 has an interrupt line per ADC block.
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
@ -180,6 +182,33 @@ allOf:
|
||||
maximum: 36000000
|
||||
default: 36000000
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: st,stm32mp13-adc-core
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: adc
|
||||
minItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: ADC interrupt line
|
||||
|
||||
st,max-clk-rate-hz:
|
||||
minimum: 150000
|
||||
maximum: 75000000
|
||||
default: 75000000
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
@ -208,6 +237,7 @@ patternProperties:
|
||||
- st,stm32f4-adc
|
||||
- st,stm32h7-adc
|
||||
- st,stm32mp1-adc
|
||||
- st,stm32mp13-adc
|
||||
|
||||
reg:
|
||||
description: |
|
||||
@ -229,7 +259,7 @@ patternProperties:
|
||||
interrupts:
|
||||
description: |
|
||||
IRQ Line for the ADC instance. Valid values are:
|
||||
- 0 for adc@0
|
||||
- 0 for adc@0 (single adc for stm32mp13)
|
||||
- 1 for adc@100
|
||||
- 2 for adc@200 (stm32f4 only)
|
||||
maxItems: 1
|
||||
@ -250,13 +280,14 @@ patternProperties:
|
||||
assigned-resolution-bits:
|
||||
description: |
|
||||
Resolution (bits) to use for conversions:
|
||||
- can be 6, 8, 10 or 12 on stm32f4
|
||||
- can be 6, 8, 10 or 12 on stm32f4 and stm32mp13
|
||||
- can be 8, 10, 12, 14 or 16 on stm32h7 and stm32mp1
|
||||
|
||||
st,adc-channels:
|
||||
description: |
|
||||
List of single-ended channels muxed for this ADC. It can have up to:
|
||||
- 16 channels, numbered from 0 to 15 (for in0..in15) on stm32f4
|
||||
- 19 channels, numbered from 0 to 18 (for in0..in18) on stm32mp13.
|
||||
- 20 channels, numbered from 0 to 19 (for in0..in19) on stm32h7 and
|
||||
stm32mp1.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
@ -322,7 +353,7 @@ patternProperties:
|
||||
label:
|
||||
description: |
|
||||
Unique name to identify which channel this is.
|
||||
Reserved label names "vddcore", "vrefint" and "vbat"
|
||||
Reserved label names "vddcore", "vddcpu", "vddq_ddr", "vrefint" and "vbat"
|
||||
are used to identify internal channels with matching names.
|
||||
|
||||
diff-channels:
|
||||
@ -419,6 +450,37 @@ patternProperties:
|
||||
items:
|
||||
minimum: 40
|
||||
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: st,stm32mp13-adc
|
||||
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
const: 0x0
|
||||
|
||||
interrupts:
|
||||
const: 0
|
||||
|
||||
assigned-resolution-bits:
|
||||
enum: [6, 8, 10, 12]
|
||||
default: 12
|
||||
|
||||
st,adc-channels:
|
||||
minItems: 1
|
||||
maxItems: 19
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 18
|
||||
|
||||
st,min-sample-time-nsecs:
|
||||
minItems: 1
|
||||
maxItems: 19
|
||||
items:
|
||||
minimum: 40
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
|
@ -58,8 +58,6 @@ required:
|
||||
- spi-cpol
|
||||
- refin-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
patternProperties:
|
||||
"^channel@[0-3]$":
|
||||
type: object
|
||||
@ -103,6 +101,11 @@ patternProperties:
|
||||
required:
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
@ -113,10 +116,7 @@ examples:
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cs-gpios = <&gpio 17 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
|
||||
ad74413r@0 {
|
||||
addac@0 {
|
||||
compatible = "adi,ad74413r";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <1000000>;
|
||||
|
@ -102,8 +102,7 @@ allOf:
|
||||
- if:
|
||||
properties:
|
||||
adi,dc-dc-mode:
|
||||
contains:
|
||||
enum: [1, 3]
|
||||
enum: [1, 3]
|
||||
then:
|
||||
properties:
|
||||
adi,range-microvolt: false
|
||||
|
@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Analog Devices AD5766 DAC device driver
|
||||
|
||||
maintainers:
|
||||
- Cristian Pop <cristian.pop@analog.com>
|
||||
- Nuno Sá <nuno.sa@analog.com>
|
||||
|
||||
description: |
|
||||
Bindings for the Analog Devices AD5766 current DAC device. Datasheet can be
|
||||
|
@ -160,13 +160,16 @@ properties:
|
||||
2: +2dBm
|
||||
3: +5dBm
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi {
|
||||
|
@ -70,7 +70,10 @@ required:
|
||||
- clock-names
|
||||
- vcm-supply
|
||||
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -104,7 +104,10 @@ required:
|
||||
- clock-names
|
||||
- vcm-supply
|
||||
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: ADMV4420 K Band Downconverter
|
||||
|
||||
maintainers:
|
||||
- Cristian Pop <cristian.pop@analog.com>
|
||||
- Nuno Sá <nuno.sa@analog.com>
|
||||
|
||||
description:
|
||||
The ADMV4420 is a highly integrated, double balanced, active
|
||||
@ -37,7 +37,11 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -113,7 +113,10 @@ required:
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -38,7 +38,10 @@ required:
|
||||
- spi-cpol
|
||||
- spi-cpha
|
||||
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -56,7 +56,10 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -79,6 +79,7 @@ required:
|
||||
- spi-cpol
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
@ -107,7 +108,7 @@ allOf:
|
||||
dependencies:
|
||||
adi,sync-mode: [ clocks ]
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -31,6 +31,7 @@ properties:
|
||||
- invensense,icm42602
|
||||
- invensense,icm42605
|
||||
- invensense,icm42622
|
||||
- invensense,icm42631
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -32,12 +32,16 @@ properties:
|
||||
- st,lsm6dsrx
|
||||
- st,lsm6dst
|
||||
- st,lsm6dsop
|
||||
- st,lsm6dsv
|
||||
- items:
|
||||
- const: st,asm330lhhx
|
||||
- const: st,lsm6dsr
|
||||
- items:
|
||||
- const: st,lsm6dstx
|
||||
- const: st,lsm6dst
|
||||
- items:
|
||||
- const: st,lsm6dsv16x
|
||||
- const: st,lsm6dsv
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -30,7 +30,10 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
@ -52,6 +55,7 @@ examples:
|
||||
compatible = "meas,ms5611";
|
||||
reg = <0>;
|
||||
vdd-supply = <&ldo_3v3_gnss>;
|
||||
spi-max-frequency = <20000000>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
@ -33,7 +33,10 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -49,7 +49,10 @@ required:
|
||||
- spi-cpha
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -33,8 +33,6 @@ properties:
|
||||
|
||||
spi-cpha: true
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@ -43,6 +41,11 @@ dependencies:
|
||||
spi-cpol: [ spi-cpha ]
|
||||
spi-cpha: [ spi-cpol ]
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi {
|
||||
|
@ -4,19 +4,30 @@
|
||||
$id: http://devicetree.org/schemas/iio/temperature/adi,ltc2983.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Analog Devices LTC2983 Multi-sensor Temperature system
|
||||
title: Analog Devices LTC2983, LTC2986, LTM2985 Multi-sensor Temperature system
|
||||
|
||||
maintainers:
|
||||
- Nuno Sá <nuno.sa@analog.com>
|
||||
|
||||
description: |
|
||||
Analog Devices LTC2983 Multi-Sensor Digital Temperature Measurement System
|
||||
Analog Devices LTC2983, LTC2984, LTC2986, LTM2985 Multi-Sensor Digital
|
||||
Temperature Measurement Systems
|
||||
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/2983fc.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/2984fb.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/29861fa.pdf
|
||||
https://www.analog.com/media/en/technical-documentation/data-sheets/ltm2985.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- adi,ltc2983
|
||||
oneOf:
|
||||
- enum:
|
||||
- adi,ltc2983
|
||||
- adi,ltc2986
|
||||
- adi,ltm2985
|
||||
- items:
|
||||
- const: adi,ltc2984
|
||||
- const: adi,ltc2983
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -25,26 +36,26 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
adi,mux-delay-config-us:
|
||||
description:
|
||||
The LTC2983 performs 2 or 3 internal conversion cycles per temperature
|
||||
result. Each conversion cycle is performed with different excitation and
|
||||
input multiplexer configurations. Prior to each conversion, these
|
||||
excitation circuits and input switch configurations are changed and an
|
||||
internal 1ms delay ensures settling prior to the conversion cycle in most
|
||||
cases. An extra delay can be configured using this property. The value is
|
||||
rounded to nearest 100us.
|
||||
description: |
|
||||
Extra delay prior to each conversion, in addition to the internal 1ms
|
||||
delay, for the multiplexer to switch input configurations and
|
||||
excitation values.
|
||||
|
||||
This property is supposed to be in microseconds, but to maintain
|
||||
compatibility, this value will be multiplied by 100 before usage.
|
||||
maximum: 255
|
||||
default: 0
|
||||
|
||||
adi,filter-notch-freq:
|
||||
description:
|
||||
Set's the default setting of the digital filter. The default is
|
||||
simultaneous 50/60Hz rejection.
|
||||
Notch frequency of the digital filter.
|
||||
0 - 50/60Hz rejection
|
||||
1 - 60Hz rejection
|
||||
2 - 50Hz rejection
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 2
|
||||
default: 0
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
@ -53,19 +64,20 @@ properties:
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"@([1-9]|1[0-9]|20)$":
|
||||
"@([0-9a-f]+)$":
|
||||
type: object
|
||||
description: Sensor.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
description:
|
||||
The channel number. It can be connected to one of the 20 channels of
|
||||
the device.
|
||||
Channel number. Connects the sensor to the channel with this number
|
||||
of the device.
|
||||
minimum: 1
|
||||
maximum: 20
|
||||
|
||||
adi,sensor-type:
|
||||
description: Identifies the type of sensor connected to the device.
|
||||
description: Type of sensor connected to the device.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
required:
|
||||
@ -74,9 +86,7 @@ patternProperties:
|
||||
|
||||
"^thermocouple@":
|
||||
type: object
|
||||
description:
|
||||
Represents a thermocouple sensor which is connected to one of the device
|
||||
channels.
|
||||
description: Thermocouple sensor.
|
||||
|
||||
properties:
|
||||
adi,sensor-type:
|
||||
@ -95,86 +105,87 @@ patternProperties:
|
||||
maximum: 9
|
||||
|
||||
adi,single-ended:
|
||||
description:
|
||||
Boolean property which set's the thermocouple as single-ended.
|
||||
description: Whether the sensor is single-ended.
|
||||
type: boolean
|
||||
|
||||
adi,sensor-oc-current-microamp:
|
||||
description:
|
||||
This property set's the pulsed current value applied during
|
||||
open-circuit detect.
|
||||
description: Pulsed current value applied during open-circuit detect.
|
||||
enum: [10, 100, 500, 1000]
|
||||
default: 10
|
||||
|
||||
adi,cold-junction-handle:
|
||||
description:
|
||||
Phandle which points to a sensor object responsible for measuring
|
||||
the thermocouple cold junction temperature.
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
Sensor responsible for measuring the thermocouple cold junction
|
||||
temperature.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
adi,custom-thermocouple:
|
||||
description:
|
||||
This is a table, where each entry should be a pair of
|
||||
voltage(mv)-temperature(K). The entries must be given in nv and uK
|
||||
so that, the original values must be multiplied by 1000000. For
|
||||
more details look at table 69 and 70.
|
||||
Note should be signed, but dtc doesn't currently maintain the
|
||||
sign.
|
||||
Used for digitizing custom thermocouples.
|
||||
See Page 59 of the datasheet.
|
||||
$ref: /schemas/types.yaml#/definitions/uint64-matrix
|
||||
minItems: 3
|
||||
maxItems: 64
|
||||
items:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: Voltage point in nV, signed.
|
||||
- description: Temperature point in uK.
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
adi,sensor-type:
|
||||
const: 9
|
||||
then:
|
||||
required:
|
||||
- adi,custom-thermocouple
|
||||
|
||||
"^diode@":
|
||||
type: object
|
||||
description:
|
||||
Represents a diode sensor which is connected to one of the device
|
||||
channels.
|
||||
description: Diode sensor.
|
||||
|
||||
properties:
|
||||
adi,sensor-type:
|
||||
description: Identifies the sensor as a diode.
|
||||
description: Sensor type for diodes.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
const: 28
|
||||
|
||||
adi,single-ended:
|
||||
description: Boolean property which set's the diode as single-ended.
|
||||
description: Whether the sensor is single-ended.
|
||||
type: boolean
|
||||
|
||||
adi,three-conversion-cycles:
|
||||
description:
|
||||
Boolean property which set's three conversion cycles removing
|
||||
parasitic resistance effects between the LTC2983 and the diode.
|
||||
Whether to use three conversion cycles to remove parasitic
|
||||
resistance between the device and the diode.
|
||||
type: boolean
|
||||
|
||||
adi,average-on:
|
||||
description:
|
||||
Boolean property which enables a running average of the diode
|
||||
temperature reading. This reduces the noise when the diode is used
|
||||
as a cold junction temperature element on an isothermal block
|
||||
where temperatures change slowly.
|
||||
Whether to use a running average of the diode temperature
|
||||
reading to reduce the noise when the diode is used as a cold
|
||||
junction temperature element on an isothermal block where
|
||||
temperatures change slowly.
|
||||
type: boolean
|
||||
|
||||
adi,excitation-current-microamp:
|
||||
description:
|
||||
This property controls the magnitude of the excitation current
|
||||
applied to the diode. Depending on the number of conversions
|
||||
cycles, this property will assume different predefined values on
|
||||
each cycle. Just set the value of the first cycle (1l).
|
||||
Magnitude of the 1l excitation current applied to the diode.
|
||||
4l excitation current will be 4 times this value, and 8l
|
||||
excitation current will be 8 times value.
|
||||
enum: [10, 20, 40, 80]
|
||||
default: 10
|
||||
|
||||
adi,ideal-factor-value:
|
||||
description:
|
||||
This property sets the diode ideality factor. The real value must
|
||||
be multiplied by 1000000 to remove the fractional part. For more
|
||||
information look at table 20 of the datasheet.
|
||||
Diode ideality factor.
|
||||
Set this property to 1000000 times the real value.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
default: 0
|
||||
|
||||
"^rtd@":
|
||||
type: object
|
||||
description:
|
||||
Represents a rtd sensor which is connected to one of the device channels.
|
||||
description: RTD sensor.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
@ -197,68 +208,82 @@ patternProperties:
|
||||
maximum: 18
|
||||
|
||||
adi,rsense-handle:
|
||||
description:
|
||||
Phandle pointing to a rsense object associated with this RTD.
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: Associated sense resistor sensor.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
adi,number-of-wires:
|
||||
description:
|
||||
Identifies the number of wires used by the RTD. Setting this
|
||||
property to 5 means 4 wires with Kelvin Rsense.
|
||||
Number of wires used by the RTD.
|
||||
5 means 4 wires with Kelvin sense resistor.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [2, 3, 4, 5]
|
||||
default: 2
|
||||
|
||||
adi,rsense-share:
|
||||
description:
|
||||
Boolean property which enables Rsense sharing, where one sense
|
||||
resistor is used for multiple 2-, 3-, and/or 4-wire RTDs.
|
||||
type: boolean
|
||||
|
||||
adi,current-rotate:
|
||||
description:
|
||||
Boolean property which enables excitation current rotation to
|
||||
automatically remove parasitic thermocouple effects. Note that
|
||||
this property is not allowed for 2- and 3-wire RTDs.
|
||||
Whether to enable sense resistor sharing, where one sense
|
||||
resistor is used by multiple sensors.
|
||||
type: boolean
|
||||
|
||||
adi,excitation-current-microamp:
|
||||
description:
|
||||
This property controls the magnitude of the excitation current
|
||||
applied to the RTD.
|
||||
description: Excitation current applied to the RTD.
|
||||
enum: [5, 10, 25, 50, 100, 250, 500, 1000]
|
||||
default: 5
|
||||
|
||||
adi,rtd-curve:
|
||||
description:
|
||||
This property set the RTD curve used and the corresponding
|
||||
Callendar-VanDusen constants. Look at table 30 of the datasheet.
|
||||
description: |
|
||||
RTD curve and the corresponding Callendar-VanDusen constants.
|
||||
0 - European
|
||||
1 - American
|
||||
2 - Japanese
|
||||
3 - ITS-90
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 3
|
||||
default: 0
|
||||
|
||||
adi,custom-rtd:
|
||||
description:
|
||||
This is a table, where each entry should be a pair of
|
||||
resistance(ohm)-temperature(K). The entries added here are in uohm
|
||||
and uK. For more details values look at table 74 and 75.
|
||||
Used for digitizing custom RTDs.
|
||||
See Page 62 of the datasheet.
|
||||
$ref: /schemas/types.yaml#/definitions/uint64-matrix
|
||||
minItems: 3
|
||||
maxItems: 64
|
||||
items:
|
||||
minItems: 3
|
||||
maxItems: 64
|
||||
items:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
- description: Resistance point in uOhms.
|
||||
- description: Temperature point in uK.
|
||||
|
||||
required:
|
||||
- adi,rsense-handle
|
||||
|
||||
dependencies:
|
||||
adi,current-rotate: [ "adi,rsense-share" ]
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
adi,number-of-wires:
|
||||
const: 4
|
||||
then:
|
||||
properties:
|
||||
adi,current-rotate:
|
||||
description:
|
||||
Whether to enable excitation current rotation to automatically
|
||||
remove parasitic thermocouple effects.
|
||||
type: boolean
|
||||
|
||||
dependencies:
|
||||
adi,current-rotate: [ "adi,rsense-share" ]
|
||||
|
||||
- if:
|
||||
properties:
|
||||
adi,sensor-type:
|
||||
const: 18
|
||||
then:
|
||||
required:
|
||||
- adi,custom-rtd
|
||||
|
||||
"^thermistor@":
|
||||
type: object
|
||||
description:
|
||||
Represents a thermistor sensor which is connected to one of the device
|
||||
channels.
|
||||
description: Thermistor sensor.
|
||||
|
||||
properties:
|
||||
adi,sensor-type:
|
||||
@ -277,61 +302,54 @@ patternProperties:
|
||||
maximum: 27
|
||||
|
||||
adi,rsense-handle:
|
||||
description:
|
||||
Phandle pointing to a rsense object associated with this
|
||||
thermistor.
|
||||
$ref: "/schemas/types.yaml#/definitions/phandle"
|
||||
description: Associated sense resistor sensor.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
adi,single-ended:
|
||||
description:
|
||||
Boolean property which set's the thermistor as single-ended.
|
||||
description: Whether the sensor is single-ended.
|
||||
type: boolean
|
||||
|
||||
adi,rsense-share:
|
||||
description:
|
||||
Boolean property which enables Rsense sharing, where one sense
|
||||
resistor is used for multiple thermistors. Note that this property
|
||||
is ignored if adi,single-ended is set.
|
||||
Whether to enable sense resistor sharing, where one sense
|
||||
resistor is used by multiple sensors.
|
||||
type: boolean
|
||||
|
||||
adi,current-rotate:
|
||||
description:
|
||||
Boolean property which enables excitation current rotation to
|
||||
automatically remove parasitic thermocouple effects.
|
||||
Whether to enable excitation current rotation to automatically
|
||||
remove parasitic thermocouple effects.
|
||||
type: boolean
|
||||
|
||||
adi,excitation-current-nanoamp:
|
||||
description:
|
||||
This property controls the magnitude of the excitation current
|
||||
applied to the thermistor. Value 0 set's the sensor in auto-range
|
||||
mode.
|
||||
Excitation current applied to the thermistor.
|
||||
0 sets the sensor in auto-range mode.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 250, 500, 1000, 5000, 10000, 25000, 50000, 100000, 250000,
|
||||
500000, 1000000]
|
||||
default: 0
|
||||
|
||||
adi,custom-thermistor:
|
||||
description:
|
||||
This is a table, where each entry should be a pair of
|
||||
resistance(ohm)-temperature(K). The entries added here are in uohm
|
||||
and uK only for custom thermistors. For more details look at table
|
||||
78 and 79.
|
||||
Used for digitizing custom thermistors.
|
||||
See Page 65 of the datasheet.
|
||||
$ref: /schemas/types.yaml#/definitions/uint64-matrix
|
||||
minItems: 3
|
||||
maxItems: 64
|
||||
items:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: Resistance point in uOhms.
|
||||
- description: Temperature point in uK.
|
||||
|
||||
adi,custom-steinhart:
|
||||
description:
|
||||
Steinhart-Hart coefficients are also supported and can
|
||||
be programmed into the device memory using this property. For
|
||||
Steinhart sensors the coefficients are given in the raw
|
||||
format. Look at table 82 for more information.
|
||||
Steinhart-Hart coefficients in raw format, used for digitizing
|
||||
custom thermistors.
|
||||
See Page 68 of the datasheet.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
|
||||
required:
|
||||
- adi,rsense-handle
|
||||
@ -339,25 +357,78 @@ patternProperties:
|
||||
dependencies:
|
||||
adi,current-rotate: [ "adi,rsense-share" ]
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
adi,sensor-type:
|
||||
const: 26
|
||||
then:
|
||||
properties:
|
||||
adi,excitation-current-nanoamp:
|
||||
enum: [250, 500, 1000, 5000, 10000, 25000, 50000, 100000,
|
||||
250000, 500000, 1000000]
|
||||
default: 1000
|
||||
required:
|
||||
- adi,custom-steinhart
|
||||
- if:
|
||||
properties:
|
||||
adi,sensor-type:
|
||||
const: 27
|
||||
then:
|
||||
properties:
|
||||
adi,excitation-current-nanoamp:
|
||||
enum: [250, 500, 1000, 5000, 10000, 25000, 50000, 100000,
|
||||
250000, 500000, 1000000]
|
||||
default: 1000
|
||||
required:
|
||||
- adi,custom-thermistor
|
||||
|
||||
"^adc@":
|
||||
type: object
|
||||
description: Represents a channel which is being used as a direct adc.
|
||||
description: Direct ADC sensor.
|
||||
|
||||
properties:
|
||||
adi,sensor-type:
|
||||
description: Identifies the sensor as a direct adc.
|
||||
description: Sensor type for direct ADC sensors.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
const: 30
|
||||
|
||||
adi,single-ended:
|
||||
description: Boolean property which set's the adc as single-ended.
|
||||
description: Whether the sensor is single-ended.
|
||||
type: boolean
|
||||
|
||||
"^temp@":
|
||||
type: object
|
||||
description: Active analog temperature sensor.
|
||||
|
||||
properties:
|
||||
adi,sensor-type:
|
||||
description: Sensor type for active analog temperature sensors.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
const: 31
|
||||
|
||||
adi,single-ended:
|
||||
description: Whether the sensor is single-ended.
|
||||
type: boolean
|
||||
|
||||
adi,custom-temp:
|
||||
description:
|
||||
Used for digitizing active analog temperature sensors.
|
||||
See Page 67 of the LTM2985 datasheet.
|
||||
$ref: /schemas/types.yaml#/definitions/uint64-matrix
|
||||
minItems: 3
|
||||
maxItems: 64
|
||||
items:
|
||||
items:
|
||||
- description: Voltage point in nV, signed.
|
||||
- description: Temperature point in uK.
|
||||
|
||||
required:
|
||||
- adi,custom-temp
|
||||
|
||||
"^rsense@":
|
||||
type: object
|
||||
description:
|
||||
Represents a rsense which is connected to one of the device channels.
|
||||
Rsense are used by thermistors and RTD's.
|
||||
description: Sense resistor sensor.
|
||||
|
||||
properties:
|
||||
reg:
|
||||
@ -365,14 +436,12 @@ patternProperties:
|
||||
maximum: 20
|
||||
|
||||
adi,sensor-type:
|
||||
description: Identifies the sensor as a rsense.
|
||||
description: Sensor type sense resistor sensors.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
const: 29
|
||||
|
||||
adi,rsense-val-milli-ohms:
|
||||
description:
|
||||
Sets the value of the sense resistor. Look at table 20 of the
|
||||
datasheet for information.
|
||||
description: Value of the sense resistor.
|
||||
|
||||
required:
|
||||
- adi,rsense-val-milli-ohms
|
||||
@ -384,6 +453,18 @@ required:
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- adi,ltc2983
|
||||
- adi,ltc2984
|
||||
then:
|
||||
patternProperties:
|
||||
"^temp@": false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
@ -391,7 +472,7 @@ examples:
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
sensor_ltc2983: ltc2983@0 {
|
||||
temperature-sensor@0 {
|
||||
compatible = "adi,ltc2983";
|
||||
reg = <0>;
|
||||
|
||||
|
15
MAINTAINERS
15
MAINTAINERS
@ -1117,6 +1117,15 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
|
||||
F: drivers/net/amt.c
|
||||
|
||||
ANALOG DEVICES INC AD4130 DRIVER
|
||||
M: Cosmin Tanislav <cosmin.tanislav@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://ez.analog.com/community/linux-device-drivers
|
||||
F: Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130
|
||||
F: Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml
|
||||
F: drivers/iio/adc/ad4130.c
|
||||
|
||||
ANALOG DEVICES INC AD7192 DRIVER
|
||||
M: Alexandru Tachici <alexandru.tachici@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
@ -11446,6 +11455,12 @@ F: drivers/mfd/khadas-mcu.c
|
||||
F: include/linux/mfd/khadas-mcu.h
|
||||
F: drivers/thermal/khadas_mcu_fan.c
|
||||
|
||||
KIONIX/ROHM KX022A ACCELEROMETER
|
||||
M: Matti Vaittinen <mazziesaccount@gmail.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/iio/accel/kionix-kx022a*
|
||||
|
||||
KMEMLEAK
|
||||
M: Catalin Marinas <catalin.marinas@arm.com>
|
||||
S: Maintained
|
||||
|
@ -2236,6 +2236,20 @@ int i2c_get_device_id(const struct i2c_client *client,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_get_device_id);
|
||||
|
||||
/**
|
||||
* i2c_client_get_device_id - get the driver match table entry of a device
|
||||
* @client: the device to query. The device must be bound to a driver
|
||||
*
|
||||
* Returns a pointer to the matching entry if found, NULL otherwise.
|
||||
*/
|
||||
const struct i2c_device_id *i2c_client_get_device_id(const struct i2c_client *client)
|
||||
{
|
||||
const struct i2c_driver *drv = to_i2c_driver(client->dev.driver);
|
||||
|
||||
return i2c_match_id(drv->id_table, client);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_client_get_device_id);
|
||||
|
||||
/* ----------------------------------------------------
|
||||
* the i2c address scanning function
|
||||
* Will not work for 10-bit addresses!
|
||||
|
@ -7,9 +7,6 @@ tree
|
||||
- ABI Documentation
|
||||
- Audit driviers/iio/staging/Documentation
|
||||
|
||||
- Replace iio_dev->mlock by either a local lock or use
|
||||
iio_claim_direct.(Requires analysis of the purpose of the lock.)
|
||||
|
||||
- Converting drivers from device tree centric to more generic
|
||||
property handlers.
|
||||
|
||||
|
@ -409,6 +409,27 @@ config IIO_ST_ACCEL_SPI_3AXIS
|
||||
To compile this driver as a module, choose M here. The module
|
||||
will be called st_accel_spi.
|
||||
|
||||
config IIO_KX022A
|
||||
tristate
|
||||
|
||||
config IIO_KX022A_SPI
|
||||
tristate "Kionix KX022A tri-axis digital accelerometer SPI interface"
|
||||
depends on SPI
|
||||
select IIO_KX022A
|
||||
select REGMAP_SPI
|
||||
help
|
||||
Enable support for the Kionix KX022A digital tri-axis
|
||||
accelerometer connected to I2C interface.
|
||||
|
||||
config IIO_KX022A_I2C
|
||||
tristate "Kionix KX022A tri-axis digital accelerometer I2C interface"
|
||||
depends on I2C
|
||||
select IIO_KX022A
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Enable support for the Kionix KX022A digital tri-axis
|
||||
accelerometer connected to I2C interface.
|
||||
|
||||
config KXSD9
|
||||
tristate "Kionix KXSD9 Accelerometer Driver"
|
||||
select IIO_BUFFER
|
||||
|
@ -40,6 +40,9 @@ obj-$(CONFIG_FXLS8962AF) += fxls8962af-core.o
|
||||
obj-$(CONFIG_FXLS8962AF_I2C) += fxls8962af-i2c.o
|
||||
obj-$(CONFIG_FXLS8962AF_SPI) += fxls8962af-spi.o
|
||||
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
|
||||
obj-$(CONFIG_IIO_KX022A) += kionix-kx022a.o
|
||||
obj-$(CONFIG_IIO_KX022A_I2C) += kionix-kx022a-i2c.o
|
||||
obj-$(CONFIG_IIO_KX022A_SPI) += kionix-kx022a-spi.o
|
||||
obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
|
||||
obj-$(CONFIG_KXSD9) += kxsd9.o
|
||||
obj-$(CONFIG_KXSD9_SPI) += kxsd9-spi.o
|
||||
|
@ -10,12 +10,30 @@
|
||||
|
||||
#include <linux/regmap.h>
|
||||
|
||||
enum adxl355_device_type {
|
||||
ADXL355,
|
||||
ADXL359,
|
||||
};
|
||||
|
||||
struct adxl355_fractional_type {
|
||||
int integer;
|
||||
int decimal;
|
||||
};
|
||||
|
||||
struct device;
|
||||
|
||||
struct adxl355_chip_info {
|
||||
const char *name;
|
||||
u8 part_id;
|
||||
struct adxl355_fractional_type accel_scale;
|
||||
struct adxl355_fractional_type temp_offset;
|
||||
};
|
||||
|
||||
extern const struct regmap_access_table adxl355_readable_regs_tbl;
|
||||
extern const struct regmap_access_table adxl355_writeable_regs_tbl;
|
||||
extern const struct adxl355_chip_info adxl35x_chip_info[];
|
||||
|
||||
int adxl355_core_probe(struct device *dev, struct regmap *regmap,
|
||||
const char *name);
|
||||
const struct adxl355_chip_info *chip_info);
|
||||
|
||||
#endif /* _ADXL355_H_ */
|
||||
|
@ -60,6 +60,7 @@
|
||||
#define ADXL355_DEVID_AD_VAL 0xAD
|
||||
#define ADXL355_DEVID_MST_VAL 0x1D
|
||||
#define ADXL355_PARTID_VAL 0xED
|
||||
#define ADXL359_PARTID_VAL 0xE9
|
||||
#define ADXL355_RESET_CODE 0x52
|
||||
|
||||
static const struct regmap_range adxl355_read_reg_range[] = {
|
||||
@ -83,6 +84,60 @@ const struct regmap_access_table adxl355_writeable_regs_tbl = {
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(adxl355_writeable_regs_tbl, IIO_ADXL355);
|
||||
|
||||
const struct adxl355_chip_info adxl35x_chip_info[] = {
|
||||
[ADXL355] = {
|
||||
.name = "adxl355",
|
||||
.part_id = ADXL355_PARTID_VAL,
|
||||
/*
|
||||
* At +/- 2g with 20-bit resolution, scale is given in datasheet
|
||||
* as 3.9ug/LSB = 0.0000039 * 9.80665 = 0.00003824593 m/s^2.
|
||||
*/
|
||||
.accel_scale = {
|
||||
.integer = 0,
|
||||
.decimal = 38245,
|
||||
},
|
||||
/*
|
||||
* The datasheet defines an intercept of 1885 LSB at 25 degC
|
||||
* and a slope of -9.05 LSB/C. The following formula can be used
|
||||
* to find the temperature:
|
||||
* Temp = ((RAW - 1885)/(-9.05)) + 25 but this doesn't follow
|
||||
* the format of the IIO which is Temp = (RAW + OFFSET) * SCALE.
|
||||
* Hence using some rearranging we get the scale as -110.497238
|
||||
* and offset as -2111.25.
|
||||
*/
|
||||
.temp_offset = {
|
||||
.integer = -2111,
|
||||
.decimal = 250000,
|
||||
},
|
||||
},
|
||||
[ADXL359] = {
|
||||
.name = "adxl359",
|
||||
.part_id = ADXL359_PARTID_VAL,
|
||||
/*
|
||||
* At +/- 10g with 20-bit resolution, scale is given in datasheet
|
||||
* as 19.5ug/LSB = 0.0000195 * 9.80665 = 0.0.00019122967 m/s^2.
|
||||
*/
|
||||
.accel_scale = {
|
||||
.integer = 0,
|
||||
.decimal = 191229,
|
||||
},
|
||||
/*
|
||||
* The datasheet defines an intercept of 1852 LSB at 25 degC
|
||||
* and a slope of -9.05 LSB/C. The following formula can be used
|
||||
* to find the temperature:
|
||||
* Temp = ((RAW - 1852)/(-9.05)) + 25 but this doesn't follow
|
||||
* the format of the IIO which is Temp = (RAW + OFFSET) * SCALE.
|
||||
* Hence using some rearranging we get the scale as -110.497238
|
||||
* and offset as -2079.25.
|
||||
*/
|
||||
.temp_offset = {
|
||||
.integer = -2079,
|
||||
.decimal = 250000,
|
||||
},
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(adxl35x_chip_info, IIO_ADXL355);
|
||||
|
||||
enum adxl355_op_mode {
|
||||
ADXL355_MEASUREMENT,
|
||||
ADXL355_STANDBY,
|
||||
@ -162,6 +217,7 @@ static const struct adxl355_chan_info adxl355_chans[] = {
|
||||
};
|
||||
|
||||
struct adxl355_data {
|
||||
const struct adxl355_chip_info *chip_info;
|
||||
struct regmap *regmap;
|
||||
struct device *dev;
|
||||
struct mutex lock; /* lock to protect op_mode */
|
||||
@ -262,10 +318,8 @@ static int adxl355_setup(struct adxl355_data *data)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (regval != ADXL355_PARTID_VAL) {
|
||||
dev_err(data->dev, "Invalid DEV ID 0x%02x\n", regval);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (regval != ADXL355_PARTID_VAL)
|
||||
dev_warn(data->dev, "Invalid DEV ID 0x%02x\n", regval);
|
||||
|
||||
/*
|
||||
* Perform a software reset to make sure the device is in a consistent
|
||||
@ -458,33 +512,25 @@ static int adxl355_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
switch (chan->type) {
|
||||
/*
|
||||
* The datasheet defines an intercept of 1885 LSB at 25 degC
|
||||
* and a slope of -9.05 LSB/C. The following formula can be used
|
||||
* to find the temperature:
|
||||
* Temp = ((RAW - 1885)/(-9.05)) + 25 but this doesn't follow
|
||||
* the format of the IIO which is Temp = (RAW + OFFSET) * SCALE.
|
||||
* Hence using some rearranging we get the scale as -110.497238
|
||||
* and offset as -2111.25.
|
||||
*/
|
||||
case IIO_TEMP:
|
||||
/*
|
||||
* Temperature scale is -110.497238.
|
||||
* See the detailed explanation in adxl35x_chip_info
|
||||
* definition above.
|
||||
*/
|
||||
*val = -110;
|
||||
*val2 = 497238;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
/*
|
||||
* At +/- 2g with 20-bit resolution, scale is given in datasheet
|
||||
* as 3.9ug/LSB = 0.0000039 * 9.80665 = 0.00003824593 m/s^2.
|
||||
*/
|
||||
case IIO_ACCEL:
|
||||
*val = 0;
|
||||
*val2 = 38245;
|
||||
*val = data->chip_info->accel_scale.integer;
|
||||
*val2 = data->chip_info->accel_scale.decimal;
|
||||
return IIO_VAL_INT_PLUS_NANO;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
case IIO_CHAN_INFO_OFFSET:
|
||||
*val = -2111;
|
||||
*val2 = 250000;
|
||||
*val = data->chip_info->temp_offset.integer;
|
||||
*val2 = data->chip_info->temp_offset.decimal;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
case IIO_CHAN_INFO_CALIBBIAS:
|
||||
*val = sign_extend32(data->calibbias[chan->address], 15);
|
||||
@ -707,7 +753,7 @@ static int adxl355_probe_trigger(struct iio_dev *indio_dev, int irq)
|
||||
}
|
||||
|
||||
int adxl355_core_probe(struct device *dev, struct regmap *regmap,
|
||||
const char *name)
|
||||
const struct adxl355_chip_info *chip_info)
|
||||
{
|
||||
struct adxl355_data *data;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -722,9 +768,10 @@ int adxl355_core_probe(struct device *dev, struct regmap *regmap,
|
||||
data->regmap = regmap;
|
||||
data->dev = dev;
|
||||
data->op_mode = ADXL355_STANDBY;
|
||||
data->chip_info = chip_info;
|
||||
mutex_init(&data->lock);
|
||||
|
||||
indio_dev->name = name;
|
||||
indio_dev->name = chip_info->name;
|
||||
indio_dev->info = &adxl355_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->channels = adxl355_channels;
|
||||
|
@ -23,6 +23,20 @@ static const struct regmap_config adxl355_i2c_regmap_config = {
|
||||
static int adxl355_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
const struct adxl355_chip_info *chip_data;
|
||||
const struct i2c_device_id *adxl355;
|
||||
|
||||
chip_data = device_get_match_data(&client->dev);
|
||||
if (!chip_data) {
|
||||
adxl355 = to_i2c_driver(client->dev.driver)->id_table;
|
||||
if (!adxl355)
|
||||
return -EINVAL;
|
||||
|
||||
chip_data = (void *)i2c_match_id(adxl355, client)->driver_data;
|
||||
|
||||
if (!chip_data)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap = devm_regmap_init_i2c(client, &adxl355_i2c_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
@ -32,17 +46,19 @@ static int adxl355_i2c_probe(struct i2c_client *client)
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
return adxl355_core_probe(&client->dev, regmap, client->name);
|
||||
return adxl355_core_probe(&client->dev, regmap, chip_data);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id adxl355_i2c_id[] = {
|
||||
{ "adxl355", 0 },
|
||||
{ "adxl355", (kernel_ulong_t)&adxl35x_chip_info[ADXL355] },
|
||||
{ "adxl359", (kernel_ulong_t)&adxl35x_chip_info[ADXL359] },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, adxl355_i2c_id);
|
||||
|
||||
static const struct of_device_id adxl355_of_match[] = {
|
||||
{ .compatible = "adi,adxl355" },
|
||||
{ .compatible = "adi,adxl355", .data = &adxl35x_chip_info[ADXL355] },
|
||||
{ .compatible = "adi,adxl359", .data = &adxl35x_chip_info[ADXL359] },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, adxl355_of_match);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#include "adxl355.h"
|
||||
|
||||
@ -24,9 +25,17 @@ static const struct regmap_config adxl355_spi_regmap_config = {
|
||||
|
||||
static int adxl355_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
const struct adxl355_chip_info *chip_data;
|
||||
struct regmap *regmap;
|
||||
|
||||
chip_data = device_get_match_data(&spi->dev);
|
||||
if (!chip_data) {
|
||||
chip_data = (void *)spi_get_device_id(spi)->driver_data;
|
||||
|
||||
if (!chip_data)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap = devm_regmap_init_spi(spi, &adxl355_spi_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(&spi->dev, "Error initializing spi regmap: %ld\n",
|
||||
@ -35,17 +44,19 @@ static int adxl355_spi_probe(struct spi_device *spi)
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
return adxl355_core_probe(&spi->dev, regmap, id->name);
|
||||
return adxl355_core_probe(&spi->dev, regmap, chip_data);
|
||||
}
|
||||
|
||||
static const struct spi_device_id adxl355_spi_id[] = {
|
||||
{ "adxl355", 0 },
|
||||
{ "adxl355", (kernel_ulong_t)&adxl35x_chip_info[ADXL355] },
|
||||
{ "adxl359", (kernel_ulong_t)&adxl35x_chip_info[ADXL359] },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, adxl355_spi_id);
|
||||
|
||||
static const struct of_device_id adxl355_of_match[] = {
|
||||
{ .compatible = "adi,adxl355" },
|
||||
{ .compatible = "adi,adxl355", .data = &adxl35x_chip_info[ADXL355] },
|
||||
{ .compatible = "adi,adxl359", .data = &adxl35x_chip_info[ADXL359] },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, adxl355_of_match);
|
||||
|
@ -160,8 +160,6 @@ struct adxl367_state {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
|
||||
struct regulator_bulk_data regulators[2];
|
||||
|
||||
/*
|
||||
* Synchronize access to members of driver state, and ensure atomicity
|
||||
* of consecutive regmap operations.
|
||||
@ -1185,32 +1183,19 @@ static ssize_t adxl367_get_fifo_watermark(struct device *dev,
|
||||
return sysfs_emit(buf, "%d\n", fifo_watermark);
|
||||
}
|
||||
|
||||
static ssize_t hwfifo_watermark_min_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", "1");
|
||||
}
|
||||
|
||||
static ssize_t hwfifo_watermark_max_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", __stringify(ADXL367_FIFO_MAX_WATERMARK));
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0);
|
||||
static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
|
||||
IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "1");
|
||||
IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max,
|
||||
__stringify(ADXL367_FIFO_MAX_WATERMARK));
|
||||
static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
|
||||
adxl367_get_fifo_watermark, NULL, 0);
|
||||
static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
|
||||
adxl367_get_fifo_enabled, NULL, 0);
|
||||
|
||||
static const struct attribute *adxl367_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_enabled.dev_attr.attr,
|
||||
static const struct iio_dev_attr *adxl367_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_watermark_min,
|
||||
&iio_dev_attr_hwfifo_watermark_max,
|
||||
&iio_dev_attr_hwfifo_watermark,
|
||||
&iio_dev_attr_hwfifo_enabled,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@ -1487,16 +1472,10 @@ static int adxl367_setup(struct adxl367_state *st)
|
||||
return adxl367_set_measure_en(st, true);
|
||||
}
|
||||
|
||||
static void adxl367_disable_regulators(void *data)
|
||||
{
|
||||
struct adxl367_state *st = data;
|
||||
|
||||
regulator_bulk_disable(ARRAY_SIZE(st->regulators), st->regulators);
|
||||
}
|
||||
|
||||
int adxl367_probe(struct device *dev, const struct adxl367_ops *ops,
|
||||
void *context, struct regmap *regmap, int irq)
|
||||
{
|
||||
static const char * const regulator_names[] = { "vdd", "vddio" };
|
||||
struct iio_dev *indio_dev;
|
||||
struct adxl367_state *st;
|
||||
int ret;
|
||||
@ -1520,25 +1499,13 @@ int adxl367_probe(struct device *dev, const struct adxl367_ops *ops,
|
||||
indio_dev->info = &adxl367_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
st->regulators[0].supply = "vdd";
|
||||
st->regulators[1].supply = "vddio";
|
||||
|
||||
ret = devm_regulator_bulk_get(st->dev, ARRAY_SIZE(st->regulators),
|
||||
st->regulators);
|
||||
ret = devm_regulator_bulk_get_enable(st->dev,
|
||||
ARRAY_SIZE(regulator_names),
|
||||
regulator_names);
|
||||
if (ret)
|
||||
return dev_err_probe(st->dev, ret,
|
||||
"Failed to get regulators\n");
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(st->regulators), st->regulators);
|
||||
if (ret)
|
||||
return dev_err_probe(st->dev, ret,
|
||||
"Failed to enable regulators\n");
|
||||
|
||||
ret = devm_add_action_or_reset(st->dev, adxl367_disable_regulators, st);
|
||||
if (ret)
|
||||
return dev_err_probe(st->dev, ret,
|
||||
"Failed to add regulators disable action\n");
|
||||
|
||||
ret = regmap_write(st->regmap, ADXL367_REG_RESET, ADXL367_RESET_CODE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -41,8 +41,7 @@ static const struct adxl367_ops adxl367_i2c_ops = {
|
||||
.read_fifo = adxl367_i2c_read_fifo,
|
||||
};
|
||||
|
||||
static int adxl367_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int adxl367_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
struct adxl367_i2c_state *st;
|
||||
struct regmap *regmap;
|
||||
@ -78,7 +77,7 @@ static struct i2c_driver adxl367_i2c_driver = {
|
||||
.name = "adxl367_i2c",
|
||||
.of_match_table = adxl367_of_match,
|
||||
},
|
||||
.probe = adxl367_i2c_probe,
|
||||
.probe_new = adxl367_i2c_probe,
|
||||
.id_table = adxl367_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -998,32 +998,19 @@ static ssize_t adxl372_get_fifo_watermark(struct device *dev,
|
||||
return sprintf(buf, "%d\n", st->watermark);
|
||||
}
|
||||
|
||||
static ssize_t hwfifo_watermark_min_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", "1");
|
||||
}
|
||||
|
||||
static ssize_t hwfifo_watermark_max_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", __stringify(ADXL372_FIFO_SIZE));
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0);
|
||||
static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
|
||||
IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "1");
|
||||
IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max,
|
||||
__stringify(ADXL372_FIFO_SIZE));
|
||||
static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
|
||||
adxl372_get_fifo_watermark, NULL, 0);
|
||||
static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
|
||||
adxl372_get_fifo_enabled, NULL, 0);
|
||||
|
||||
static const struct attribute *adxl372_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_enabled.dev_attr.attr,
|
||||
static const struct iio_dev_attr *adxl372_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_watermark_min,
|
||||
&iio_dev_attr_hwfifo_watermark_max,
|
||||
&iio_dev_attr_hwfifo_watermark,
|
||||
&iio_dev_attr_hwfifo_enabled,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -874,14 +874,10 @@ static int bma400_init(struct bma400_data *data)
|
||||
ret = devm_regulator_bulk_get(data->dev,
|
||||
ARRAY_SIZE(data->regulators),
|
||||
data->regulators);
|
||||
if (ret) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(data->dev,
|
||||
"Failed to get regulators: %d\n",
|
||||
ret);
|
||||
if (ret)
|
||||
return dev_err_probe(data->dev, ret, "Failed to get regulators: %d\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
|
||||
data->regulators);
|
||||
if (ret) {
|
||||
|
@ -925,32 +925,19 @@ static const struct iio_chan_spec_ext_info bmc150_accel_ext_info[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static ssize_t hwfifo_watermark_min_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", "1");
|
||||
}
|
||||
|
||||
static ssize_t hwfifo_watermark_max_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", __stringify(BMC150_ACCEL_FIFO_LENGTH));
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0);
|
||||
static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
|
||||
IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "1");
|
||||
IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max,
|
||||
__stringify(BMC150_ACCEL_FIFO_LENGTH));
|
||||
static IIO_DEVICE_ATTR(hwfifo_enabled, S_IRUGO,
|
||||
bmc150_accel_get_fifo_state, NULL, 0);
|
||||
static IIO_DEVICE_ATTR(hwfifo_watermark, S_IRUGO,
|
||||
bmc150_accel_get_fifo_watermark, NULL, 0);
|
||||
|
||||
static const struct attribute *bmc150_accel_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_enabled.dev_attr.attr,
|
||||
static const struct iio_dev_attr *bmc150_accel_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_watermark_min,
|
||||
&iio_dev_attr_hwfifo_watermark_max,
|
||||
&iio_dev_attr_hwfifo_watermark,
|
||||
&iio_dev_attr_hwfifo_enabled,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@ -1678,7 +1665,7 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
|
||||
enum bmc150_type type, const char *name,
|
||||
bool block_supported)
|
||||
{
|
||||
const struct attribute **fifo_attrs;
|
||||
const struct iio_dev_attr **fifo_attrs;
|
||||
struct bmc150_accel_data *data;
|
||||
struct iio_dev *indio_dev;
|
||||
int ret;
|
||||
|
@ -217,8 +217,7 @@ static void da311_disable(void *client)
|
||||
da311_enable(client, false);
|
||||
}
|
||||
|
||||
static int da311_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int da311_probe(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -279,7 +278,7 @@ static struct i2c_driver da311_driver = {
|
||||
.name = "da311",
|
||||
.pm = pm_sleep_ptr(&da311_pm_ops),
|
||||
},
|
||||
.probe = da311_probe,
|
||||
.probe_new = da311_probe,
|
||||
.id_table = da311_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -125,8 +125,7 @@ static const struct iio_info dmard06_info = {
|
||||
.read_raw = dmard06_read_raw,
|
||||
};
|
||||
|
||||
static int dmard06_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int dmard06_probe(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -218,7 +217,7 @@ static const struct of_device_id dmard06_of_match[] = {
|
||||
MODULE_DEVICE_TABLE(of, dmard06_of_match);
|
||||
|
||||
static struct i2c_driver dmard06_driver = {
|
||||
.probe = dmard06_probe,
|
||||
.probe_new = dmard06_probe,
|
||||
.id_table = dmard06_id,
|
||||
.driver = {
|
||||
.name = DMARD06_DRV_NAME,
|
||||
|
@ -88,8 +88,7 @@ static const struct iio_info dmard09_info = {
|
||||
.read_raw = dmard09_read_raw,
|
||||
};
|
||||
|
||||
static int dmard09_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int dmard09_probe(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -136,7 +135,7 @@ static struct i2c_driver dmard09_driver = {
|
||||
.driver = {
|
||||
.name = DMARD09_DRV_NAME
|
||||
},
|
||||
.probe = dmard09_probe,
|
||||
.probe_new = dmard09_probe,
|
||||
.id_table = dmard09_id,
|
||||
};
|
||||
|
||||
|
@ -175,8 +175,7 @@ static void dmard10_shutdown_cleanup(void *client)
|
||||
dmard10_shutdown(client);
|
||||
}
|
||||
|
||||
static int dmard10_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int dmard10_probe(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -242,7 +241,7 @@ static struct i2c_driver dmard10_driver = {
|
||||
.name = "dmard10",
|
||||
.pm = pm_sleep_ptr(&dmard10_pm_ops),
|
||||
},
|
||||
.probe = dmard10_probe,
|
||||
.probe_new = dmard10_probe,
|
||||
.id_table = dmard10_i2c_id,
|
||||
};
|
||||
|
||||
|
@ -159,7 +159,6 @@ struct fxls8962af_chip_info {
|
||||
struct fxls8962af_data {
|
||||
struct regmap *regmap;
|
||||
const struct fxls8962af_chip_info *chip_info;
|
||||
struct regulator *vdd_reg;
|
||||
struct {
|
||||
__le16 channels[3];
|
||||
s64 ts __aligned(8);
|
||||
@ -1051,13 +1050,6 @@ static irqreturn_t fxls8962af_interrupt(int irq, void *p)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static void fxls8962af_regulator_disable(void *data_ptr)
|
||||
{
|
||||
struct fxls8962af_data *data = data_ptr;
|
||||
|
||||
regulator_disable(data->vdd_reg);
|
||||
}
|
||||
|
||||
static void fxls8962af_pm_disable(void *dev_ptr)
|
||||
{
|
||||
struct device *dev = dev_ptr;
|
||||
@ -1171,20 +1163,10 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
data->vdd_reg = devm_regulator_get(dev, "vdd");
|
||||
if (IS_ERR(data->vdd_reg))
|
||||
return dev_err_probe(dev, PTR_ERR(data->vdd_reg),
|
||||
"Failed to get vdd regulator\n");
|
||||
|
||||
ret = regulator_enable(data->vdd_reg);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to enable vdd regulator: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(dev, fxls8962af_regulator_disable, data);
|
||||
ret = devm_regulator_get_enable(dev, "vdd");
|
||||
if (ret)
|
||||
return ret;
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to get vdd regulator\n");
|
||||
|
||||
ret = regmap_read(data->regmap, FXLS8962AF_WHO_AM_I, ®);
|
||||
if (ret)
|
||||
@ -1241,7 +1223,7 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq)
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(fxls8962af_core_probe, IIO_FXLS8962AF);
|
||||
|
||||
static int __maybe_unused fxls8962af_runtime_suspend(struct device *dev)
|
||||
static int fxls8962af_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct fxls8962af_data *data = iio_priv(dev_get_drvdata(dev));
|
||||
int ret;
|
||||
@ -1255,14 +1237,14 @@ static int __maybe_unused fxls8962af_runtime_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused fxls8962af_runtime_resume(struct device *dev)
|
||||
static int fxls8962af_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct fxls8962af_data *data = iio_priv(dev_get_drvdata(dev));
|
||||
|
||||
return fxls8962af_active(data);
|
||||
}
|
||||
|
||||
static int __maybe_unused fxls8962af_suspend(struct device *dev)
|
||||
static int fxls8962af_suspend(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct fxls8962af_data *data = iio_priv(indio_dev);
|
||||
@ -1283,7 +1265,7 @@ static int __maybe_unused fxls8962af_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused fxls8962af_resume(struct device *dev)
|
||||
static int fxls8962af_resume(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct fxls8962af_data *data = iio_priv(indio_dev);
|
||||
@ -1300,12 +1282,10 @@ static int __maybe_unused fxls8962af_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct dev_pm_ops fxls8962af_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(fxls8962af_suspend, fxls8962af_resume)
|
||||
SET_RUNTIME_PM_OPS(fxls8962af_runtime_suspend,
|
||||
fxls8962af_runtime_resume, NULL)
|
||||
EXPORT_NS_GPL_DEV_PM_OPS(fxls8962af_pm_ops, IIO_FXLS8962AF) = {
|
||||
SYSTEM_SLEEP_PM_OPS(fxls8962af_suspend, fxls8962af_resume)
|
||||
RUNTIME_PM_OPS(fxls8962af_runtime_suspend, fxls8962af_runtime_resume, NULL)
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(fxls8962af_pm_ops, IIO_FXLS8962AF);
|
||||
|
||||
MODULE_AUTHOR("Sean Nyekjaer <sean@geanix.com>");
|
||||
MODULE_DESCRIPTION("NXP FXLS8962AF/FXLS8964AF accelerometer driver");
|
||||
|
@ -45,7 +45,7 @@ static struct i2c_driver fxls8962af_driver = {
|
||||
.driver = {
|
||||
.name = "fxls8962af_i2c",
|
||||
.of_match_table = fxls8962af_of_match,
|
||||
.pm = &fxls8962af_pm_ops,
|
||||
.pm = pm_ptr(&fxls8962af_pm_ops),
|
||||
},
|
||||
.probe_new = fxls8962af_probe,
|
||||
.id_table = fxls8962af_id,
|
||||
|
@ -44,7 +44,7 @@ MODULE_DEVICE_TABLE(spi, fxls8962af_spi_id_table);
|
||||
static struct spi_driver fxls8962af_driver = {
|
||||
.driver = {
|
||||
.name = "fxls8962af_spi",
|
||||
.pm = &fxls8962af_pm_ops,
|
||||
.pm = pm_ptr(&fxls8962af_pm_ops),
|
||||
.of_match_table = fxls8962af_spi_of_match,
|
||||
},
|
||||
.probe = fxls8962af_probe,
|
||||
|
51
drivers/iio/accel/kionix-kx022a-i2c.c
Normal file
51
drivers/iio/accel/kionix-kx022a-i2c.c
Normal file
@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2022 ROHM Semiconductors
|
||||
*
|
||||
* ROHM/KIONIX KX022A accelerometer driver
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "kionix-kx022a.h"
|
||||
|
||||
static int kx022a_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct device *dev = &i2c->dev;
|
||||
struct regmap *regmap;
|
||||
|
||||
if (!i2c->irq) {
|
||||
dev_err(dev, "No IRQ configured\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c, &kx022a_regmap);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap),
|
||||
"Failed to initialize Regmap\n");
|
||||
|
||||
return kx022a_probe_internal(dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id kx022a_of_match[] = {
|
||||
{ .compatible = "kionix,kx022a", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, kx022a_of_match);
|
||||
|
||||
static struct i2c_driver kx022a_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "kx022a-i2c",
|
||||
.of_match_table = kx022a_of_match,
|
||||
},
|
||||
.probe_new = kx022a_i2c_probe,
|
||||
};
|
||||
module_i2c_driver(kx022a_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ROHM/Kionix KX022A accelerometer driver");
|
||||
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(IIO_KX022A);
|
58
drivers/iio/accel/kionix-kx022a-spi.c
Normal file
58
drivers/iio/accel/kionix-kx022a-spi.c
Normal file
@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2022 ROHM Semiconductors
|
||||
*
|
||||
* ROHM/KIONIX KX022A accelerometer driver
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include "kionix-kx022a.h"
|
||||
|
||||
static int kx022a_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct device *dev = &spi->dev;
|
||||
struct regmap *regmap;
|
||||
|
||||
if (!spi->irq) {
|
||||
dev_err(dev, "No IRQ configured\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regmap = devm_regmap_init_spi(spi, &kx022a_regmap);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap),
|
||||
"Failed to initialize Regmap\n");
|
||||
|
||||
return kx022a_probe_internal(dev);
|
||||
}
|
||||
|
||||
static const struct spi_device_id kx022a_id[] = {
|
||||
{ "kx022a" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, kx022a_id);
|
||||
|
||||
static const struct of_device_id kx022a_of_match[] = {
|
||||
{ .compatible = "kionix,kx022a", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, kx022a_of_match);
|
||||
|
||||
static struct spi_driver kx022a_spi_driver = {
|
||||
.driver = {
|
||||
.name = "kx022a-spi",
|
||||
.of_match_table = kx022a_of_match,
|
||||
},
|
||||
.probe = kx022a_spi_probe,
|
||||
.id_table = kx022a_id,
|
||||
};
|
||||
module_spi_driver(kx022a_spi_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ROHM/Kionix kx022A accelerometer driver");
|
||||
MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(IIO_KX022A);
|
1142
drivers/iio/accel/kionix-kx022a.c
Normal file
1142
drivers/iio/accel/kionix-kx022a.c
Normal file
File diff suppressed because it is too large
Load Diff
82
drivers/iio/accel/kionix-kx022a.h
Normal file
82
drivers/iio/accel/kionix-kx022a.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2022 ROHM Semiconductors
|
||||
*
|
||||
* ROHM/KIONIX KX022A accelerometer driver
|
||||
*/
|
||||
|
||||
#ifndef _KX022A_H_
|
||||
#define _KX022A_H_
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define KX022A_REG_WHO 0x0f
|
||||
#define KX022A_ID 0xc8
|
||||
|
||||
#define KX022A_REG_CNTL2 0x19
|
||||
#define KX022A_MASK_SRST BIT(7)
|
||||
#define KX022A_REG_CNTL 0x18
|
||||
#define KX022A_MASK_PC1 BIT(7)
|
||||
#define KX022A_MASK_RES BIT(6)
|
||||
#define KX022A_MASK_DRDY BIT(5)
|
||||
#define KX022A_MASK_GSEL GENMASK(4, 3)
|
||||
#define KX022A_GSEL_SHIFT 3
|
||||
#define KX022A_GSEL_2 0x0
|
||||
#define KX022A_GSEL_4 BIT(3)
|
||||
#define KX022A_GSEL_8 BIT(4)
|
||||
#define KX022A_GSEL_16 GENMASK(4, 3)
|
||||
|
||||
#define KX022A_REG_INS2 0x13
|
||||
#define KX022A_MASK_INS2_DRDY BIT(4)
|
||||
#define KX122_MASK_INS2_WMI BIT(5)
|
||||
|
||||
#define KX022A_REG_XHP_L 0x0
|
||||
#define KX022A_REG_XOUT_L 0x06
|
||||
#define KX022A_REG_YOUT_L 0x08
|
||||
#define KX022A_REG_ZOUT_L 0x0a
|
||||
#define KX022A_REG_COTR 0x0c
|
||||
#define KX022A_REG_TSCP 0x10
|
||||
#define KX022A_REG_INT_REL 0x17
|
||||
|
||||
#define KX022A_REG_ODCNTL 0x1b
|
||||
|
||||
#define KX022A_REG_BTS_WUF_TH 0x31
|
||||
#define KX022A_REG_MAN_WAKE 0x2c
|
||||
|
||||
#define KX022A_REG_BUF_CNTL1 0x3a
|
||||
#define KX022A_MASK_WM_TH GENMASK(6, 0)
|
||||
#define KX022A_REG_BUF_CNTL2 0x3b
|
||||
#define KX022A_MASK_BUF_EN BIT(7)
|
||||
#define KX022A_MASK_BRES16 BIT(6)
|
||||
#define KX022A_REG_BUF_STATUS_1 0x3c
|
||||
#define KX022A_REG_BUF_STATUS_2 0x3d
|
||||
#define KX022A_REG_BUF_CLEAR 0x3e
|
||||
#define KX022A_REG_BUF_READ 0x3f
|
||||
#define KX022A_MASK_ODR GENMASK(3, 0)
|
||||
#define KX022A_ODR_SHIFT 3
|
||||
#define KX022A_FIFO_MAX_WMI_TH 41
|
||||
|
||||
#define KX022A_REG_INC1 0x1c
|
||||
#define KX022A_REG_INC5 0x20
|
||||
#define KX022A_REG_INC6 0x21
|
||||
#define KX022A_MASK_IEN BIT(5)
|
||||
#define KX022A_MASK_IPOL BIT(4)
|
||||
#define KX022A_IPOL_LOW 0
|
||||
#define KX022A_IPOL_HIGH KX022A_MASK_IPOL1
|
||||
#define KX022A_MASK_ITYP BIT(3)
|
||||
#define KX022A_ITYP_PULSE KX022A_MASK_ITYP
|
||||
#define KX022A_ITYP_LEVEL 0
|
||||
|
||||
#define KX022A_REG_INC4 0x1f
|
||||
#define KX022A_MASK_WMI BIT(5)
|
||||
|
||||
#define KX022A_REG_SELF_TEST 0x60
|
||||
#define KX022A_MAX_REGISTER 0x60
|
||||
|
||||
struct device;
|
||||
|
||||
int kx022a_probe_internal(struct device *dev);
|
||||
extern const struct regmap_config kx022a_regmap;
|
||||
|
||||
#endif
|
@ -241,7 +241,6 @@ enum kxcjk1013_axis {
|
||||
};
|
||||
|
||||
struct kxcjk1013_data {
|
||||
struct regulator_bulk_data regulators[2];
|
||||
struct i2c_client *client;
|
||||
struct iio_trigger *dready_trig;
|
||||
struct iio_trigger *motion_trig;
|
||||
@ -1425,16 +1424,10 @@ static const char *kxcjk1013_match_acpi_device(struct device *dev,
|
||||
return dev_name(dev);
|
||||
}
|
||||
|
||||
static void kxcjk1013_disable_regulators(void *d)
|
||||
{
|
||||
struct kxcjk1013_data *data = d;
|
||||
|
||||
regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators);
|
||||
}
|
||||
|
||||
static int kxcjk1013_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
static const char * const regulator_names[] = { "vdd", "vddio" };
|
||||
struct kxcjk1013_data *data;
|
||||
struct iio_dev *indio_dev;
|
||||
struct kxcjk_1013_platform_data *pdata;
|
||||
@ -1461,22 +1454,12 @@ static int kxcjk1013_probe(struct i2c_client *client,
|
||||
return ret;
|
||||
}
|
||||
|
||||
data->regulators[0].supply = "vdd";
|
||||
data->regulators[1].supply = "vddio";
|
||||
ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(data->regulators),
|
||||
data->regulators);
|
||||
ret = devm_regulator_bulk_get_enable(&client->dev,
|
||||
ARRAY_SIZE(regulator_names),
|
||||
regulator_names);
|
||||
if (ret)
|
||||
return dev_err_probe(&client->dev, ret, "Failed to get regulators\n");
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(data->regulators),
|
||||
data->regulators);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(&client->dev, kxcjk1013_disable_regulators, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* A typical delay of 10ms is required for powering up
|
||||
* according to the data sheets of supported chips.
|
||||
|
@ -10,8 +10,7 @@
|
||||
|
||||
#include "kxsd9.h"
|
||||
|
||||
static int kxsd9_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
static int kxsd9_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
static const struct regmap_config config = {
|
||||
.reg_bits = 8,
|
||||
@ -55,7 +54,7 @@ static struct i2c_driver kxsd9_i2c_driver = {
|
||||
.of_match_table = kxsd9_of_match,
|
||||
.pm = pm_ptr(&kxsd9_dev_pm_ops),
|
||||
},
|
||||
.probe = kxsd9_i2c_probe,
|
||||
.probe_new = kxsd9_i2c_probe,
|
||||
.remove = kxsd9_i2c_remove,
|
||||
.id_table = kxsd9_i2c_id,
|
||||
};
|
||||
|
@ -106,8 +106,7 @@ static const struct iio_info mc3230_info = {
|
||||
.read_raw = mc3230_read_raw,
|
||||
};
|
||||
|
||||
static int mc3230_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int mc3230_probe(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -191,7 +190,7 @@ static struct i2c_driver mc3230_driver = {
|
||||
.name = "mc3230",
|
||||
.pm = pm_sleep_ptr(&mc3230_pm_ops),
|
||||
},
|
||||
.probe = mc3230_probe,
|
||||
.probe_new = mc3230_probe,
|
||||
.remove = mc3230_remove,
|
||||
.id_table = mc3230_i2c_id,
|
||||
};
|
||||
|
@ -169,8 +169,7 @@ static const struct iio_info mma7660_info = {
|
||||
.attrs = &mma7660_attribute_group,
|
||||
};
|
||||
|
||||
static int mma7660_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int mma7660_probe(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -267,7 +266,7 @@ static struct i2c_driver mma7660_driver = {
|
||||
.of_match_table = mma7660_of_match,
|
||||
.acpi_match_table = mma7660_acpi_id,
|
||||
},
|
||||
.probe = mma7660_probe,
|
||||
.probe_new = mma7660_probe,
|
||||
.remove = mma7660_remove,
|
||||
.id_table = mma7660_i2c_id,
|
||||
};
|
||||
|
@ -351,7 +351,6 @@ static const struct regmap_config msa311_regmap_config = {
|
||||
* @chip_name: Chip name in the format "msa311-%02x" % partid
|
||||
* @new_data_trig: Optional NEW_DATA interrupt driven trigger used
|
||||
* to notify external consumers a new sample is ready
|
||||
* @vdd: Optional external voltage regulator for the device power supply
|
||||
*/
|
||||
struct msa311_priv {
|
||||
struct regmap *regs;
|
||||
@ -362,7 +361,6 @@ struct msa311_priv {
|
||||
char *chip_name;
|
||||
|
||||
struct iio_trigger *new_data_trig;
|
||||
struct regulator *vdd;
|
||||
};
|
||||
|
||||
enum msa311_si {
|
||||
@ -1146,11 +1144,6 @@ static void msa311_powerdown(void *msa311)
|
||||
msa311_set_pwr_mode(msa311, MSA311_PWR_MODE_SUSPEND);
|
||||
}
|
||||
|
||||
static void msa311_vdd_disable(void *vdd)
|
||||
{
|
||||
regulator_disable(vdd);
|
||||
}
|
||||
|
||||
static int msa311_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct device *dev = &i2c->dev;
|
||||
@ -1173,19 +1166,9 @@ static int msa311_probe(struct i2c_client *i2c)
|
||||
|
||||
mutex_init(&msa311->lock);
|
||||
|
||||
msa311->vdd = devm_regulator_get(dev, "vdd");
|
||||
if (IS_ERR(msa311->vdd))
|
||||
return dev_err_probe(dev, PTR_ERR(msa311->vdd),
|
||||
"can't get vdd supply\n");
|
||||
|
||||
err = regulator_enable(msa311->vdd);
|
||||
err = devm_regulator_get_enable(dev, "vdd");
|
||||
if (err)
|
||||
return dev_err_probe(dev, err, "can't enable vdd supply\n");
|
||||
|
||||
err = devm_add_action_or_reset(dev, msa311_vdd_disable, msa311->vdd);
|
||||
if (err)
|
||||
return dev_err_probe(dev, err,
|
||||
"can't add vdd disable action\n");
|
||||
return dev_err_probe(dev, err, "can't get vdd supply\n");
|
||||
|
||||
err = msa311_check_partid(msa311);
|
||||
if (err)
|
||||
|
@ -385,8 +385,7 @@ static int mxc4005_chip_init(struct mxc4005_data *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc4005_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int mxc4005_probe(struct i2c_client *client)
|
||||
{
|
||||
struct mxc4005_data *data;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -489,7 +488,7 @@ static struct i2c_driver mxc4005_driver = {
|
||||
.name = MXC4005_DRV_NAME,
|
||||
.acpi_match_table = ACPI_PTR(mxc4005_acpi_match),
|
||||
},
|
||||
.probe = mxc4005_probe,
|
||||
.probe_new = mxc4005_probe,
|
||||
.id_table = mxc4005_id,
|
||||
};
|
||||
|
||||
|
@ -113,8 +113,7 @@ static const struct regmap_config mxc6255_regmap_config = {
|
||||
.readable_reg = mxc6255_is_readable_reg,
|
||||
};
|
||||
|
||||
static int mxc6255_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int mxc6255_probe(struct i2c_client *client)
|
||||
{
|
||||
struct mxc6255_data *data;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -184,7 +183,7 @@ static struct i2c_driver mxc6255_driver = {
|
||||
.name = MXC6255_DRV_NAME,
|
||||
.acpi_match_table = ACPI_PTR(mxc6255_acpi_match),
|
||||
},
|
||||
.probe = mxc6255_probe,
|
||||
.probe_new = mxc6255_probe,
|
||||
.id_table = mxc6255_id,
|
||||
};
|
||||
|
||||
|
@ -679,12 +679,20 @@ static const struct of_device_id sca3300_dt_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sca3300_dt_ids);
|
||||
|
||||
static const struct spi_device_id sca3300_ids[] = {
|
||||
{ "sca3300" },
|
||||
{ "scl3300" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, sca3300_ids);
|
||||
|
||||
static struct spi_driver sca3300_driver = {
|
||||
.driver = {
|
||||
.driver = {
|
||||
.name = SCA3300_ALIAS,
|
||||
.of_match_table = sca3300_dt_ids,
|
||||
},
|
||||
.probe = sca3300_probe,
|
||||
.probe = sca3300_probe,
|
||||
.id_table = sca3300_ids,
|
||||
};
|
||||
module_spi_driver(sca3300_driver);
|
||||
|
||||
|
@ -498,8 +498,7 @@ static const struct iio_buffer_setup_ops stk8312_buffer_setup_ops = {
|
||||
.postdisable = stk8312_buffer_postdisable,
|
||||
};
|
||||
|
||||
static int stk8312_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int stk8312_probe(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -645,7 +644,7 @@ static struct i2c_driver stk8312_driver = {
|
||||
.name = STK8312_DRIVER_NAME,
|
||||
.pm = pm_sleep_ptr(&stk8312_pm_ops),
|
||||
},
|
||||
.probe = stk8312_probe,
|
||||
.probe_new = stk8312_probe,
|
||||
.remove = stk8312_remove,
|
||||
.id_table = stk8312_i2c_id,
|
||||
};
|
||||
|
@ -379,8 +379,7 @@ static const struct iio_buffer_setup_ops stk8ba50_buffer_setup_ops = {
|
||||
.postdisable = stk8ba50_buffer_postdisable,
|
||||
};
|
||||
|
||||
static int stk8ba50_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
static int stk8ba50_probe(struct i2c_client *client)
|
||||
{
|
||||
int ret;
|
||||
struct iio_dev *indio_dev;
|
||||
@ -544,7 +543,7 @@ static struct i2c_driver stk8ba50_driver = {
|
||||
.pm = pm_sleep_ptr(&stk8ba50_pm_ops),
|
||||
.acpi_match_table = ACPI_PTR(stk8ba50_acpi_id),
|
||||
},
|
||||
.probe = stk8ba50_probe,
|
||||
.probe_new = stk8ba50_probe,
|
||||
.remove = stk8ba50_remove,
|
||||
.id_table = stk8ba50_i2c_id,
|
||||
};
|
||||
|
@ -21,6 +21,21 @@ config AD_SIGMA_DELTA
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
|
||||
config AD4130
|
||||
tristate "Analog Device AD4130 ADC Driver"
|
||||
depends on SPI
|
||||
depends on GPIOLIB
|
||||
select IIO_BUFFER
|
||||
select IIO_KFIFO_BUF
|
||||
select REGMAP_SPI
|
||||
depends on COMMON_CLK
|
||||
help
|
||||
Say yes here to build support for Analog Devices AD4130-8 SPI analog
|
||||
to digital converters (ADC).
|
||||
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called ad4130.
|
||||
|
||||
config AD7091R5
|
||||
tristate "Analog Devices AD7091R5 ADC Driver"
|
||||
depends on I2C
|
||||
@ -667,6 +682,19 @@ config MAX11205
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called max11205.
|
||||
|
||||
config MAX11410
|
||||
tristate "Analog Devices MAX11410 ADC driver"
|
||||
depends on SPI
|
||||
select REGMAP_SPI
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
help
|
||||
Say yes here to build support for Analog Devices MAX11410 ADCs.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called max11410.
|
||||
|
||||
config MAX1241
|
||||
tristate "Maxim max1241 ADC driver"
|
||||
depends on SPI_MASTER
|
||||
@ -752,6 +780,18 @@ config MEDIATEK_MT6360_ADC
|
||||
is used in smartphones and tablets and supports a 11 channel
|
||||
general purpose ADC.
|
||||
|
||||
config MEDIATEK_MT6370_ADC
|
||||
tristate "MediaTek MT6370 ADC driver"
|
||||
depends on MFD_MT6370
|
||||
help
|
||||
Say yes here to enable MediaTek MT6370 ADC support.
|
||||
|
||||
This ADC driver provides 9 channels for system monitoring (charger
|
||||
current, voltage, and temperature).
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called "mt6370-adc".
|
||||
|
||||
config MEDIATEK_MT6577_AUXADC
|
||||
tristate "MediaTek AUXADC driver"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
|
@ -6,6 +6,7 @@
|
||||
# When adding new entries keep the list in alphabetical order
|
||||
obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
|
||||
obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
|
||||
obj-$(CONFIG_AD4130) += ad4130.o
|
||||
obj-$(CONFIG_AD7091R5) += ad7091r5.o ad7091r-base.o
|
||||
obj-$(CONFIG_AD7124) += ad7124.o
|
||||
obj-$(CONFIG_AD7192) += ad7192.o
|
||||
@ -62,6 +63,7 @@ obj-$(CONFIG_MAX1027) += max1027.o
|
||||
obj-$(CONFIG_MAX11100) += max11100.o
|
||||
obj-$(CONFIG_MAX1118) += max1118.o
|
||||
obj-$(CONFIG_MAX11205) += max11205.o
|
||||
obj-$(CONFIG_MAX11410) += max11410.o
|
||||
obj-$(CONFIG_MAX1241) += max1241.o
|
||||
obj-$(CONFIG_MAX1363) += max1363.o
|
||||
obj-$(CONFIG_MAX9611) += max9611.o
|
||||
@ -69,6 +71,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o
|
||||
obj-$(CONFIG_MCP3422) += mcp3422.o
|
||||
obj-$(CONFIG_MCP3911) += mcp3911.o
|
||||
obj-$(CONFIG_MEDIATEK_MT6360_ADC) += mt6360-adc.o
|
||||
obj-$(CONFIG_MEDIATEK_MT6370_ADC) += mt6370-adc.o
|
||||
obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
|
||||
obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
|
||||
obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
|
||||
|
2100
drivers/iio/adc/ad4130.c
Normal file
2100
drivers/iio/adc/ad4130.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -944,6 +944,8 @@ static int ad7124_probe(struct spi_device *spi)
|
||||
int i, ret;
|
||||
|
||||
info = of_device_get_match_data(&spi->dev);
|
||||
if (!info)
|
||||
info = (void *)spi_get_device_id(spi)->driver_data;
|
||||
if (!info)
|
||||
return -ENODEV;
|
||||
|
||||
@ -1021,12 +1023,20 @@ static const struct of_device_id ad7124_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ad7124_of_match);
|
||||
|
||||
static const struct spi_device_id ad71124_ids[] = {
|
||||
{ "ad7124-4", (kernel_ulong_t)&ad7124_chip_info_tbl[ID_AD7124_4] },
|
||||
{ "ad7124-8", (kernel_ulong_t)&ad7124_chip_info_tbl[ID_AD7124_8] },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, ad71124_ids);
|
||||
|
||||
static struct spi_driver ad71124_driver = {
|
||||
.driver = {
|
||||
.name = "ad7124",
|
||||
.of_match_table = ad7124_of_match,
|
||||
},
|
||||
.probe = ad7124_probe,
|
||||
.id_table = ad71124_ids,
|
||||
};
|
||||
module_spi_driver(ad71124_driver);
|
||||
|
||||
|
@ -177,7 +177,6 @@ struct ad7192_chip_info {
|
||||
struct ad7192_state {
|
||||
const struct ad7192_chip_info *chip_info;
|
||||
struct regulator *avdd;
|
||||
struct regulator *dvdd;
|
||||
struct clk *mclk;
|
||||
u16 int_vref_mv;
|
||||
u32 fclk;
|
||||
@ -1015,19 +1014,9 @@ static int ad7192_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
st->dvdd = devm_regulator_get(&spi->dev, "dvdd");
|
||||
if (IS_ERR(st->dvdd))
|
||||
return PTR_ERR(st->dvdd);
|
||||
|
||||
ret = regulator_enable(st->dvdd);
|
||||
if (ret) {
|
||||
dev_err(&spi->dev, "Failed to enable specified DVdd supply\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(&spi->dev, ad7192_reg_disable, st->dvdd);
|
||||
ret = devm_regulator_get_enable(&spi->dev, "dvdd");
|
||||
if (ret)
|
||||
return ret;
|
||||
return dev_err_probe(&spi->dev, ret, "Failed to enable specified DVdd supply\n");
|
||||
|
||||
ret = regulator_get_voltage(st->avdd);
|
||||
if (ret < 0) {
|
||||
@ -1037,6 +1026,8 @@ static int ad7192_probe(struct spi_device *spi)
|
||||
st->int_vref_mv = ret / 1000;
|
||||
|
||||
st->chip_info = of_device_get_match_data(&spi->dev);
|
||||
if (!st->chip_info)
|
||||
st->chip_info = (void *)spi_get_device_id(spi)->driver_data;
|
||||
indio_dev->name = st->chip_info->name;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
@ -1098,12 +1089,22 @@ static const struct of_device_id ad7192_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ad7192_of_match);
|
||||
|
||||
static const struct spi_device_id ad7192_ids[] = {
|
||||
{ "ad7190", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7190] },
|
||||
{ "ad7192", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7192] },
|
||||
{ "ad7193", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7193] },
|
||||
{ "ad7195", (kernel_ulong_t)&ad7192_chip_info_tbl[ID_AD7195] },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, ad7192_ids);
|
||||
|
||||
static struct spi_driver ad7192_driver = {
|
||||
.driver = {
|
||||
.name = "ad7192",
|
||||
.of_match_table = ad7192_of_match,
|
||||
},
|
||||
.probe = ad7192_probe,
|
||||
.id_table = ad7192_ids,
|
||||
};
|
||||
module_spi_driver(ad7192_driver);
|
||||
|
||||
|
@ -368,16 +368,7 @@ static int ad7476_probe(struct spi_device *spi)
|
||||
}
|
||||
|
||||
if (st->chip_info->has_vdrive) {
|
||||
reg = devm_regulator_get(&spi->dev, "vdrive");
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
ret = regulator_enable(reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(&spi->dev, ad7476_reg_disable,
|
||||
reg);
|
||||
ret = devm_regulator_get_enable(&spi->dev, "vdrive");
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -557,13 +557,6 @@ static const struct iio_trigger_ops ad7606_trigger_ops = {
|
||||
.validate_device = iio_trigger_validate_own_device,
|
||||
};
|
||||
|
||||
static void ad7606_regulator_disable(void *data)
|
||||
{
|
||||
struct ad7606_state *st = data;
|
||||
|
||||
regulator_disable(st->reg);
|
||||
}
|
||||
|
||||
int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
|
||||
const char *name, unsigned int id,
|
||||
const struct ad7606_bus_ops *bops)
|
||||
@ -589,19 +582,10 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
|
||||
st->scale_avail = ad7606_scale_avail;
|
||||
st->num_scales = ARRAY_SIZE(ad7606_scale_avail);
|
||||
|
||||
st->reg = devm_regulator_get(dev, "avcc");
|
||||
if (IS_ERR(st->reg))
|
||||
return PTR_ERR(st->reg);
|
||||
|
||||
ret = regulator_enable(st->reg);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to enable specified AVcc supply\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(dev, ad7606_regulator_disable, st);
|
||||
ret = devm_regulator_get_enable(dev, "avcc");
|
||||
if (ret)
|
||||
return ret;
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to enable specified AVcc supply\n");
|
||||
|
||||
st->chip_info = &ad7606_chip_info_tbl[id];
|
||||
|
||||
|
@ -62,7 +62,6 @@ struct ad7606_chip_info {
|
||||
* struct ad7606_state - driver instance specific data
|
||||
* @dev pointer to kernel device
|
||||
* @chip_info entry in the table of chips that describes this device
|
||||
* @reg regulator info for the power supply of the device
|
||||
* @bops bus operations (SPI or parallel)
|
||||
* @range voltage range selection, selects which scale to apply
|
||||
* @oversampling oversampling selection
|
||||
@ -92,7 +91,6 @@ struct ad7606_chip_info {
|
||||
struct ad7606_state {
|
||||
struct device *dev;
|
||||
const struct ad7606_chip_info *chip_info;
|
||||
struct regulator *reg;
|
||||
const struct ad7606_bus_ops *bops;
|
||||
unsigned int range[16];
|
||||
unsigned int oversampling;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include <linux/iio/iio.h>
|
||||
@ -125,6 +126,8 @@ struct ad799x_state {
|
||||
const struct ad799x_chip_config *chip_config;
|
||||
struct regulator *reg;
|
||||
struct regulator *vref;
|
||||
/* lock to protect against multiple access to the device */
|
||||
struct mutex lock;
|
||||
unsigned id;
|
||||
u16 config;
|
||||
|
||||
@ -290,7 +293,9 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
|
||||
ret = iio_device_claim_direct_mode(indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
mutex_lock(&st->lock);
|
||||
ret = ad799x_scan_direct(st, chan->scan_index);
|
||||
mutex_unlock(&st->lock);
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
|
||||
if (ret < 0)
|
||||
@ -351,7 +356,8 @@ static ssize_t ad799x_write_frequency(struct device *dev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->lock);
|
||||
|
||||
ret = i2c_smbus_read_byte_data(st->client, AD7998_CYCLE_TMR_REG);
|
||||
if (ret < 0)
|
||||
goto error_ret_mutex;
|
||||
@ -373,7 +379,7 @@ static ssize_t ad799x_write_frequency(struct device *dev,
|
||||
ret = len;
|
||||
|
||||
error_ret_mutex:
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -407,6 +413,8 @@ static int ad799x_write_event_config(struct iio_dev *indio_dev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&st->lock);
|
||||
|
||||
if (state)
|
||||
st->config |= BIT(chan->scan_index) << AD799X_CHANNEL_SHIFT;
|
||||
else
|
||||
@ -418,6 +426,7 @@ static int ad799x_write_event_config(struct iio_dev *indio_dev,
|
||||
st->config &= ~AD7998_ALERT_EN;
|
||||
|
||||
ret = ad799x_write_config(st, st->config);
|
||||
mutex_unlock(&st->lock);
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
return ret;
|
||||
}
|
||||
@ -454,11 +463,9 @@ static int ad799x_write_event_value(struct iio_dev *indio_dev,
|
||||
if (val < 0 || val > GENMASK(chan->scan_type.realbits - 1, 0))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
ret = i2c_smbus_write_word_swapped(st->client,
|
||||
ad799x_threshold_reg(chan, dir, info),
|
||||
val << chan->scan_type.shift);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -473,10 +480,8 @@ static int ad799x_read_event_value(struct iio_dev *indio_dev,
|
||||
int ret;
|
||||
struct ad799x_state *st = iio_priv(indio_dev);
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
ret = i2c_smbus_read_word_swapped(st->client,
|
||||
ad799x_threshold_reg(chan, dir, info));
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*val = (ret >> chan->scan_type.shift) &
|
||||
@ -863,6 +868,9 @@ static int ad799x_probe(struct i2c_client *client,
|
||||
if (ret)
|
||||
goto error_cleanup_ring;
|
||||
}
|
||||
|
||||
mutex_init(&st->lock);
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret)
|
||||
goto error_cleanup_ring;
|
||||
|
@ -387,6 +387,8 @@ static int ad9467_probe(struct spi_device *spi)
|
||||
int ret;
|
||||
|
||||
info = of_device_get_match_data(&spi->dev);
|
||||
if (!info)
|
||||
info = (void *)spi_get_device_id(spi)->driver_data;
|
||||
if (!info)
|
||||
return -ENODEV;
|
||||
|
||||
@ -447,12 +449,21 @@ static const struct of_device_id ad9467_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ad9467_of_match);
|
||||
|
||||
static const struct spi_device_id ad9467_ids[] = {
|
||||
{ "ad9265", (kernel_ulong_t)&ad9467_chip_tbl[ID_AD9265] },
|
||||
{ "ad9434", (kernel_ulong_t)&ad9467_chip_tbl[ID_AD9434] },
|
||||
{ "ad9467", (kernel_ulong_t)&ad9467_chip_tbl[ID_AD9467] },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, ad9467_ids);
|
||||
|
||||
static struct spi_driver ad9467_driver = {
|
||||
.driver = {
|
||||
.name = "ad9467",
|
||||
.of_match_table = ad9467_of_match,
|
||||
},
|
||||
.probe = ad9467_probe,
|
||||
.id_table = ad9467_ids,
|
||||
};
|
||||
module_spi_driver(ad9467_driver);
|
||||
|
||||
|
@ -281,10 +281,10 @@ int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
|
||||
unsigned int data_reg;
|
||||
int ret = 0;
|
||||
|
||||
if (iio_buffer_enabled(indio_dev))
|
||||
return -EBUSY;
|
||||
ret = iio_device_claim_direct_mode(indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
ad_sigma_delta_set_channel(sigma_delta, chan->address);
|
||||
|
||||
spi_bus_lock(sigma_delta->spi->master);
|
||||
@ -323,7 +323,7 @@ out:
|
||||
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
|
||||
sigma_delta->bus_locked = false;
|
||||
spi_bus_unlock(sigma_delta->spi->master);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -2193,32 +2193,19 @@ static ssize_t at91_adc_get_watermark(struct device *dev,
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", st->dma_st.watermark);
|
||||
}
|
||||
|
||||
static ssize_t hwfifo_watermark_min_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", "2");
|
||||
}
|
||||
|
||||
static ssize_t hwfifo_watermark_max_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%s\n", AT91_HWFIFO_MAX_SIZE_STR);
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
|
||||
at91_adc_get_fifo_state, NULL, 0);
|
||||
static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
|
||||
at91_adc_get_watermark, NULL, 0);
|
||||
static IIO_DEVICE_ATTR_RO(hwfifo_watermark_min, 0);
|
||||
static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
|
||||
|
||||
static const struct attribute *at91_adc_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_watermark_min.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_enabled.dev_attr.attr,
|
||||
IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_min, "2");
|
||||
IIO_STATIC_CONST_DEVICE_ATTR(hwfifo_watermark_max, AT91_HWFIFO_MAX_SIZE_STR);
|
||||
|
||||
static const struct iio_dev_attr *at91_adc_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_watermark_min,
|
||||
&iio_dev_attr_hwfifo_watermark_max,
|
||||
&iio_dev_attr_hwfifo_watermark,
|
||||
&iio_dev_attr_hwfifo_enabled,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@ -2235,7 +2222,7 @@ static int at91_adc_buffer_and_trigger_init(struct device *dev,
|
||||
struct iio_dev *indio)
|
||||
{
|
||||
struct at91_adc_state *st = iio_priv(indio);
|
||||
const struct attribute **fifo_attrs;
|
||||
const struct iio_dev_attr **fifo_attrs;
|
||||
int ret;
|
||||
|
||||
if (st->selected_trig->hw_trig)
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/regmap.h>
|
||||
@ -50,6 +51,8 @@ enum axp288_adc_id {
|
||||
struct axp288_adc_info {
|
||||
int irq;
|
||||
struct regmap *regmap;
|
||||
/* lock to protect against multiple access to the device */
|
||||
struct mutex lock;
|
||||
bool ts_enabled;
|
||||
};
|
||||
|
||||
@ -161,7 +164,7 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
|
||||
int ret;
|
||||
struct axp288_adc_info *info = iio_priv(indio_dev);
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&info->lock);
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
if (axp288_adc_set_ts(info, AXP288_ADC_TS_CURRENT_ON_ONDEMAND,
|
||||
@ -178,7 +181,7 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&info->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -289,6 +292,8 @@ static int axp288_adc_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mutex_init(&info->lock);
|
||||
|
||||
return devm_iio_device_register(&pdev->dev, indio_dev);
|
||||
}
|
||||
|
||||
|
@ -305,16 +305,27 @@ static int cc10001_adc_channel_init(struct iio_dev *indio_dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cc10001_reg_disable(void *priv)
|
||||
{
|
||||
regulator_disable(priv);
|
||||
}
|
||||
|
||||
static void cc10001_pd_cb(void *priv)
|
||||
{
|
||||
cc10001_adc_power_down(priv);
|
||||
}
|
||||
|
||||
static int cc10001_adc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
struct cc10001_adc_device *adc_dev;
|
||||
unsigned long adc_clk_rate;
|
||||
struct iio_dev *indio_dev;
|
||||
unsigned long channel_map;
|
||||
int ret;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*adc_dev));
|
||||
if (indio_dev == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -326,7 +337,7 @@ static int cc10001_adc_probe(struct platform_device *pdev)
|
||||
channel_map &= ~ret;
|
||||
}
|
||||
|
||||
adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
|
||||
adc_dev->reg = devm_regulator_get(dev, "vref");
|
||||
if (IS_ERR(adc_dev->reg))
|
||||
return PTR_ERR(adc_dev->reg);
|
||||
|
||||
@ -334,34 +345,28 @@ static int cc10001_adc_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
indio_dev->name = dev_name(&pdev->dev);
|
||||
ret = devm_add_action_or_reset(dev, cc10001_reg_disable, adc_dev->reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
indio_dev->name = dev_name(dev);
|
||||
indio_dev->info = &cc10001_adc_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
adc_dev->reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(adc_dev->reg_base)) {
|
||||
ret = PTR_ERR(adc_dev->reg_base);
|
||||
goto err_disable_reg;
|
||||
}
|
||||
if (IS_ERR(adc_dev->reg_base))
|
||||
return PTR_ERR(adc_dev->reg_base);
|
||||
|
||||
adc_dev->adc_clk = devm_clk_get(&pdev->dev, "adc");
|
||||
adc_dev->adc_clk = devm_clk_get_enabled(dev, "adc");
|
||||
if (IS_ERR(adc_dev->adc_clk)) {
|
||||
dev_err(&pdev->dev, "failed to get the clock\n");
|
||||
ret = PTR_ERR(adc_dev->adc_clk);
|
||||
goto err_disable_reg;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(adc_dev->adc_clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to enable the clock\n");
|
||||
goto err_disable_reg;
|
||||
dev_err(dev, "failed to get/enable the clock\n");
|
||||
return PTR_ERR(adc_dev->adc_clk);
|
||||
}
|
||||
|
||||
adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
|
||||
if (!adc_clk_rate) {
|
||||
ret = -EINVAL;
|
||||
dev_err(&pdev->dev, "null clock rate!\n");
|
||||
goto err_disable_clk;
|
||||
dev_err(dev, "null clock rate!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
|
||||
@ -375,47 +380,22 @@ static int cc10001_adc_probe(struct platform_device *pdev)
|
||||
if (adc_dev->shared)
|
||||
cc10001_adc_power_up(adc_dev);
|
||||
|
||||
ret = devm_add_action_or_reset(dev, cc10001_pd_cb, adc_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* Setup the ADC channels available on the device */
|
||||
ret = cc10001_adc_channel_init(indio_dev, channel_map);
|
||||
if (ret < 0)
|
||||
goto err_disable_clk;
|
||||
return ret;
|
||||
|
||||
mutex_init(&adc_dev->lock);
|
||||
|
||||
ret = iio_triggered_buffer_setup(indio_dev, NULL,
|
||||
&cc10001_adc_trigger_h, NULL);
|
||||
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
|
||||
&cc10001_adc_trigger_h, NULL);
|
||||
if (ret < 0)
|
||||
goto err_disable_clk;
|
||||
return ret;
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret < 0)
|
||||
goto err_cleanup_buffer;
|
||||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_cleanup_buffer:
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
err_disable_clk:
|
||||
clk_disable_unprepare(adc_dev->adc_clk);
|
||||
err_disable_reg:
|
||||
regulator_disable(adc_dev->reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cc10001_adc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
|
||||
struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
|
||||
|
||||
cc10001_adc_power_down(adc_dev);
|
||||
iio_device_unregister(indio_dev);
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
clk_disable_unprepare(adc_dev->adc_clk);
|
||||
regulator_disable(adc_dev->reg);
|
||||
|
||||
return 0;
|
||||
return devm_iio_device_register(dev, indio_dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id cc10001_adc_dt_ids[] = {
|
||||
@ -430,7 +410,6 @@ static struct platform_driver cc10001_adc_driver = {
|
||||
.of_match_table = cc10001_adc_dt_ids,
|
||||
},
|
||||
.probe = cc10001_adc_probe,
|
||||
.remove = cc10001_adc_remove,
|
||||
};
|
||||
module_platform_driver(cc10001_adc_driver);
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
@ -108,7 +109,8 @@ struct imx7d_adc {
|
||||
struct device *dev;
|
||||
void __iomem *regs;
|
||||
struct clk *clk;
|
||||
|
||||
/* lock to protect against multiple access to the device */
|
||||
struct mutex lock;
|
||||
u32 vref_uv;
|
||||
u32 value;
|
||||
u32 channel;
|
||||
@ -293,7 +295,7 @@ static int imx7d_adc_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&info->lock);
|
||||
reinit_completion(&info->completion);
|
||||
|
||||
channel = chan->channel & 0x03;
|
||||
@ -303,16 +305,16 @@ static int imx7d_adc_read_raw(struct iio_dev *indio_dev,
|
||||
ret = wait_for_completion_interruptible_timeout
|
||||
(&info->completion, IMX7D_ADC_TIMEOUT);
|
||||
if (ret == 0) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&info->lock);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&info->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*val = info->value;
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&info->lock);
|
||||
return IIO_VAL_INT;
|
||||
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
@ -531,6 +533,8 @@ static int imx7d_adc_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_init(&info->lock);
|
||||
|
||||
ret = devm_iio_device_register(dev, indio_dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Couldn't register the device.\n");
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
@ -49,6 +50,8 @@ struct lpc32xx_adc_state {
|
||||
struct clk *clk;
|
||||
struct completion completion;
|
||||
struct regulator *vref;
|
||||
/* lock to protect against multiple access to the device */
|
||||
struct mutex lock;
|
||||
|
||||
u32 value;
|
||||
};
|
||||
@ -64,10 +67,10 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->lock);
|
||||
ret = clk_prepare_enable(st->clk);
|
||||
if (ret) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
return ret;
|
||||
}
|
||||
/* Measurement setup */
|
||||
@ -80,7 +83,7 @@ static int lpc32xx_read_raw(struct iio_dev *indio_dev,
|
||||
wait_for_completion(&st->completion); /* set by ISR */
|
||||
clk_disable_unprepare(st->clk);
|
||||
*val = st->value;
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
return IIO_VAL_INT;
|
||||
|
||||
@ -201,6 +204,8 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
|
||||
iodev->modes = INDIO_DIRECT_MODE;
|
||||
iodev->num_channels = ARRAY_SIZE(lpc32xx_adc_iio_channels);
|
||||
|
||||
mutex_init(&st->lock);
|
||||
|
||||
retval = devm_iio_device_register(&pdev->dev, iodev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/driver.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include "ltc2497.h"
|
||||
@ -81,9 +82,9 @@ static int ltc2497core_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&ddata->lock);
|
||||
ret = ltc2497core_read(ddata, chan->address, val);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&ddata->lock);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -214,6 +215,8 @@ int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev)
|
||||
ddata->addr_prev = LTC2497_CONFIG_DEFAULT;
|
||||
ddata->time_prev = ktime_get();
|
||||
|
||||
mutex_init(&ddata->lock);
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret < 0)
|
||||
goto err_array_unregister;
|
||||
|
@ -12,6 +12,8 @@ struct ltc2497_chip_info {
|
||||
struct ltc2497core_driverdata {
|
||||
struct regulator *ref;
|
||||
ktime_t time_prev;
|
||||
/* lock to protect against multiple access to the device */
|
||||
struct mutex lock;
|
||||
const struct ltc2497_chip_info *chip_info;
|
||||
u8 addr_prev;
|
||||
int (*result_and_measure)(struct ltc2497core_driverdata *ddata,
|
||||
|
1050
drivers/iio/adc/max11410.c
Normal file
1050
drivers/iio/adc/max11410.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,6 @@ enum max1241_id {
|
||||
struct max1241 {
|
||||
struct spi_device *spi;
|
||||
struct mutex lock;
|
||||
struct regulator *vdd;
|
||||
struct regulator *vref;
|
||||
struct gpio_desc *shutdown;
|
||||
|
||||
@ -110,17 +109,6 @@ static const struct iio_info max1241_info = {
|
||||
.read_raw = max1241_read_raw,
|
||||
};
|
||||
|
||||
static void max1241_disable_vdd_action(void *data)
|
||||
{
|
||||
struct max1241 *adc = data;
|
||||
struct device *dev = &adc->spi->dev;
|
||||
int err;
|
||||
|
||||
err = regulator_disable(adc->vdd);
|
||||
if (err)
|
||||
dev_err(dev, "could not disable vdd regulator.\n");
|
||||
}
|
||||
|
||||
static void max1241_disable_vref_action(void *data)
|
||||
{
|
||||
struct max1241 *adc = data;
|
||||
@ -147,20 +135,10 @@ static int max1241_probe(struct spi_device *spi)
|
||||
adc->spi = spi;
|
||||
mutex_init(&adc->lock);
|
||||
|
||||
adc->vdd = devm_regulator_get(dev, "vdd");
|
||||
if (IS_ERR(adc->vdd))
|
||||
return dev_err_probe(dev, PTR_ERR(adc->vdd),
|
||||
"failed to get vdd regulator\n");
|
||||
|
||||
ret = regulator_enable(adc->vdd);
|
||||
ret = devm_regulator_get_enable(dev, "vdd");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, max1241_disable_vdd_action, adc);
|
||||
if (ret) {
|
||||
dev_err(dev, "could not set up vdd regulator cleanup action\n");
|
||||
return ret;
|
||||
}
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to get/enable vdd regulator\n");
|
||||
|
||||
adc->vref = devm_regulator_get(dev, "vref");
|
||||
if (IS_ERR(adc->vref))
|
||||
|
@ -148,7 +148,6 @@ struct max1363_chip_info {
|
||||
* @chip_info: chip model specific constants, available modes, etc.
|
||||
* @current_mode: the scan mode of this chip
|
||||
* @requestedmask: a valid requested set of channels
|
||||
* @reg: supply regulator
|
||||
* @lock: lock to ensure state is consistent
|
||||
* @monitor_on: whether monitor mode is enabled
|
||||
* @monitor_speed: parameter corresponding to device monitor speed setting
|
||||
@ -168,7 +167,6 @@ struct max1363_state {
|
||||
const struct max1363_chip_info *chip_info;
|
||||
const struct max1363_mode *current_mode;
|
||||
u32 requestedmask;
|
||||
struct regulator *reg;
|
||||
struct mutex lock;
|
||||
|
||||
/* Using monitor modes and buffer at the same time is
|
||||
@ -1597,15 +1595,7 @@ static int max1363_probe(struct i2c_client *client,
|
||||
st = iio_priv(indio_dev);
|
||||
|
||||
mutex_init(&st->lock);
|
||||
st->reg = devm_regulator_get(&client->dev, "vcc");
|
||||
if (IS_ERR(st->reg))
|
||||
return PTR_ERR(st->reg);
|
||||
|
||||
ret = regulator_enable(st->reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(&client->dev, max1363_reg_disable, st->reg);
|
||||
ret = devm_regulator_get_enable(&client->dev, "vcc");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
#define MCP3911_REG_MOD 0x06
|
||||
#define MCP3911_REG_PHASE 0x07
|
||||
#define MCP3911_REG_GAIN 0x09
|
||||
#define MCP3911_GAIN_MASK(ch) (GENMASK(2, 0) << 3 * ch)
|
||||
#define MCP3911_GAIN_VAL(ch, val) ((val << 3 * ch) & MCP3911_GAIN_MASK(ch))
|
||||
|
||||
#define MCP3911_REG_STATUSCOM 0x0a
|
||||
#define MCP3911_STATUSCOM_DRHIZ BIT(12)
|
||||
@ -60,8 +62,10 @@
|
||||
#define MCP3911_REG_MASK GENMASK(4, 1)
|
||||
|
||||
#define MCP3911_NUM_CHANNELS 2
|
||||
#define MCP3911_NUM_SCALES 6
|
||||
|
||||
static const int mcp3911_osr_table[] = { 32, 64, 128, 256, 512, 1024, 2048, 4096 };
|
||||
static u32 mcp3911_scale_table[MCP3911_NUM_SCALES][2];
|
||||
|
||||
struct mcp3911 {
|
||||
struct spi_device *spi;
|
||||
@ -70,6 +74,7 @@ struct mcp3911 {
|
||||
struct clk *clki;
|
||||
u32 dev_addr;
|
||||
struct iio_trigger *trig;
|
||||
u32 gain[MCP3911_NUM_CHANNELS];
|
||||
struct {
|
||||
u32 channels[MCP3911_NUM_CHANNELS];
|
||||
s64 ts __aligned(8);
|
||||
@ -146,6 +151,11 @@ static int mcp3911_read_avail(struct iio_dev *indio_dev,
|
||||
*vals = mcp3911_osr_table;
|
||||
*length = ARRAY_SIZE(mcp3911_osr_table);
|
||||
return IIO_AVAIL_LIST;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*type = IIO_VAL_INT_PLUS_NANO;
|
||||
*vals = (int *)mcp3911_scale_table;
|
||||
*length = ARRAY_SIZE(mcp3911_scale_table) * 2;
|
||||
return IIO_AVAIL_LIST;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -190,29 +200,9 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
|
||||
break;
|
||||
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
if (adc->vref) {
|
||||
ret = regulator_get_voltage(adc->vref);
|
||||
if (ret < 0) {
|
||||
dev_err(indio_dev->dev.parent,
|
||||
"failed to get vref voltage: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
*val = ret / 1000;
|
||||
} else {
|
||||
*val = MCP3911_INT_VREF_MV;
|
||||
}
|
||||
|
||||
/*
|
||||
* For 24bit Conversion
|
||||
* Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
|
||||
* Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
|
||||
*/
|
||||
|
||||
/* val2 = (2^23 * 1.5) */
|
||||
*val2 = 12582912;
|
||||
ret = IIO_VAL_FRACTIONAL;
|
||||
*val = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][0];
|
||||
*val2 = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][1];
|
||||
ret = IIO_VAL_INT_PLUS_NANO;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -230,6 +220,18 @@ static int mcp3911_write_raw(struct iio_dev *indio_dev,
|
||||
|
||||
mutex_lock(&adc->lock);
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
for (int i = 0; i < MCP3911_NUM_SCALES; i++) {
|
||||
if (val == mcp3911_scale_table[i][0] &&
|
||||
val2 == mcp3911_scale_table[i][1]) {
|
||||
|
||||
adc->gain[channel->channel] = BIT(i);
|
||||
ret = mcp3911_update(adc, MCP3911_REG_GAIN,
|
||||
MCP3911_GAIN_MASK(channel->channel),
|
||||
MCP3911_GAIN_VAL(channel->channel, i), 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IIO_CHAN_INFO_OFFSET:
|
||||
if (val2 != 0) {
|
||||
ret = -EINVAL;
|
||||
@ -265,6 +267,44 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mcp3911_calc_scale_table(struct mcp3911 *adc)
|
||||
{
|
||||
u32 ref = MCP3911_INT_VREF_MV;
|
||||
u32 div;
|
||||
int ret;
|
||||
u64 tmp;
|
||||
|
||||
if (adc->vref) {
|
||||
ret = regulator_get_voltage(adc->vref);
|
||||
if (ret < 0) {
|
||||
dev_err(&adc->spi->dev,
|
||||
"failed to get vref voltage: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ref = ret / 1000;
|
||||
}
|
||||
|
||||
/*
|
||||
* For 24-bit Conversion
|
||||
* Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
|
||||
* Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
|
||||
*
|
||||
* ref = Reference voltage
|
||||
* div = (2^23 * 1.5 * gain) = 12582912 * gain
|
||||
*/
|
||||
for (int i = 0; i < MCP3911_NUM_SCALES; i++) {
|
||||
div = 12582912 * BIT(i);
|
||||
tmp = div_s64((s64)ref * 1000000000LL, div);
|
||||
|
||||
mcp3911_scale_table[i][0] = 0;
|
||||
mcp3911_scale_table[i][1] = tmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MCP3911_CHAN(idx) { \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.indexed = 1, \
|
||||
@ -274,8 +314,10 @@ out:
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
||||
BIT(IIO_CHAN_INFO_OFFSET) | \
|
||||
BIT(IIO_CHAN_INFO_SCALE), \
|
||||
.info_mask_shared_by_type_available = \
|
||||
.info_mask_shared_by_type_available = \
|
||||
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
|
||||
.info_mask_separate_available = \
|
||||
BIT(IIO_CHAN_INFO_SCALE), \
|
||||
.scan_type = { \
|
||||
.sign = 's', \
|
||||
.realbits = 24, \
|
||||
@ -482,6 +524,20 @@ static int mcp3911_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mcp3911_calc_scale_table(adc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set gain to 1 for all channels */
|
||||
for (int i = 0; i < MCP3911_NUM_CHANNELS; i++) {
|
||||
adc->gain[i] = 1;
|
||||
ret = mcp3911_update(adc, MCP3911_REG_GAIN,
|
||||
MCP3911_GAIN_MASK(i),
|
||||
MCP3911_GAIN_VAL(i, 0), 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
indio_dev->name = spi_get_device_id(spi)->name;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->info = &mcp3911_info;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of.h>
|
||||
@ -276,6 +277,8 @@ struct meson_sar_adc_priv {
|
||||
struct clk *adc_div_clk;
|
||||
struct clk_divider clk_div;
|
||||
struct completion done;
|
||||
/* lock to protect against multiple access to the device */
|
||||
struct mutex lock;
|
||||
int calibbias;
|
||||
int calibscale;
|
||||
struct regmap *tsc_regmap;
|
||||
@ -486,7 +489,7 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev)
|
||||
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
|
||||
int val, ret;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
if (priv->param->has_bl30_integration) {
|
||||
/* prevent BL30 from using the SAR ADC while we are using it */
|
||||
@ -504,7 +507,7 @@ static int meson_sar_adc_lock(struct iio_dev *indio_dev)
|
||||
!(val & MESON_SAR_ADC_DELAY_BL30_BUSY),
|
||||
1, 10000);
|
||||
if (ret) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&priv->lock);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -521,7 +524,7 @@ static void meson_sar_adc_unlock(struct iio_dev *indio_dev)
|
||||
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
|
||||
MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
|
||||
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&priv->lock);
|
||||
}
|
||||
|
||||
static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev)
|
||||
@ -1250,6 +1253,8 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
mutex_init(&priv->lock);
|
||||
|
||||
ret = meson_sar_adc_hw_enable(indio_dev);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
305
drivers/iio/adc/mt6370-adc.c
Normal file
305
drivers/iio/adc/mt6370-adc.c
Normal file
@ -0,0 +1,305 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2022 Richtek Technology Corp.
|
||||
*
|
||||
* Author: ChiaEn Wu <chiaen_wu@richtek.com>
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include <dt-bindings/iio/adc/mediatek,mt6370_adc.h>
|
||||
|
||||
#define MT6370_REG_CHG_CTRL3 0x113
|
||||
#define MT6370_REG_CHG_CTRL7 0x117
|
||||
#define MT6370_REG_CHG_ADC 0x121
|
||||
#define MT6370_REG_ADC_DATA_H 0x14C
|
||||
|
||||
#define MT6370_ADC_START_MASK BIT(0)
|
||||
#define MT6370_ADC_IN_SEL_MASK GENMASK(7, 4)
|
||||
#define MT6370_AICR_ICHG_MASK GENMASK(7, 2)
|
||||
|
||||
#define MT6370_AICR_100_mA 0x0
|
||||
#define MT6370_AICR_150_mA 0x1
|
||||
#define MT6370_AICR_200_mA 0x2
|
||||
#define MT6370_AICR_250_mA 0x3
|
||||
#define MT6370_AICR_300_mA 0x4
|
||||
#define MT6370_AICR_350_mA 0x5
|
||||
|
||||
#define MT6370_ICHG_100_mA 0x0
|
||||
#define MT6370_ICHG_200_mA 0x1
|
||||
#define MT6370_ICHG_300_mA 0x2
|
||||
#define MT6370_ICHG_400_mA 0x3
|
||||
#define MT6370_ICHG_500_mA 0x4
|
||||
#define MT6370_ICHG_600_mA 0x5
|
||||
#define MT6370_ICHG_700_mA 0x6
|
||||
#define MT6370_ICHG_800_mA 0x7
|
||||
|
||||
#define ADC_CONV_TIME_MS 35
|
||||
#define ADC_CONV_POLLING_TIME_US 1000
|
||||
|
||||
struct mt6370_adc_data {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
/*
|
||||
* This mutex lock is for preventing the different ADC channels
|
||||
* from being read at the same time.
|
||||
*/
|
||||
struct mutex adc_lock;
|
||||
};
|
||||
|
||||
static int mt6370_adc_read_channel(struct mt6370_adc_data *priv, int chan,
|
||||
unsigned long addr, int *val)
|
||||
{
|
||||
unsigned int reg_val;
|
||||
__be16 be_val;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&priv->adc_lock);
|
||||
|
||||
reg_val = MT6370_ADC_START_MASK |
|
||||
FIELD_PREP(MT6370_ADC_IN_SEL_MASK, addr);
|
||||
ret = regmap_write(priv->regmap, MT6370_REG_CHG_ADC, reg_val);
|
||||
if (ret)
|
||||
goto adc_unlock;
|
||||
|
||||
msleep(ADC_CONV_TIME_MS);
|
||||
|
||||
ret = regmap_read_poll_timeout(priv->regmap,
|
||||
MT6370_REG_CHG_ADC, reg_val,
|
||||
!(reg_val & MT6370_ADC_START_MASK),
|
||||
ADC_CONV_POLLING_TIME_US,
|
||||
ADC_CONV_TIME_MS * MILLI * 3);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "Failed to read ADC register (%d)\n", ret);
|
||||
goto adc_unlock;
|
||||
}
|
||||
|
||||
ret = regmap_raw_read(priv->regmap, MT6370_REG_ADC_DATA_H,
|
||||
&be_val, sizeof(be_val));
|
||||
if (ret)
|
||||
goto adc_unlock;
|
||||
|
||||
*val = be16_to_cpu(be_val);
|
||||
ret = IIO_VAL_INT;
|
||||
|
||||
adc_unlock:
|
||||
mutex_unlock(&priv->adc_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mt6370_adc_read_scale(struct mt6370_adc_data *priv,
|
||||
int chan, int *val1, int *val2)
|
||||
{
|
||||
unsigned int reg_val;
|
||||
int ret;
|
||||
|
||||
switch (chan) {
|
||||
case MT6370_CHAN_VBAT:
|
||||
case MT6370_CHAN_VSYS:
|
||||
case MT6370_CHAN_CHG_VDDP:
|
||||
*val1 = 5;
|
||||
return IIO_VAL_INT;
|
||||
case MT6370_CHAN_IBUS:
|
||||
ret = regmap_read(priv->regmap, MT6370_REG_CHG_CTRL3, ®_val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reg_val = FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val);
|
||||
switch (reg_val) {
|
||||
case MT6370_AICR_100_mA:
|
||||
case MT6370_AICR_150_mA:
|
||||
case MT6370_AICR_200_mA:
|
||||
case MT6370_AICR_250_mA:
|
||||
case MT6370_AICR_300_mA:
|
||||
case MT6370_AICR_350_mA:
|
||||
*val1 = 3350;
|
||||
break;
|
||||
default:
|
||||
*val1 = 5000;
|
||||
break;
|
||||
}
|
||||
|
||||
*val2 = 100;
|
||||
|
||||
return IIO_VAL_FRACTIONAL;
|
||||
case MT6370_CHAN_IBAT:
|
||||
ret = regmap_read(priv->regmap, MT6370_REG_CHG_CTRL7, ®_val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reg_val = FIELD_GET(MT6370_AICR_ICHG_MASK, reg_val);
|
||||
switch (reg_val) {
|
||||
case MT6370_ICHG_100_mA:
|
||||
case MT6370_ICHG_200_mA:
|
||||
case MT6370_ICHG_300_mA:
|
||||
case MT6370_ICHG_400_mA:
|
||||
*val1 = 2375;
|
||||
break;
|
||||
case MT6370_ICHG_500_mA:
|
||||
case MT6370_ICHG_600_mA:
|
||||
case MT6370_ICHG_700_mA:
|
||||
case MT6370_ICHG_800_mA:
|
||||
*val1 = 2680;
|
||||
break;
|
||||
default:
|
||||
*val1 = 5000;
|
||||
break;
|
||||
}
|
||||
|
||||
*val2 = 100;
|
||||
|
||||
return IIO_VAL_FRACTIONAL;
|
||||
case MT6370_CHAN_VBUSDIV5:
|
||||
*val1 = 25;
|
||||
return IIO_VAL_INT;
|
||||
case MT6370_CHAN_VBUSDIV2:
|
||||
*val1 = 10;
|
||||
return IIO_VAL_INT;
|
||||
case MT6370_CHAN_TS_BAT:
|
||||
*val1 = 25;
|
||||
*val2 = 10000;
|
||||
return IIO_VAL_FRACTIONAL;
|
||||
case MT6370_CHAN_TEMP_JC:
|
||||
*val1 = 2000;
|
||||
return IIO_VAL_INT;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int mt6370_adc_read_offset(struct mt6370_adc_data *priv,
|
||||
int chan, int *val)
|
||||
{
|
||||
*val = -20;
|
||||
|
||||
return IIO_VAL_INT;
|
||||
}
|
||||
|
||||
static int mt6370_adc_read_raw(struct iio_dev *iio_dev,
|
||||
const struct iio_chan_spec *chan,
|
||||
int *val, int *val2, long mask)
|
||||
{
|
||||
struct mt6370_adc_data *priv = iio_priv(iio_dev);
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
return mt6370_adc_read_channel(priv, chan->channel,
|
||||
chan->address, val);
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
return mt6370_adc_read_scale(priv, chan->channel, val, val2);
|
||||
case IIO_CHAN_INFO_OFFSET:
|
||||
return mt6370_adc_read_offset(priv, chan->channel, val);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static const char * const mt6370_channel_labels[MT6370_CHAN_MAX] = {
|
||||
[MT6370_CHAN_VBUSDIV5] = "vbusdiv5",
|
||||
[MT6370_CHAN_VBUSDIV2] = "vbusdiv2",
|
||||
[MT6370_CHAN_VSYS] = "vsys",
|
||||
[MT6370_CHAN_VBAT] = "vbat",
|
||||
[MT6370_CHAN_TS_BAT] = "ts_bat",
|
||||
[MT6370_CHAN_IBUS] = "ibus",
|
||||
[MT6370_CHAN_IBAT] = "ibat",
|
||||
[MT6370_CHAN_CHG_VDDP] = "chg_vddp",
|
||||
[MT6370_CHAN_TEMP_JC] = "temp_jc",
|
||||
};
|
||||
|
||||
static int mt6370_adc_read_label(struct iio_dev *iio_dev,
|
||||
struct iio_chan_spec const *chan, char *label)
|
||||
{
|
||||
return sysfs_emit(label, "%s\n", mt6370_channel_labels[chan->channel]);
|
||||
}
|
||||
|
||||
static const struct iio_info mt6370_adc_iio_info = {
|
||||
.read_raw = mt6370_adc_read_raw,
|
||||
.read_label = mt6370_adc_read_label,
|
||||
};
|
||||
|
||||
#define MT6370_ADC_CHAN(_idx, _type, _addr, _extra_info) { \
|
||||
.type = _type, \
|
||||
.channel = MT6370_CHAN_##_idx, \
|
||||
.address = _addr, \
|
||||
.scan_index = MT6370_CHAN_##_idx, \
|
||||
.indexed = 1, \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
||||
BIT(IIO_CHAN_INFO_SCALE) | \
|
||||
_extra_info, \
|
||||
}
|
||||
|
||||
static const struct iio_chan_spec mt6370_adc_channels[] = {
|
||||
MT6370_ADC_CHAN(VBUSDIV5, IIO_VOLTAGE, 1, 0),
|
||||
MT6370_ADC_CHAN(VBUSDIV2, IIO_VOLTAGE, 2, 0),
|
||||
MT6370_ADC_CHAN(VSYS, IIO_VOLTAGE, 3, 0),
|
||||
MT6370_ADC_CHAN(VBAT, IIO_VOLTAGE, 4, 0),
|
||||
MT6370_ADC_CHAN(TS_BAT, IIO_VOLTAGE, 6, 0),
|
||||
MT6370_ADC_CHAN(IBUS, IIO_CURRENT, 8, 0),
|
||||
MT6370_ADC_CHAN(IBAT, IIO_CURRENT, 9, 0),
|
||||
MT6370_ADC_CHAN(CHG_VDDP, IIO_VOLTAGE, 11, 0),
|
||||
MT6370_ADC_CHAN(TEMP_JC, IIO_TEMP, 12, BIT(IIO_CHAN_INFO_OFFSET)),
|
||||
};
|
||||
|
||||
static int mt6370_adc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct mt6370_adc_data *priv;
|
||||
struct iio_dev *indio_dev;
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
if (!regmap)
|
||||
return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n");
|
||||
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
priv = iio_priv(indio_dev);
|
||||
priv->dev = dev;
|
||||
priv->regmap = regmap;
|
||||
mutex_init(&priv->adc_lock);
|
||||
|
||||
ret = regmap_write(priv->regmap, MT6370_REG_CHG_ADC, 0);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to reset ADC\n");
|
||||
|
||||
indio_dev->name = "mt6370-adc";
|
||||
indio_dev->info = &mt6370_adc_iio_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->channels = mt6370_adc_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(mt6370_adc_channels);
|
||||
|
||||
return devm_iio_device_register(dev, indio_dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id mt6370_adc_of_id[] = {
|
||||
{ .compatible = "mediatek,mt6370-adc", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mt6370_adc_of_id);
|
||||
|
||||
static struct platform_driver mt6370_adc_driver = {
|
||||
.driver = {
|
||||
.name = "mt6370-adc",
|
||||
.of_match_table = mt6370_adc_of_id,
|
||||
},
|
||||
.probe = mt6370_adc_probe,
|
||||
};
|
||||
module_platform_driver(mt6370_adc_driver);
|
||||
|
||||
MODULE_AUTHOR("ChiaEn Wu <chiaen_wu@richtek.com>");
|
||||
MODULE_DESCRIPTION("MT6370 ADC Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
@ -49,6 +50,8 @@ struct rockchip_saradc {
|
||||
struct clk *clk;
|
||||
struct completion completion;
|
||||
struct regulator *vref;
|
||||
/* lock to protect against multiple access to the device */
|
||||
struct mutex lock;
|
||||
int uv_vref;
|
||||
struct reset_control *reset;
|
||||
const struct rockchip_saradc_data *data;
|
||||
@ -94,17 +97,17 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&info->lock);
|
||||
|
||||
ret = rockchip_saradc_conversion(info, chan);
|
||||
if (ret) {
|
||||
rockchip_saradc_power_down(info);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&info->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*val = info->last_val;
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&info->lock);
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = info->uv_vref / 1000;
|
||||
@ -270,7 +273,7 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p)
|
||||
int ret;
|
||||
int i, j = 0;
|
||||
|
||||
mutex_lock(&i_dev->mlock);
|
||||
mutex_lock(&info->lock);
|
||||
|
||||
for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength) {
|
||||
const struct iio_chan_spec *chan = &i_dev->channels[i];
|
||||
@ -287,7 +290,7 @@ static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p)
|
||||
|
||||
iio_push_to_buffers_with_timestamp(i_dev, &data, iio_get_time_ns(i_dev));
|
||||
out:
|
||||
mutex_unlock(&i_dev->mlock);
|
||||
mutex_unlock(&info->lock);
|
||||
|
||||
iio_trigger_notify_done(i_dev->trig);
|
||||
|
||||
@ -478,6 +481,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_init(&info->lock);
|
||||
|
||||
return devm_iio_device_register(&pdev->dev, indio_dev);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <linux/hwspinlock.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
@ -83,6 +84,8 @@ struct sc27xx_adc_data {
|
||||
struct device *dev;
|
||||
struct regulator *volref;
|
||||
struct regmap *regmap;
|
||||
/* lock to protect against multiple access to the device */
|
||||
struct mutex lock;
|
||||
/*
|
||||
* One hardware spinlock to synchronize between the multiple
|
||||
* subsystems which will access the unique ADC controller.
|
||||
@ -664,9 +667,9 @@ static int sc27xx_adc_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&data->lock);
|
||||
ret = sc27xx_adc_read(data, chan->channel, scale, &tmp);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -675,10 +678,10 @@ static int sc27xx_adc_read_raw(struct iio_dev *indio_dev,
|
||||
return IIO_VAL_INT;
|
||||
|
||||
case IIO_CHAN_INFO_PROCESSED:
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&data->lock);
|
||||
ret = sc27xx_adc_read_processed(data, chan->channel, scale,
|
||||
&tmp);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -934,6 +937,9 @@ static int sc27xx_adc_probe(struct platform_device *pdev)
|
||||
indio_dev->info = &sc27xx_info;
|
||||
indio_dev->channels = sc27xx_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(sc27xx_channels);
|
||||
|
||||
mutex_init(&sc27xx_data->lock);
|
||||
|
||||
ret = devm_iio_device_register(dev, indio_dev);
|
||||
if (ret)
|
||||
dev_err(dev, "could not register iio (ADC)");
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include "stm32-adc-core.h"
|
||||
|
||||
@ -306,8 +307,8 @@ out:
|
||||
static const struct stm32_adc_common_regs stm32f4_adc_common_regs = {
|
||||
.csr = STM32F4_ADC_CSR,
|
||||
.ccr = STM32F4_ADC_CCR,
|
||||
.eoc_msk = { STM32F4_EOC1, STM32F4_EOC2, STM32F4_EOC3},
|
||||
.ovr_msk = { STM32F4_OVR1, STM32F4_OVR2, STM32F4_OVR3},
|
||||
.eoc_msk = { STM32F4_EOC1, STM32F4_EOC2, STM32F4_EOC3 },
|
||||
.ovr_msk = { STM32F4_OVR1, STM32F4_OVR2, STM32F4_OVR3 },
|
||||
.ier = STM32F4_ADC_CR1,
|
||||
.eocie_msk = STM32F4_EOCIE,
|
||||
};
|
||||
@ -316,8 +317,18 @@ static const struct stm32_adc_common_regs stm32f4_adc_common_regs = {
|
||||
static const struct stm32_adc_common_regs stm32h7_adc_common_regs = {
|
||||
.csr = STM32H7_ADC_CSR,
|
||||
.ccr = STM32H7_ADC_CCR,
|
||||
.eoc_msk = { STM32H7_EOC_MST, STM32H7_EOC_SLV},
|
||||
.ovr_msk = { STM32H7_OVR_MST, STM32H7_OVR_SLV},
|
||||
.eoc_msk = { STM32H7_EOC_MST, STM32H7_EOC_SLV },
|
||||
.ovr_msk = { STM32H7_OVR_MST, STM32H7_OVR_SLV },
|
||||
.ier = STM32H7_ADC_IER,
|
||||
.eocie_msk = STM32H7_EOCIE,
|
||||
};
|
||||
|
||||
/* STM32MP13 common registers definitions */
|
||||
static const struct stm32_adc_common_regs stm32mp13_adc_common_regs = {
|
||||
.csr = STM32H7_ADC_CSR,
|
||||
.ccr = STM32H7_ADC_CCR,
|
||||
.eoc_msk = { STM32H7_EOC_MST },
|
||||
.ovr_msk = { STM32H7_OVR_MST },
|
||||
.ier = STM32H7_ADC_IER,
|
||||
.eocie_msk = STM32H7_EOCIE,
|
||||
};
|
||||
@ -868,6 +879,14 @@ static const struct stm32_adc_priv_cfg stm32mp1_adc_priv_cfg = {
|
||||
.num_irqs = 2,
|
||||
};
|
||||
|
||||
static const struct stm32_adc_priv_cfg stm32mp13_adc_priv_cfg = {
|
||||
.regs = &stm32mp13_adc_common_regs,
|
||||
.clk_sel = stm32h7_adc_clk_sel,
|
||||
.max_clk_rate_hz = 75 * HZ_PER_MHZ,
|
||||
.ipid = STM32MP13_IPIDR_NUMBER,
|
||||
.num_irqs = 1,
|
||||
};
|
||||
|
||||
static const struct of_device_id stm32_adc_of_match[] = {
|
||||
{
|
||||
.compatible = "st,stm32f4-adc-core",
|
||||
@ -878,6 +897,9 @@ static const struct of_device_id stm32_adc_of_match[] = {
|
||||
}, {
|
||||
.compatible = "st,stm32mp1-adc-core",
|
||||
.data = (void *)&stm32mp1_adc_priv_cfg
|
||||
}, {
|
||||
.compatible = "st,stm32mp13-adc-core",
|
||||
.data = (void *)&stm32mp13_adc_priv_cfg
|
||||
}, {
|
||||
},
|
||||
};
|
||||
|
@ -112,6 +112,11 @@
|
||||
#define STM32MP1_ADC_IPDR 0x3F8
|
||||
#define STM32MP1_ADC_SIDR 0x3FC
|
||||
|
||||
/* STM32MP13 - Registers for each ADC instance */
|
||||
#define STM32MP13_ADC_DIFSEL 0xB0
|
||||
#define STM32MP13_ADC_CALFACT 0xB4
|
||||
#define STM32MP13_ADC2_OR 0xC8
|
||||
|
||||
/* STM32H7 - common registers for all ADC instances */
|
||||
#define STM32H7_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00)
|
||||
#define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08)
|
||||
@ -161,6 +166,9 @@ enum stm32h7_adc_dmngt {
|
||||
STM32H7_DMNGT_DMA_CIRC, /* DMA circular mode */
|
||||
};
|
||||
|
||||
/* STM32H7_ADC_DIFSEL - bit fields */
|
||||
#define STM32H7_DIFSEL_MASK GENMASK(19, 0)
|
||||
|
||||
/* STM32H7_ADC_CALFACT - bit fields */
|
||||
#define STM32H7_CALFACT_D_SHIFT 16
|
||||
#define STM32H7_CALFACT_D_MASK GENMASK(26, 16)
|
||||
@ -210,7 +218,29 @@ enum stm32h7_adc_dmngt {
|
||||
/* STM32MP1_ADC_SIDR - bit fields */
|
||||
#define STM32MP1_SIDR_MASK GENMASK(31, 0)
|
||||
|
||||
/* STM32MP13_ADC_CFGR specific bit fields */
|
||||
#define STM32MP13_DMAEN BIT(0)
|
||||
#define STM32MP13_DMACFG BIT(1)
|
||||
#define STM32MP13_DFSDMCFG BIT(2)
|
||||
#define STM32MP13_RES_SHIFT 3
|
||||
#define STM32MP13_RES_MASK GENMASK(4, 3)
|
||||
|
||||
/* STM32MP13_ADC_DIFSEL - bit fields */
|
||||
#define STM32MP13_DIFSEL_MASK GENMASK(18, 0)
|
||||
|
||||
/* STM32MP13_ADC_CALFACT - bit fields */
|
||||
#define STM32MP13_CALFACT_D_SHIFT 16
|
||||
#define STM32MP13_CALFACT_D_MASK GENMASK(22, 16)
|
||||
#define STM32MP13_CALFACT_S_SHIFT 0
|
||||
#define STM32MP13_CALFACT_S_MASK GENMASK(6, 0)
|
||||
|
||||
/* STM32MP13_ADC2_OR - bit fields */
|
||||
#define STM32MP13_OP2 BIT(2)
|
||||
#define STM32MP13_OP1 BIT(1)
|
||||
#define STM32MP13_OP0 BIT(0)
|
||||
|
||||
#define STM32MP15_IPIDR_NUMBER 0x00110005
|
||||
#define STM32MP13_IPIDR_NUMBER 0x00110006
|
||||
|
||||
/**
|
||||
* struct stm32_adc_common - stm32 ADC driver common data (for all instances)
|
||||
|
@ -82,6 +82,8 @@ enum stm32_adc_extsel {
|
||||
enum stm32_adc_int_ch {
|
||||
STM32_ADC_INT_CH_NONE = -1,
|
||||
STM32_ADC_INT_CH_VDDCORE,
|
||||
STM32_ADC_INT_CH_VDDCPU,
|
||||
STM32_ADC_INT_CH_VDDQ_DDR,
|
||||
STM32_ADC_INT_CH_VREFINT,
|
||||
STM32_ADC_INT_CH_VBAT,
|
||||
STM32_ADC_INT_CH_NB,
|
||||
@ -99,6 +101,8 @@ struct stm32_adc_ic {
|
||||
|
||||
static const struct stm32_adc_ic stm32_adc_ic[STM32_ADC_INT_CH_NB] = {
|
||||
{ "vddcore", STM32_ADC_INT_CH_VDDCORE },
|
||||
{ "vddcpu", STM32_ADC_INT_CH_VDDCPU },
|
||||
{ "vddq_ddr", STM32_ADC_INT_CH_VDDQ_DDR },
|
||||
{ "vrefint", STM32_ADC_INT_CH_VREFINT },
|
||||
{ "vbat", STM32_ADC_INT_CH_VBAT },
|
||||
};
|
||||
@ -160,9 +164,14 @@ struct stm32_adc_vrefint {
|
||||
* @exten: trigger control register & bitfield
|
||||
* @extsel: trigger selection register & bitfield
|
||||
* @res: resolution selection register & bitfield
|
||||
* @difsel: differential mode selection register & bitfield
|
||||
* @calfact_s: single-ended calibration factors register & bitfield
|
||||
* @calfact_d: differential calibration factors register & bitfield
|
||||
* @smpr: smpr1 & smpr2 registers offset array
|
||||
* @smp_bits: smpr1 & smpr2 index and bitfields
|
||||
* @or_vdd: option register & vddcore bitfield
|
||||
* @or_vddcore: option register & vddcore bitfield
|
||||
* @or_vddcpu: option register & vddcpu bitfield
|
||||
* @or_vddq_ddr: option register & vddq_ddr bitfield
|
||||
* @ccr_vbat: common register & vbat bitfield
|
||||
* @ccr_vref: common register & vrefint bitfield
|
||||
*/
|
||||
@ -176,9 +185,14 @@ struct stm32_adc_regspec {
|
||||
const struct stm32_adc_regs exten;
|
||||
const struct stm32_adc_regs extsel;
|
||||
const struct stm32_adc_regs res;
|
||||
const struct stm32_adc_regs difsel;
|
||||
const struct stm32_adc_regs calfact_s;
|
||||
const struct stm32_adc_regs calfact_d;
|
||||
const u32 smpr[2];
|
||||
const struct stm32_adc_regs *smp_bits;
|
||||
const struct stm32_adc_regs or_vdd;
|
||||
const struct stm32_adc_regs or_vddcore;
|
||||
const struct stm32_adc_regs or_vddcpu;
|
||||
const struct stm32_adc_regs or_vddq_ddr;
|
||||
const struct stm32_adc_regs ccr_vbat;
|
||||
const struct stm32_adc_regs ccr_vref;
|
||||
};
|
||||
@ -192,13 +206,16 @@ struct stm32_adc;
|
||||
* @trigs: external trigger sources
|
||||
* @clk_required: clock is required
|
||||
* @has_vregready: vregready status flag presence
|
||||
* @has_boostmode: boost mode support flag
|
||||
* @has_linearcal: linear calibration support flag
|
||||
* @has_presel: channel preselection support flag
|
||||
* @prepare: optional prepare routine (power-up, enable)
|
||||
* @start_conv: routine to start conversions
|
||||
* @stop_conv: routine to stop conversions
|
||||
* @unprepare: optional unprepare routine (disable, power-down)
|
||||
* @irq_clear: routine to clear irqs
|
||||
* @smp_cycles: programmable sampling time (ADC clock cycles)
|
||||
* @ts_vrefint_ns: vrefint minimum sampling time in ns
|
||||
* @ts_int_ch: pointer to array of internal channels minimum sampling time in ns
|
||||
*/
|
||||
struct stm32_adc_cfg {
|
||||
const struct stm32_adc_regspec *regs;
|
||||
@ -206,13 +223,16 @@ struct stm32_adc_cfg {
|
||||
struct stm32_adc_trig_info *trigs;
|
||||
bool clk_required;
|
||||
bool has_vregready;
|
||||
bool has_boostmode;
|
||||
bool has_linearcal;
|
||||
bool has_presel;
|
||||
int (*prepare)(struct iio_dev *);
|
||||
void (*start_conv)(struct iio_dev *, bool dma);
|
||||
void (*stop_conv)(struct iio_dev *);
|
||||
void (*unprepare)(struct iio_dev *);
|
||||
void (*irq_clear)(struct iio_dev *indio_dev, u32 msk);
|
||||
const unsigned int *smp_cycles;
|
||||
const unsigned int ts_vrefint_ns;
|
||||
const unsigned int *ts_int_ch;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -312,6 +332,13 @@ static const struct stm32_adc_info stm32h7_adc_info = {
|
||||
.num_res = ARRAY_SIZE(stm32h7_adc_resolutions),
|
||||
};
|
||||
|
||||
/* stm32mp13 can have up to 19 channels */
|
||||
static const struct stm32_adc_info stm32mp13_adc_info = {
|
||||
.max_channels = 19,
|
||||
.resolutions = stm32f4_adc_resolutions,
|
||||
.num_res = ARRAY_SIZE(stm32f4_adc_resolutions),
|
||||
};
|
||||
|
||||
/*
|
||||
* stm32f4_sq - describe regular sequence registers
|
||||
* - L: sequence len (register & bit field)
|
||||
@ -497,10 +524,45 @@ static const struct stm32_adc_regspec stm32h7_adc_regspec = {
|
||||
.extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK,
|
||||
STM32H7_EXTSEL_SHIFT },
|
||||
.res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT },
|
||||
.difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK},
|
||||
.calfact_s = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_S_MASK,
|
||||
STM32H7_CALFACT_S_SHIFT },
|
||||
.calfact_d = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_D_MASK,
|
||||
STM32H7_CALFACT_D_SHIFT },
|
||||
.smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 },
|
||||
.smp_bits = stm32h7_smp_bits,
|
||||
};
|
||||
|
||||
/* STM32MP13 programmable sampling time (ADC clock cycles, rounded down) */
|
||||
static const unsigned int stm32mp13_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = {
|
||||
2, 6, 12, 24, 47, 92, 247, 640,
|
||||
};
|
||||
|
||||
static const struct stm32_adc_regspec stm32mp13_adc_regspec = {
|
||||
.dr = STM32H7_ADC_DR,
|
||||
.ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE },
|
||||
.ier_ovr = { STM32H7_ADC_IER, STM32H7_OVRIE },
|
||||
.isr_eoc = { STM32H7_ADC_ISR, STM32H7_EOC },
|
||||
.isr_ovr = { STM32H7_ADC_ISR, STM32H7_OVR },
|
||||
.sqr = stm32h7_sq,
|
||||
.exten = { STM32H7_ADC_CFGR, STM32H7_EXTEN_MASK, STM32H7_EXTEN_SHIFT },
|
||||
.extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK,
|
||||
STM32H7_EXTSEL_SHIFT },
|
||||
.res = { STM32H7_ADC_CFGR, STM32MP13_RES_MASK, STM32MP13_RES_SHIFT },
|
||||
.difsel = { STM32MP13_ADC_DIFSEL, STM32MP13_DIFSEL_MASK},
|
||||
.calfact_s = { STM32MP13_ADC_CALFACT, STM32MP13_CALFACT_S_MASK,
|
||||
STM32MP13_CALFACT_S_SHIFT },
|
||||
.calfact_d = { STM32MP13_ADC_CALFACT, STM32MP13_CALFACT_D_MASK,
|
||||
STM32MP13_CALFACT_D_SHIFT },
|
||||
.smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 },
|
||||
.smp_bits = stm32h7_smp_bits,
|
||||
.or_vddcore = { STM32MP13_ADC2_OR, STM32MP13_OP0 },
|
||||
.or_vddcpu = { STM32MP13_ADC2_OR, STM32MP13_OP1 },
|
||||
.or_vddq_ddr = { STM32MP13_ADC2_OR, STM32MP13_OP2 },
|
||||
.ccr_vbat = { STM32H7_ADC_CCR, STM32H7_VBATEN },
|
||||
.ccr_vref = { STM32H7_ADC_CCR, STM32H7_VREFEN },
|
||||
};
|
||||
|
||||
static const struct stm32_adc_regspec stm32mp1_adc_regspec = {
|
||||
.dr = STM32H7_ADC_DR,
|
||||
.ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE },
|
||||
@ -512,9 +574,14 @@ static const struct stm32_adc_regspec stm32mp1_adc_regspec = {
|
||||
.extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK,
|
||||
STM32H7_EXTSEL_SHIFT },
|
||||
.res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT },
|
||||
.difsel = { STM32H7_ADC_DIFSEL, STM32H7_DIFSEL_MASK},
|
||||
.calfact_s = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_S_MASK,
|
||||
STM32H7_CALFACT_S_SHIFT },
|
||||
.calfact_d = { STM32H7_ADC_CALFACT, STM32H7_CALFACT_D_MASK,
|
||||
STM32H7_CALFACT_D_SHIFT },
|
||||
.smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 },
|
||||
.smp_bits = stm32h7_smp_bits,
|
||||
.or_vdd = { STM32MP1_ADC2_OR, STM32MP1_VDDCOREEN },
|
||||
.or_vddcore = { STM32MP1_ADC2_OR, STM32MP1_VDDCOREEN },
|
||||
.ccr_vbat = { STM32H7_ADC_CCR, STM32H7_VBATEN },
|
||||
.ccr_vref = { STM32H7_ADC_CCR, STM32H7_VREFEN },
|
||||
};
|
||||
@ -675,8 +742,18 @@ static void stm32_adc_int_ch_enable(struct iio_dev *indio_dev)
|
||||
switch (i) {
|
||||
case STM32_ADC_INT_CH_VDDCORE:
|
||||
dev_dbg(&indio_dev->dev, "Enable VDDCore\n");
|
||||
stm32_adc_set_bits(adc, adc->cfg->regs->or_vdd.reg,
|
||||
adc->cfg->regs->or_vdd.mask);
|
||||
stm32_adc_set_bits(adc, adc->cfg->regs->or_vddcore.reg,
|
||||
adc->cfg->regs->or_vddcore.mask);
|
||||
break;
|
||||
case STM32_ADC_INT_CH_VDDCPU:
|
||||
dev_dbg(&indio_dev->dev, "Enable VDDCPU\n");
|
||||
stm32_adc_set_bits(adc, adc->cfg->regs->or_vddcpu.reg,
|
||||
adc->cfg->regs->or_vddcpu.mask);
|
||||
break;
|
||||
case STM32_ADC_INT_CH_VDDQ_DDR:
|
||||
dev_dbg(&indio_dev->dev, "Enable VDDQ_DDR\n");
|
||||
stm32_adc_set_bits(adc, adc->cfg->regs->or_vddq_ddr.reg,
|
||||
adc->cfg->regs->or_vddq_ddr.mask);
|
||||
break;
|
||||
case STM32_ADC_INT_CH_VREFINT:
|
||||
dev_dbg(&indio_dev->dev, "Enable VREFInt\n");
|
||||
@ -702,8 +779,16 @@ static void stm32_adc_int_ch_disable(struct stm32_adc *adc)
|
||||
|
||||
switch (i) {
|
||||
case STM32_ADC_INT_CH_VDDCORE:
|
||||
stm32_adc_clr_bits(adc, adc->cfg->regs->or_vdd.reg,
|
||||
adc->cfg->regs->or_vdd.mask);
|
||||
stm32_adc_clr_bits(adc, adc->cfg->regs->or_vddcore.reg,
|
||||
adc->cfg->regs->or_vddcore.mask);
|
||||
break;
|
||||
case STM32_ADC_INT_CH_VDDCPU:
|
||||
stm32_adc_clr_bits(adc, adc->cfg->regs->or_vddcpu.reg,
|
||||
adc->cfg->regs->or_vddcpu.mask);
|
||||
break;
|
||||
case STM32_ADC_INT_CH_VDDQ_DDR:
|
||||
stm32_adc_clr_bits(adc, adc->cfg->regs->or_vddq_ddr.reg,
|
||||
adc->cfg->regs->or_vddq_ddr.mask);
|
||||
break;
|
||||
case STM32_ADC_INT_CH_VREFINT:
|
||||
stm32_adc_clr_bits_common(adc, adc->cfg->regs->ccr_vref.reg,
|
||||
@ -801,6 +886,7 @@ static void stm32h7_adc_stop_conv(struct iio_dev *indio_dev)
|
||||
if (ret)
|
||||
dev_warn(&indio_dev->dev, "stop failed\n");
|
||||
|
||||
/* STM32H7_DMNGT_MASK covers STM32MP13_DMAEN & STM32MP13_DMACFG */
|
||||
stm32_adc_clr_bits(adc, STM32H7_ADC_CFGR, STM32H7_DMNGT_MASK);
|
||||
}
|
||||
|
||||
@ -811,6 +897,17 @@ static void stm32h7_adc_irq_clear(struct iio_dev *indio_dev, u32 msk)
|
||||
stm32_adc_set_bits(adc, adc->cfg->regs->isr_eoc.reg, msk);
|
||||
}
|
||||
|
||||
static void stm32mp13_adc_start_conv(struct iio_dev *indio_dev, bool dma)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
|
||||
if (dma)
|
||||
stm32_adc_set_bits(adc, STM32H7_ADC_CFGR,
|
||||
STM32MP13_DMAEN | STM32MP13_DMACFG);
|
||||
|
||||
stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADSTART);
|
||||
}
|
||||
|
||||
static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
@ -821,7 +918,8 @@ static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev)
|
||||
stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_DEEPPWD);
|
||||
stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADVREGEN);
|
||||
|
||||
if (adc->common->rate > STM32H7_BOOST_CLKRATE)
|
||||
if (adc->cfg->has_boostmode &&
|
||||
adc->common->rate > STM32H7_BOOST_CLKRATE)
|
||||
stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST);
|
||||
|
||||
/* Wait for startup time */
|
||||
@ -843,7 +941,8 @@ static int stm32h7_adc_exit_pwr_down(struct iio_dev *indio_dev)
|
||||
|
||||
static void stm32h7_adc_enter_pwr_down(struct stm32_adc *adc)
|
||||
{
|
||||
stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST);
|
||||
if (adc->cfg->has_boostmode)
|
||||
stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_BOOST);
|
||||
|
||||
/* Setting DEEPPWD disables ADC vreg and clears ADVREGEN */
|
||||
stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_DEEPPWD);
|
||||
@ -901,6 +1000,9 @@ static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev)
|
||||
int i, ret;
|
||||
u32 lincalrdyw_mask, val;
|
||||
|
||||
if (!adc->cfg->has_linearcal)
|
||||
goto skip_linearcal;
|
||||
|
||||
/* Read linearity calibration */
|
||||
lincalrdyw_mask = STM32H7_LINCALRDYW6;
|
||||
for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) {
|
||||
@ -923,12 +1025,13 @@ static int stm32h7_adc_read_selfcalib(struct iio_dev *indio_dev)
|
||||
lincalrdyw_mask >>= 1;
|
||||
}
|
||||
|
||||
skip_linearcal:
|
||||
/* Read offset calibration */
|
||||
val = stm32_adc_readl(adc, STM32H7_ADC_CALFACT);
|
||||
adc->cal.calfact_s = (val & STM32H7_CALFACT_S_MASK);
|
||||
adc->cal.calfact_s >>= STM32H7_CALFACT_S_SHIFT;
|
||||
adc->cal.calfact_d = (val & STM32H7_CALFACT_D_MASK);
|
||||
adc->cal.calfact_d >>= STM32H7_CALFACT_D_SHIFT;
|
||||
val = stm32_adc_readl(adc, adc->cfg->regs->calfact_s.reg);
|
||||
adc->cal.calfact_s = (val & adc->cfg->regs->calfact_s.mask);
|
||||
adc->cal.calfact_s >>= adc->cfg->regs->calfact_s.shift;
|
||||
adc->cal.calfact_d = (val & adc->cfg->regs->calfact_d.mask);
|
||||
adc->cal.calfact_d >>= adc->cfg->regs->calfact_d.shift;
|
||||
adc->cal.calibrated = true;
|
||||
|
||||
return 0;
|
||||
@ -945,9 +1048,12 @@ static int stm32h7_adc_restore_selfcalib(struct iio_dev *indio_dev)
|
||||
int i, ret;
|
||||
u32 lincalrdyw_mask, val;
|
||||
|
||||
val = (adc->cal.calfact_s << STM32H7_CALFACT_S_SHIFT) |
|
||||
(adc->cal.calfact_d << STM32H7_CALFACT_D_SHIFT);
|
||||
stm32_adc_writel(adc, STM32H7_ADC_CALFACT, val);
|
||||
val = (adc->cal.calfact_s << adc->cfg->regs->calfact_s.shift) |
|
||||
(adc->cal.calfact_d << adc->cfg->regs->calfact_d.shift);
|
||||
stm32_adc_writel(adc, adc->cfg->regs->calfact_s.reg, val);
|
||||
|
||||
if (!adc->cfg->has_linearcal)
|
||||
return 0;
|
||||
|
||||
lincalrdyw_mask = STM32H7_LINCALRDYW6;
|
||||
for (i = STM32H7_LINCALFACT_NUM - 1; i >= 0; i--) {
|
||||
@ -1016,11 +1122,14 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
int ret;
|
||||
u32 msk = STM32H7_ADCALDIF;
|
||||
u32 val;
|
||||
|
||||
if (adc->cal.calibrated)
|
||||
return true;
|
||||
|
||||
if (adc->cfg->has_linearcal)
|
||||
msk |= STM32H7_ADCALLIN;
|
||||
/* ADC must be disabled for calibration */
|
||||
stm32h7_adc_disable(indio_dev);
|
||||
|
||||
@ -1029,8 +1138,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev)
|
||||
* - Offset calibration for single ended inputs
|
||||
* - No linearity calibration (do it later, before reading it)
|
||||
*/
|
||||
stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALDIF);
|
||||
stm32_adc_clr_bits(adc, STM32H7_ADC_CR, STM32H7_ADCALLIN);
|
||||
stm32_adc_clr_bits(adc, STM32H7_ADC_CR, msk);
|
||||
|
||||
/* Start calibration, then wait for completion */
|
||||
stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADCAL);
|
||||
@ -1048,8 +1156,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev)
|
||||
* - Linearity calibration (needs to be done only once for single/diff)
|
||||
* will run simultaneously with offset calibration.
|
||||
*/
|
||||
stm32_adc_set_bits(adc, STM32H7_ADC_CR,
|
||||
STM32H7_ADCALDIF | STM32H7_ADCALLIN);
|
||||
stm32_adc_set_bits(adc, STM32H7_ADC_CR, msk);
|
||||
stm32_adc_set_bits(adc, STM32H7_ADC_CR, STM32H7_ADCAL);
|
||||
ret = stm32_adc_readl_poll_timeout(STM32H7_ADC_CR, val,
|
||||
!(val & STM32H7_ADCAL), 100,
|
||||
@ -1060,8 +1167,7 @@ static int stm32h7_adc_selfcalib(struct iio_dev *indio_dev)
|
||||
}
|
||||
|
||||
out:
|
||||
stm32_adc_clr_bits(adc, STM32H7_ADC_CR,
|
||||
STM32H7_ADCALDIF | STM32H7_ADCALLIN);
|
||||
stm32_adc_clr_bits(adc, STM32H7_ADC_CR, msk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1093,7 +1199,7 @@ static int stm32h7_adc_prepare(struct iio_dev *indio_dev)
|
||||
|
||||
stm32_adc_int_ch_enable(indio_dev);
|
||||
|
||||
stm32_adc_writel(adc, STM32H7_ADC_DIFSEL, adc->difsel);
|
||||
stm32_adc_writel(adc, adc->cfg->regs->difsel.reg, adc->difsel);
|
||||
|
||||
ret = stm32h7_adc_enable(indio_dev);
|
||||
if (ret)
|
||||
@ -1107,7 +1213,8 @@ static int stm32h7_adc_prepare(struct iio_dev *indio_dev)
|
||||
if (ret)
|
||||
goto disable;
|
||||
|
||||
stm32_adc_writel(adc, STM32H7_ADC_PCSEL, adc->pcsel);
|
||||
if (adc->cfg->has_presel)
|
||||
stm32_adc_writel(adc, STM32H7_ADC_PCSEL, adc->pcsel);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1125,7 +1232,8 @@ static void stm32h7_adc_unprepare(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
|
||||
stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0);
|
||||
if (adc->cfg->has_presel)
|
||||
stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0);
|
||||
stm32h7_adc_disable(indio_dev);
|
||||
stm32_adc_int_ch_disable(adc);
|
||||
stm32h7_adc_enter_pwr_down(adc);
|
||||
@ -1802,14 +1910,15 @@ static void stm32_adc_smpr_init(struct stm32_adc *adc, int channel, u32 smp_ns)
|
||||
{
|
||||
const struct stm32_adc_regs *smpr = &adc->cfg->regs->smp_bits[channel];
|
||||
u32 period_ns, shift = smpr->shift, mask = smpr->mask;
|
||||
unsigned int smp, r = smpr->reg;
|
||||
unsigned int i, smp, r = smpr->reg;
|
||||
|
||||
/*
|
||||
* For vrefint channel, ensure that the sampling time cannot
|
||||
* For internal channels, ensure that the sampling time cannot
|
||||
* be lower than the one specified in the datasheet
|
||||
*/
|
||||
if (channel == adc->int_ch[STM32_ADC_INT_CH_VREFINT])
|
||||
smp_ns = max(smp_ns, adc->cfg->ts_vrefint_ns);
|
||||
for (i = 0; i < STM32_ADC_INT_CH_NB; i++)
|
||||
if (channel == adc->int_ch[i] && adc->int_ch[i] != STM32_ADC_INT_CH_NONE)
|
||||
smp_ns = max(smp_ns, adc->cfg->ts_int_ch[i]);
|
||||
|
||||
/* Determine sampling time (ADC clock cycles) */
|
||||
period_ns = NSEC_PER_SEC / adc->common->rate;
|
||||
@ -1857,7 +1966,7 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
|
||||
adc->pcsel |= BIT(chan->channel);
|
||||
if (differential) {
|
||||
/* pre-build diff channels mask */
|
||||
adc->difsel |= BIT(chan->channel);
|
||||
adc->difsel |= BIT(chan->channel) & adc->cfg->regs->difsel.mask;
|
||||
/* Also add negative input to pre-selected channels */
|
||||
adc->pcsel |= BIT(chan->channel2);
|
||||
}
|
||||
@ -1998,6 +2107,35 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n
|
||||
|
||||
for (i = 0; i < STM32_ADC_INT_CH_NB; i++) {
|
||||
if (!strncmp(stm32_adc_ic[i].name, ch_name, STM32_ADC_CH_SZ)) {
|
||||
/* Check internal channel availability */
|
||||
switch (i) {
|
||||
case STM32_ADC_INT_CH_VDDCORE:
|
||||
if (!adc->cfg->regs->or_vddcore.reg)
|
||||
dev_warn(&indio_dev->dev,
|
||||
"%s channel not available\n", ch_name);
|
||||
break;
|
||||
case STM32_ADC_INT_CH_VDDCPU:
|
||||
if (!adc->cfg->regs->or_vddcpu.reg)
|
||||
dev_warn(&indio_dev->dev,
|
||||
"%s channel not available\n", ch_name);
|
||||
break;
|
||||
case STM32_ADC_INT_CH_VDDQ_DDR:
|
||||
if (!adc->cfg->regs->or_vddq_ddr.reg)
|
||||
dev_warn(&indio_dev->dev,
|
||||
"%s channel not available\n", ch_name);
|
||||
break;
|
||||
case STM32_ADC_INT_CH_VREFINT:
|
||||
if (!adc->cfg->regs->ccr_vref.reg)
|
||||
dev_warn(&indio_dev->dev,
|
||||
"%s channel not available\n", ch_name);
|
||||
break;
|
||||
case STM32_ADC_INT_CH_VBAT:
|
||||
if (!adc->cfg->regs->ccr_vbat.reg)
|
||||
dev_warn(&indio_dev->dev,
|
||||
"%s channel not available\n", ch_name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) {
|
||||
adc->int_ch[i] = chan;
|
||||
break;
|
||||
@ -2431,36 +2569,66 @@ static const struct stm32_adc_cfg stm32f4_adc_cfg = {
|
||||
.irq_clear = stm32f4_adc_irq_clear,
|
||||
};
|
||||
|
||||
const unsigned int stm32_adc_min_ts_h7[] = { 0, 0, 0, 4300, 9000 };
|
||||
static_assert(ARRAY_SIZE(stm32_adc_min_ts_h7) == STM32_ADC_INT_CH_NB);
|
||||
|
||||
static const struct stm32_adc_cfg stm32h7_adc_cfg = {
|
||||
.regs = &stm32h7_adc_regspec,
|
||||
.adc_info = &stm32h7_adc_info,
|
||||
.trigs = stm32h7_adc_trigs,
|
||||
.has_boostmode = true,
|
||||
.has_linearcal = true,
|
||||
.has_presel = true,
|
||||
.start_conv = stm32h7_adc_start_conv,
|
||||
.stop_conv = stm32h7_adc_stop_conv,
|
||||
.prepare = stm32h7_adc_prepare,
|
||||
.unprepare = stm32h7_adc_unprepare,
|
||||
.smp_cycles = stm32h7_adc_smp_cycles,
|
||||
.irq_clear = stm32h7_adc_irq_clear,
|
||||
.ts_int_ch = stm32_adc_min_ts_h7,
|
||||
};
|
||||
|
||||
const unsigned int stm32_adc_min_ts_mp1[] = { 100, 100, 100, 4300, 9800 };
|
||||
static_assert(ARRAY_SIZE(stm32_adc_min_ts_mp1) == STM32_ADC_INT_CH_NB);
|
||||
|
||||
static const struct stm32_adc_cfg stm32mp1_adc_cfg = {
|
||||
.regs = &stm32mp1_adc_regspec,
|
||||
.adc_info = &stm32h7_adc_info,
|
||||
.trigs = stm32h7_adc_trigs,
|
||||
.has_vregready = true,
|
||||
.has_boostmode = true,
|
||||
.has_linearcal = true,
|
||||
.has_presel = true,
|
||||
.start_conv = stm32h7_adc_start_conv,
|
||||
.stop_conv = stm32h7_adc_stop_conv,
|
||||
.prepare = stm32h7_adc_prepare,
|
||||
.unprepare = stm32h7_adc_unprepare,
|
||||
.smp_cycles = stm32h7_adc_smp_cycles,
|
||||
.irq_clear = stm32h7_adc_irq_clear,
|
||||
.ts_vrefint_ns = 4300,
|
||||
.ts_int_ch = stm32_adc_min_ts_mp1,
|
||||
};
|
||||
|
||||
const unsigned int stm32_adc_min_ts_mp13[] = { 100, 0, 0, 4300, 9800 };
|
||||
static_assert(ARRAY_SIZE(stm32_adc_min_ts_mp13) == STM32_ADC_INT_CH_NB);
|
||||
|
||||
static const struct stm32_adc_cfg stm32mp13_adc_cfg = {
|
||||
.regs = &stm32mp13_adc_regspec,
|
||||
.adc_info = &stm32mp13_adc_info,
|
||||
.trigs = stm32h7_adc_trigs,
|
||||
.start_conv = stm32mp13_adc_start_conv,
|
||||
.stop_conv = stm32h7_adc_stop_conv,
|
||||
.prepare = stm32h7_adc_prepare,
|
||||
.unprepare = stm32h7_adc_unprepare,
|
||||
.smp_cycles = stm32mp13_adc_smp_cycles,
|
||||
.irq_clear = stm32h7_adc_irq_clear,
|
||||
.ts_int_ch = stm32_adc_min_ts_mp13,
|
||||
};
|
||||
|
||||
static const struct of_device_id stm32_adc_of_match[] = {
|
||||
{ .compatible = "st,stm32f4-adc", .data = (void *)&stm32f4_adc_cfg },
|
||||
{ .compatible = "st,stm32h7-adc", .data = (void *)&stm32h7_adc_cfg },
|
||||
{ .compatible = "st,stm32mp1-adc", .data = (void *)&stm32mp1_adc_cfg },
|
||||
{ .compatible = "st,stm32mp13-adc", .data = (void *)&stm32mp13_adc_cfg },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_adc_of_match);
|
||||
|
@ -807,6 +807,8 @@ static int ads131e08_probe(struct spi_device *spi)
|
||||
int ret;
|
||||
|
||||
info = device_get_match_data(&spi->dev);
|
||||
if (!info)
|
||||
info = (void *)spi_get_device_id(spi)->driver_data;
|
||||
if (!info) {
|
||||
dev_err(&spi->dev, "failed to get match data\n");
|
||||
return -ENODEV;
|
||||
@ -926,12 +928,21 @@ static const struct of_device_id ads131e08_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ads131e08_of_match);
|
||||
|
||||
static const struct spi_device_id ads131e08_ids[] = {
|
||||
{ "ads131e04", (kernel_ulong_t)&ads131e08_info_tbl[ads131e04] },
|
||||
{ "ads131e06", (kernel_ulong_t)&ads131e08_info_tbl[ads131e06] },
|
||||
{ "ads131e08", (kernel_ulong_t)&ads131e08_info_tbl[ads131e08] },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, ads131e08_ids);
|
||||
|
||||
static struct spi_driver ads131e08_driver = {
|
||||
.driver = {
|
||||
.name = "ads131e08",
|
||||
.of_match_table = ads131e08_of_match,
|
||||
},
|
||||
.probe = ads131e08_probe,
|
||||
.id_table = ads131e08_ids,
|
||||
};
|
||||
module_spi_driver(ads131e08_driver);
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
@ -156,6 +157,9 @@ struct vf610_adc {
|
||||
void __iomem *regs;
|
||||
struct clk *clk;
|
||||
|
||||
/* lock to protect against multiple access to the device */
|
||||
struct mutex lock;
|
||||
|
||||
u32 vref_uv;
|
||||
u32 value;
|
||||
struct regulator *vref;
|
||||
@ -467,11 +471,11 @@ static int vf610_set_conversion_mode(struct iio_dev *indio_dev,
|
||||
{
|
||||
struct vf610_adc *info = iio_priv(indio_dev);
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&info->lock);
|
||||
info->adc_feature.conv_mode = mode;
|
||||
vf610_adc_calculate_rates(info);
|
||||
vf610_adc_hw_init(info);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&info->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -622,6 +626,58 @@ static const struct attribute_group vf610_attribute_group = {
|
||||
.attrs = vf610_attributes,
|
||||
};
|
||||
|
||||
static int vf610_read_sample(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan, int *val)
|
||||
{
|
||||
struct vf610_adc *info = iio_priv(indio_dev);
|
||||
unsigned int hc_cfg;
|
||||
int ret;
|
||||
|
||||
ret = iio_device_claim_direct_mode(indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&info->lock);
|
||||
reinit_completion(&info->completion);
|
||||
hc_cfg = VF610_ADC_ADCHC(chan->channel);
|
||||
hc_cfg |= VF610_ADC_AIEN;
|
||||
writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
|
||||
ret = wait_for_completion_interruptible_timeout(&info->completion,
|
||||
VF610_ADC_TIMEOUT);
|
||||
if (ret == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
switch (chan->type) {
|
||||
case IIO_VOLTAGE:
|
||||
*val = info->value;
|
||||
break;
|
||||
case IIO_TEMP:
|
||||
/*
|
||||
* Calculate in degree Celsius times 1000
|
||||
* Using the typical sensor slope of 1.84 mV/°C
|
||||
* and VREFH_ADC at 3.3V, V at 25°C of 699 mV
|
||||
*/
|
||||
*val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) *
|
||||
1000000 / VF610_TEMP_SLOPE_COEFF;
|
||||
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&info->lock);
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vf610_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int *val,
|
||||
@ -629,53 +685,15 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
|
||||
long mask)
|
||||
{
|
||||
struct vf610_adc *info = iio_priv(indio_dev);
|
||||
unsigned int hc_cfg;
|
||||
long ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
case IIO_CHAN_INFO_PROCESSED:
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
if (iio_buffer_enabled(indio_dev)) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
reinit_completion(&info->completion);
|
||||
hc_cfg = VF610_ADC_ADCHC(chan->channel);
|
||||
hc_cfg |= VF610_ADC_AIEN;
|
||||
writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
|
||||
ret = wait_for_completion_interruptible_timeout
|
||||
(&info->completion, VF610_ADC_TIMEOUT);
|
||||
if (ret == 0) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
ret = vf610_read_sample(indio_dev, chan, val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (chan->type) {
|
||||
case IIO_VOLTAGE:
|
||||
*val = info->value;
|
||||
break;
|
||||
case IIO_TEMP:
|
||||
/*
|
||||
* Calculate in degree Celsius times 1000
|
||||
* Using the typical sensor slope of 1.84 mV/°C
|
||||
* and VREFH_ADC at 3.3V, V at 25°C of 699 mV
|
||||
*/
|
||||
*val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) *
|
||||
1000000 / VF610_TEMP_SLOPE_COEFF;
|
||||
|
||||
break;
|
||||
default:
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return IIO_VAL_INT;
|
||||
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
@ -878,6 +896,8 @@ static int vf610_adc_probe(struct platform_device *pdev)
|
||||
goto error_iio_device_register;
|
||||
}
|
||||
|
||||
mutex_init(&info->lock);
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Couldn't register the device.\n");
|
||||
|
@ -34,7 +34,6 @@ struct hmc425a_chip_info {
|
||||
};
|
||||
|
||||
struct hmc425a_state {
|
||||
struct regulator *reg;
|
||||
struct mutex lock; /* protect sensor state */
|
||||
struct hmc425a_chip_info *chip_info;
|
||||
struct gpio_descs *gpios;
|
||||
@ -162,13 +161,6 @@ static const struct of_device_id hmc425a_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, hmc425a_of_match);
|
||||
|
||||
static void hmc425a_reg_disable(void *data)
|
||||
{
|
||||
struct hmc425a_state *st = data;
|
||||
|
||||
regulator_disable(st->reg);
|
||||
}
|
||||
|
||||
static struct hmc425a_chip_info hmc425a_chip_info_tbl[] = {
|
||||
[ID_HMC425A] = {
|
||||
.name = "hmc425a",
|
||||
@ -211,14 +203,7 @@ static int hmc425a_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
st->reg = devm_regulator_get(&pdev->dev, "vcc-supply");
|
||||
if (IS_ERR(st->reg))
|
||||
return PTR_ERR(st->reg);
|
||||
|
||||
ret = regulator_enable(st->reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = devm_add_action_or_reset(&pdev->dev, hmc425a_reg_disable, st);
|
||||
ret = devm_regulator_get_enable(&pdev->dev, "vcc-supply");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -142,8 +142,8 @@ static ssize_t iio_dmaengine_buffer_get_length_align(struct device *dev,
|
||||
static IIO_DEVICE_ATTR(length_align_bytes, 0444,
|
||||
iio_dmaengine_buffer_get_length_align, NULL, 0);
|
||||
|
||||
static const struct attribute *iio_dmaengine_buffer_attrs[] = {
|
||||
&iio_dev_attr_length_align_bytes.dev_attr.attr,
|
||||
static const struct iio_dev_attr *iio_dmaengine_buffer_attrs[] = {
|
||||
&iio_dev_attr_length_align_bytes,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -41,7 +41,7 @@ int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev,
|
||||
irqreturn_t (*thread)(int irq, void *p),
|
||||
enum iio_buffer_direction direction,
|
||||
const struct iio_buffer_setup_ops *setup_ops,
|
||||
const struct attribute **buffer_attrs)
|
||||
const struct iio_dev_attr **buffer_attrs)
|
||||
{
|
||||
struct iio_buffer *buffer;
|
||||
int ret;
|
||||
@ -110,7 +110,7 @@ int devm_iio_triggered_buffer_setup_ext(struct device *dev,
|
||||
irqreturn_t (*thread)(int irq, void *p),
|
||||
enum iio_buffer_direction direction,
|
||||
const struct iio_buffer_setup_ops *ops,
|
||||
const struct attribute **buffer_attrs)
|
||||
const struct iio_dev_attr **buffer_attrs)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -270,7 +270,7 @@ static struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev)
|
||||
int devm_iio_kfifo_buffer_setup_ext(struct device *dev,
|
||||
struct iio_dev *indio_dev,
|
||||
const struct iio_buffer_setup_ops *setup_ops,
|
||||
const struct attribute **buffer_attrs)
|
||||
const struct iio_dev_attr **buffer_attrs)
|
||||
{
|
||||
struct iio_buffer *buffer;
|
||||
|
||||
|
@ -536,19 +536,11 @@ static const struct iio_info ad7150_info_no_irq = {
|
||||
.read_raw = &ad7150_read_raw,
|
||||
};
|
||||
|
||||
static void ad7150_reg_disable(void *data)
|
||||
{
|
||||
struct regulator *reg = data;
|
||||
|
||||
regulator_disable(reg);
|
||||
}
|
||||
|
||||
static int ad7150_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct ad7150_chip_info *chip;
|
||||
struct iio_dev *indio_dev;
|
||||
struct regulator *reg;
|
||||
int ret;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
|
||||
@ -563,15 +555,7 @@ static int ad7150_probe(struct i2c_client *client,
|
||||
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
reg = devm_regulator_get(&client->dev, "vdd");
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
ret = regulator_enable(reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(&client->dev, ad7150_reg_disable, reg);
|
||||
ret = devm_regulator_get_enable(&client->dev, "vdd");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -172,9 +172,9 @@ static ssize_t hwfifo_watermark_max_show(struct device *dev,
|
||||
|
||||
static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
|
||||
|
||||
static const struct attribute *cros_ec_sensor_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_timeout.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
|
||||
static const struct iio_dev_attr *cros_ec_sensor_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_timeout,
|
||||
&iio_dev_attr_hwfifo_watermark_max,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -75,9 +75,9 @@ static IIO_DEVICE_ATTR(hwfifo_timeout, 0644,
|
||||
static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
|
||||
_hid_sensor_get_fifo_state, NULL, 0);
|
||||
|
||||
static const struct attribute *hid_sensor_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_timeout.dev_attr.attr,
|
||||
&iio_dev_attr_hwfifo_enabled.dev_attr.attr,
|
||||
static const struct iio_dev_attr *hid_sensor_fifo_attributes[] = {
|
||||
&iio_dev_attr_hwfifo_timeout,
|
||||
&iio_dev_attr_hwfifo_enabled,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@ -231,7 +231,7 @@ static const struct iio_trigger_ops hid_sensor_trigger_ops = {
|
||||
int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
|
||||
struct hid_sensor_common *attrb)
|
||||
{
|
||||
const struct attribute **fifo_attrs;
|
||||
const struct iio_dev_attr **fifo_attrs;
|
||||
int ret;
|
||||
struct iio_trigger *trig;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user