Second set of IIO new device support, features and cleanup for the 5.2 cycle.
New device suport * ad7606 - Support the AD7616 16 channel, 12bit ADC. * fxas21002c - New driver for this gyroscope with I2C and SPI support. * lsm6dsx - Support the lsm6dsr, new device information structure and dt bindings. * srf04 - Addition device IDs for mb1000, mb1010, mb1020, mb1030 and mb1040 + support of different required trigger pulse lengths. * st-accel - Support the ls2de12, new device info and dt bindings. * ti-ads8344 - New driver for this 8 channel, 16 bit SPI ADC. Binding conversions to yaml - we have started doing these in general for IIO. * avia-hx711 * bmp085 Cleanups and minor fixes / additions * ad5758 - Fixup for some changes between preproduction parts and final part. * ad7606 - Refactor handling of oversampling to make it easy to vary between supported devices. * ad9832 - Organise includes. - Clock framework to handle clocks. * ad9834 - Drop unnecessary parenthesis. * bmc150 - Use __func__ rather than hardcoding. * dummy_evgen. - Fix a memleak on error in probe. * kxcjk1013 - Add KXCJ91008 ACPI ID as seen in the wild. - Use __func__ rather than hardcoding. * imx7d - Local dev variable to simplify code a bit. - dev_err replaces pr_err to give more info. - devm_platform_ioremap_resource for small reduction in boilerplate. - Simplify probe and remove by sharing suspend / resume logic. - Devm for iio_device_register as remove only contains the unregister. * lsm6dsx - Remove a variable that was never read. - Open code values where they are effectively described by what is assigned to them rather than using uninformative defines. * max31856 - Avoid an unintialized ret variable in a path that can't actually occur but is hard for a static checker to know. * max9611 - White space * mpu3050 - Reduce a sleep worst case by switching from msleep to usleep_range. * qcom-spmi-adc5 - Add MODULE_DEVICE_TABLE to assist autoloading of this as a module. * stm32-dfsdm - Fix missing dependencies. * stm32-timer trigger - Fix a build issue when disabled. * ti-ads7950 - Fix mising dependency on CONFIG_GPIOLIB. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAlzAvGYRHGppYzIzQGtl cm5lbC5vcmcACgkQVIU0mcT0FoiurRAAtP0JCVyeh1y7xLhJevl7pm3YZ5vdPPNw VlaB0zbjH9kJM3KehdZZDxgE+5ZZ66wVCtq4quLb7/kHhHCJ97kPPT1sqdVI/sfQ KnwOIJ7JSC+fXxmpBWDyDMvB1NXGWHmNJHAw7SGtJa1/lVdHxPnZ5bMmdfFMadh5 eNOX5NOxTinafp2sX8M4LPeyOCp2mV4iIUNr14rl2TZruv+xP3Y4N9RTfJDclgCI iuK9f6wneSFQ6it48sBE0MGX76az1WvufOEbpl9hWYDoYKl721Yc9WoP2QzTtKMb +3Klq/rEMyJjrzm/mu1G/hkPDgnYwsPBAb24b4qSacv70tXlwbwzTEaPu/3avb5r 22h+fsU61nU1m0GFtNjwwe6p0bm6H3UKHjRaspfq63tEZUUZfRdapmLLTDCRZfcK NNRJsqgRvUcqNgR5P/1PBSK+xvp2btgTDy7SrwnrC06RBQ6XY0vq3PpjpTXygH/z zbLmNiufIP3k0Z0g2o2PMmHl2tF3ue8LCq4p1FyU1iV8qn7qL40+8LkkZQihDpGT i2sMYxexO9qHmm2/GLxrwDTOnLacw2YZRIGthwtVCB8iA1NKkfVCxi1AfasSMJYc t5uGmNQKIdXMV0olzflXMoXJ1pTKncTlqKicgWwDeCLUcq4XhobKSoiE5VfCWL+V 7UBlgLznT/o= =McKo -----END PGP SIGNATURE----- Merge tag 'iio-for-5.2b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next Jonathan writes: Second set of IIO new device support, features and cleanup for the 5.2 cycle. New device suport * ad7606 - Support the AD7616 16 channel, 12bit ADC. * fxas21002c - New driver for this gyroscope with I2C and SPI support. * lsm6dsx - Support the lsm6dsr, new device information structure and dt bindings. * srf04 - Addition device IDs for mb1000, mb1010, mb1020, mb1030 and mb1040 + support of different required trigger pulse lengths. * st-accel - Support the ls2de12, new device info and dt bindings. * ti-ads8344 - New driver for this 8 channel, 16 bit SPI ADC. Binding conversions to yaml - we have started doing these in general for IIO. * avia-hx711 * bmp085 Cleanups and minor fixes / additions * ad5758 - Fixup for some changes between preproduction parts and final part. * ad7606 - Refactor handling of oversampling to make it easy to vary between supported devices. * ad9832 - Organise includes. - Clock framework to handle clocks. * ad9834 - Drop unnecessary parenthesis. * bmc150 - Use __func__ rather than hardcoding. * dummy_evgen. - Fix a memleak on error in probe. * kxcjk1013 - Add KXCJ91008 ACPI ID as seen in the wild. - Use __func__ rather than hardcoding. * imx7d - Local dev variable to simplify code a bit. - dev_err replaces pr_err to give more info. - devm_platform_ioremap_resource for small reduction in boilerplate. - Simplify probe and remove by sharing suspend / resume logic. - Devm for iio_device_register as remove only contains the unregister. * lsm6dsx - Remove a variable that was never read. - Open code values where they are effectively described by what is assigned to them rather than using uninformative defines. * max31856 - Avoid an unintialized ret variable in a path that can't actually occur but is hard for a static checker to know. * max9611 - White space * mpu3050 - Reduce a sleep worst case by switching from msleep to usleep_range. * qcom-spmi-adc5 - Add MODULE_DEVICE_TABLE to assist autoloading of this as a module. * stm32-dfsdm - Fix missing dependencies. * stm32-timer trigger - Fix a build issue when disabled. * ti-ads7950 - Fix mising dependency on CONFIG_GPIOLIB. * tag 'iio-for-5.2b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (42 commits) iio: adc: qcom-spmi-adc5: Fix of-based module autoloading iio: dummy_evgen: fix possible memleak in evgen init iio:accel:Switch hardcoded function name with a reference to __func__ making the code more maintainable iio: adc: stm32-dfsdm: fix triggered buffer build dependency iio: adc: stm32-dfsdm: fix unmet direct dependencies detected iio: trigger: stm32-timer: fix build issue when disabled iio: imx7d_adc: Use devm_iio_device_register() iio: imx7d_adc: Simplify imx7d_adc_remove() with imx7d_adc_suspend() iio: imx7d_adc: Simplify imx7d_adc_probe() with imx7d_adc_resume() drivers/iio/gyro/mpu3050-core.c: This patch fix the following checkpatch warning. iio: dac: ad5758: Modifications for new revision iio: imu: st_lsm6dsx: inline per-sensor data iio: adc: Add driver for the TI ADS8344 A/DC chips dt-bindings: iio: adc: Add bindings for TI ADS8344 A/DC chips MAINTAINERS: add entry for fxas21002c gyro driver iio: gyro: fxas21002c: add spi driver iio: gyro: fxas21002c: add i2c driver iio: gyro: add core driver for fxas21002c iio: gyro: add DT bindings to fxas21002c Kconfig: change configuration of srf04 ultrasonic iio sensor ...
This commit is contained in:
Коммит
bf402c08eb
|
@ -7,6 +7,7 @@ Required properties for the AD7606:
|
|||
* "adi,ad7606-8"
|
||||
* "adi,ad7606-6"
|
||||
* "adi,ad7606-4"
|
||||
* "adi,ad7616"
|
||||
- reg: SPI chip select number for the device
|
||||
- spi-max-frequency: Max SPI frequency to use
|
||||
see: Documentation/devicetree/bindings/spi/spi-bus.txt
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
* AVIA HX711 ADC chip for weight cells
|
||||
Bit-banging driver
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "avia,hx711"
|
||||
- sck-gpios: Definition of the GPIO for the clock
|
||||
- dout-gpios: Definition of the GPIO for data-out
|
||||
See Documentation/devicetree/bindings/gpio/gpio.txt
|
||||
- avdd-supply: Definition of the regulator used as analog supply
|
||||
|
||||
Optional properties:
|
||||
- clock-frequency: Frequency of PD_SCK in Hz
|
||||
Minimum value allowed is 10 kHz because of maximum
|
||||
high time of 50 microseconds.
|
||||
|
||||
Example:
|
||||
weight {
|
||||
compatible = "avia,hx711";
|
||||
sck-gpios = <&gpio3 10 GPIO_ACTIVE_HIGH>;
|
||||
dout-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
|
||||
avdd-suppy = <&avdd>;
|
||||
clock-frequency = <100000>;
|
||||
};
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/iio/adc/avia-hx711.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: AVIA HX711 ADC chip for weight cells
|
||||
|
||||
maintainers:
|
||||
- Andreas Klinger <ak@it-klinger.de>
|
||||
|
||||
description: |
|
||||
Bit-banging driver using two GPIOs:
|
||||
- sck-gpio gives a clock to the sensor with 24 cycles for data retrieval
|
||||
and up to 3 cycles for selection of the input channel and gain for the
|
||||
next measurement
|
||||
- dout-gpio is the sensor data the sensor responds to the clock
|
||||
|
||||
Specifications about the driver can be found at:
|
||||
http://www.aviaic.com/ENProducts.aspx
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- avia,hx711
|
||||
|
||||
sck-gpios:
|
||||
description:
|
||||
Definition of the GPIO for the clock (output). In the datasheet it is
|
||||
named PD_SCK
|
||||
maxItems: 1
|
||||
|
||||
dout-gpios:
|
||||
description:
|
||||
Definition of the GPIO for the data-out sent by the sensor in
|
||||
response to the clock (input).
|
||||
See Documentation/devicetree/bindings/gpio/gpio.txt for information
|
||||
on how to specify a consumer gpio.
|
||||
maxItems: 1
|
||||
|
||||
avdd-supply:
|
||||
description:
|
||||
Definition of the regulator used as analog supply
|
||||
maxItems: 1
|
||||
|
||||
clock-frequency:
|
||||
minimum: 20000
|
||||
maximum: 2500000
|
||||
default: 400000
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- sck-gpios
|
||||
- dout-gpios
|
||||
- avdd-supply
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
weight {
|
||||
compatible = "avia,hx711";
|
||||
sck-gpios = <&gpio3 10 GPIO_ACTIVE_HIGH>;
|
||||
dout-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
|
||||
avdd-suppy = <&avdd>;
|
||||
clock-frequency = <100000>;
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
* Texas Instruments ADS8344 A/DC chip
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "ti,ads8344"
|
||||
- reg: SPI chip select number for the device
|
||||
- vref-supply: phandle to a regulator node that supplies the
|
||||
reference voltage
|
||||
|
||||
Recommended properties:
|
||||
- spi-max-frequency: Definition as per
|
||||
Documentation/devicetree/bindings/spi/spi-bus.txt
|
||||
|
||||
Example:
|
||||
adc@0 {
|
||||
compatible = "ti,ads8344";
|
||||
reg = <0>;
|
||||
vref-supply = <&refin_supply>;
|
||||
spi-max-frequency = <10000000>;
|
||||
};
|
|
@ -0,0 +1,31 @@
|
|||
* NXP FXAS21002C Gyroscope device tree bindings
|
||||
|
||||
http://www.nxp.com/products/sensors/gyroscopes/3-axis-digital-gyroscope:FXAS21002C
|
||||
|
||||
Required properties:
|
||||
- compatible : should be "nxp,fxas21002c"
|
||||
- reg : the I2C address of the sensor or SPI chip select number for the
|
||||
device.
|
||||
- vdd-supply: phandle to the regulator that provides power to the sensor.
|
||||
- vddio-supply: phandle to the regulator that provides power to the bus.
|
||||
|
||||
Optional properties:
|
||||
- reset-gpios : gpio used to reset the device, see gpio/gpio.txt
|
||||
- interrupts : device support 2 interrupts, INT1 and INT2,
|
||||
the interrupts can be triggered on rising or falling edges.
|
||||
See interrupt-controller/interrupts.txt
|
||||
- interrupt-names: should contain "INT1" or "INT2", the gyroscope interrupt
|
||||
line in use.
|
||||
- drive-open-drain: the interrupt/data ready line will be configured
|
||||
as open drain, which is useful if several sensors share
|
||||
the same interrupt line. This is a boolean property.
|
||||
(This binding is taken from pinctrl/pinctrl-bindings.txt)
|
||||
|
||||
Example:
|
||||
|
||||
gyroscope@20 {
|
||||
compatible = "nxp,fxas21002c";
|
||||
reg = <0x20>;
|
||||
vdd-supply = <®_peri_3p15v>;
|
||||
vddio-supply = <®_peri_3p15v>;
|
||||
};
|
|
@ -10,6 +10,7 @@ Required properties:
|
|||
"st,lsm6dso"
|
||||
"st,asm330lhh"
|
||||
"st,lsm6dsox"
|
||||
"st,lsm6dsr"
|
||||
- reg: i2c address of the sensor / spi cs line
|
||||
|
||||
Optional properties:
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
BMP085/BMP18x/BMP28x digital pressure sensors
|
||||
|
||||
Required properties:
|
||||
- compatible: must be one of:
|
||||
"bosch,bmp085"
|
||||
"bosch,bmp180"
|
||||
"bosch,bmp280"
|
||||
"bosch,bme280"
|
||||
|
||||
Optional properties:
|
||||
- interrupts: interrupt mapping for IRQ
|
||||
- reset-gpios: a GPIO line handling reset of the sensor: as the line is
|
||||
active low, it should be marked GPIO_ACTIVE_LOW (see gpio/gpio.txt)
|
||||
- vddd-supply: digital voltage regulator (see regulator/regulator.txt)
|
||||
- vdda-supply: analog voltage regulator (see regulator/regulator.txt)
|
||||
|
||||
Example:
|
||||
|
||||
pressure@77 {
|
||||
compatible = "bosch,bmp085";
|
||||
reg = <0x77>;
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
|
||||
reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
|
||||
vddd-supply = <&foo>;
|
||||
vdda-supply = <&bar>;
|
||||
};
|
До Ширина: | Высота: | Размер: 745 B |
|
@ -0,0 +1,70 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/iio/pressure/bmp085.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: BMP085/BMP180/BMP280/BME280 pressure iio sensors
|
||||
|
||||
maintainers:
|
||||
- Andreas Klinger <ak@it-klinger.de>
|
||||
|
||||
description: |
|
||||
Pressure, temperature and humidity iio sensors with i2c and spi interfaces
|
||||
|
||||
Specifications about the sensor can be found at:
|
||||
https://www.bosch-sensortec.com/bst/products/all_products/bmp180
|
||||
https://www.bosch-sensortec.com/bst/products/all_products/bmp280
|
||||
https://www.bosch-sensortec.com/bst/products/all_products/bme280
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- bosch,bmp085
|
||||
- bosch,bmp180
|
||||
- bosch,bmp280
|
||||
- bosch,bme280
|
||||
|
||||
vddd-supply:
|
||||
description:
|
||||
digital voltage regulator (see regulator/regulator.txt)
|
||||
maxItems: 1
|
||||
|
||||
vdda-supply:
|
||||
description:
|
||||
analog voltage regulator (see regulator/regulator.txt)
|
||||
maxItems: 1
|
||||
|
||||
reset-gpios:
|
||||
description:
|
||||
A GPIO line handling reset of the sensor. As the line is active low,
|
||||
it should be marked GPIO_ACTIVE_LOW (see gpio/gpio.txt)
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
description:
|
||||
interrupt mapping for IRQ (BMP085 only)
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- vddd-supply
|
||||
- vdda-supply
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
i2c0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pressure@77 {
|
||||
compatible = "bosch,bmp085";
|
||||
reg = <0x77>;
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
|
||||
reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
|
||||
vddd-supply = <&foo>;
|
||||
vdda-supply = <&bar>;
|
||||
};
|
||||
};
|
|
@ -4,7 +4,7 @@
|
|||
$id: http://devicetree.org/schemas/iio/proximity/devantech-srf04.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Devantech SRF04 ultrasonic range finder
|
||||
title: Devantech SRF04 and Maxbotix mb1000 ultrasonic range finder
|
||||
|
||||
maintainers:
|
||||
- Andreas Klinger <ak@it-klinger.de>
|
||||
|
@ -16,19 +16,28 @@ description: |
|
|||
- echo-gpio is held high by the sensor after sending ultrasonic burst
|
||||
until it is received once again
|
||||
|
||||
Specifications about the driver can be found at:
|
||||
Specifications about the devices can be found at:
|
||||
http://www.robot-electronics.co.uk/htm/srf04tech.htm
|
||||
|
||||
http://www.maxbotix.com/documents/LV-MaxSonar-EZ_Datasheet.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: devantech,srf04
|
||||
enum:
|
||||
- devantech,srf04
|
||||
- maxbotix,mb1000
|
||||
- maxbotix,mb1010
|
||||
- maxbotix,mb1020
|
||||
- maxbotix,mb1030
|
||||
- maxbotix,mb1040
|
||||
|
||||
trig-gpios:
|
||||
description:
|
||||
Definition of the GPIO for the triggering (output) This GPIO is set
|
||||
for about 10 us by the driver to tell the device it should initiate
|
||||
the measurement cycle.
|
||||
Definition of the GPIO for the triggering (output)
|
||||
This GPIO is set for about 10 us by the driver to tell the device it
|
||||
should initiate the measurement cycle.
|
||||
See Documentation/devicetree/bindings/gpio/gpio.txt for information
|
||||
on how to specify a consumer gpio.
|
||||
maxItems: 1
|
||||
|
||||
echo-gpios:
|
||||
|
@ -40,8 +49,6 @@ properties:
|
|||
trip.
|
||||
It needs to be an GPIO which is able to deliver an interrupt because
|
||||
the time between two interrupts is measured in the driver.
|
||||
See Documentation/devicetree/bindings/gpio/gpio.txt for information
|
||||
on how to specify a consumer gpio.
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
|
|
|
@ -49,6 +49,7 @@ Accelerometers:
|
|||
- st,lis2dw12
|
||||
- st,lis3dhh
|
||||
- st,lis3de
|
||||
- st,lis2de12
|
||||
|
||||
Gyroscopes:
|
||||
- st,l3g4200d-gyro
|
||||
|
|
10
MAINTAINERS
10
MAINTAINERS
|
@ -11124,6 +11124,16 @@ F: Documentation/ABI/stable/sysfs-bus-nvmem
|
|||
F: include/linux/nvmem-consumer.h
|
||||
F: include/linux/nvmem-provider.h
|
||||
|
||||
NXP FXAS21002C DRIVER
|
||||
M: Rui Miguel Silva <rmfrfs@gmail.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/iio/gyroscope/fxas21002c.txt
|
||||
F: drivers/iio/gyro/fxas21002c_core.c
|
||||
F: drivers/iio/gyro/fxas21002c.h
|
||||
F: drivers/iio/gyro/fxas21002c_i2c.c
|
||||
F: drivers/iio/gyro/fxas21002c_spi.c
|
||||
|
||||
NXP SGTL5000 DRIVER
|
||||
M: Fabio Estevam <festevam@gmail.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
|
|
|
@ -223,7 +223,7 @@ config IIO_ST_ACCEL_3AXIS
|
|||
Say yes here to build support for STMicroelectronics accelerometers:
|
||||
LSM303DLH, LSM303DLHC, LIS3DH, LSM330D, LSM330DL, LSM330DLC,
|
||||
LIS331DLH, LSM303DL, LSM303DLM, LSM330, LIS2DH12, H3LIS331DL,
|
||||
LNG2DM, LIS3DE
|
||||
LNG2DM, LIS3DE, LIS2DE12
|
||||
|
||||
This driver can also be built as a module. If so, these modules
|
||||
will be created:
|
||||
|
|
|
@ -394,7 +394,7 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
|
|||
|
||||
if (ret < 0) {
|
||||
dev_err(dev,
|
||||
"Failed: bmc150_accel_set_power_state for %d\n", on);
|
||||
"Failed: %s for %d\n", __func__, on);
|
||||
if (on)
|
||||
pm_runtime_put_noidle(dev);
|
||||
|
||||
|
|
|
@ -451,7 +451,7 @@ static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
|
|||
}
|
||||
if (ret < 0) {
|
||||
dev_err(&data->client->dev,
|
||||
"Failed: kxcjk1013_set_power_state for %d\n", on);
|
||||
"Failed: %s for %d\n", __func__, on);
|
||||
if (on)
|
||||
pm_runtime_put_noidle(&data->client->dev);
|
||||
return ret;
|
||||
|
@ -1491,6 +1491,7 @@ static const struct acpi_device_id kx_acpi_match[] = {
|
|||
{"KXCJ1013", KXCJK1013},
|
||||
{"KXCJ1008", KXCJ91008},
|
||||
{"KXCJ9000", KXCJ91008},
|
||||
{"KIOX0008", KXCJ91008},
|
||||
{"KIOX0009", KXTJ21009},
|
||||
{"KIOX000A", KXCJ91008},
|
||||
{"KIOX010A", KXCJ91008}, /* KXCJ91008 inside the display of a 2-in-1 */
|
||||
|
|
|
@ -34,6 +34,7 @@ enum st_accel_type {
|
|||
LIS3LV02DL,
|
||||
LIS2DW12,
|
||||
LIS3DHH,
|
||||
LIS2DE12,
|
||||
ST_ACCEL_MAX,
|
||||
};
|
||||
|
||||
|
@ -57,6 +58,7 @@ enum st_accel_type {
|
|||
#define LIS2DW12_ACCEL_DEV_NAME "lis2dw12"
|
||||
#define LIS3DHH_ACCEL_DEV_NAME "lis3dhh"
|
||||
#define LIS3DE_ACCEL_DEV_NAME "lis3de"
|
||||
#define LIS2DE12_ACCEL_DEV_NAME "lis2de12"
|
||||
|
||||
/**
|
||||
* struct st_sensors_platform_data - default accel platform data
|
||||
|
|
|
@ -831,6 +831,82 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
|
|||
.multi_read_bit = false,
|
||||
.bootime = 2,
|
||||
},
|
||||
{
|
||||
.wai = 0x33,
|
||||
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
|
||||
.sensors_supported = {
|
||||
[0] = LIS2DE12_ACCEL_DEV_NAME,
|
||||
},
|
||||
.ch = (struct iio_chan_spec *)st_accel_8bit_channels,
|
||||
.odr = {
|
||||
.addr = 0x20,
|
||||
.mask = 0xf0,
|
||||
.odr_avl = {
|
||||
{ .hz = 1, .value = 0x01, },
|
||||
{ .hz = 10, .value = 0x02, },
|
||||
{ .hz = 25, .value = 0x03, },
|
||||
{ .hz = 50, .value = 0x04, },
|
||||
{ .hz = 100, .value = 0x05, },
|
||||
{ .hz = 200, .value = 0x06, },
|
||||
{ .hz = 400, .value = 0x07, },
|
||||
{ .hz = 1620, .value = 0x08, },
|
||||
{ .hz = 5376, .value = 0x09, },
|
||||
},
|
||||
},
|
||||
.pw = {
|
||||
.addr = 0x20,
|
||||
.mask = 0xf0,
|
||||
.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
|
||||
},
|
||||
.enable_axis = {
|
||||
.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
|
||||
.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
|
||||
},
|
||||
.fs = {
|
||||
.addr = 0x23,
|
||||
.mask = 0x30,
|
||||
.fs_avl = {
|
||||
[0] = {
|
||||
.num = ST_ACCEL_FS_AVL_2G,
|
||||
.value = 0x00,
|
||||
.gain = IIO_G_TO_M_S_2(15600),
|
||||
},
|
||||
[1] = {
|
||||
.num = ST_ACCEL_FS_AVL_4G,
|
||||
.value = 0x01,
|
||||
.gain = IIO_G_TO_M_S_2(31200),
|
||||
},
|
||||
[2] = {
|
||||
.num = ST_ACCEL_FS_AVL_8G,
|
||||
.value = 0x02,
|
||||
.gain = IIO_G_TO_M_S_2(62500),
|
||||
},
|
||||
[3] = {
|
||||
.num = ST_ACCEL_FS_AVL_16G,
|
||||
.value = 0x03,
|
||||
.gain = IIO_G_TO_M_S_2(187500),
|
||||
},
|
||||
},
|
||||
},
|
||||
.drdy_irq = {
|
||||
.int1 = {
|
||||
.addr = 0x22,
|
||||
.mask = 0x10,
|
||||
},
|
||||
.addr_ihl = 0x25,
|
||||
.mask_ihl = 0x02,
|
||||
.stat_drdy = {
|
||||
.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
|
||||
.mask = 0x07,
|
||||
},
|
||||
},
|
||||
.sim = {
|
||||
.addr = 0x23,
|
||||
.value = BIT(0),
|
||||
},
|
||||
.multi_read_bit = true,
|
||||
.bootime = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static int st_accel_read_raw(struct iio_dev *indio_dev,
|
||||
|
|
|
@ -102,6 +102,10 @@ static const struct of_device_id st_accel_of_match[] = {
|
|||
.compatible = "st,lis3de",
|
||||
.data = LIS3DE_ACCEL_DEV_NAME,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lis2de12",
|
||||
.data = LIS2DE12_ACCEL_DEV_NAME,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_accel_of_match);
|
||||
|
@ -140,6 +144,7 @@ static const struct i2c_device_id st_accel_id_table[] = {
|
|||
{ LIS3LV02DL_ACCEL_DEV_NAME },
|
||||
{ LIS2DW12_ACCEL_DEV_NAME },
|
||||
{ LIS3DE_ACCEL_DEV_NAME },
|
||||
{ LIS2DE12_ACCEL_DEV_NAME },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
|
||||
|
|
|
@ -821,7 +821,9 @@ config STM32_DFSDM_ADC
|
|||
depends on (ARCH_STM32 && OF) || COMPILE_TEST
|
||||
select STM32_DFSDM_CORE
|
||||
select REGMAP_MMIO
|
||||
select IIO_BUFFER
|
||||
select IIO_BUFFER_HW_CONSUMER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
help
|
||||
Select this option to support ADCSigma delta modulator for
|
||||
STMicroelectronics STM32 digital filter for sigma delta converter.
|
||||
|
@ -968,7 +970,7 @@ config TI_ADS1015
|
|||
|
||||
config TI_ADS7950
|
||||
tristate "Texas Instruments ADS7950 ADC driver"
|
||||
depends on SPI
|
||||
depends on SPI && GPIOLIB
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
help
|
||||
|
@ -979,6 +981,16 @@ config TI_ADS7950
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called ti-ads7950.
|
||||
|
||||
config TI_ADS8344
|
||||
tristate "Texas Instruments ADS8344"
|
||||
depends on SPI && OF
|
||||
help
|
||||
If you say yes here you get support for Texas Instruments ADS8344
|
||||
ADC chips
|
||||
|
||||
This driver can also be built as a module. If so, the module will be
|
||||
called ti-ads8344.
|
||||
|
||||
config TI_ADS8688
|
||||
tristate "Texas Instruments ADS8688"
|
||||
depends on SPI && OF
|
||||
|
|
|
@ -88,6 +88,7 @@ obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
|
|||
obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
|
||||
obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
|
||||
obj-$(CONFIG_TI_ADS7950) += ti-ads7950.o
|
||||
obj-$(CONFIG_TI_ADS8344) += ti-ads8344.o
|
||||
obj-$(CONFIG_TI_ADS8688) += ti-ads8688.o
|
||||
obj-$(CONFIG_TI_ADS124S08) += ti-ads124s08.o
|
||||
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
* Scales are computed as 5000/32768 and 10000/32768 respectively,
|
||||
* so that when applied to the raw values they provide mV values
|
||||
*/
|
||||
static const unsigned int scale_avail[2] = {
|
||||
static const unsigned int ad7606_scale_avail[2] = {
|
||||
152588, 305176
|
||||
};
|
||||
|
||||
|
@ -39,6 +39,10 @@ static const unsigned int ad7606_oversampling_avail[7] = {
|
|||
1, 2, 4, 8, 16, 32, 64,
|
||||
};
|
||||
|
||||
static const unsigned int ad7616_oversampling_avail[8] = {
|
||||
1, 2, 4, 8, 16, 32, 64, 128,
|
||||
};
|
||||
|
||||
static int ad7606_reset(struct ad7606_state *st)
|
||||
{
|
||||
if (st->gpio_reset) {
|
||||
|
@ -154,7 +158,7 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
|
|||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = 0;
|
||||
*val2 = scale_avail[st->range];
|
||||
*val2 = st->scale_avail[st->range];
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
|
||||
*val = st->oversampling;
|
||||
|
@ -163,19 +167,29 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static ssize_t ad7606_show_avail(char *buf, const unsigned int *vals,
|
||||
unsigned int n, bool micros)
|
||||
{
|
||||
size_t len = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
micros ? "0.%06u " : "%u ", vals[i]);
|
||||
}
|
||||
buf[len - 1] = '\n';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t in_voltage_scale_available_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int i, len = 0;
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct ad7606_state *st = iio_priv(indio_dev);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(scale_avail); i++)
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
|
||||
scale_avail[i]);
|
||||
|
||||
buf[len - 1] = '\n';
|
||||
|
||||
return len;
|
||||
return ad7606_show_avail(buf, st->scale_avail, st->num_scales, true);
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0);
|
||||
|
@ -193,7 +207,7 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
|
|||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
mutex_lock(&st->lock);
|
||||
i = find_closest(val2, scale_avail, ARRAY_SIZE(scale_avail));
|
||||
i = find_closest(val2, st->scale_avail, st->num_scales);
|
||||
gpiod_set_value(st->gpio_range, i);
|
||||
st->range = i;
|
||||
mutex_unlock(&st->lock);
|
||||
|
@ -202,15 +216,20 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
|
|||
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
|
||||
if (val2)
|
||||
return -EINVAL;
|
||||
i = find_closest(val, ad7606_oversampling_avail,
|
||||
ARRAY_SIZE(ad7606_oversampling_avail));
|
||||
i = find_closest(val, st->oversampling_avail,
|
||||
st->num_os_ratios);
|
||||
|
||||
values[0] = i;
|
||||
|
||||
mutex_lock(&st->lock);
|
||||
gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc,
|
||||
st->gpio_os->info, values);
|
||||
st->oversampling = ad7606_oversampling_avail[i];
|
||||
|
||||
/* AD7616 requires a reset to update value */
|
||||
if (st->chip_info->os_req_reset)
|
||||
ad7606_reset(st);
|
||||
|
||||
st->oversampling = st->oversampling_avail[i];
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
return 0;
|
||||
|
@ -219,11 +238,23 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
|
|||
}
|
||||
}
|
||||
|
||||
static IIO_CONST_ATTR(oversampling_ratio_available, "1 2 4 8 16 32 64");
|
||||
static ssize_t ad7606_oversampling_ratio_avail(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct ad7606_state *st = iio_priv(indio_dev);
|
||||
|
||||
return ad7606_show_avail(buf, st->oversampling_avail,
|
||||
st->num_os_ratios, false);
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR(oversampling_ratio_available, 0444,
|
||||
ad7606_oversampling_ratio_avail, NULL, 0);
|
||||
|
||||
static struct attribute *ad7606_attributes_os_and_range[] = {
|
||||
&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
|
||||
&iio_const_attr_oversampling_ratio_available.dev_attr.attr,
|
||||
&iio_dev_attr_oversampling_ratio_available.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -232,7 +263,7 @@ static const struct attribute_group ad7606_attribute_group_os_and_range = {
|
|||
};
|
||||
|
||||
static struct attribute *ad7606_attributes_os[] = {
|
||||
&iio_const_attr_oversampling_ratio_available.dev_attr.attr,
|
||||
&iio_dev_attr_oversampling_ratio_available.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -292,6 +323,36 @@ static const struct iio_chan_spec ad7606_channels[] = {
|
|||
AD7606_CHANNEL(7),
|
||||
};
|
||||
|
||||
/*
|
||||
* The current assumption that this driver makes for AD7616, is that it's
|
||||
* working in Hardware Mode with Serial, Burst and Sequencer modes activated.
|
||||
* To activate them, following pins must be pulled high:
|
||||
* -SER/PAR
|
||||
* -SEQEN
|
||||
* And following pins must be pulled low:
|
||||
* -WR/BURST
|
||||
* -DB4/SER1W
|
||||
*/
|
||||
static const struct iio_chan_spec ad7616_channels[] = {
|
||||
IIO_CHAN_SOFT_TIMESTAMP(16),
|
||||
AD7606_CHANNEL(0),
|
||||
AD7606_CHANNEL(1),
|
||||
AD7606_CHANNEL(2),
|
||||
AD7606_CHANNEL(3),
|
||||
AD7606_CHANNEL(4),
|
||||
AD7606_CHANNEL(5),
|
||||
AD7606_CHANNEL(6),
|
||||
AD7606_CHANNEL(7),
|
||||
AD7606_CHANNEL(8),
|
||||
AD7606_CHANNEL(9),
|
||||
AD7606_CHANNEL(10),
|
||||
AD7606_CHANNEL(11),
|
||||
AD7606_CHANNEL(12),
|
||||
AD7606_CHANNEL(13),
|
||||
AD7606_CHANNEL(14),
|
||||
AD7606_CHANNEL(15),
|
||||
};
|
||||
|
||||
static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
|
||||
/* More devices added in future */
|
||||
[ID_AD7605_4] = {
|
||||
|
@ -301,17 +362,27 @@ static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
|
|||
[ID_AD7606_8] = {
|
||||
.channels = ad7606_channels,
|
||||
.num_channels = 9,
|
||||
.has_oversampling = true,
|
||||
.oversampling_avail = ad7606_oversampling_avail,
|
||||
.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
|
||||
},
|
||||
[ID_AD7606_6] = {
|
||||
.channels = ad7606_channels,
|
||||
.num_channels = 7,
|
||||
.has_oversampling = true,
|
||||
.oversampling_avail = ad7606_oversampling_avail,
|
||||
.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
|
||||
},
|
||||
[ID_AD7606_4] = {
|
||||
.channels = ad7606_channels,
|
||||
.num_channels = 5,
|
||||
.has_oversampling = true,
|
||||
.oversampling_avail = ad7606_oversampling_avail,
|
||||
.oversampling_num = ARRAY_SIZE(ad7606_oversampling_avail),
|
||||
},
|
||||
[ID_AD7616] = {
|
||||
.channels = ad7616_channels,
|
||||
.num_channels = 17,
|
||||
.oversampling_avail = ad7616_oversampling_avail,
|
||||
.oversampling_num = ARRAY_SIZE(ad7616_oversampling_avail),
|
||||
.os_req_reset = true,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -343,7 +414,7 @@ static int ad7606_request_gpios(struct ad7606_state *st)
|
|||
if (IS_ERR(st->gpio_frstdata))
|
||||
return PTR_ERR(st->gpio_frstdata);
|
||||
|
||||
if (!st->chip_info->has_oversampling)
|
||||
if (!st->chip_info->oversampling_num)
|
||||
return 0;
|
||||
|
||||
st->gpio_os = devm_gpiod_get_array_optional(dev,
|
||||
|
@ -467,6 +538,8 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
|
|||
/* tied to logic low, analog input range is +/- 5V */
|
||||
st->range = 0;
|
||||
st->oversampling = 1;
|
||||
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))
|
||||
|
@ -484,6 +557,11 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
|
|||
|
||||
st->chip_info = &ad7606_chip_info_tbl[id];
|
||||
|
||||
if (st->chip_info->oversampling_num) {
|
||||
st->oversampling_avail = st->chip_info->oversampling_avail;
|
||||
st->num_os_ratios = st->chip_info->oversampling_num;
|
||||
}
|
||||
|
||||
ret = ad7606_request_gpios(st);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -12,12 +12,17 @@
|
|||
* struct ad7606_chip_info - chip specific information
|
||||
* @channels: channel specification
|
||||
* @num_channels: number of channels
|
||||
* @has_oversampling: whether the device has oversampling support
|
||||
* @oversampling_avail pointer to the array which stores the available
|
||||
* oversampling ratios.
|
||||
* @oversampling_num number of elements stored in oversampling_avail array
|
||||
* @os_req_reset some devices require a reset to update oversampling
|
||||
*/
|
||||
struct ad7606_chip_info {
|
||||
const struct iio_chan_spec *channels;
|
||||
unsigned int num_channels;
|
||||
bool has_oversampling;
|
||||
const unsigned int *oversampling_avail;
|
||||
unsigned int oversampling_num;
|
||||
bool os_req_reset;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -29,6 +34,11 @@ struct ad7606_chip_info {
|
|||
* @range voltage range selection, selects which scale to apply
|
||||
* @oversampling oversampling selection
|
||||
* @base_address address from where to read data in parallel operation
|
||||
* @scale_avail pointer to the array which stores the available scales
|
||||
* @num_scales number of elements stored in the scale_avail array
|
||||
* @oversampling_avail pointer to the array which stores the available
|
||||
* oversampling ratios.
|
||||
* @num_os_ratios number of elements stored in oversampling_avail array
|
||||
* @lock protect sensor state from concurrent accesses to GPIOs
|
||||
* @gpio_convst GPIO descriptor for conversion start signal (CONVST)
|
||||
* @gpio_reset GPIO descriptor for device hard-reset
|
||||
|
@ -50,6 +60,10 @@ struct ad7606_state {
|
|||
unsigned int range;
|
||||
unsigned int oversampling;
|
||||
void __iomem *base_address;
|
||||
const unsigned int *scale_avail;
|
||||
unsigned int num_scales;
|
||||
const unsigned int *oversampling_avail;
|
||||
unsigned int num_os_ratios;
|
||||
|
||||
struct mutex lock; /* protect sensor state */
|
||||
struct gpio_desc *gpio_convst;
|
||||
|
@ -64,9 +78,9 @@ struct ad7606_state {
|
|||
/*
|
||||
* DMA (thus cache coherency maintenance) requires the
|
||||
* transfer buffers to live in their own cache lines.
|
||||
* 8 * 16-bit samples + 64-bit timestamp
|
||||
* 16 * 16-bit samples + 64-bit timestamp
|
||||
*/
|
||||
unsigned short data[12] ____cacheline_aligned;
|
||||
unsigned short data[20] ____cacheline_aligned;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -86,7 +100,8 @@ enum ad7606_supported_device_ids {
|
|||
ID_AD7605_4,
|
||||
ID_AD7606_8,
|
||||
ID_AD7606_6,
|
||||
ID_AD7606_4
|
||||
ID_AD7606_4,
|
||||
ID_AD7616,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
|
|
@ -53,6 +53,7 @@ static const struct spi_device_id ad7606_id_table[] = {
|
|||
{ "ad7606-4", ID_AD7606_4 },
|
||||
{ "ad7606-6", ID_AD7606_6 },
|
||||
{ "ad7606-8", ID_AD7606_8 },
|
||||
{ "ad7616", ID_AD7616 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, ad7606_id_table);
|
||||
|
@ -62,6 +63,7 @@ static const struct of_device_id ad7606_of_match[] = {
|
|||
{ .compatible = "adi,ad7606-4" },
|
||||
{ .compatible = "adi,ad7606-6" },
|
||||
{ .compatible = "adi,ad7606-8" },
|
||||
{ .compatible = "adi,ad7616" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ad7606_of_match);
|
||||
|
|
|
@ -388,8 +388,9 @@ static irqreturn_t imx7d_adc_isr(int irq, void *dev_id)
|
|||
* timeout flags.
|
||||
*/
|
||||
if (status & IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT) {
|
||||
pr_err("%s: ADC got conversion time out interrupt: 0x%08x\n",
|
||||
dev_name(info->dev), status);
|
||||
dev_err(info->dev,
|
||||
"ADC got conversion time out interrupt: 0x%08x\n",
|
||||
status);
|
||||
status &= ~IMX7D_REG_ADC_INT_STATUS_CHANNEL_CONV_TIME_OUT;
|
||||
writel(status, info->regs + IMX7D_REG_ADC_INT_STATUS);
|
||||
}
|
||||
|
@ -433,136 +434,7 @@ static void imx7d_adc_power_down(struct imx7d_adc *info)
|
|||
writel(adc_cfg, info->regs + IMX7D_REG_ADC_ADC_CFG);
|
||||
}
|
||||
|
||||
static int imx7d_adc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct imx7d_adc *info;
|
||||
struct iio_dev *indio_dev;
|
||||
struct resource *mem;
|
||||
int irq;
|
||||
int ret;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
|
||||
if (!indio_dev) {
|
||||
dev_err(&pdev->dev, "Failed allocating iio device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
info = iio_priv(indio_dev);
|
||||
info->dev = &pdev->dev;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
info->regs = devm_ioremap_resource(&pdev->dev, mem);
|
||||
if (IS_ERR(info->regs)) {
|
||||
ret = PTR_ERR(info->regs);
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to remap adc memory, err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "No irq resource?\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
info->clk = devm_clk_get(&pdev->dev, "adc");
|
||||
if (IS_ERR(info->clk)) {
|
||||
ret = PTR_ERR(info->clk);
|
||||
dev_err(&pdev->dev, "Failed getting clock, err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
info->vref = devm_regulator_get(&pdev->dev, "vref");
|
||||
if (IS_ERR(info->vref)) {
|
||||
ret = PTR_ERR(info->vref);
|
||||
dev_err(&pdev->dev,
|
||||
"Failed getting reference voltage, err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regulator_enable(info->vref);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Can't enable adc reference top voltage, err = %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
init_completion(&info->completion);
|
||||
|
||||
indio_dev->name = dev_name(&pdev->dev);
|
||||
indio_dev->dev.parent = &pdev->dev;
|
||||
indio_dev->info = &imx7d_adc_iio_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->channels = imx7d_adc_iio_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(imx7d_adc_iio_channels);
|
||||
|
||||
ret = clk_prepare_enable(info->clk);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Could not prepare or enable the clock.\n");
|
||||
goto error_adc_clk_enable;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(info->dev, irq,
|
||||
imx7d_adc_isr, 0,
|
||||
dev_name(&pdev->dev), info);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed requesting irq, irq = %d\n", irq);
|
||||
goto error_iio_device_register;
|
||||
}
|
||||
|
||||
imx7d_adc_feature_config(info);
|
||||
imx7d_adc_hw_init(info);
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret) {
|
||||
imx7d_adc_power_down(info);
|
||||
dev_err(&pdev->dev, "Couldn't register the device.\n");
|
||||
goto error_iio_device_register;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_iio_device_register:
|
||||
clk_disable_unprepare(info->clk);
|
||||
error_adc_clk_enable:
|
||||
regulator_disable(info->vref);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int imx7d_adc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
|
||||
struct imx7d_adc *info = iio_priv(indio_dev);
|
||||
|
||||
iio_device_unregister(indio_dev);
|
||||
|
||||
imx7d_adc_power_down(info);
|
||||
|
||||
clk_disable_unprepare(info->clk);
|
||||
regulator_disable(info->vref);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused imx7d_adc_suspend(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct imx7d_adc *info = iio_priv(indio_dev);
|
||||
|
||||
imx7d_adc_power_down(info);
|
||||
|
||||
clk_disable_unprepare(info->clk);
|
||||
regulator_disable(info->vref);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused imx7d_adc_resume(struct device *dev)
|
||||
static int imx7d_adc_enable(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct imx7d_adc *info = iio_priv(indio_dev);
|
||||
|
@ -589,11 +461,112 @@ static int __maybe_unused imx7d_adc_resume(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(imx7d_adc_pm_ops, imx7d_adc_suspend, imx7d_adc_resume);
|
||||
static int imx7d_adc_disable(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct imx7d_adc *info = iio_priv(indio_dev);
|
||||
|
||||
imx7d_adc_power_down(info);
|
||||
|
||||
clk_disable_unprepare(info->clk);
|
||||
regulator_disable(info->vref);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __imx7d_adc_disable(void *data)
|
||||
{
|
||||
imx7d_adc_disable(data);
|
||||
}
|
||||
|
||||
static int imx7d_adc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct imx7d_adc *info;
|
||||
struct iio_dev *indio_dev;
|
||||
struct device *dev = &pdev->dev;
|
||||
int irq;
|
||||
int ret;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*info));
|
||||
if (!indio_dev) {
|
||||
dev_err(&pdev->dev, "Failed allocating iio device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
info = iio_priv(indio_dev);
|
||||
info->dev = dev;
|
||||
|
||||
info->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(info->regs)) {
|
||||
ret = PTR_ERR(info->regs);
|
||||
dev_err(dev, "Failed to remap adc memory, err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "No irq resource?\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
info->clk = devm_clk_get(dev, "adc");
|
||||
if (IS_ERR(info->clk)) {
|
||||
ret = PTR_ERR(info->clk);
|
||||
dev_err(dev, "Failed getting clock, err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
info->vref = devm_regulator_get(dev, "vref");
|
||||
if (IS_ERR(info->vref)) {
|
||||
ret = PTR_ERR(info->vref);
|
||||
dev_err(dev,
|
||||
"Failed getting reference voltage, err = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
init_completion(&info->completion);
|
||||
|
||||
indio_dev->name = dev_name(dev);
|
||||
indio_dev->dev.parent = dev;
|
||||
indio_dev->info = &imx7d_adc_iio_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->channels = imx7d_adc_iio_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(imx7d_adc_iio_channels);
|
||||
|
||||
ret = devm_request_irq(dev, irq,
|
||||
imx7d_adc_isr, 0,
|
||||
dev_name(dev), info);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed requesting irq, irq = %d\n", irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
imx7d_adc_feature_config(info);
|
||||
|
||||
ret = imx7d_adc_enable(&indio_dev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, __imx7d_adc_disable,
|
||||
&indio_dev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_iio_device_register(dev, indio_dev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Couldn't register the device.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(imx7d_adc_pm_ops, imx7d_adc_disable, imx7d_adc_enable);
|
||||
|
||||
static struct platform_driver imx7d_adc_driver = {
|
||||
.probe = imx7d_adc_probe,
|
||||
.remove = imx7d_adc_remove,
|
||||
.driver = {
|
||||
.name = "imx7d_adc",
|
||||
.of_match_table = imx7d_adc_match,
|
||||
|
|
|
@ -664,6 +664,7 @@ static const struct of_device_id adc5_match_table[] = {
|
|||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, adc5_match_table);
|
||||
|
||||
static int adc5_get_dt_data(struct adc5_chip *adc, struct device_node *node)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* ADS8344 16-bit 8-Channel ADC driver
|
||||
*
|
||||
* Author: Gregory CLEMENT <gregory.clement@bootlin.com>
|
||||
*
|
||||
* Datasheet: http://www.ti.com/lit/ds/symlink/ads8344.pdf
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/iio/buffer.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#define ADS8344_START BIT(7)
|
||||
#define ADS8344_SINGLE_END BIT(2)
|
||||
#define ADS8344_CHANNEL(channel) ((channel) << 4)
|
||||
#define ADS8344_CLOCK_INTERNAL 0x2 /* PD1 = 1 and PD0 = 0 */
|
||||
|
||||
struct ads8344 {
|
||||
struct spi_device *spi;
|
||||
struct regulator *reg;
|
||||
/*
|
||||
* Lock protecting access to adc->tx_buff and rx_buff,
|
||||
* especially from concurrent read on sysfs file.
|
||||
*/
|
||||
struct mutex lock;
|
||||
|
||||
u8 tx_buf ____cacheline_aligned;
|
||||
u16 rx_buf;
|
||||
};
|
||||
|
||||
#define ADS8344_VOLTAGE_CHANNEL(chan, si) \
|
||||
{ \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.indexed = 1, \
|
||||
.channel = chan, \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
|
||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
|
||||
}
|
||||
|
||||
#define ADS8344_VOLTAGE_CHANNEL_DIFF(chan1, chan2, si) \
|
||||
{ \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.indexed = 1, \
|
||||
.channel = (chan1), \
|
||||
.channel2 = (chan2), \
|
||||
.differential = 1, \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
|
||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
|
||||
}
|
||||
|
||||
static const struct iio_chan_spec ads8344_channels[] = {
|
||||
ADS8344_VOLTAGE_CHANNEL(0, 0),
|
||||
ADS8344_VOLTAGE_CHANNEL(1, 4),
|
||||
ADS8344_VOLTAGE_CHANNEL(2, 1),
|
||||
ADS8344_VOLTAGE_CHANNEL(3, 5),
|
||||
ADS8344_VOLTAGE_CHANNEL(4, 2),
|
||||
ADS8344_VOLTAGE_CHANNEL(5, 6),
|
||||
ADS8344_VOLTAGE_CHANNEL(6, 3),
|
||||
ADS8344_VOLTAGE_CHANNEL(7, 7),
|
||||
ADS8344_VOLTAGE_CHANNEL_DIFF(0, 1, 8),
|
||||
ADS8344_VOLTAGE_CHANNEL_DIFF(2, 3, 9),
|
||||
ADS8344_VOLTAGE_CHANNEL_DIFF(4, 5, 10),
|
||||
ADS8344_VOLTAGE_CHANNEL_DIFF(6, 7, 11),
|
||||
ADS8344_VOLTAGE_CHANNEL_DIFF(1, 0, 12),
|
||||
ADS8344_VOLTAGE_CHANNEL_DIFF(3, 2, 13),
|
||||
ADS8344_VOLTAGE_CHANNEL_DIFF(5, 4, 14),
|
||||
ADS8344_VOLTAGE_CHANNEL_DIFF(7, 6, 15),
|
||||
};
|
||||
|
||||
static int ads8344_adc_conversion(struct ads8344 *adc, int channel,
|
||||
bool differential)
|
||||
{
|
||||
struct spi_device *spi = adc->spi;
|
||||
int ret;
|
||||
|
||||
adc->tx_buf = ADS8344_START;
|
||||
if (!differential)
|
||||
adc->tx_buf |= ADS8344_SINGLE_END;
|
||||
adc->tx_buf |= ADS8344_CHANNEL(channel);
|
||||
adc->tx_buf |= ADS8344_CLOCK_INTERNAL;
|
||||
|
||||
ret = spi_write(spi, &adc->tx_buf, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
udelay(9);
|
||||
|
||||
ret = spi_read(spi, &adc->rx_buf, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return adc->rx_buf;
|
||||
}
|
||||
|
||||
static int ads8344_read_raw(struct iio_dev *iio,
|
||||
struct iio_chan_spec const *channel, int *value,
|
||||
int *shift, long mask)
|
||||
{
|
||||
struct ads8344 *adc = iio_priv(iio);
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
mutex_lock(&adc->lock);
|
||||
*value = ads8344_adc_conversion(adc, channel->scan_index,
|
||||
channel->differential);
|
||||
mutex_unlock(&adc->lock);
|
||||
if (*value < 0)
|
||||
return *value;
|
||||
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*value = regulator_get_voltage(adc->reg);
|
||||
if (*value < 0)
|
||||
return *value;
|
||||
|
||||
/* convert regulator output voltage to mV */
|
||||
*value /= 1000;
|
||||
*shift = 16;
|
||||
|
||||
return IIO_VAL_FRACTIONAL_LOG2;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct iio_info ads8344_info = {
|
||||
.read_raw = ads8344_read_raw,
|
||||
};
|
||||
|
||||
static int ads8344_probe(struct spi_device *spi)
|
||||
{
|
||||
struct iio_dev *indio_dev;
|
||||
struct ads8344 *adc;
|
||||
int ret;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
adc = iio_priv(indio_dev);
|
||||
adc->spi = spi;
|
||||
mutex_init(&adc->lock);
|
||||
|
||||
indio_dev->name = dev_name(&spi->dev);
|
||||
indio_dev->dev.parent = &spi->dev;
|
||||
indio_dev->dev.of_node = spi->dev.of_node;
|
||||
indio_dev->info = &ads8344_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->channels = ads8344_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(ads8344_channels);
|
||||
|
||||
adc->reg = devm_regulator_get(&spi->dev, "vref");
|
||||
if (IS_ERR(adc->reg))
|
||||
return PTR_ERR(adc->reg);
|
||||
|
||||
ret = regulator_enable(adc->reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spi_set_drvdata(spi, indio_dev);
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret) {
|
||||
regulator_disable(adc->reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ads8344_remove(struct spi_device *spi)
|
||||
{
|
||||
struct iio_dev *indio_dev = spi_get_drvdata(spi);
|
||||
struct ads8344 *adc = iio_priv(indio_dev);
|
||||
|
||||
iio_device_unregister(indio_dev);
|
||||
regulator_disable(adc->reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id ads8344_of_match[] = {
|
||||
{ .compatible = "ti,ads8344", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ads8344_of_match);
|
||||
|
||||
static struct spi_driver ads8344_driver = {
|
||||
.driver = {
|
||||
.name = "ads8344",
|
||||
.of_match_table = ads8344_of_match,
|
||||
},
|
||||
.probe = ads8344_probe,
|
||||
.remove = ads8344_remove,
|
||||
};
|
||||
module_spi_driver(ads8344_driver);
|
||||
|
||||
MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@bootlin.com>");
|
||||
MODULE_DESCRIPTION("ADS8344 driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -72,8 +72,6 @@
|
|||
#define AD5758_DCDC_CONFIG1_DCDC_VPROG_MODE(x) (((x) & 0x1F) << 0)
|
||||
#define AD5758_DCDC_CONFIG1_DCDC_MODE_MSK GENMASK(6, 5)
|
||||
#define AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(x) (((x) & 0x3) << 5)
|
||||
#define AD5758_DCDC_CONFIG1_PROT_SW_EN_MSK BIT(7)
|
||||
#define AD5758_DCDC_CONFIG1_PROT_SW_EN_MODE(x) (((x) & 0x1) << 7)
|
||||
|
||||
/* AD5758_DCDC_CONFIG2 */
|
||||
#define AD5758_DCDC_CONFIG2_ILIMIT_MSK GENMASK(3, 1)
|
||||
|
@ -84,6 +82,10 @@
|
|||
/* AD5758_DIGITAL_DIAG_RESULTS */
|
||||
#define AD5758_CAL_MEM_UNREFRESHED_MSK BIT(15)
|
||||
|
||||
/* AD5758_ADC_CONFIG */
|
||||
#define AD5758_ADC_CONFIG_PPC_BUF_EN(x) (((x) & 0x1) << 11)
|
||||
#define AD5758_ADC_CONFIG_PPC_BUF_MSK BIT(11)
|
||||
|
||||
#define AD5758_WR_FLAG_MSK(x) (0x80 | ((x) & 0x1F))
|
||||
|
||||
#define AD5758_FULL_SCALE_MICRO 65535000000ULL
|
||||
|
@ -315,6 +317,18 @@ static int ad5758_set_dc_dc_conv_mode(struct ad5758_state *st,
|
|||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* The ENABLE_PPC_BUFFERS bit must be set prior to enabling PPC current
|
||||
* mode.
|
||||
*/
|
||||
if (mode == AD5758_DCDC_MODE_PPC_CURRENT) {
|
||||
ret = ad5758_spi_write_mask(st, AD5758_ADC_CONFIG,
|
||||
AD5758_ADC_CONFIG_PPC_BUF_MSK,
|
||||
AD5758_ADC_CONFIG_PPC_BUF_EN(1));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG1,
|
||||
AD5758_DCDC_CONFIG1_DCDC_MODE_MSK,
|
||||
AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(mode));
|
||||
|
@ -444,23 +458,6 @@ static int ad5758_set_out_range(struct ad5758_state *st, int range)
|
|||
AD5758_CAL_MEM_UNREFRESHED_MSK);
|
||||
}
|
||||
|
||||
static int ad5758_fault_prot_switch_en(struct ad5758_state *st, bool enable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG1,
|
||||
AD5758_DCDC_CONFIG1_PROT_SW_EN_MSK,
|
||||
AD5758_DCDC_CONFIG1_PROT_SW_EN_MODE(enable));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/*
|
||||
* Poll the BUSY_3WI bit in the DCDC_CONFIG2 register until it is 0.
|
||||
* This allows the 3-wire interface communication to complete.
|
||||
*/
|
||||
return ad5758_wait_for_task_complete(st, AD5758_DCDC_CONFIG2,
|
||||
AD5758_DCDC_CONFIG2_BUSY_3WI_MSK);
|
||||
}
|
||||
|
||||
static int ad5758_internal_buffers_en(struct ad5758_state *st, bool enable)
|
||||
{
|
||||
int ret;
|
||||
|
@ -585,8 +582,8 @@ static ssize_t ad5758_write_powerdown(struct iio_dev *indio_dev,
|
|||
{
|
||||
struct ad5758_state *st = iio_priv(indio_dev);
|
||||
bool pwr_down;
|
||||
unsigned int dcdc_config1_mode, dc_dc_mode, dac_config_mode, val;
|
||||
unsigned long int dcdc_config1_msk, dac_config_msk;
|
||||
unsigned int dc_dc_mode, dac_config_mode, val;
|
||||
unsigned long int dac_config_msk;
|
||||
int ret;
|
||||
|
||||
ret = kstrtobool(buf, &pwr_down);
|
||||
|
@ -602,17 +599,6 @@ static ssize_t ad5758_write_powerdown(struct iio_dev *indio_dev,
|
|||
val = 1;
|
||||
}
|
||||
|
||||
dcdc_config1_mode = AD5758_DCDC_CONFIG1_DCDC_MODE_MODE(dc_dc_mode) |
|
||||
AD5758_DCDC_CONFIG1_PROT_SW_EN_MODE(val);
|
||||
dcdc_config1_msk = AD5758_DCDC_CONFIG1_DCDC_MODE_MSK |
|
||||
AD5758_DCDC_CONFIG1_PROT_SW_EN_MSK;
|
||||
|
||||
ret = ad5758_spi_write_mask(st, AD5758_DCDC_CONFIG1,
|
||||
dcdc_config1_msk,
|
||||
dcdc_config1_mode);
|
||||
if (ret < 0)
|
||||
goto err_unlock;
|
||||
|
||||
dac_config_mode = AD5758_DAC_CONFIG_OUT_EN_MODE(val) |
|
||||
AD5758_DAC_CONFIG_INT_EN_MODE(val);
|
||||
dac_config_msk = AD5758_DAC_CONFIG_OUT_EN_MSK |
|
||||
|
@ -841,11 +827,6 @@ static int ad5758_init(struct ad5758_state *st)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Enable the VIOUT fault protection switch (FPS is closed) */
|
||||
ret = ad5758_fault_prot_switch_en(st, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Power up the DAC and internal (INT) amplifiers */
|
||||
ret = ad5758_internal_buffers_en(st, 1);
|
||||
if (ret < 0)
|
||||
|
|
|
@ -196,7 +196,10 @@ static __init int iio_dummy_evgen_init(void)
|
|||
return ret;
|
||||
device_initialize(&iio_evgen_dev);
|
||||
dev_set_name(&iio_evgen_dev, "iio_evgen");
|
||||
return device_add(&iio_evgen_dev);
|
||||
ret = device_add(&iio_evgen_dev);
|
||||
if (ret)
|
||||
put_device(&iio_evgen_dev);
|
||||
return ret;
|
||||
}
|
||||
module_init(iio_dummy_evgen_init);
|
||||
|
||||
|
|
|
@ -73,6 +73,28 @@ config BMG160_SPI
|
|||
tristate
|
||||
select REGMAP_SPI
|
||||
|
||||
config FXAS21002C
|
||||
tristate "NXP FXAS21002C Gyro Sensor"
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
select FXAS21002C_I2C if (I2C)
|
||||
select FXAS21002C_SPI if (SPI)
|
||||
depends on (I2C || SPI_MASTER)
|
||||
help
|
||||
Say yes here to build support for NXP FXAS21002C Tri-axis Gyro
|
||||
Sensor driver connected via I2C or SPI.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called fxas21002c_i2c or fxas21002c_spi.
|
||||
|
||||
config FXAS21002C_I2C
|
||||
tristate
|
||||
select REGMAP_I2C
|
||||
|
||||
config FXAS21002C_SPI
|
||||
tristate
|
||||
select REGMAP_SPI
|
||||
|
||||
config HID_SENSOR_GYRO_3D
|
||||
depends on HID_SENSOR_HUB
|
||||
select IIO_BUFFER
|
||||
|
|
|
@ -12,6 +12,9 @@ obj-$(CONFIG_ADXRS450) += adxrs450.o
|
|||
obj-$(CONFIG_BMG160) += bmg160_core.o
|
||||
obj-$(CONFIG_BMG160_I2C) += bmg160_i2c.o
|
||||
obj-$(CONFIG_BMG160_SPI) += bmg160_spi.o
|
||||
obj-$(CONFIG_FXAS21002C) += fxas21002c_core.o
|
||||
obj-$(CONFIG_FXAS21002C_I2C) += fxas21002c_i2c.o
|
||||
obj-$(CONFIG_FXAS21002C_SPI) += fxas21002c_spi.o
|
||||
|
||||
obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o
|
||||
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Driver for NXP FXAS21002C Gyroscope - Header
|
||||
*
|
||||
* Copyright (C) 2019 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#ifndef FXAS21002C_H_
|
||||
#define FXAS21002C_H_
|
||||
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define FXAS21002C_REG_STATUS 0x00
|
||||
#define FXAS21002C_REG_OUT_X_MSB 0x01
|
||||
#define FXAS21002C_REG_OUT_X_LSB 0x02
|
||||
#define FXAS21002C_REG_OUT_Y_MSB 0x03
|
||||
#define FXAS21002C_REG_OUT_Y_LSB 0x04
|
||||
#define FXAS21002C_REG_OUT_Z_MSB 0x05
|
||||
#define FXAS21002C_REG_OUT_Z_LSB 0x06
|
||||
#define FXAS21002C_REG_DR_STATUS 0x07
|
||||
#define FXAS21002C_REG_F_STATUS 0x08
|
||||
#define FXAS21002C_REG_F_SETUP 0x09
|
||||
#define FXAS21002C_REG_F_EVENT 0x0A
|
||||
#define FXAS21002C_REG_INT_SRC_FLAG 0x0B
|
||||
#define FXAS21002C_REG_WHO_AM_I 0x0C
|
||||
#define FXAS21002C_REG_CTRL0 0x0D
|
||||
#define FXAS21002C_REG_RT_CFG 0x0E
|
||||
#define FXAS21002C_REG_RT_SRC 0x0F
|
||||
#define FXAS21002C_REG_RT_THS 0x10
|
||||
#define FXAS21002C_REG_RT_COUNT 0x11
|
||||
#define FXAS21002C_REG_TEMP 0x12
|
||||
#define FXAS21002C_REG_CTRL1 0x13
|
||||
#define FXAS21002C_REG_CTRL2 0x14
|
||||
#define FXAS21002C_REG_CTRL3 0x15
|
||||
|
||||
enum fxas21002c_fields {
|
||||
F_DR_STATUS,
|
||||
F_OUT_X_MSB,
|
||||
F_OUT_X_LSB,
|
||||
F_OUT_Y_MSB,
|
||||
F_OUT_Y_LSB,
|
||||
F_OUT_Z_MSB,
|
||||
F_OUT_Z_LSB,
|
||||
/* DR_STATUS */
|
||||
F_ZYX_OW, F_Z_OW, F_Y_OW, F_X_OW, F_ZYX_DR, F_Z_DR, F_Y_DR, F_X_DR,
|
||||
/* F_STATUS */
|
||||
F_OVF, F_WMKF, F_CNT,
|
||||
/* F_SETUP */
|
||||
F_MODE, F_WMRK,
|
||||
/* F_EVENT */
|
||||
F_EVENT, FE_TIME,
|
||||
/* INT_SOURCE_FLAG */
|
||||
F_BOOTEND, F_SRC_FIFO, F_SRC_RT, F_SRC_DRDY,
|
||||
/* WHO_AM_I */
|
||||
F_WHO_AM_I,
|
||||
/* CTRL_REG0 */
|
||||
F_BW, F_SPIW, F_SEL, F_HPF_EN, F_FS,
|
||||
/* RT_CFG */
|
||||
F_ELE, F_ZTEFE, F_YTEFE, F_XTEFE,
|
||||
/* RT_SRC */
|
||||
F_EA, F_ZRT, F_ZRT_POL, F_YRT, F_YRT_POL, F_XRT, F_XRT_POL,
|
||||
/* RT_THS */
|
||||
F_DBCNTM, F_THS,
|
||||
/* RT_COUNT */
|
||||
F_RT_COUNT,
|
||||
/* TEMP */
|
||||
F_TEMP,
|
||||
/* CTRL_REG1 */
|
||||
F_RST, F_ST, F_DR, F_ACTIVE, F_READY,
|
||||
/* CTRL_REG2 */
|
||||
F_INT_CFG_FIFO, F_INT_EN_FIFO, F_INT_CFG_RT, F_INT_EN_RT,
|
||||
F_INT_CFG_DRDY, F_INT_EN_DRDY, F_IPOL, F_PP_OD,
|
||||
/* CTRL_REG3 */
|
||||
F_WRAPTOONE, F_EXTCTRLEN, F_FS_DOUBLE,
|
||||
/* MAX FIELDS */
|
||||
F_MAX_FIELDS,
|
||||
};
|
||||
|
||||
static const struct reg_field fxas21002c_reg_fields[] = {
|
||||
[F_DR_STATUS] = REG_FIELD(FXAS21002C_REG_STATUS, 0, 7),
|
||||
[F_OUT_X_MSB] = REG_FIELD(FXAS21002C_REG_OUT_X_MSB, 0, 7),
|
||||
[F_OUT_X_LSB] = REG_FIELD(FXAS21002C_REG_OUT_X_LSB, 0, 7),
|
||||
[F_OUT_Y_MSB] = REG_FIELD(FXAS21002C_REG_OUT_Y_MSB, 0, 7),
|
||||
[F_OUT_Y_LSB] = REG_FIELD(FXAS21002C_REG_OUT_Y_LSB, 0, 7),
|
||||
[F_OUT_Z_MSB] = REG_FIELD(FXAS21002C_REG_OUT_Z_MSB, 0, 7),
|
||||
[F_OUT_Z_LSB] = REG_FIELD(FXAS21002C_REG_OUT_Z_LSB, 0, 7),
|
||||
[F_ZYX_OW] = REG_FIELD(FXAS21002C_REG_DR_STATUS, 7, 7),
|
||||
[F_Z_OW] = REG_FIELD(FXAS21002C_REG_DR_STATUS, 6, 6),
|
||||
[F_Y_OW] = REG_FIELD(FXAS21002C_REG_DR_STATUS, 5, 5),
|
||||
[F_X_OW] = REG_FIELD(FXAS21002C_REG_DR_STATUS, 4, 4),
|
||||
[F_ZYX_DR] = REG_FIELD(FXAS21002C_REG_DR_STATUS, 3, 3),
|
||||
[F_Z_DR] = REG_FIELD(FXAS21002C_REG_DR_STATUS, 2, 2),
|
||||
[F_Y_DR] = REG_FIELD(FXAS21002C_REG_DR_STATUS, 1, 1),
|
||||
[F_X_DR] = REG_FIELD(FXAS21002C_REG_DR_STATUS, 0, 0),
|
||||
[F_OVF] = REG_FIELD(FXAS21002C_REG_F_STATUS, 7, 7),
|
||||
[F_WMKF] = REG_FIELD(FXAS21002C_REG_F_STATUS, 6, 6),
|
||||
[F_CNT] = REG_FIELD(FXAS21002C_REG_F_STATUS, 0, 5),
|
||||
[F_MODE] = REG_FIELD(FXAS21002C_REG_F_SETUP, 6, 7),
|
||||
[F_WMRK] = REG_FIELD(FXAS21002C_REG_F_SETUP, 0, 5),
|
||||
[F_EVENT] = REG_FIELD(FXAS21002C_REG_F_EVENT, 5, 5),
|
||||
[FE_TIME] = REG_FIELD(FXAS21002C_REG_F_EVENT, 0, 4),
|
||||
[F_BOOTEND] = REG_FIELD(FXAS21002C_REG_INT_SRC_FLAG, 3, 3),
|
||||
[F_SRC_FIFO] = REG_FIELD(FXAS21002C_REG_INT_SRC_FLAG, 2, 2),
|
||||
[F_SRC_RT] = REG_FIELD(FXAS21002C_REG_INT_SRC_FLAG, 1, 1),
|
||||
[F_SRC_DRDY] = REG_FIELD(FXAS21002C_REG_INT_SRC_FLAG, 0, 0),
|
||||
[F_WHO_AM_I] = REG_FIELD(FXAS21002C_REG_WHO_AM_I, 0, 7),
|
||||
[F_BW] = REG_FIELD(FXAS21002C_REG_CTRL0, 6, 7),
|
||||
[F_SPIW] = REG_FIELD(FXAS21002C_REG_CTRL0, 5, 5),
|
||||
[F_SEL] = REG_FIELD(FXAS21002C_REG_CTRL0, 3, 4),
|
||||
[F_HPF_EN] = REG_FIELD(FXAS21002C_REG_CTRL0, 2, 2),
|
||||
[F_FS] = REG_FIELD(FXAS21002C_REG_CTRL0, 0, 1),
|
||||
[F_ELE] = REG_FIELD(FXAS21002C_REG_RT_CFG, 3, 3),
|
||||
[F_ZTEFE] = REG_FIELD(FXAS21002C_REG_RT_CFG, 2, 2),
|
||||
[F_YTEFE] = REG_FIELD(FXAS21002C_REG_RT_CFG, 1, 1),
|
||||
[F_XTEFE] = REG_FIELD(FXAS21002C_REG_RT_CFG, 0, 0),
|
||||
[F_EA] = REG_FIELD(FXAS21002C_REG_RT_SRC, 6, 6),
|
||||
[F_ZRT] = REG_FIELD(FXAS21002C_REG_RT_SRC, 5, 5),
|
||||
[F_ZRT_POL] = REG_FIELD(FXAS21002C_REG_RT_SRC, 4, 4),
|
||||
[F_YRT] = REG_FIELD(FXAS21002C_REG_RT_SRC, 3, 3),
|
||||
[F_YRT_POL] = REG_FIELD(FXAS21002C_REG_RT_SRC, 2, 2),
|
||||
[F_XRT] = REG_FIELD(FXAS21002C_REG_RT_SRC, 1, 1),
|
||||
[F_XRT_POL] = REG_FIELD(FXAS21002C_REG_RT_SRC, 0, 0),
|
||||
[F_DBCNTM] = REG_FIELD(FXAS21002C_REG_RT_THS, 7, 7),
|
||||
[F_THS] = REG_FIELD(FXAS21002C_REG_RT_SRC, 0, 6),
|
||||
[F_RT_COUNT] = REG_FIELD(FXAS21002C_REG_RT_COUNT, 0, 7),
|
||||
[F_TEMP] = REG_FIELD(FXAS21002C_REG_TEMP, 0, 7),
|
||||
[F_RST] = REG_FIELD(FXAS21002C_REG_CTRL1, 6, 6),
|
||||
[F_ST] = REG_FIELD(FXAS21002C_REG_CTRL1, 5, 5),
|
||||
[F_DR] = REG_FIELD(FXAS21002C_REG_CTRL1, 2, 4),
|
||||
[F_ACTIVE] = REG_FIELD(FXAS21002C_REG_CTRL1, 1, 1),
|
||||
[F_READY] = REG_FIELD(FXAS21002C_REG_CTRL1, 0, 0),
|
||||
[F_INT_CFG_FIFO] = REG_FIELD(FXAS21002C_REG_CTRL2, 7, 7),
|
||||
[F_INT_EN_FIFO] = REG_FIELD(FXAS21002C_REG_CTRL2, 6, 6),
|
||||
[F_INT_CFG_RT] = REG_FIELD(FXAS21002C_REG_CTRL2, 5, 5),
|
||||
[F_INT_EN_RT] = REG_FIELD(FXAS21002C_REG_CTRL2, 4, 4),
|
||||
[F_INT_CFG_DRDY] = REG_FIELD(FXAS21002C_REG_CTRL2, 3, 3),
|
||||
[F_INT_EN_DRDY] = REG_FIELD(FXAS21002C_REG_CTRL2, 2, 2),
|
||||
[F_IPOL] = REG_FIELD(FXAS21002C_REG_CTRL2, 1, 1),
|
||||
[F_PP_OD] = REG_FIELD(FXAS21002C_REG_CTRL2, 0, 0),
|
||||
[F_WRAPTOONE] = REG_FIELD(FXAS21002C_REG_CTRL3, 3, 3),
|
||||
[F_EXTCTRLEN] = REG_FIELD(FXAS21002C_REG_CTRL3, 2, 2),
|
||||
[F_FS_DOUBLE] = REG_FIELD(FXAS21002C_REG_CTRL3, 0, 0),
|
||||
};
|
||||
|
||||
extern const struct dev_pm_ops fxas21002c_pm_ops;
|
||||
|
||||
int fxas21002c_core_probe(struct device *dev, struct regmap *regmap, int irq,
|
||||
const char *name);
|
||||
void fxas21002c_core_remove(struct device *dev);
|
||||
#endif
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,69 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Driver for NXP FXAS21002C Gyroscope - I2C
|
||||
*
|
||||
* Copyright (C) 2018 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "fxas21002c.h"
|
||||
|
||||
static const struct regmap_config fxas21002c_regmap_i2c_conf = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = FXAS21002C_REG_CTRL3,
|
||||
};
|
||||
|
||||
static int fxas21002c_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c, &fxas21002c_regmap_i2c_conf);
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(&i2c->dev, "Failed to register i2c regmap: %ld\n",
|
||||
PTR_ERR(regmap));
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
return fxas21002c_core_probe(&i2c->dev, regmap, i2c->irq, i2c->name);
|
||||
}
|
||||
|
||||
static int fxas21002c_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
fxas21002c_core_remove(&i2c->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id fxas21002c_i2c_id[] = {
|
||||
{ "fxas21002c", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, fxas21002c_i2c_id);
|
||||
|
||||
static const struct of_device_id fxas21002c_i2c_of_match[] = {
|
||||
{ .compatible = "nxp,fxas21002c", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fxas21002c_i2c_of_match);
|
||||
|
||||
static struct i2c_driver fxas21002c_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "fxas21002c_i2c",
|
||||
.pm = &fxas21002c_pm_ops,
|
||||
.of_match_table = fxas21002c_i2c_of_match,
|
||||
},
|
||||
.probe_new = fxas21002c_i2c_probe,
|
||||
.remove = fxas21002c_i2c_remove,
|
||||
.id_table = fxas21002c_i2c_id,
|
||||
};
|
||||
module_i2c_driver(fxas21002c_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Rui Miguel Silva <rui.silva@linaro.org>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("FXAS21002C I2C Gyro driver");
|
|
@ -0,0 +1,70 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Driver for NXP Fxas21002c Gyroscope - SPI
|
||||
*
|
||||
* Copyright (C) 2019 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
#include "fxas21002c.h"
|
||||
|
||||
static const struct regmap_config fxas21002c_regmap_spi_conf = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = FXAS21002C_REG_CTRL3,
|
||||
};
|
||||
|
||||
static int fxas21002c_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = devm_regmap_init_spi(spi, &fxas21002c_regmap_spi_conf);
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(&spi->dev, "Failed to register spi regmap: %ld\n",
|
||||
PTR_ERR(regmap));
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
return fxas21002c_core_probe(&spi->dev, regmap, spi->irq, id->name);
|
||||
}
|
||||
|
||||
static int fxas21002c_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
fxas21002c_core_remove(&spi->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spi_device_id fxas21002c_spi_id[] = {
|
||||
{ "fxas21002c", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, fxas21002c_spi_id);
|
||||
|
||||
static const struct of_device_id fxas21002c_spi_of_match[] = {
|
||||
{ .compatible = "nxp,fxas21002c", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fxas21002c_spi_of_match);
|
||||
|
||||
static struct spi_driver fxas21002c_spi_driver = {
|
||||
.driver = {
|
||||
.name = "fxas21002c_spi",
|
||||
.pm = &fxas21002c_pm_ops,
|
||||
.of_match_table = fxas21002c_spi_of_match,
|
||||
},
|
||||
.probe = fxas21002c_spi_probe,
|
||||
.remove = fxas21002c_spi_remove,
|
||||
.id_table = fxas21002c_spi_id,
|
||||
};
|
||||
module_spi_driver(fxas21002c_spi_driver);
|
||||
|
||||
MODULE_AUTHOR("Rui Miguel Silva <rui.silva@linaro.org>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("FXAS21002C SPI Gyro driver");
|
|
@ -865,7 +865,7 @@ static int mpu3050_power_up(struct mpu3050 *mpu3050)
|
|||
dev_err(mpu3050->dev, "error setting power mode\n");
|
||||
return ret;
|
||||
}
|
||||
msleep(10);
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ config IIO_ST_LSM6DSX
|
|||
help
|
||||
Say yes here to build support for STMicroelectronics LSM6DSx imu
|
||||
sensor. Supported devices: lsm6ds3, lsm6ds3h, lsm6dsl, lsm6dsm,
|
||||
ism330dlc, lsm6dso, lsm6dsox, asm330lhh
|
||||
ism330dlc, lsm6dso, lsm6dsox, asm330lhh, lsm6dsr
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called st_lsm6dsx.
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define ST_LSM6DSO_DEV_NAME "lsm6dso"
|
||||
#define ST_ASM330LHH_DEV_NAME "asm330lhh"
|
||||
#define ST_LSM6DSOX_DEV_NAME "lsm6dsox"
|
||||
#define ST_LSM6DSR_DEV_NAME "lsm6dsr"
|
||||
|
||||
enum st_lsm6dsx_hw_id {
|
||||
ST_LSM6DS3_ID,
|
||||
|
@ -32,6 +33,7 @@ enum st_lsm6dsx_hw_id {
|
|||
ST_LSM6DSO_ID,
|
||||
ST_ASM330LHH_ID,
|
||||
ST_LSM6DSOX_ID,
|
||||
ST_LSM6DSR_ID,
|
||||
ST_LSM6DSX_MAX_ID,
|
||||
};
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
* (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated depending on the
|
||||
* value of the decimation factor and ODR set for each FIFO data set.
|
||||
*
|
||||
* LSM6DSO/LSM6DSOX/ASM330LHH: The FIFO buffer can be configured to store data
|
||||
* from gyroscope and accelerometer. Each sample is queued with a tag (1B)
|
||||
* indicating data source (gyroscope, accelerometer, hw timer).
|
||||
* LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR: The FIFO buffer can be configured to
|
||||
* store data from gyroscope and accelerometer. Each sample is queued with
|
||||
* a tag (1B) indicating data source (gyroscope, accelerometer, hw timer).
|
||||
*
|
||||
* FIFO supported modes:
|
||||
* - BYPASS: FIFO disabled
|
||||
|
@ -506,7 +506,7 @@ st_lsm6dsx_push_tagged_data(struct st_lsm6dsx_hw *hw, u8 tag,
|
|||
}
|
||||
|
||||
/**
|
||||
* st_lsm6dsx_read_tagged_fifo() - LSM6DSO/LSM6DSOX/ASM330LHH read FIFO routine
|
||||
* st_lsm6dsx_read_tagged_fifo() - tagged hw FIFO read routine
|
||||
* @hw: Pointer to instance of struct st_lsm6dsx_hw.
|
||||
*
|
||||
* Read samples from the hw FIFO and push them to IIO buffers.
|
||||
|
@ -517,7 +517,6 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
|
|||
{
|
||||
u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE;
|
||||
u16 fifo_len, fifo_diff_mask;
|
||||
struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor;
|
||||
u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE], tag;
|
||||
bool reset_ts = false;
|
||||
int i, err, read_len;
|
||||
|
@ -539,9 +538,6 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
|
|||
if (!fifo_len)
|
||||
return 0;
|
||||
|
||||
acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
|
||||
gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
|
||||
|
||||
for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
|
||||
err = st_lsm6dsx_read_block(hw,
|
||||
ST_LSM6DSX_REG_FIFO_OUT_TAG_ADDR,
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
|
||||
* - FIFO size: 4KB
|
||||
*
|
||||
* - LSM6DSO/LSM6DSOX/ASM330LHH
|
||||
* - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR
|
||||
* - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
|
||||
* - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
|
||||
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
|
||||
|
@ -62,37 +62,19 @@
|
|||
#define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13
|
||||
#define ST_LSM6DSX_REG_INT2_ON_INT1_MASK BIT(5)
|
||||
|
||||
#define ST_LSM6DSX_REG_ACC_ODR_ADDR 0x10
|
||||
#define ST_LSM6DSX_REG_ACC_ODR_MASK GENMASK(7, 4)
|
||||
#define ST_LSM6DSX_REG_ACC_FS_ADDR 0x10
|
||||
#define ST_LSM6DSX_REG_ACC_FS_MASK GENMASK(3, 2)
|
||||
#define ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR 0x28
|
||||
#define ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR 0x2a
|
||||
#define ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR 0x2c
|
||||
|
||||
#define ST_LSM6DSX_REG_GYRO_ODR_ADDR 0x11
|
||||
#define ST_LSM6DSX_REG_GYRO_ODR_MASK GENMASK(7, 4)
|
||||
#define ST_LSM6DSX_REG_GYRO_FS_ADDR 0x11
|
||||
#define ST_LSM6DSX_REG_GYRO_FS_MASK GENMASK(3, 2)
|
||||
#define ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR 0x22
|
||||
#define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR 0x24
|
||||
#define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR 0x26
|
||||
|
||||
#define ST_LSM6DSX_ACC_FS_2G_GAIN IIO_G_TO_M_S_2(61)
|
||||
#define ST_LSM6DSX_ACC_FS_4G_GAIN IIO_G_TO_M_S_2(122)
|
||||
#define ST_LSM6DSX_ACC_FS_8G_GAIN IIO_G_TO_M_S_2(244)
|
||||
#define ST_LSM6DSX_ACC_FS_16G_GAIN IIO_G_TO_M_S_2(488)
|
||||
|
||||
#define ST_LSM6DSX_GYRO_FS_245_GAIN IIO_DEGREE_TO_RAD(8750)
|
||||
#define ST_LSM6DSX_GYRO_FS_500_GAIN IIO_DEGREE_TO_RAD(17500)
|
||||
#define ST_LSM6DSX_GYRO_FS_1000_GAIN IIO_DEGREE_TO_RAD(35000)
|
||||
#define ST_LSM6DSX_GYRO_FS_2000_GAIN IIO_DEGREE_TO_RAD(70000)
|
||||
|
||||
static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = {
|
||||
[ST_LSM6DSX_ID_ACC] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSX_REG_ACC_ODR_ADDR,
|
||||
.mask = ST_LSM6DSX_REG_ACC_ODR_MASK,
|
||||
.addr = 0x10,
|
||||
.mask = GENMASK(7, 4),
|
||||
},
|
||||
.odr_avl[0] = { 13, 0x01 },
|
||||
.odr_avl[1] = { 26, 0x02 },
|
||||
|
@ -103,8 +85,8 @@ static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = {
|
|||
},
|
||||
[ST_LSM6DSX_ID_GYRO] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSX_REG_GYRO_ODR_ADDR,
|
||||
.mask = ST_LSM6DSX_REG_GYRO_ODR_MASK,
|
||||
.addr = 0x11,
|
||||
.mask = GENMASK(7, 4),
|
||||
},
|
||||
.odr_avl[0] = { 13, 0x01 },
|
||||
.odr_avl[1] = { 26, 0x02 },
|
||||
|
@ -118,23 +100,23 @@ static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = {
|
|||
static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = {
|
||||
[ST_LSM6DSX_ID_ACC] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSX_REG_ACC_FS_ADDR,
|
||||
.mask = ST_LSM6DSX_REG_ACC_FS_MASK,
|
||||
.addr = 0x10,
|
||||
.mask = GENMASK(3, 2),
|
||||
},
|
||||
.fs_avl[0] = { ST_LSM6DSX_ACC_FS_2G_GAIN, 0x0 },
|
||||
.fs_avl[1] = { ST_LSM6DSX_ACC_FS_4G_GAIN, 0x2 },
|
||||
.fs_avl[2] = { ST_LSM6DSX_ACC_FS_8G_GAIN, 0x3 },
|
||||
.fs_avl[3] = { ST_LSM6DSX_ACC_FS_16G_GAIN, 0x1 },
|
||||
.fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
|
||||
.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
|
||||
.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
|
||||
.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
|
||||
},
|
||||
[ST_LSM6DSX_ID_GYRO] = {
|
||||
.reg = {
|
||||
.addr = ST_LSM6DSX_REG_GYRO_FS_ADDR,
|
||||
.mask = ST_LSM6DSX_REG_GYRO_FS_MASK,
|
||||
.addr = 0x11,
|
||||
.mask = GENMASK(3, 2),
|
||||
},
|
||||
.fs_avl[0] = { ST_LSM6DSX_GYRO_FS_245_GAIN, 0x0 },
|
||||
.fs_avl[1] = { ST_LSM6DSX_GYRO_FS_500_GAIN, 0x1 },
|
||||
.fs_avl[2] = { ST_LSM6DSX_GYRO_FS_1000_GAIN, 0x2 },
|
||||
.fs_avl[3] = { ST_LSM6DSX_GYRO_FS_2000_GAIN, 0x3 },
|
||||
.fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
|
||||
.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
|
||||
.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
|
||||
.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -387,6 +369,71 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
.wai = 0x6b,
|
||||
.max_fifo_size = 512,
|
||||
.id = {
|
||||
[0] = ST_LSM6DSR_ID,
|
||||
},
|
||||
.batch = {
|
||||
[ST_LSM6DSX_ID_ACC] = {
|
||||
.addr = 0x09,
|
||||
.mask = GENMASK(3, 0),
|
||||
},
|
||||
[ST_LSM6DSX_ID_GYRO] = {
|
||||
.addr = 0x09,
|
||||
.mask = GENMASK(7, 4),
|
||||
},
|
||||
},
|
||||
.fifo_ops = {
|
||||
.read_fifo = st_lsm6dsx_read_tagged_fifo,
|
||||
.fifo_th = {
|
||||
.addr = 0x07,
|
||||
.mask = GENMASK(8, 0),
|
||||
},
|
||||
.fifo_diff = {
|
||||
.addr = 0x3a,
|
||||
.mask = GENMASK(8, 0),
|
||||
},
|
||||
.th_wl = 1,
|
||||
},
|
||||
.ts_settings = {
|
||||
.timer_en = {
|
||||
.addr = 0x19,
|
||||
.mask = BIT(5),
|
||||
},
|
||||
.decimator = {
|
||||
.addr = 0x0a,
|
||||
.mask = GENMASK(7, 6),
|
||||
},
|
||||
},
|
||||
.shub_settings = {
|
||||
.page_mux = {
|
||||
.addr = 0x01,
|
||||
.mask = BIT(6),
|
||||
},
|
||||
.master_en = {
|
||||
.addr = 0x14,
|
||||
.mask = BIT(2),
|
||||
},
|
||||
.pullup_en = {
|
||||
.addr = 0x14,
|
||||
.mask = BIT(3),
|
||||
},
|
||||
.aux_sens = {
|
||||
.addr = 0x14,
|
||||
.mask = GENMASK(1, 0),
|
||||
},
|
||||
.wr_once = {
|
||||
.addr = 0x14,
|
||||
.mask = BIT(6),
|
||||
},
|
||||
.shub_out = 0x02,
|
||||
.slv0_addr = 0x15,
|
||||
.dw_slv0_addr = 0x21,
|
||||
.batch_en = BIT(3),
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
|
||||
|
|
|
@ -73,6 +73,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
|
|||
.compatible = "st,lsm6dsox",
|
||||
.data = (void *)ST_LSM6DSOX_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lsm6dsr",
|
||||
.data = (void *)ST_LSM6DSR_ID,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
|
||||
|
@ -86,6 +90,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
|
|||
{ ST_LSM6DSO_DEV_NAME, ST_LSM6DSO_ID },
|
||||
{ ST_ASM330LHH_DEV_NAME, ST_ASM330LHH_ID },
|
||||
{ ST_LSM6DSOX_DEV_NAME, ST_LSM6DSOX_ID },
|
||||
{ ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
|
||||
|
|
|
@ -73,6 +73,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
|
|||
.compatible = "st,lsm6dsox",
|
||||
.data = (void *)ST_LSM6DSOX_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lsm6dsr",
|
||||
.data = (void *)ST_LSM6DSR_ID,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
|
||||
|
@ -86,6 +90,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
|
|||
{ ST_LSM6DSO_DEV_NAME, ST_LSM6DSO_ID },
|
||||
{ ST_ASM330LHH_DEV_NAME, ST_ASM330LHH_ID },
|
||||
{ ST_LSM6DSOX_DEV_NAME, ST_LSM6DSOX_ID },
|
||||
{ ST_LSM6DSR_DEV_NAME, ST_LSM6DSR_ID },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
|
||||
|
|
|
@ -68,12 +68,19 @@ config RFD77402
|
|||
module will be called rfd77402.
|
||||
|
||||
config SRF04
|
||||
tristate "Devantech SRF04 ultrasonic ranger sensor"
|
||||
tristate "GPIO bitbanged ultrasonic ranger sensor (SRF04, MB1000)"
|
||||
depends on GPIOLIB
|
||||
help
|
||||
Say Y here to build a driver for Devantech SRF04 ultrasonic
|
||||
Say Y here to build a driver for GPIO bitbanged ultrasonic
|
||||
ranger sensor. This driver can be used to measure the distance
|
||||
of objects. It is using two GPIOs.
|
||||
Actually Supported types are:
|
||||
- Devantech SRF04
|
||||
- Maxbotix mb1000
|
||||
- Maxbotix mb1010
|
||||
- Maxbotix mb1020
|
||||
- Maxbotix mb1030
|
||||
- Maxbotix mb1040
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called srf04.
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* trig: --+ +------------------------------------------------------
|
||||
* ^ ^
|
||||
* |<->|
|
||||
* udelay(10)
|
||||
* udelay(trigger_pulse_us)
|
||||
*
|
||||
* ultra +-+ +-+ +-+
|
||||
* sonic | | | | | |
|
||||
|
@ -48,6 +48,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/sched.h>
|
||||
|
@ -56,6 +57,10 @@
|
|||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/sysfs.h>
|
||||
|
||||
struct srf04_cfg {
|
||||
unsigned long trigger_pulse_us;
|
||||
};
|
||||
|
||||
struct srf04_data {
|
||||
struct device *dev;
|
||||
struct gpio_desc *gpiod_trig;
|
||||
|
@ -66,6 +71,15 @@ struct srf04_data {
|
|||
ktime_t ts_falling;
|
||||
struct completion rising;
|
||||
struct completion falling;
|
||||
const struct srf04_cfg *cfg;
|
||||
};
|
||||
|
||||
static const struct srf04_cfg srf04_cfg = {
|
||||
.trigger_pulse_us = 10,
|
||||
};
|
||||
|
||||
static const struct srf04_cfg mb_lv_cfg = {
|
||||
.trigger_pulse_us = 20,
|
||||
};
|
||||
|
||||
static irqreturn_t srf04_handle_irq(int irq, void *dev_id)
|
||||
|
@ -102,7 +116,7 @@ static int srf04_read(struct srf04_data *data)
|
|||
reinit_completion(&data->falling);
|
||||
|
||||
gpiod_set_value(data->gpiod_trig, 1);
|
||||
udelay(10);
|
||||
udelay(data->cfg->trigger_pulse_us);
|
||||
gpiod_set_value(data->gpiod_trig, 0);
|
||||
|
||||
/* it cannot take more than 20 ms */
|
||||
|
@ -215,6 +229,18 @@ static const struct iio_chan_spec srf04_chan_spec[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct of_device_id of_srf04_match[] = {
|
||||
{ .compatible = "devantech,srf04", .data = &srf04_cfg},
|
||||
{ .compatible = "maxbotix,mb1000", .data = &mb_lv_cfg},
|
||||
{ .compatible = "maxbotix,mb1010", .data = &mb_lv_cfg},
|
||||
{ .compatible = "maxbotix,mb1020", .data = &mb_lv_cfg},
|
||||
{ .compatible = "maxbotix,mb1030", .data = &mb_lv_cfg},
|
||||
{ .compatible = "maxbotix,mb1040", .data = &mb_lv_cfg},
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, of_srf04_match);
|
||||
|
||||
static int srf04_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
@ -230,6 +256,7 @@ static int srf04_probe(struct platform_device *pdev)
|
|||
|
||||
data = iio_priv(indio_dev);
|
||||
data->dev = dev;
|
||||
data->cfg = of_match_device(of_srf04_match, dev)->data;
|
||||
|
||||
mutex_init(&data->lock);
|
||||
init_completion(&data->rising);
|
||||
|
@ -280,13 +307,6 @@ static int srf04_probe(struct platform_device *pdev)
|
|||
return devm_iio_device_register(dev, indio_dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id of_srf04_match[] = {
|
||||
{ .compatible = "devantech,srf04", },
|
||||
{},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, of_srf04_match);
|
||||
|
||||
static struct platform_driver srf04_driver = {
|
||||
.probe = srf04_probe,
|
||||
.driver = {
|
||||
|
|
|
@ -210,6 +210,9 @@ static int max31856_read_raw(struct iio_dev *indio_dev,
|
|||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -5,22 +5,25 @@
|
|||
* Copyright 2011 Analog Devices Inc.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/sysfs.h>
|
||||
#include "dds.h"
|
||||
|
||||
#include "ad9832.h"
|
||||
|
||||
#include "dds.h"
|
||||
|
||||
/* Registers */
|
||||
|
||||
#define AD9832_FREQ0LL 0x0
|
||||
|
@ -93,7 +96,7 @@ struct ad9832_state {
|
|||
struct spi_device *spi;
|
||||
struct regulator *avdd;
|
||||
struct regulator *dvdd;
|
||||
unsigned long mclk;
|
||||
struct clk *mclk;
|
||||
unsigned short ctrl_fp;
|
||||
unsigned short ctrl_ss;
|
||||
unsigned short ctrl_src;
|
||||
|
@ -128,10 +131,10 @@ static int ad9832_write_frequency(struct ad9832_state *st,
|
|||
{
|
||||
unsigned long regval;
|
||||
|
||||
if (fout > (st->mclk / 2))
|
||||
if (fout > (clk_get_rate(st->mclk) / 2))
|
||||
return -EINVAL;
|
||||
|
||||
regval = ad9832_calc_freqreg(st->mclk, fout);
|
||||
regval = ad9832_calc_freqreg(clk_get_rate(st->mclk), fout);
|
||||
|
||||
st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) |
|
||||
(addr << ADD_SHIFT) |
|
||||
|
@ -332,7 +335,16 @@ static int ad9832_probe(struct spi_device *spi)
|
|||
goto error_disable_avdd;
|
||||
}
|
||||
|
||||
st->mclk = pdata->mclk;
|
||||
st->mclk = devm_clk_get(&spi->dev, "mclk");
|
||||
if (IS_ERR(st->mclk)) {
|
||||
ret = PTR_ERR(st->mclk);
|
||||
goto error_disable_dvdd;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(st->mclk);
|
||||
if (ret < 0)
|
||||
goto error_disable_dvdd;
|
||||
|
||||
st->spi = spi;
|
||||
mutex_init(&st->lock);
|
||||
|
||||
|
@ -383,39 +395,41 @@ static int ad9832_probe(struct spi_device *spi)
|
|||
ret = spi_sync(st->spi, &st->msg);
|
||||
if (ret) {
|
||||
dev_err(&spi->dev, "device init failed\n");
|
||||
goto error_disable_dvdd;
|
||||
goto error_unprepare_mclk;
|
||||
}
|
||||
|
||||
ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0);
|
||||
if (ret)
|
||||
goto error_disable_dvdd;
|
||||
goto error_unprepare_mclk;
|
||||
|
||||
ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1);
|
||||
if (ret)
|
||||
goto error_disable_dvdd;
|
||||
goto error_unprepare_mclk;
|
||||
|
||||
ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0);
|
||||
if (ret)
|
||||
goto error_disable_dvdd;
|
||||
goto error_unprepare_mclk;
|
||||
|
||||
ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1);
|
||||
if (ret)
|
||||
goto error_disable_dvdd;
|
||||
goto error_unprepare_mclk;
|
||||
|
||||
ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2);
|
||||
if (ret)
|
||||
goto error_disable_dvdd;
|
||||
goto error_unprepare_mclk;
|
||||
|
||||
ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3);
|
||||
if (ret)
|
||||
goto error_disable_dvdd;
|
||||
goto error_unprepare_mclk;
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret)
|
||||
goto error_disable_dvdd;
|
||||
goto error_unprepare_mclk;
|
||||
|
||||
return 0;
|
||||
|
||||
error_unprepare_mclk:
|
||||
clk_disable_unprepare(st->mclk);
|
||||
error_disable_dvdd:
|
||||
regulator_disable(st->dvdd);
|
||||
error_disable_avdd:
|
||||
|
@ -430,6 +444,7 @@ static int ad9832_remove(struct spi_device *spi)
|
|||
struct ad9832_state *st = iio_priv(indio_dev);
|
||||
|
||||
iio_device_unregister(indio_dev);
|
||||
clk_disable_unprepare(st->mclk);
|
||||
regulator_disable(st->dvdd);
|
||||
regulator_disable(st->avdd);
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
|
||||
struct ad9832_platform_data {
|
||||
unsigned long mclk;
|
||||
unsigned long freq0;
|
||||
unsigned long freq1;
|
||||
unsigned short phase0;
|
||||
|
|
|
@ -285,7 +285,7 @@ ssize_t ad9834_show_out0_wavetype_available(struct device *dev,
|
|||
struct ad9834_state *st = iio_priv(indio_dev);
|
||||
char *str;
|
||||
|
||||
if ((st->devid == ID_AD9833) || (st->devid == ID_AD9837))
|
||||
if (st->devid == ID_AD9833 || st->devid == ID_AD9837)
|
||||
str = "sine triangle square";
|
||||
else if (st->control & AD9834_OPBITEN)
|
||||
str = "sine";
|
||||
|
|
|
@ -73,6 +73,15 @@
|
|||
|
||||
#define TIM17_OC1 "tim17_oc1"
|
||||
|
||||
#if IS_REACHABLE(CONFIG_IIO_STM32_TIMER_TRIGGER)
|
||||
bool is_stm32_timer_trigger(struct iio_trigger *trig);
|
||||
|
||||
#else
|
||||
static inline bool is_stm32_timer_trigger(struct iio_trigger *trig)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_IIO_STM32_TIMER_TRIGGER)
|
||||
pr_warn_once("stm32-timer-trigger not linked in\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче