mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-19 18:53:52 +08:00
First set of IIO new device support, features and cleanup for 5.19
Usual mixed bag. Stand out this time is Andy Shevchenko's continuing effort to move drivers over the generic firmware interfaces. Device support * sprd,sc2720 - upm9620 binding addition. - Refactor and support for sc2720, sc2721 and sc2730. * ti,ads1015 - Refactor driver and add support for TLA2024. Device support (IDs only) * invensense,mpu6050 - Add ID for ICM-20608-D. * st,accel: - Add ID for lis302dl. * st,lsm6dsx - Add support for ASM330LHHX (can fallback to LSM6DSR.) Features * convert drivers to device properties - IIO core - adi,ad7266 - adi,adis16480 - adi,adxl355 - bosch,bmi160 - domintech,dmard06 - fsl,fxas21002c - invensense,mpu3050 - linear,ltc2983 - linear,ltc2632 - maxbotix,mb1232 - maxim,max31856 - maxim,max31865 - multiplexer - ping - rescale - taos,tsl2772 * core - Add runtime check on whether realbits fit in storagebits for each channel. * adi,ad_sigma_delta - Add sequencer support and relevant update_scan_mode callbacks for adi,ad7192 and adi,ad7124. Cleanup and minor fixes * MAINTAINERS - Update Lorenzo Bianconi's email address for IIO drivers. - Add entry for ad3552r and update maintainer in dt-binding doc. * tree-wide - Replace strtobool() with kstrtobool(). - Drop false OF dependencies. * core - Tidy up and document IIO modes. - Take iio_buffer_enabled() out of header allowing current_mode to be moved to the opaque structure. - As all kfifo buffers use the same mode value, drop that parameter and set it unconditionally. - White space fixes and similar. - Drop use of list iterator variable for list_for_each_entry_continue_reverse and use list_prepare_entry to restart. * sysfs-trigger - Replace use of 'found' variable with dedicate list iterator variable. * adi,ad7124 - Drop misleading shift. * adi,ad2s1210 - Remove redundant local variable assignment. * adi,adis16480 - Use local device pointer to reduce repetition. - Improve handling of clocks. * domintech,dmard09 - White space. * dummy driver - Improve error handling. * fsl,mma8452 - Add missing documentation of name element. * invensense,mpu3050 - Stop remove() returning non 0. * kionix,kxsd9 - White space. * linear,ltc2688 - Use local variable for struct device. - Combine of_node_put() error handling paths. * linear,ltc2983 - Avoid use of constants in messages where a define is available. * microchip,mcp4131 - Fix compatible in dt example. * pni,rm3100 - Stop directly accessing iio_dev->current_mode just to find out if the buffer is enabled. * renesas,rzg2l - Relax kconfig constraint to include newer devices. * sprd,sc27xx - Fix wrong scaling mask. - Improve the calibration values. * samsung,ssp - Replace a 'found' variable in favor of an explicit value that was found. * sensortek,stk3xx - Add proximity-near-level binding and driver support. * st,st_sensors: - Drop unused accel_type enum. - Return early in *_write_raw() - Drop unnecessary locking in _avail functions. - Add local lock to protect odr against concurrent updates allowing mlock to no longer be used outside of the core. - Use iio_device_claim_direct_mode() rather than racy checking of the current mode. * st,stmpe-adc - Fix checks on wait_for_completion_timeout(). - Allow use of of_device_id for matching. * st,stm32-dfsdm - Stop accessing iio_dev->current_mode to find out if the buffer is enabled (so we can hide that variable in the opaque structure) * st,vl53l0x - Fix checks on wait_for_completion_timeout. * ti,ads1015 - Add missing ID for ti,ads1115 in binding doc. - Convert from repeated chip ID look up to selecting static const data. - Switch to read_avail() callback. * ti,ads8688 - Use of_device_id for driver matching. * ti,palmas-adc - Drop a warning on minor calibration mismatch leading to slightly negative values after applying the calibration. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmJy4f0RHGppYzIzQGtl cm5lbC5vcmcACgkQVIU0mcT0FohyzQ//e2RJF/oUjd5WreX9fywnK2qwXE0n6yfQ OrXuLvdAZ4ZwELmQyCg7XWVZY1u6JXvW1/TJXpjI0Y4sXSCSs+Z514BJOQYOrEyv 2MH5mqkXq5IeskKAOxKBLeOz8e8txKyB2S4lDSVH11y40i32U+3SMdZHUt4ThVJU xd6FMJqEvXrbramQSj3O61YvICBedOcoKe4Da7nJtmr42zkDuBYJRlmtCnRoXx1l wrNgozEdqMh/JIRayVjlKfPpu3OiEFwt/uKvLEepKei/djUMdRnMyjTcXTziDGNg +B/51pWm7BLKE3YiqVAFZGBOi7OXZ0bRFVaUZyPOOP/xRr7DrdDRgFVpM4/Z9D0y p3anrWwkp6UF+IlatxjIDNGiAlWlWgNUZsFxWBMjRHAunOGhlrTNV7PVh81+LNBM I8Z9B+FDW/ECuxRSP2oK0an+4fVwJiOfGWSnuo6cIkW2ewh8kwr6Vvnu3bDytyew 7xU9TvJN3fhYgU8pWK1VQ3ZIYan4zcAL/v40KBHDVIF49iKerYbKHGkCI4vJvakH lzf+dsUzYfQesTmB2sQUDdVvwpBtVd/xbD+mytRWv3bjapGIZ9r9LDGbjr8rgH0M egyPpxfdfVYjTWdpIx/tDHfyPEkuL7EjitKV7B83NbMq0N6GhQN2sT8L8DM7aC5p 0x7kV5B4ZnE= =wZYX -----END PGP SIGNATURE----- Merge tag 'iio-for-5.19a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-next Jonathan writes: First set of IIO new device support, features and cleanup for 5.19 Usual mixed bag. Stand out this time is Andy Shevchenko's continuing effort to move drivers over the generic firmware interfaces. Device support * sprd,sc2720 - upm9620 binding addition. - Refactor and support for sc2720, sc2721 and sc2730. * ti,ads1015 - Refactor driver and add support for TLA2024. Device support (IDs only) * invensense,mpu6050 - Add ID for ICM-20608-D. * st,accel: - Add ID for lis302dl. * st,lsm6dsx - Add support for ASM330LHHX (can fallback to LSM6DSR.) Features * convert drivers to device properties - IIO core - adi,ad7266 - adi,adis16480 - adi,adxl355 - bosch,bmi160 - domintech,dmard06 - fsl,fxas21002c - invensense,mpu3050 - linear,ltc2983 - linear,ltc2632 - maxbotix,mb1232 - maxim,max31856 - maxim,max31865 - multiplexer - ping - rescale - taos,tsl2772 * core - Add runtime check on whether realbits fit in storagebits for each channel. * adi,ad_sigma_delta - Add sequencer support and relevant update_scan_mode callbacks for adi,ad7192 and adi,ad7124. Cleanup and minor fixes * MAINTAINERS - Update Lorenzo Bianconi's email address for IIO drivers. - Add entry for ad3552r and update maintainer in dt-binding doc. * tree-wide - Replace strtobool() with kstrtobool(). - Drop false OF dependencies. * core - Tidy up and document IIO modes. - Take iio_buffer_enabled() out of header allowing current_mode to be moved to the opaque structure. - As all kfifo buffers use the same mode value, drop that parameter and set it unconditionally. - White space fixes and similar. - Drop use of list iterator variable for list_for_each_entry_continue_reverse and use list_prepare_entry to restart. * sysfs-trigger - Replace use of 'found' variable with dedicate list iterator variable. * adi,ad7124 - Drop misleading shift. * adi,ad2s1210 - Remove redundant local variable assignment. * adi,adis16480 - Use local device pointer to reduce repetition. - Improve handling of clocks. * domintech,dmard09 - White space. * dummy driver - Improve error handling. * fsl,mma8452 - Add missing documentation of name element. * invensense,mpu3050 - Stop remove() returning non 0. * kionix,kxsd9 - White space. * linear,ltc2688 - Use local variable for struct device. - Combine of_node_put() error handling paths. * linear,ltc2983 - Avoid use of constants in messages where a define is available. * microchip,mcp4131 - Fix compatible in dt example. * pni,rm3100 - Stop directly accessing iio_dev->current_mode just to find out if the buffer is enabled. * renesas,rzg2l - Relax kconfig constraint to include newer devices. * sprd,sc27xx - Fix wrong scaling mask. - Improve the calibration values. * samsung,ssp - Replace a 'found' variable in favor of an explicit value that was found. * sensortek,stk3xx - Add proximity-near-level binding and driver support. * st,st_sensors: - Drop unused accel_type enum. - Return early in *_write_raw() - Drop unnecessary locking in _avail functions. - Add local lock to protect odr against concurrent updates allowing mlock to no longer be used outside of the core. - Use iio_device_claim_direct_mode() rather than racy checking of the current mode. * st,stmpe-adc - Fix checks on wait_for_completion_timeout(). - Allow use of of_device_id for matching. * st,stm32-dfsdm - Stop accessing iio_dev->current_mode to find out if the buffer is enabled (so we can hide that variable in the opaque structure) * st,vl53l0x - Fix checks on wait_for_completion_timeout. * ti,ads1015 - Add missing ID for ti,ads1115 in binding doc. - Convert from repeated chip ID look up to selecting static const data. - Switch to read_avail() callback. * ti,ads8688 - Use of_device_id for driver matching. * ti,palmas-adc - Drop a warning on minor calibration mismatch leading to slightly negative values after applying the calibration. * tag 'iio-for-5.19a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (95 commits) iio: ti-ads8688: use of_device_id for OF matching iio: stmpe-adc: use of_device_id for OF matching dt-bindings: iio: Fix incorrect compatible strings in examples iio: gyro: mpu3050: Make mpu3050_common_remove() return void iio: dac: ltc2632: Make use of device properties iio: temperature: max31865: Make use of device properties iio: proximity: mb1232: Switch to use fwnode_irq_get() iio: imu: adis16480: Improve getting the optional clocks iio: imu: adis16480: Use temporary variable for struct device iio: imu: adis16480: Make use of device properties staging: iio: ad2s1210: remove redundant assignment to variable negative iio: adc: sc27xx: add support for PMIC sc2730 iio: adc: sc27xx: add support for PMIC sc2720 and sc2721 iio: adc: sc27xx: refactor some functions for support more PMiCs iio: adc: sc27xx: structure adjustment and optimization iio: adc: sc27xx: Fine tune the scale calibration values iio: adc: sc27xx: fix read big scale voltage not right dt-bindings:iio:adc: add sprd,ump9620-adc dt-binding iio: proximity: stk3310: Export near level property for proximity sensor dt-bindings: iio: light: stk33xx: Add proximity-near-level ...
This commit is contained in:
commit
bcfa954650
@ -19,7 +19,8 @@ properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- renesas,r9a07g044-adc # RZ/G2{L,LC}
|
||||
- renesas,r9a07g044-adc # RZ/G2L
|
||||
- renesas,r9a07g054-adc # RZ/V2L
|
||||
- const: renesas,rzg2l-adc
|
||||
|
||||
reg:
|
||||
|
@ -20,6 +20,7 @@ properties:
|
||||
- sprd,sc2723-adc
|
||||
- sprd,sc2730-adc
|
||||
- sprd,sc2731-adc
|
||||
- sprd,ump9620-adc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -33,13 +34,39 @@ properties:
|
||||
hwlocks:
|
||||
maxItems: 1
|
||||
|
||||
nvmem-cells:
|
||||
maxItems: 2
|
||||
nvmem-cells: true
|
||||
|
||||
nvmem-cell-names:
|
||||
items:
|
||||
- const: big_scale_calib
|
||||
- const: small_scale_calib
|
||||
nvmem-cell-names: true
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- sprd,ump9620-adc
|
||||
then:
|
||||
properties:
|
||||
nvmem-cells:
|
||||
maxItems: 2
|
||||
nvmem-cell-names:
|
||||
items:
|
||||
- const: big_scale_calib
|
||||
- const: small_scale_calib
|
||||
|
||||
else:
|
||||
properties:
|
||||
nvmem-cells:
|
||||
maxItems: 6
|
||||
nvmem-cell-names:
|
||||
items:
|
||||
- const: big_scale_calib1
|
||||
- const: big_scale_calib2
|
||||
- const: small_scale_calib1
|
||||
- const: small_scale_calib2
|
||||
- const: vbat_det_cal1
|
||||
- const: vbat_det_cal2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
@ -69,4 +96,25 @@ examples:
|
||||
nvmem-cell-names = "big_scale_calib", "small_scale_calib";
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
pmic {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
adc@504 {
|
||||
compatible = "sprd,ump9620-adc";
|
||||
reg = <0x504>;
|
||||
interrupt-parent = <&ump9620_pmic>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#io-channel-cells = <1>;
|
||||
hwlocks = <&hwlock 4>;
|
||||
nvmem-cells = <&adc_bcal1>, <&adc_bcal2>,
|
||||
<&adc_scal1>, <&adc_scal2>,
|
||||
<&vbat_det_cal1>, <&vbat_det_cal2>;
|
||||
nvmem-cell-names = "big_scale_calib1", "big_scale_calib2",
|
||||
"small_scale_calib1", "small_scale_calib2",
|
||||
"vbat_det_cal1", "vbat_det_cal2";
|
||||
};
|
||||
};
|
||||
...
|
||||
|
@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/iio/adc/ti,ads1015.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI ADS1015 4 channel I2C analog to digital converter
|
||||
title: TI ADS1015/ADS1115 4 channel I2C analog to digital converter
|
||||
|
||||
maintainers:
|
||||
- Daniel Baluta <daniel.baluta@nxp.com>
|
||||
@ -15,7 +15,10 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,ads1015
|
||||
enum:
|
||||
- ti,ads1015
|
||||
- ti,ads1115
|
||||
- ti,tla2024
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -8,7 +8,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Analog Devices AD2552R DAC device driver
|
||||
|
||||
maintainers:
|
||||
- Mihail Chindris <mihail.chindris@analog.com>
|
||||
- Nuno Sá <nuno.sa@analog.com>
|
||||
|
||||
description: |
|
||||
Bindings for the Analog Devices AD3552R DAC device and similar.
|
||||
|
@ -68,7 +68,7 @@ examples:
|
||||
#size-cells = <0>;
|
||||
|
||||
dac@0 {
|
||||
compatible = "lltc,ltc2632";
|
||||
compatible = "lltc,ltc2632-l12";
|
||||
reg = <0>; /* CS0 */
|
||||
spi-max-frequency = <1000000>;
|
||||
vref-supply = <&vref>;
|
||||
|
@ -14,21 +14,25 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- invensense,iam20680
|
||||
- invensense,icm20608
|
||||
- invensense,icm20609
|
||||
- invensense,icm20689
|
||||
- invensense,icm20602
|
||||
- invensense,icm20690
|
||||
- invensense,mpu6000
|
||||
- invensense,mpu6050
|
||||
- invensense,mpu6500
|
||||
- invensense,mpu6515
|
||||
- invensense,mpu6880
|
||||
- invensense,mpu9150
|
||||
- invensense,mpu9250
|
||||
- invensense,mpu9255
|
||||
oneOf:
|
||||
- enum:
|
||||
- invensense,iam20680
|
||||
- invensense,icm20608
|
||||
- invensense,icm20609
|
||||
- invensense,icm20689
|
||||
- invensense,icm20602
|
||||
- invensense,icm20690
|
||||
- invensense,mpu6000
|
||||
- invensense,mpu6050
|
||||
- invensense,mpu6500
|
||||
- invensense,mpu6515
|
||||
- invensense,mpu6880
|
||||
- invensense,mpu9150
|
||||
- invensense,mpu9250
|
||||
- invensense,mpu9255
|
||||
- items:
|
||||
- const: invensense,icm20608d
|
||||
- const: invensense,icm20608
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -14,23 +14,27 @@ description:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- st,lsm6ds3
|
||||
- st,lsm6ds3h
|
||||
- st,lsm6dsl
|
||||
- st,lsm6dsm
|
||||
- st,ism330dlc
|
||||
- st,lsm6dso
|
||||
- st,asm330lhh
|
||||
- st,lsm6dsox
|
||||
- st,lsm6dsr
|
||||
- st,lsm6ds3tr-c
|
||||
- st,ism330dhcx
|
||||
- st,lsm9ds1-imu
|
||||
- st,lsm6ds0
|
||||
- st,lsm6dsrx
|
||||
- st,lsm6dst
|
||||
- st,lsm6dsop
|
||||
oneOf:
|
||||
- enum:
|
||||
- st,lsm6ds3
|
||||
- st,lsm6ds3h
|
||||
- st,lsm6dsl
|
||||
- st,lsm6dsm
|
||||
- st,ism330dlc
|
||||
- st,lsm6dso
|
||||
- st,asm330lhh
|
||||
- st,lsm6dsox
|
||||
- st,lsm6dsr
|
||||
- st,lsm6ds3tr-c
|
||||
- st,ism330dhcx
|
||||
- st,lsm9ds1-imu
|
||||
- st,lsm6ds0
|
||||
- st,lsm6dsrx
|
||||
- st,lsm6dst
|
||||
- st,lsm6dsop
|
||||
- items:
|
||||
- const: st,asm330lhhx
|
||||
- const: st,lsm6dsr
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -13,6 +13,9 @@ maintainers:
|
||||
description: |
|
||||
Ambient light and proximity sensor over an i2c interface.
|
||||
|
||||
allOf:
|
||||
- $ref: ../common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
@ -26,6 +29,8 @@ properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
proximity-near-level: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@ -44,6 +49,7 @@ examples:
|
||||
stk3310@48 {
|
||||
compatible = "sensortek,stk3310";
|
||||
reg = <0x48>;
|
||||
proximity-near-level = <25>;
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
|
@ -95,7 +95,7 @@ examples:
|
||||
#size-cells = <0>;
|
||||
|
||||
potentiometer@0 {
|
||||
compatible = "mcp4131-502";
|
||||
compatible = "microchip,mcp4131-502";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <500000>;
|
||||
};
|
||||
|
@ -29,6 +29,7 @@ properties:
|
||||
- st,lis2dw12
|
||||
- st,lis2hh12
|
||||
- st,lis2dh12-accel
|
||||
- st,lis302dl
|
||||
- st,lis331dl-accel
|
||||
- st,lis331dlh-accel
|
||||
- st,lis3de
|
||||
|
12
MAINTAINERS
12
MAINTAINERS
@ -1091,6 +1091,14 @@ W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/adc/adi,ad7292.yaml
|
||||
F: drivers/iio/adc/ad7292.c
|
||||
|
||||
ANALOG DEVICES INC AD3552R DRIVER
|
||||
M: Nuno Sá <nuno.sa@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
W: https://ez.analog.com/linux-software-drivers
|
||||
F: Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
|
||||
F: drivers/iio/dac/ad3552r.c
|
||||
|
||||
ANALOG DEVICES INC AD7293 DRIVER
|
||||
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
@ -9006,7 +9014,7 @@ S: Maintained
|
||||
F: drivers/input/touchscreen/htcpen.c
|
||||
|
||||
HTS221 TEMPERATURE-HUMIDITY IIO DRIVER
|
||||
M: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||
M: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://www.st.com/
|
||||
@ -18637,7 +18645,7 @@ S: Maintained
|
||||
F: arch/alpha/kernel/srm_env.c
|
||||
|
||||
ST LSM6DSx IMU IIO DRIVER
|
||||
M: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||||
M: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
L: linux-iio@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://www.st.com/
|
||||
|
@ -290,7 +290,6 @@ config DA311
|
||||
|
||||
config DMARD06
|
||||
tristate "Domintech DMARD06 Digital Accelerometer Driver"
|
||||
depends on OF || COMPILE_TEST
|
||||
depends on I2C
|
||||
help
|
||||
Say yes here to build support for the Domintech low-g tri-axial
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <linux/math64.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
@ -745,10 +745,7 @@ int adxl355_core_probe(struct device *dev, struct regmap *regmap,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Would be good to move it to the generic version.
|
||||
*/
|
||||
irq = of_irq_get_byname(dev->of_node, "DRDY");
|
||||
irq = fwnode_irq_get_byname(dev_fwnode(dev), "DRDY");
|
||||
if (irq > 0) {
|
||||
ret = adxl355_probe_trigger(indio_dev, irq);
|
||||
if (ret)
|
||||
|
@ -1567,7 +1567,6 @@ int adxl367_probe(struct device *dev, const struct adxl367_ops *ops,
|
||||
return ret;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup_ext(st->dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&adxl367_buffer_ops,
|
||||
adxl367_fifo_attributes);
|
||||
if (ret)
|
||||
|
@ -1525,7 +1525,7 @@ static int bmc150_accel_buffer_postenable(struct iio_dev *indio_dev)
|
||||
struct bmc150_accel_data *data = iio_priv(indio_dev);
|
||||
int ret = 0;
|
||||
|
||||
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED)
|
||||
if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
@ -1557,7 +1557,7 @@ static int bmc150_accel_buffer_predisable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct bmc150_accel_data *data = iio_priv(indio_dev);
|
||||
|
||||
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED)
|
||||
if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
|
@ -24,7 +24,7 @@
|
||||
#define DMARD09_AXIS_Y 1
|
||||
#define DMARD09_AXIS_Z 2
|
||||
#define DMARD09_AXIS_X_OFFSET ((DMARD09_AXIS_X + 1) * 2)
|
||||
#define DMARD09_AXIS_Y_OFFSET ((DMARD09_AXIS_Y + 1 )* 2)
|
||||
#define DMARD09_AXIS_Y_OFFSET ((DMARD09_AXIS_Y + 1) * 2)
|
||||
#define DMARD09_AXIS_Z_OFFSET ((DMARD09_AXIS_Z + 1) * 2)
|
||||
|
||||
struct dmard09_data {
|
||||
|
@ -1217,7 +1217,6 @@ int fxls8962af_core_probe(struct device *dev, struct regmap *regmap, int irq)
|
||||
return ret;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&fxls8962af_buffer_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -44,8 +44,8 @@ static const struct spi_device_id kxsd9_spi_id[] = {
|
||||
MODULE_DEVICE_TABLE(spi, kxsd9_spi_id);
|
||||
|
||||
static const struct of_device_id kxsd9_of_match[] = {
|
||||
{ .compatible = "kionix,kxsd9" },
|
||||
{ },
|
||||
{ .compatible = "kionix,kxsd9" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, kxsd9_of_match);
|
||||
|
||||
|
@ -166,6 +166,7 @@ static const struct mma8452_event_regs trans_ev_regs = {
|
||||
|
||||
/**
|
||||
* struct mma_chip_info - chip specific data
|
||||
* @name: part number of device reported via 'name' attr
|
||||
* @chip_id: WHO_AM_I register's value
|
||||
* @channels: struct iio_chan_spec matching the device's
|
||||
* capabilities
|
||||
|
@ -1474,7 +1474,6 @@ static int sca3000_probe(struct spi_device *spi)
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(&spi->dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&sca3000_ring_setup_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -113,7 +113,6 @@ static int ssp_accel_probe(struct platform_device *pdev)
|
||||
indio_dev->available_scan_masks = ssp_accel_scan_mask;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(&pdev->dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&ssp_accel_buffer_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -14,32 +14,6 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/iio/common/st_sensors.h>
|
||||
|
||||
enum st_accel_type {
|
||||
LSM303DLH,
|
||||
LSM303DLHC,
|
||||
LIS3DH,
|
||||
LSM330D,
|
||||
LSM330DL,
|
||||
LSM330DLC,
|
||||
LIS331DLH,
|
||||
LSM303DL,
|
||||
LSM303DLM,
|
||||
LSM330,
|
||||
LSM303AGR,
|
||||
LIS2DH12,
|
||||
LIS3L02DQ,
|
||||
LNG2DM,
|
||||
H3LIS331DL,
|
||||
LIS331DL,
|
||||
LIS3LV02DL,
|
||||
LIS2DW12,
|
||||
LIS3DHH,
|
||||
LIS2DE12,
|
||||
LIS2HH12,
|
||||
SC7A20,
|
||||
ST_ACCEL_MAX,
|
||||
};
|
||||
|
||||
#define H3LIS331DL_ACCEL_DEV_NAME "h3lis331dl_accel"
|
||||
#define LIS3LV02DL_ACCEL_DEV_NAME "lis3lv02dl_accel"
|
||||
#define LSM303DLHC_ACCEL_DEV_NAME "lsm303dlhc_accel"
|
||||
@ -62,8 +36,10 @@ enum st_accel_type {
|
||||
#define LIS3DE_ACCEL_DEV_NAME "lis3de"
|
||||
#define LIS2DE12_ACCEL_DEV_NAME "lis2de12"
|
||||
#define LIS2HH12_ACCEL_DEV_NAME "lis2hh12"
|
||||
#define LIS302DL_ACCEL_DEV_NAME "lis302dl"
|
||||
#define SC7A20_ACCEL_DEV_NAME "sc7a20"
|
||||
|
||||
|
||||
#ifdef CONFIG_IIO_BUFFER
|
||||
int st_accel_allocate_ring(struct iio_dev *indio_dev);
|
||||
int st_accel_trig_set_state(struct iio_trigger *trig, bool state);
|
||||
|
@ -444,6 +444,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
|
||||
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
|
||||
.sensors_supported = {
|
||||
[0] = LIS331DL_ACCEL_DEV_NAME,
|
||||
[1] = LIS302DL_ACCEL_DEV_NAME,
|
||||
},
|
||||
.ch = (struct iio_chan_spec *)st_accel_8bit_channels,
|
||||
.odr = {
|
||||
@ -1209,28 +1210,21 @@ read_error:
|
||||
static int st_accel_write_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan, int val, int val2, long mask)
|
||||
{
|
||||
int err;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SCALE: {
|
||||
int gain;
|
||||
|
||||
gain = val * 1000000 + val2;
|
||||
err = st_sensors_set_fullscale_by_gain(indio_dev, gain);
|
||||
break;
|
||||
return st_sensors_set_fullscale_by_gain(indio_dev, gain);
|
||||
}
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
if (val2)
|
||||
return -EINVAL;
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
err = st_sensors_set_odr(indio_dev, val);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return err;
|
||||
|
||||
return st_sensors_set_odr(indio_dev, val);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
|
||||
|
@ -107,6 +107,10 @@ static const struct of_device_id st_accel_of_match[] = {
|
||||
.compatible = "st,lis2hh12",
|
||||
.data = LIS2HH12_ACCEL_DEV_NAME,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lis302dl",
|
||||
.data = LIS302DL_ACCEL_DEV_NAME,
|
||||
},
|
||||
{
|
||||
.compatible = "silan,sc7a20",
|
||||
.data = SC7A20_ACCEL_DEV_NAME,
|
||||
@ -146,6 +150,7 @@ static const struct i2c_device_id st_accel_id_table[] = {
|
||||
{ LIS3DE_ACCEL_DEV_NAME },
|
||||
{ LIS2DE12_ACCEL_DEV_NAME },
|
||||
{ LIS2HH12_ACCEL_DEV_NAME },
|
||||
{ LIS302DL_ACCEL_DEV_NAME },
|
||||
{ SC7A20_ACCEL_DEV_NAME },
|
||||
{},
|
||||
};
|
||||
|
@ -92,6 +92,10 @@ static const struct of_device_id st_accel_of_match[] = {
|
||||
.compatible = "st,lis3de",
|
||||
.data = LIS3DE_ACCEL_DEV_NAME,
|
||||
},
|
||||
{
|
||||
.compatible = "st,lis302dl",
|
||||
.data = LIS302DL_ACCEL_DEV_NAME,
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_accel_of_match);
|
||||
@ -147,6 +151,7 @@ static const struct spi_device_id st_accel_id_table[] = {
|
||||
{ LIS2DW12_ACCEL_DEV_NAME },
|
||||
{ LIS3DHH_ACCEL_DEV_NAME },
|
||||
{ LIS3DE_ACCEL_DEV_NAME },
|
||||
{ LIS302DL_ACCEL_DEV_NAME },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, st_accel_id_table);
|
||||
|
@ -910,7 +910,7 @@ config ROCKCHIP_SARADC
|
||||
|
||||
config RZG2L_ADC
|
||||
tristate "Renesas RZ/G2L ADC driver"
|
||||
depends on ARCH_R9A07G044 || COMPILE_TEST
|
||||
depends on ARCH_RZG2L || COMPILE_TEST
|
||||
help
|
||||
Say yes here to build support for the ADC found in Renesas
|
||||
RZ/G2L family.
|
||||
|
@ -43,6 +43,8 @@
|
||||
#define AD7124_STATUS_POR_FLAG_MSK BIT(4)
|
||||
|
||||
/* AD7124_ADC_CONTROL */
|
||||
#define AD7124_ADC_STATUS_EN_MSK BIT(10)
|
||||
#define AD7124_ADC_STATUS_EN(x) FIELD_PREP(AD7124_ADC_STATUS_EN_MSK, x)
|
||||
#define AD7124_ADC_CTRL_REF_EN_MSK BIT(8)
|
||||
#define AD7124_ADC_CTRL_REF_EN(x) FIELD_PREP(AD7124_ADC_CTRL_REF_EN_MSK, x)
|
||||
#define AD7124_ADC_CTRL_PWR_MSK GENMASK(7, 6)
|
||||
@ -188,7 +190,6 @@ static const struct iio_chan_spec ad7124_channel_template = {
|
||||
.sign = 'u',
|
||||
.realbits = 24,
|
||||
.storagebits = 32,
|
||||
.shift = 8,
|
||||
.endianness = IIO_BE,
|
||||
},
|
||||
};
|
||||
@ -501,26 +502,70 @@ static int ad7124_prepare_read(struct ad7124_state *st, int address)
|
||||
return ad7124_enable_channel(st, &st->channels[address]);
|
||||
}
|
||||
|
||||
static int __ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
|
||||
{
|
||||
struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);
|
||||
|
||||
return ad7124_prepare_read(st, channel);
|
||||
}
|
||||
|
||||
static int ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
|
||||
{
|
||||
struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&st->cfgs_lock);
|
||||
ret = ad7124_prepare_read(st, channel);
|
||||
ret = __ad7124_set_channel(sd, channel);
|
||||
mutex_unlock(&st->cfgs_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ad7124_append_status(struct ad_sigma_delta *sd, bool append)
|
||||
{
|
||||
struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);
|
||||
unsigned int adc_control = st->adc_control;
|
||||
int ret;
|
||||
|
||||
adc_control &= ~AD7124_ADC_STATUS_EN_MSK;
|
||||
adc_control |= AD7124_ADC_STATUS_EN(append);
|
||||
|
||||
ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, adc_control);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
st->adc_control = adc_control;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ad7124_disable_all(struct ad_sigma_delta *sd)
|
||||
{
|
||||
struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < st->num_channels; i++) {
|
||||
ret = ad7124_spi_write_mask(st, AD7124_CHANNEL(i), AD7124_CHANNEL_EN_MSK, 0, 2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ad_sigma_delta_info ad7124_sigma_delta_info = {
|
||||
.set_channel = ad7124_set_channel,
|
||||
.append_status = ad7124_append_status,
|
||||
.disable_all = ad7124_disable_all,
|
||||
.set_mode = ad7124_set_mode,
|
||||
.has_registers = true,
|
||||
.addr_shift = 0,
|
||||
.read_mask = BIT(6),
|
||||
.status_ch_mask = GENMASK(3, 0),
|
||||
.data_reg = AD7124_DATA,
|
||||
.irq_flags = IRQF_TRIGGER_FALLING
|
||||
.num_slots = 8,
|
||||
.irq_flags = IRQF_TRIGGER_FALLING,
|
||||
};
|
||||
|
||||
static int ad7124_read_raw(struct iio_dev *indio_dev,
|
||||
@ -670,11 +715,40 @@ static const struct attribute_group ad7124_attrs_group = {
|
||||
.attrs = ad7124_attributes,
|
||||
};
|
||||
|
||||
static int ad7124_update_scan_mode(struct iio_dev *indio_dev,
|
||||
const unsigned long *scan_mask)
|
||||
{
|
||||
struct ad7124_state *st = iio_priv(indio_dev);
|
||||
bool bit_set;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
mutex_lock(&st->cfgs_lock);
|
||||
for (i = 0; i < st->num_channels; i++) {
|
||||
bit_set = test_bit(i, scan_mask);
|
||||
if (bit_set)
|
||||
ret = __ad7124_set_channel(&st->sd, i);
|
||||
else
|
||||
ret = ad7124_spi_write_mask(st, AD7124_CHANNEL(i), AD7124_CHANNEL_EN_MSK,
|
||||
0, 2);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&st->cfgs_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&st->cfgs_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct iio_info ad7124_info = {
|
||||
.read_raw = ad7124_read_raw,
|
||||
.write_raw = ad7124_write_raw,
|
||||
.debugfs_reg_access = &ad7124_reg_access,
|
||||
.validate_trigger = ad_sd_validate_trigger,
|
||||
.update_scan_mode = ad7124_update_scan_mode,
|
||||
.attrs = &ad7124_attrs_group,
|
||||
};
|
||||
|
||||
@ -886,12 +960,14 @@ static int ad7124_probe(struct spi_device *spi)
|
||||
|
||||
st->chip_info = info;
|
||||
|
||||
ad_sd_init(&st->sd, indio_dev, spi, &ad7124_sigma_delta_info);
|
||||
|
||||
indio_dev->name = st->chip_info->name;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->info = &ad7124_info;
|
||||
|
||||
ret = ad_sd_init(&st->sd, indio_dev, spi, &ad7124_sigma_delta_info);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = ad7124_of_parse_channel_config(indio_dev, spi->dev.of_node);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
@ -58,7 +58,8 @@
|
||||
/* Mode Register Bit Designations (AD7192_REG_MODE) */
|
||||
#define AD7192_MODE_SEL(x) (((x) & 0x7) << 21) /* Operation Mode Select */
|
||||
#define AD7192_MODE_SEL_MASK (0x7 << 21) /* Operation Mode Select Mask */
|
||||
#define AD7192_MODE_DAT_STA BIT(20) /* Status Register transmission */
|
||||
#define AD7192_MODE_STA(x) (((x) & 0x1) << 20) /* Status Register transmission */
|
||||
#define AD7192_MODE_STA_MASK BIT(20) /* Status Register transmission Mask */
|
||||
#define AD7192_MODE_CLKSRC(x) (((x) & 0x3) << 18) /* Clock Source Select */
|
||||
#define AD7192_MODE_SINC3 BIT(15) /* SINC3 Filter Select */
|
||||
#define AD7192_MODE_ACX BIT(14) /* AC excitation enable(AD7195 only)*/
|
||||
@ -225,7 +226,7 @@ static ssize_t ad7192_write_syscalib(struct iio_dev *indio_dev,
|
||||
bool sys_calib;
|
||||
int ret, temp;
|
||||
|
||||
ret = strtobool(buf, &sys_calib);
|
||||
ret = kstrtobool(buf, &sys_calib);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -288,12 +289,51 @@ static int ad7192_set_mode(struct ad_sigma_delta *sd,
|
||||
return ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, st->mode);
|
||||
}
|
||||
|
||||
static int ad7192_append_status(struct ad_sigma_delta *sd, bool append)
|
||||
{
|
||||
struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd);
|
||||
unsigned int mode = st->mode;
|
||||
int ret;
|
||||
|
||||
mode &= ~AD7192_MODE_STA_MASK;
|
||||
mode |= AD7192_MODE_STA(append);
|
||||
|
||||
ret = ad_sd_write_reg(&st->sd, AD7192_REG_MODE, 3, mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
st->mode = mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ad7192_disable_all(struct ad_sigma_delta *sd)
|
||||
{
|
||||
struct ad7192_state *st = ad_sigma_delta_to_ad7192(sd);
|
||||
u32 conf = st->conf;
|
||||
int ret;
|
||||
|
||||
conf &= ~AD7192_CONF_CHAN_MASK;
|
||||
|
||||
ret = ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, conf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
st->conf = conf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ad_sigma_delta_info ad7192_sigma_delta_info = {
|
||||
.set_channel = ad7192_set_channel,
|
||||
.append_status = ad7192_append_status,
|
||||
.disable_all = ad7192_disable_all,
|
||||
.set_mode = ad7192_set_mode,
|
||||
.has_registers = true,
|
||||
.addr_shift = 3,
|
||||
.read_mask = BIT(6),
|
||||
.status_ch_mask = GENMASK(3, 0),
|
||||
.num_slots = 4,
|
||||
.irq_flags = IRQF_TRIGGER_FALLING,
|
||||
};
|
||||
|
||||
@ -457,7 +497,7 @@ static ssize_t ad7192_set(struct device *dev,
|
||||
int ret;
|
||||
bool val;
|
||||
|
||||
ret = strtobool(buf, &val);
|
||||
ret = kstrtobool(buf, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -783,6 +823,26 @@ static int ad7192_read_avail(struct iio_dev *indio_dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int ad7192_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask)
|
||||
{
|
||||
struct ad7192_state *st = iio_priv(indio_dev);
|
||||
u32 conf = st->conf;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
conf &= ~AD7192_CONF_CHAN_MASK;
|
||||
for_each_set_bit(i, scan_mask, 8)
|
||||
conf |= AD7192_CONF_CHAN(i);
|
||||
|
||||
ret = ad_sd_write_reg(&st->sd, AD7192_REG_CONF, 3, conf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
st->conf = conf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct iio_info ad7192_info = {
|
||||
.read_raw = ad7192_read_raw,
|
||||
.write_raw = ad7192_write_raw,
|
||||
@ -790,6 +850,7 @@ static const struct iio_info ad7192_info = {
|
||||
.read_avail = ad7192_read_avail,
|
||||
.attrs = &ad7192_attribute_group,
|
||||
.validate_trigger = ad_sd_validate_trigger,
|
||||
.update_scan_mode = ad7192_update_scan_mode,
|
||||
};
|
||||
|
||||
static const struct iio_info ad7195_info = {
|
||||
@ -799,6 +860,7 @@ static const struct iio_info ad7195_info = {
|
||||
.read_avail = ad7192_read_avail,
|
||||
.attrs = &ad7195_attribute_group,
|
||||
.validate_trigger = ad_sd_validate_trigger,
|
||||
.update_scan_mode = ad7192_update_scan_mode,
|
||||
};
|
||||
|
||||
#define __AD719x_CHANNEL(_si, _channel1, _channel2, _address, _extend_name, \
|
||||
|
@ -378,6 +378,11 @@ static const char * const ad7266_gpio_labels[] = {
|
||||
"ad0", "ad1", "ad2",
|
||||
};
|
||||
|
||||
static void ad7266_reg_disable(void *reg)
|
||||
{
|
||||
regulator_disable(reg);
|
||||
}
|
||||
|
||||
static int ad7266_probe(struct spi_device *spi)
|
||||
{
|
||||
struct ad7266_platform_data *pdata = spi->dev.platform_data;
|
||||
@ -398,9 +403,13 @@ static int ad7266_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(&spi->dev, ad7266_reg_disable, st->reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regulator_get_voltage(st->reg);
|
||||
if (ret < 0)
|
||||
goto error_disable_reg;
|
||||
return ret;
|
||||
|
||||
st->vref_mv = ret / 1000;
|
||||
} else {
|
||||
@ -423,7 +432,7 @@ static int ad7266_probe(struct spi_device *spi)
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(st->gpios[i])) {
|
||||
ret = PTR_ERR(st->gpios[i]);
|
||||
goto error_disable_reg;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -433,7 +442,6 @@ static int ad7266_probe(struct spi_device *spi)
|
||||
st->mode = AD7266_MODE_DIFF;
|
||||
}
|
||||
|
||||
spi_set_drvdata(spi, indio_dev);
|
||||
st->spi = spi;
|
||||
|
||||
indio_dev->name = spi_get_device_id(spi)->name;
|
||||
@ -459,35 +467,12 @@ static int ad7266_probe(struct spi_device *spi)
|
||||
spi_message_add_tail(&st->single_xfer[1], &st->single_msg);
|
||||
spi_message_add_tail(&st->single_xfer[2], &st->single_msg);
|
||||
|
||||
ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
|
||||
ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, &iio_pollfunc_store_time,
|
||||
&ad7266_trigger_handler, &iio_triggered_buffer_setup_ops);
|
||||
if (ret)
|
||||
goto error_disable_reg;
|
||||
return ret;
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret)
|
||||
goto error_buffer_cleanup;
|
||||
|
||||
return 0;
|
||||
|
||||
error_buffer_cleanup:
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
error_disable_reg:
|
||||
if (!IS_ERR(st->reg))
|
||||
regulator_disable(st->reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ad7266_remove(struct spi_device *spi)
|
||||
{
|
||||
struct iio_dev *indio_dev = spi_get_drvdata(spi);
|
||||
struct ad7266_state *st = iio_priv(indio_dev);
|
||||
|
||||
iio_device_unregister(indio_dev);
|
||||
iio_triggered_buffer_cleanup(indio_dev);
|
||||
if (!IS_ERR(st->reg))
|
||||
regulator_disable(st->reg);
|
||||
return devm_iio_device_register(&spi->dev, indio_dev);
|
||||
}
|
||||
|
||||
static const struct spi_device_id ad7266_id[] = {
|
||||
@ -502,7 +487,6 @@ static struct spi_driver ad7266_driver = {
|
||||
.name = "ad7266",
|
||||
},
|
||||
.probe = ad7266_probe,
|
||||
.remove = ad7266_remove,
|
||||
.id_table = ad7266_id,
|
||||
};
|
||||
module_spi_driver(ad7266_driver);
|
||||
|
@ -488,7 +488,7 @@ static ssize_t ad7280_store_balance_sw(struct iio_dev *indio_dev,
|
||||
bool readin;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &readin);
|
||||
ret = kstrtobool(buf, &readin);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
* Author: Lars-Peter Clausen <lars@metafoo.de>
|
||||
*/
|
||||
|
||||
#include <linux/align.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -342,15 +343,49 @@ EXPORT_SYMBOL_NS_GPL(ad_sigma_delta_single_conversion, IIO_AD_SIGMA_DELTA);
|
||||
static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
|
||||
unsigned int i, slot, samples_buf_size;
|
||||
unsigned int channel;
|
||||
uint8_t *samples_buf;
|
||||
int ret;
|
||||
|
||||
channel = find_first_bit(indio_dev->active_scan_mask,
|
||||
indio_dev->masklength);
|
||||
ret = ad_sigma_delta_set_channel(sigma_delta,
|
||||
indio_dev->channels[channel].address);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (sigma_delta->num_slots == 1) {
|
||||
channel = find_first_bit(indio_dev->active_scan_mask,
|
||||
indio_dev->masklength);
|
||||
ret = ad_sigma_delta_set_channel(sigma_delta,
|
||||
indio_dev->channels[channel].address);
|
||||
if (ret)
|
||||
return ret;
|
||||
slot = 1;
|
||||
} else {
|
||||
/*
|
||||
* At this point update_scan_mode already enabled the required channels.
|
||||
* For sigma-delta sequencer drivers with multiple slots, an update_scan_mode
|
||||
* implementation is mandatory.
|
||||
*/
|
||||
slot = 0;
|
||||
for_each_set_bit(i, indio_dev->active_scan_mask, indio_dev->masklength) {
|
||||
sigma_delta->slots[slot] = indio_dev->channels[i].address;
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
|
||||
sigma_delta->active_slots = slot;
|
||||
sigma_delta->current_slot = 0;
|
||||
|
||||
if (sigma_delta->active_slots > 1) {
|
||||
ret = ad_sigma_delta_append_status(sigma_delta, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
samples_buf_size = ALIGN(slot * indio_dev->channels[0].scan_type.storagebits, 8);
|
||||
samples_buf_size += sizeof(int64_t);
|
||||
samples_buf = devm_krealloc(&sigma_delta->spi->dev, sigma_delta->samples_buf,
|
||||
samples_buf_size, GFP_KERNEL);
|
||||
if (!samples_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
sigma_delta->samples_buf = samples_buf;
|
||||
|
||||
spi_bus_lock(sigma_delta->spi->master);
|
||||
sigma_delta->bus_locked = true;
|
||||
@ -386,6 +421,10 @@ static int ad_sd_buffer_postdisable(struct iio_dev *indio_dev)
|
||||
sigma_delta->keep_cs_asserted = false;
|
||||
ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
|
||||
|
||||
if (sigma_delta->status_appended)
|
||||
ad_sigma_delta_append_status(sigma_delta, false);
|
||||
|
||||
ad_sigma_delta_disable_all(sigma_delta);
|
||||
sigma_delta->bus_locked = false;
|
||||
return spi_bus_unlock(sigma_delta->spi->master);
|
||||
}
|
||||
@ -396,6 +435,10 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
|
||||
struct iio_dev *indio_dev = pf->indio_dev;
|
||||
struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
|
||||
uint8_t *data = sigma_delta->rx_buf;
|
||||
unsigned int transfer_size;
|
||||
unsigned int sample_size;
|
||||
unsigned int sample_pos;
|
||||
unsigned int status_pos;
|
||||
unsigned int reg_size;
|
||||
unsigned int data_reg;
|
||||
|
||||
@ -408,21 +451,69 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
|
||||
else
|
||||
data_reg = AD_SD_REG_DATA;
|
||||
|
||||
/* Status word will be appended to the sample during transfer */
|
||||
if (sigma_delta->status_appended)
|
||||
transfer_size = reg_size + 1;
|
||||
else
|
||||
transfer_size = reg_size;
|
||||
|
||||
switch (reg_size) {
|
||||
case 4:
|
||||
case 2:
|
||||
case 1:
|
||||
ad_sd_read_reg_raw(sigma_delta, data_reg, reg_size, &data[0]);
|
||||
status_pos = reg_size;
|
||||
ad_sd_read_reg_raw(sigma_delta, data_reg, transfer_size, &data[0]);
|
||||
break;
|
||||
case 3:
|
||||
/*
|
||||
* Data array after transfer will look like (if status is appended):
|
||||
* data[] = { [0][sample][sample][sample][status] }
|
||||
* Keeping the first byte 0 shifts the status postion by 1 byte to the right.
|
||||
*/
|
||||
status_pos = reg_size + 1;
|
||||
|
||||
/* We store 24 bit samples in a 32 bit word. Keep the upper
|
||||
* byte set to zero. */
|
||||
ad_sd_read_reg_raw(sigma_delta, data_reg, reg_size, &data[1]);
|
||||
ad_sd_read_reg_raw(sigma_delta, data_reg, transfer_size, &data[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
|
||||
/*
|
||||
* For devices sampling only one channel at
|
||||
* once, there is no need for sample number tracking.
|
||||
*/
|
||||
if (sigma_delta->active_slots == 1) {
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
|
||||
goto irq_handled;
|
||||
}
|
||||
|
||||
if (sigma_delta->status_appended) {
|
||||
u8 converted_channel;
|
||||
|
||||
converted_channel = data[status_pos] & sigma_delta->info->status_ch_mask;
|
||||
if (converted_channel != sigma_delta->slots[sigma_delta->current_slot]) {
|
||||
/*
|
||||
* Desync occurred during continuous sampling of multiple channels.
|
||||
* Drop this incomplete sample and start from first channel again.
|
||||
*/
|
||||
|
||||
sigma_delta->current_slot = 0;
|
||||
goto irq_handled;
|
||||
}
|
||||
}
|
||||
|
||||
sample_size = indio_dev->channels[0].scan_type.storagebits / 8;
|
||||
sample_pos = sample_size * sigma_delta->current_slot;
|
||||
memcpy(&sigma_delta->samples_buf[sample_pos], data, sample_size);
|
||||
sigma_delta->current_slot++;
|
||||
|
||||
if (sigma_delta->current_slot == sigma_delta->active_slots) {
|
||||
sigma_delta->current_slot = 0;
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, sigma_delta->samples_buf,
|
||||
pf->timestamp);
|
||||
}
|
||||
|
||||
irq_handled:
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
sigma_delta->irq_dis = false;
|
||||
enable_irq(sigma_delta->spi->irq);
|
||||
@ -430,10 +521,17 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static bool ad_sd_validate_scan_mask(struct iio_dev *indio_dev, const unsigned long *mask)
|
||||
{
|
||||
struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
|
||||
|
||||
return bitmap_weight(mask, indio_dev->masklength) <= sigma_delta->num_slots;
|
||||
}
|
||||
|
||||
static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = {
|
||||
.postenable = &ad_sd_buffer_postenable,
|
||||
.postdisable = &ad_sd_buffer_postdisable,
|
||||
.validate_scan_mask = &iio_validate_scan_mask_onehot,
|
||||
.validate_scan_mask = &ad_sd_validate_scan_mask,
|
||||
};
|
||||
|
||||
static irqreturn_t ad_sd_data_rdy_trig_poll(int irq, void *private)
|
||||
@ -513,8 +611,14 @@ static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_de
|
||||
*/
|
||||
int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indio_dev)
|
||||
{
|
||||
struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
|
||||
int ret;
|
||||
|
||||
sigma_delta->slots = devm_kcalloc(dev, sigma_delta->num_slots,
|
||||
sizeof(*sigma_delta->slots), GFP_KERNEL);
|
||||
if (!sigma_delta->slots)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
|
||||
&iio_pollfunc_store_time,
|
||||
&ad_sd_trigger_handler,
|
||||
@ -541,6 +645,25 @@ int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
|
||||
{
|
||||
sigma_delta->spi = spi;
|
||||
sigma_delta->info = info;
|
||||
|
||||
/* If the field is unset in ad_sigma_delta_info, asume there can only be 1 slot. */
|
||||
if (!info->num_slots)
|
||||
sigma_delta->num_slots = 1;
|
||||
else
|
||||
sigma_delta->num_slots = info->num_slots;
|
||||
|
||||
if (sigma_delta->num_slots > 1) {
|
||||
if (!indio_dev->info->update_scan_mode) {
|
||||
dev_err(&spi->dev, "iio_dev lacks update_scan_mode().\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!info->disable_all) {
|
||||
dev_err(&spi->dev, "ad_sigma_delta_info lacks disable_all().\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
iio_device_set_drvdata(indio_dev, sigma_delta);
|
||||
|
||||
return 0;
|
||||
|
@ -1117,7 +1117,7 @@ static int at91_adc_buffer_prepare(struct iio_dev *indio_dev)
|
||||
return at91_adc_configure_touch(st, true);
|
||||
|
||||
/* if we are not in triggered mode, we cannot enable the buffer. */
|
||||
if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES))
|
||||
if (!(iio_device_get_current_mode(indio_dev) & INDIO_ALL_TRIGGERED_MODES))
|
||||
return -EINVAL;
|
||||
|
||||
/* we continue with the triggered buffer */
|
||||
@ -1159,7 +1159,7 @@ static int at91_adc_buffer_postdisable(struct iio_dev *indio_dev)
|
||||
return at91_adc_configure_touch(st, false);
|
||||
|
||||
/* if we are not in triggered mode, nothing to do here */
|
||||
if (!(indio_dev->currentmode & INDIO_ALL_TRIGGERED_MODES))
|
||||
if (!(iio_device_get_current_mode(indio_dev) & INDIO_ALL_TRIGGERED_MODES))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
|
@ -550,7 +550,7 @@ static ssize_t ina2xx_allow_async_readout_store(struct device *dev,
|
||||
bool val;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &val);
|
||||
ret = kstrtobool(buf, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1027,7 +1027,6 @@ static int ina2xx_probe(struct i2c_client *client,
|
||||
indio_dev->name = id->name;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&ina2xx_setup_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -376,7 +376,8 @@ static int palmas_gpadc_get_calibrated_code(struct palmas_gpadc *adc,
|
||||
adc->adc_info[adc_chan].gain_error;
|
||||
|
||||
if (val < 0) {
|
||||
dev_err(adc->dev, "Mismatch with calibration\n");
|
||||
if (val < -10)
|
||||
dev_err(adc->dev, "Mismatch with calibration var = %d\n", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -9,12 +9,16 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/* PMIC global registers definition */
|
||||
#define SC27XX_MODULE_EN 0xc08
|
||||
#define SC2730_MODULE_EN 0x1808
|
||||
#define SC2731_MODULE_EN 0xc08
|
||||
#define SC27XX_MODULE_ADC_EN BIT(5)
|
||||
#define SC27XX_ARM_CLK_EN 0xc10
|
||||
#define SC2721_ARM_CLK_EN 0xc0c
|
||||
#define SC2730_ARM_CLK_EN 0x180c
|
||||
#define SC2731_ARM_CLK_EN 0xc10
|
||||
#define SC27XX_CLK_ADC_EN BIT(5)
|
||||
#define SC27XX_CLK_ADC_CLK_EN BIT(6)
|
||||
|
||||
@ -36,8 +40,10 @@
|
||||
|
||||
/* Bits and mask definition for SC27XX_ADC_CH_CFG register */
|
||||
#define SC27XX_ADC_CHN_ID_MASK GENMASK(4, 0)
|
||||
#define SC27XX_ADC_SCALE_MASK GENMASK(10, 8)
|
||||
#define SC27XX_ADC_SCALE_SHIFT 8
|
||||
#define SC27XX_ADC_SCALE_MASK GENMASK(10, 9)
|
||||
#define SC2721_ADC_SCALE_MASK BIT(5)
|
||||
#define SC27XX_ADC_SCALE_SHIFT 9
|
||||
#define SC2721_ADC_SCALE_SHIFT 5
|
||||
|
||||
/* Bits definitions for SC27XX_ADC_INT_EN registers */
|
||||
#define SC27XX_ADC_IRQ_EN BIT(0)
|
||||
@ -67,8 +73,15 @@
|
||||
#define SC27XX_RATIO_NUMERATOR_OFFSET 16
|
||||
#define SC27XX_RATIO_DENOMINATOR_MASK GENMASK(15, 0)
|
||||
|
||||
/* ADC specific channel reference voltage 3.5V */
|
||||
#define SC27XX_ADC_REFVOL_VDD35 3500000
|
||||
|
||||
/* ADC default channel reference voltage is 2.8V */
|
||||
#define SC27XX_ADC_REFVOL_VDD28 2800000
|
||||
|
||||
struct sc27xx_adc_data {
|
||||
struct device *dev;
|
||||
struct regulator *volref;
|
||||
struct regmap *regmap;
|
||||
/*
|
||||
* One hardware spinlock to synchronize between the multiple
|
||||
@ -78,6 +91,24 @@ struct sc27xx_adc_data {
|
||||
int channel_scale[SC27XX_ADC_CHANNEL_MAX];
|
||||
u32 base;
|
||||
int irq;
|
||||
const struct sc27xx_adc_variant_data *var_data;
|
||||
};
|
||||
|
||||
/*
|
||||
* Since different PMICs of SC27xx series can have different
|
||||
* address and ratio, we should save ratio config and base
|
||||
* in the device data structure.
|
||||
*/
|
||||
struct sc27xx_adc_variant_data {
|
||||
u32 module_en;
|
||||
u32 clk_en;
|
||||
u32 scale_shift;
|
||||
u32 scale_mask;
|
||||
const struct sc27xx_adc_linear_graph *bscale_cal;
|
||||
const struct sc27xx_adc_linear_graph *sscale_cal;
|
||||
void (*init_scale)(struct sc27xx_adc_data *data);
|
||||
int (*get_ratio)(int channel, int scale);
|
||||
bool set_volref;
|
||||
};
|
||||
|
||||
struct sc27xx_adc_linear_graph {
|
||||
@ -103,6 +134,16 @@ static struct sc27xx_adc_linear_graph small_scale_graph = {
|
||||
100, 341,
|
||||
};
|
||||
|
||||
static const struct sc27xx_adc_linear_graph sc2731_big_scale_graph_calib = {
|
||||
4200, 850,
|
||||
3600, 728,
|
||||
};
|
||||
|
||||
static const struct sc27xx_adc_linear_graph sc2731_small_scale_graph_calib = {
|
||||
1000, 838,
|
||||
100, 84,
|
||||
};
|
||||
|
||||
static const struct sc27xx_adc_linear_graph big_scale_graph_calib = {
|
||||
4200, 856,
|
||||
3600, 733,
|
||||
@ -118,49 +159,225 @@ static int sc27xx_adc_get_calib_data(u32 calib_data, int calib_adc)
|
||||
return ((calib_data & 0xff) + calib_adc - 128) * 4;
|
||||
}
|
||||
|
||||
static int sc27xx_adc_scale_calibration(struct sc27xx_adc_data *data,
|
||||
bool big_scale)
|
||||
/* get the adc nvmem cell calibration data */
|
||||
static int adc_nvmem_cell_calib_data(struct sc27xx_adc_data *data, const char *cell_name)
|
||||
{
|
||||
const struct sc27xx_adc_linear_graph *calib_graph;
|
||||
struct sc27xx_adc_linear_graph *graph;
|
||||
struct nvmem_cell *cell;
|
||||
const char *cell_name;
|
||||
u32 calib_data = 0;
|
||||
void *buf;
|
||||
u32 origin_calib_data = 0;
|
||||
size_t len;
|
||||
|
||||
if (big_scale) {
|
||||
calib_graph = &big_scale_graph_calib;
|
||||
graph = &big_scale_graph;
|
||||
cell_name = "big_scale_calib";
|
||||
} else {
|
||||
calib_graph = &small_scale_graph_calib;
|
||||
graph = &small_scale_graph;
|
||||
cell_name = "small_scale_calib";
|
||||
}
|
||||
if (!data)
|
||||
return -EINVAL;
|
||||
|
||||
cell = nvmem_cell_get(data->dev, cell_name);
|
||||
if (IS_ERR(cell))
|
||||
return PTR_ERR(cell);
|
||||
|
||||
buf = nvmem_cell_read(cell, &len);
|
||||
nvmem_cell_put(cell);
|
||||
|
||||
if (IS_ERR(buf))
|
||||
if (IS_ERR(buf)) {
|
||||
nvmem_cell_put(cell);
|
||||
return PTR_ERR(buf);
|
||||
}
|
||||
|
||||
memcpy(&calib_data, buf, min(len, sizeof(u32)));
|
||||
memcpy(&origin_calib_data, buf, min(len, sizeof(u32)));
|
||||
|
||||
kfree(buf);
|
||||
nvmem_cell_put(cell);
|
||||
return origin_calib_data;
|
||||
}
|
||||
|
||||
static int sc27xx_adc_scale_calibration(struct sc27xx_adc_data *data,
|
||||
bool big_scale)
|
||||
{
|
||||
const struct sc27xx_adc_linear_graph *calib_graph;
|
||||
struct sc27xx_adc_linear_graph *graph;
|
||||
const char *cell_name;
|
||||
u32 calib_data = 0;
|
||||
|
||||
if (big_scale) {
|
||||
calib_graph = data->var_data->bscale_cal;
|
||||
graph = &big_scale_graph;
|
||||
cell_name = "big_scale_calib";
|
||||
} else {
|
||||
calib_graph = data->var_data->sscale_cal;
|
||||
graph = &small_scale_graph;
|
||||
cell_name = "small_scale_calib";
|
||||
}
|
||||
|
||||
calib_data = adc_nvmem_cell_calib_data(data, cell_name);
|
||||
|
||||
/* Only need to calibrate the adc values in the linear graph. */
|
||||
graph->adc0 = sc27xx_adc_get_calib_data(calib_data, calib_graph->adc0);
|
||||
graph->adc1 = sc27xx_adc_get_calib_data(calib_data >> 8,
|
||||
calib_graph->adc1);
|
||||
|
||||
kfree(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sc27xx_adc_get_ratio(int channel, int scale)
|
||||
static int sc2720_adc_get_ratio(int channel, int scale)
|
||||
{
|
||||
switch (channel) {
|
||||
case 14:
|
||||
switch (scale) {
|
||||
case 0:
|
||||
return SC27XX_VOLT_RATIO(68, 900);
|
||||
case 1:
|
||||
return SC27XX_VOLT_RATIO(68, 1760);
|
||||
case 2:
|
||||
return SC27XX_VOLT_RATIO(68, 2327);
|
||||
case 3:
|
||||
return SC27XX_VOLT_RATIO(68, 3654);
|
||||
default:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
case 16:
|
||||
switch (scale) {
|
||||
case 0:
|
||||
return SC27XX_VOLT_RATIO(48, 100);
|
||||
case 1:
|
||||
return SC27XX_VOLT_RATIO(480, 1955);
|
||||
case 2:
|
||||
return SC27XX_VOLT_RATIO(480, 2586);
|
||||
case 3:
|
||||
return SC27XX_VOLT_RATIO(48, 406);
|
||||
default:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
switch (scale) {
|
||||
case 0:
|
||||
return SC27XX_VOLT_RATIO(3, 8);
|
||||
case 1:
|
||||
return SC27XX_VOLT_RATIO(375, 1955);
|
||||
case 2:
|
||||
return SC27XX_VOLT_RATIO(375, 2586);
|
||||
case 3:
|
||||
return SC27XX_VOLT_RATIO(300, 3248);
|
||||
default:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
default:
|
||||
switch (scale) {
|
||||
case 0:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
case 1:
|
||||
return SC27XX_VOLT_RATIO(1000, 1955);
|
||||
case 2:
|
||||
return SC27XX_VOLT_RATIO(1000, 2586);
|
||||
case 3:
|
||||
return SC27XX_VOLT_RATIO(100, 406);
|
||||
default:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
}
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
|
||||
static int sc2721_adc_get_ratio(int channel, int scale)
|
||||
{
|
||||
switch (channel) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return scale ? SC27XX_VOLT_RATIO(400, 1025) :
|
||||
SC27XX_VOLT_RATIO(1, 1);
|
||||
case 5:
|
||||
return SC27XX_VOLT_RATIO(7, 29);
|
||||
case 7:
|
||||
case 9:
|
||||
return scale ? SC27XX_VOLT_RATIO(100, 125) :
|
||||
SC27XX_VOLT_RATIO(1, 1);
|
||||
case 14:
|
||||
return SC27XX_VOLT_RATIO(68, 900);
|
||||
case 16:
|
||||
return SC27XX_VOLT_RATIO(48, 100);
|
||||
case 19:
|
||||
return SC27XX_VOLT_RATIO(1, 3);
|
||||
default:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
|
||||
static int sc2730_adc_get_ratio(int channel, int scale)
|
||||
{
|
||||
switch (channel) {
|
||||
case 14:
|
||||
switch (scale) {
|
||||
case 0:
|
||||
return SC27XX_VOLT_RATIO(68, 900);
|
||||
case 1:
|
||||
return SC27XX_VOLT_RATIO(68, 1760);
|
||||
case 2:
|
||||
return SC27XX_VOLT_RATIO(68, 2327);
|
||||
case 3:
|
||||
return SC27XX_VOLT_RATIO(68, 3654);
|
||||
default:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
case 15:
|
||||
switch (scale) {
|
||||
case 0:
|
||||
return SC27XX_VOLT_RATIO(1, 3);
|
||||
case 1:
|
||||
return SC27XX_VOLT_RATIO(1000, 5865);
|
||||
case 2:
|
||||
return SC27XX_VOLT_RATIO(500, 3879);
|
||||
case 3:
|
||||
return SC27XX_VOLT_RATIO(500, 6090);
|
||||
default:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
case 16:
|
||||
switch (scale) {
|
||||
case 0:
|
||||
return SC27XX_VOLT_RATIO(48, 100);
|
||||
case 1:
|
||||
return SC27XX_VOLT_RATIO(480, 1955);
|
||||
case 2:
|
||||
return SC27XX_VOLT_RATIO(480, 2586);
|
||||
case 3:
|
||||
return SC27XX_VOLT_RATIO(48, 406);
|
||||
default:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
switch (scale) {
|
||||
case 0:
|
||||
return SC27XX_VOLT_RATIO(3, 8);
|
||||
case 1:
|
||||
return SC27XX_VOLT_RATIO(375, 1955);
|
||||
case 2:
|
||||
return SC27XX_VOLT_RATIO(375, 2586);
|
||||
case 3:
|
||||
return SC27XX_VOLT_RATIO(300, 3248);
|
||||
default:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
default:
|
||||
switch (scale) {
|
||||
case 0:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
case 1:
|
||||
return SC27XX_VOLT_RATIO(1000, 1955);
|
||||
case 2:
|
||||
return SC27XX_VOLT_RATIO(1000, 2586);
|
||||
case 3:
|
||||
return SC27XX_VOLT_RATIO(1000, 4060);
|
||||
default:
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
}
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
|
||||
static int sc2731_adc_get_ratio(int channel, int scale)
|
||||
{
|
||||
switch (channel) {
|
||||
case 1:
|
||||
@ -185,10 +402,87 @@ static int sc27xx_adc_get_ratio(int channel, int scale)
|
||||
return SC27XX_VOLT_RATIO(1, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* According to the datasheet set specific value on some channel.
|
||||
*/
|
||||
static void sc2720_adc_scale_init(struct sc27xx_adc_data *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SC27XX_ADC_CHANNEL_MAX; i++) {
|
||||
switch (i) {
|
||||
case 5:
|
||||
data->channel_scale[i] = 3;
|
||||
break;
|
||||
case 7:
|
||||
case 9:
|
||||
data->channel_scale[i] = 2;
|
||||
break;
|
||||
case 13:
|
||||
data->channel_scale[i] = 1;
|
||||
break;
|
||||
case 19:
|
||||
case 30:
|
||||
case 31:
|
||||
data->channel_scale[i] = 3;
|
||||
break;
|
||||
default:
|
||||
data->channel_scale[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sc2730_adc_scale_init(struct sc27xx_adc_data *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SC27XX_ADC_CHANNEL_MAX; i++) {
|
||||
switch (i) {
|
||||
case 5:
|
||||
case 10:
|
||||
case 19:
|
||||
case 30:
|
||||
case 31:
|
||||
data->channel_scale[i] = 3;
|
||||
break;
|
||||
case 7:
|
||||
case 9:
|
||||
data->channel_scale[i] = 2;
|
||||
break;
|
||||
case 13:
|
||||
data->channel_scale[i] = 1;
|
||||
break;
|
||||
default:
|
||||
data->channel_scale[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sc2731_adc_scale_init(struct sc27xx_adc_data *data)
|
||||
{
|
||||
int i;
|
||||
/*
|
||||
* In the current software design, SC2731 support 2 scales,
|
||||
* channels 5 uses big scale, others use smale.
|
||||
*/
|
||||
for (i = 0; i < SC27XX_ADC_CHANNEL_MAX; i++) {
|
||||
switch (i) {
|
||||
case 5:
|
||||
data->channel_scale[i] = 1;
|
||||
break;
|
||||
default:
|
||||
data->channel_scale[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
|
||||
int scale, int *val)
|
||||
{
|
||||
int ret;
|
||||
int ret, ret_volref;
|
||||
u32 tmp, value, status;
|
||||
|
||||
ret = hwspin_lock_timeout_raw(data->hwlock, SC27XX_ADC_HWLOCK_TIMEOUT);
|
||||
@ -197,10 +491,25 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* According to the sc2721 chip data sheet, the reference voltage of
|
||||
* specific channel 30 and channel 31 in ADC module needs to be set from
|
||||
* the default 2.8v to 3.5v.
|
||||
*/
|
||||
if ((data->var_data->set_volref) && (channel == 30 || channel == 31)) {
|
||||
ret = regulator_set_voltage(data->volref,
|
||||
SC27XX_ADC_REFVOL_VDD35,
|
||||
SC27XX_ADC_REFVOL_VDD35);
|
||||
if (ret) {
|
||||
dev_err(data->dev, "failed to set the volref 3.5v\n");
|
||||
goto unlock_adc;
|
||||
}
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL,
|
||||
SC27XX_ADC_EN, SC27XX_ADC_EN);
|
||||
if (ret)
|
||||
goto unlock_adc;
|
||||
goto regulator_restore;
|
||||
|
||||
ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_INT_CLR,
|
||||
SC27XX_ADC_IRQ_CLR, SC27XX_ADC_IRQ_CLR);
|
||||
@ -208,10 +517,11 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
|
||||
goto disable_adc;
|
||||
|
||||
/* Configure the channel id and scale */
|
||||
tmp = (scale << SC27XX_ADC_SCALE_SHIFT) & SC27XX_ADC_SCALE_MASK;
|
||||
tmp = (scale << data->var_data->scale_shift) & data->var_data->scale_mask;
|
||||
tmp |= channel & SC27XX_ADC_CHN_ID_MASK;
|
||||
ret = regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CH_CFG,
|
||||
SC27XX_ADC_CHN_ID_MASK | SC27XX_ADC_SCALE_MASK,
|
||||
SC27XX_ADC_CHN_ID_MASK |
|
||||
data->var_data->scale_mask,
|
||||
tmp);
|
||||
if (ret)
|
||||
goto disable_adc;
|
||||
@ -249,6 +559,17 @@ static int sc27xx_adc_read(struct sc27xx_adc_data *data, int channel,
|
||||
disable_adc:
|
||||
regmap_update_bits(data->regmap, data->base + SC27XX_ADC_CTL,
|
||||
SC27XX_ADC_EN, 0);
|
||||
regulator_restore:
|
||||
if ((data->var_data->set_volref) && (channel == 30 || channel == 31)) {
|
||||
ret_volref = regulator_set_voltage(data->volref,
|
||||
SC27XX_ADC_REFVOL_VDD28,
|
||||
SC27XX_ADC_REFVOL_VDD28);
|
||||
if (ret_volref) {
|
||||
dev_err(data->dev, "failed to set the volref 2.8v,ret_volref = 0x%x\n",
|
||||
ret_volref);
|
||||
ret = ret || ret_volref;
|
||||
}
|
||||
}
|
||||
unlock_adc:
|
||||
hwspin_unlock_raw(data->hwlock);
|
||||
|
||||
@ -262,13 +583,14 @@ static void sc27xx_adc_volt_ratio(struct sc27xx_adc_data *data,
|
||||
int channel, int scale,
|
||||
u32 *div_numerator, u32 *div_denominator)
|
||||
{
|
||||
u32 ratio = sc27xx_adc_get_ratio(channel, scale);
|
||||
u32 ratio;
|
||||
|
||||
ratio = data->var_data->get_ratio(channel, scale);
|
||||
*div_numerator = ratio >> SC27XX_RATIO_NUMERATOR_OFFSET;
|
||||
*div_denominator = ratio & SC27XX_RATIO_DENOMINATOR_MASK;
|
||||
}
|
||||
|
||||
static int sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph *graph,
|
||||
static int adc_to_volt(struct sc27xx_adc_linear_graph *graph,
|
||||
int raw_adc)
|
||||
{
|
||||
int tmp;
|
||||
@ -277,6 +599,16 @@ static int sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph *graph,
|
||||
tmp /= (graph->adc0 - graph->adc1);
|
||||
tmp += graph->volt1;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int sc27xx_adc_to_volt(struct sc27xx_adc_linear_graph *graph,
|
||||
int raw_adc)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
tmp = adc_to_volt(graph, raw_adc);
|
||||
|
||||
return tmp < 0 ? 0 : tmp;
|
||||
}
|
||||
|
||||
@ -432,13 +764,13 @@ static int sc27xx_adc_enable(struct sc27xx_adc_data *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(data->regmap, SC27XX_MODULE_EN,
|
||||
ret = regmap_update_bits(data->regmap, data->var_data->module_en,
|
||||
SC27XX_MODULE_ADC_EN, SC27XX_MODULE_ADC_EN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable ADC work clock and controller clock */
|
||||
ret = regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN,
|
||||
ret = regmap_update_bits(data->regmap, data->var_data->clk_en,
|
||||
SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN,
|
||||
SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN);
|
||||
if (ret)
|
||||
@ -456,10 +788,10 @@ static int sc27xx_adc_enable(struct sc27xx_adc_data *data)
|
||||
return 0;
|
||||
|
||||
disable_clk:
|
||||
regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN,
|
||||
regmap_update_bits(data->regmap, data->var_data->clk_en,
|
||||
SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0);
|
||||
disable_adc:
|
||||
regmap_update_bits(data->regmap, SC27XX_MODULE_EN,
|
||||
regmap_update_bits(data->regmap, data->var_data->module_en,
|
||||
SC27XX_MODULE_ADC_EN, 0);
|
||||
|
||||
return ret;
|
||||
@ -470,21 +802,76 @@ static void sc27xx_adc_disable(void *_data)
|
||||
struct sc27xx_adc_data *data = _data;
|
||||
|
||||
/* Disable ADC work clock and controller clock */
|
||||
regmap_update_bits(data->regmap, SC27XX_ARM_CLK_EN,
|
||||
regmap_update_bits(data->regmap, data->var_data->clk_en,
|
||||
SC27XX_CLK_ADC_EN | SC27XX_CLK_ADC_CLK_EN, 0);
|
||||
|
||||
regmap_update_bits(data->regmap, SC27XX_MODULE_EN,
|
||||
regmap_update_bits(data->regmap, data->var_data->module_en,
|
||||
SC27XX_MODULE_ADC_EN, 0);
|
||||
}
|
||||
|
||||
static const struct sc27xx_adc_variant_data sc2731_data = {
|
||||
.module_en = SC2731_MODULE_EN,
|
||||
.clk_en = SC2731_ARM_CLK_EN,
|
||||
.scale_shift = SC27XX_ADC_SCALE_SHIFT,
|
||||
.scale_mask = SC27XX_ADC_SCALE_MASK,
|
||||
.bscale_cal = &sc2731_big_scale_graph_calib,
|
||||
.sscale_cal = &sc2731_small_scale_graph_calib,
|
||||
.init_scale = sc2731_adc_scale_init,
|
||||
.get_ratio = sc2731_adc_get_ratio,
|
||||
.set_volref = false,
|
||||
};
|
||||
|
||||
static const struct sc27xx_adc_variant_data sc2730_data = {
|
||||
.module_en = SC2730_MODULE_EN,
|
||||
.clk_en = SC2730_ARM_CLK_EN,
|
||||
.scale_shift = SC27XX_ADC_SCALE_SHIFT,
|
||||
.scale_mask = SC27XX_ADC_SCALE_MASK,
|
||||
.bscale_cal = &big_scale_graph_calib,
|
||||
.sscale_cal = &small_scale_graph_calib,
|
||||
.init_scale = sc2730_adc_scale_init,
|
||||
.get_ratio = sc2730_adc_get_ratio,
|
||||
.set_volref = false,
|
||||
};
|
||||
|
||||
static const struct sc27xx_adc_variant_data sc2721_data = {
|
||||
.module_en = SC2731_MODULE_EN,
|
||||
.clk_en = SC2721_ARM_CLK_EN,
|
||||
.scale_shift = SC2721_ADC_SCALE_SHIFT,
|
||||
.scale_mask = SC2721_ADC_SCALE_MASK,
|
||||
.bscale_cal = &sc2731_big_scale_graph_calib,
|
||||
.sscale_cal = &sc2731_small_scale_graph_calib,
|
||||
.init_scale = sc2731_adc_scale_init,
|
||||
.get_ratio = sc2721_adc_get_ratio,
|
||||
.set_volref = true,
|
||||
};
|
||||
|
||||
static const struct sc27xx_adc_variant_data sc2720_data = {
|
||||
.module_en = SC2731_MODULE_EN,
|
||||
.clk_en = SC2721_ARM_CLK_EN,
|
||||
.scale_shift = SC27XX_ADC_SCALE_SHIFT,
|
||||
.scale_mask = SC27XX_ADC_SCALE_MASK,
|
||||
.bscale_cal = &big_scale_graph_calib,
|
||||
.sscale_cal = &small_scale_graph_calib,
|
||||
.init_scale = sc2720_adc_scale_init,
|
||||
.get_ratio = sc2720_adc_get_ratio,
|
||||
.set_volref = false,
|
||||
};
|
||||
|
||||
static int sc27xx_adc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct sc27xx_adc_data *sc27xx_data;
|
||||
const struct sc27xx_adc_variant_data *pdata;
|
||||
struct iio_dev *indio_dev;
|
||||
int ret;
|
||||
|
||||
pdata = of_device_get_match_data(dev);
|
||||
if (!pdata) {
|
||||
dev_err(dev, "No matching driver data found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*sc27xx_data));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
@ -520,6 +907,16 @@ static int sc27xx_adc_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
sc27xx_data->dev = dev;
|
||||
if (pdata->set_volref) {
|
||||
sc27xx_data->volref = devm_regulator_get(dev, "vref");
|
||||
if (IS_ERR(sc27xx_data->volref)) {
|
||||
ret = PTR_ERR(sc27xx_data->volref);
|
||||
return dev_err_probe(dev, ret, "failed to get ADC volref\n");
|
||||
}
|
||||
}
|
||||
|
||||
sc27xx_data->var_data = pdata;
|
||||
sc27xx_data->var_data->init_scale(sc27xx_data);
|
||||
|
||||
ret = sc27xx_adc_enable(sc27xx_data);
|
||||
if (ret) {
|
||||
@ -546,7 +943,10 @@ static int sc27xx_adc_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id sc27xx_adc_of_match[] = {
|
||||
{ .compatible = "sprd,sc2731-adc", },
|
||||
{ .compatible = "sprd,sc2731-adc", .data = &sc2731_data},
|
||||
{ .compatible = "sprd,sc2730-adc", .data = &sc2730_data},
|
||||
{ .compatible = "sprd,sc2721-adc", .data = &sc2721_data},
|
||||
{ .compatible = "sprd,sc2720-adc", .data = &sc2720_data},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sc27xx_adc_of_match);
|
||||
|
@ -466,8 +466,7 @@ static int stm32_dfsdm_channels_configure(struct iio_dev *indio_dev,
|
||||
* In continuous mode, use fast mode configuration,
|
||||
* if it provides a better resolution.
|
||||
*/
|
||||
if (adc->nconv == 1 && !trig &&
|
||||
(indio_dev->currentmode & INDIO_BUFFER_SOFTWARE)) {
|
||||
if (adc->nconv == 1 && !trig && iio_buffer_enabled(indio_dev)) {
|
||||
if (fl->flo[1].res >= fl->flo[0].res) {
|
||||
fl->fast = 1;
|
||||
flo = &fl->flo[1];
|
||||
@ -562,7 +561,7 @@ static int stm32_dfsdm_filter_configure(struct iio_dev *indio_dev,
|
||||
cr1 = DFSDM_CR1_RCH(chan->channel);
|
||||
|
||||
/* Continuous conversions triggered by SPI clk in buffer mode */
|
||||
if (indio_dev->currentmode & INDIO_BUFFER_SOFTWARE)
|
||||
if (iio_buffer_enabled(indio_dev))
|
||||
cr1 |= DFSDM_CR1_RCONT(1);
|
||||
|
||||
cr1 |= DFSDM_CR1_RSYNC(fl->sync_mode);
|
||||
|
@ -61,7 +61,7 @@ struct stmpe_adc {
|
||||
static int stmpe_read_voltage(struct stmpe_adc *info,
|
||||
struct iio_chan_spec const *chan, int *val)
|
||||
{
|
||||
long ret;
|
||||
unsigned long ret;
|
||||
|
||||
mutex_lock(&info->lock);
|
||||
|
||||
@ -79,7 +79,7 @@ static int stmpe_read_voltage(struct stmpe_adc *info,
|
||||
|
||||
ret = wait_for_completion_timeout(&info->completion, STMPE_ADC_TIMEOUT);
|
||||
|
||||
if (ret <= 0) {
|
||||
if (ret == 0) {
|
||||
stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_STA,
|
||||
STMPE_ADC_CH(info->channel));
|
||||
mutex_unlock(&info->lock);
|
||||
@ -96,7 +96,7 @@ static int stmpe_read_voltage(struct stmpe_adc *info,
|
||||
static int stmpe_read_temp(struct stmpe_adc *info,
|
||||
struct iio_chan_spec const *chan, int *val)
|
||||
{
|
||||
long ret;
|
||||
unsigned long ret;
|
||||
|
||||
mutex_lock(&info->lock);
|
||||
|
||||
@ -114,7 +114,7 @@ static int stmpe_read_temp(struct stmpe_adc *info,
|
||||
|
||||
ret = wait_for_completion_timeout(&info->completion, STMPE_ADC_TIMEOUT);
|
||||
|
||||
if (ret <= 0) {
|
||||
if (ret == 0) {
|
||||
mutex_unlock(&info->lock);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
@ -345,21 +345,22 @@ static int __maybe_unused stmpe_adc_resume(struct device *dev)
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(stmpe_adc_pm_ops, NULL, stmpe_adc_resume);
|
||||
|
||||
static struct platform_driver stmpe_adc_driver = {
|
||||
.probe = stmpe_adc_probe,
|
||||
.driver = {
|
||||
.name = "stmpe-adc",
|
||||
.pm = &stmpe_adc_pm_ops,
|
||||
},
|
||||
};
|
||||
module_platform_driver(stmpe_adc_driver);
|
||||
|
||||
static const struct of_device_id stmpe_adc_ids[] = {
|
||||
{ .compatible = "st,stmpe-adc", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stmpe_adc_ids);
|
||||
|
||||
static struct platform_driver stmpe_adc_driver = {
|
||||
.probe = stmpe_adc_probe,
|
||||
.driver = {
|
||||
.name = "stmpe-adc",
|
||||
.pm = &stmpe_adc_pm_ops,
|
||||
.of_match_table = stmpe_adc_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(stmpe_adc_driver);
|
||||
|
||||
MODULE_AUTHOR("Stefan Agner <stefan.agner@toradex.com>");
|
||||
MODULE_DESCRIPTION("STMPEXXX ADC driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -76,10 +76,15 @@
|
||||
#define ADS1015_DEFAULT_DATA_RATE 4
|
||||
#define ADS1015_DEFAULT_CHAN 0
|
||||
|
||||
enum chip_ids {
|
||||
ADSXXXX = 0,
|
||||
ADS1015,
|
||||
ADS1115,
|
||||
struct ads1015_chip_data {
|
||||
struct iio_chan_spec const *channels;
|
||||
int num_channels;
|
||||
const struct iio_info *info;
|
||||
const int *data_rate;
|
||||
const int data_rate_len;
|
||||
const int *scale;
|
||||
const int scale_len;
|
||||
bool has_comparator;
|
||||
};
|
||||
|
||||
enum ads1015_channels {
|
||||
@ -94,11 +99,11 @@ enum ads1015_channels {
|
||||
ADS1015_TIMESTAMP,
|
||||
};
|
||||
|
||||
static const unsigned int ads1015_data_rate[] = {
|
||||
static const int ads1015_data_rate[] = {
|
||||
128, 250, 490, 920, 1600, 2400, 3300, 3300
|
||||
};
|
||||
|
||||
static const unsigned int ads1115_data_rate[] = {
|
||||
static const int ads1115_data_rate[] = {
|
||||
8, 16, 32, 64, 128, 250, 475, 860
|
||||
};
|
||||
|
||||
@ -106,10 +111,28 @@ static const unsigned int ads1115_data_rate[] = {
|
||||
* Translation from PGA bits to full-scale positive and negative input voltage
|
||||
* range in mV
|
||||
*/
|
||||
static int ads1015_fullscale_range[] = {
|
||||
static const int ads1015_fullscale_range[] = {
|
||||
6144, 4096, 2048, 1024, 512, 256, 256, 256
|
||||
};
|
||||
|
||||
static const int ads1015_scale[] = { /* 12bit ADC */
|
||||
256, 11,
|
||||
512, 11,
|
||||
1024, 11,
|
||||
2048, 11,
|
||||
4096, 11,
|
||||
6144, 11
|
||||
};
|
||||
|
||||
static const int ads1115_scale[] = { /* 16bit ADC */
|
||||
256, 15,
|
||||
512, 15,
|
||||
1024, 15,
|
||||
2048, 15,
|
||||
4096, 15,
|
||||
6144, 15
|
||||
};
|
||||
|
||||
/*
|
||||
* Translation from COMP_QUE field value to the number of successive readings
|
||||
* exceed the threshold values before an interrupt is generated
|
||||
@ -134,7 +157,29 @@ static const struct iio_event_spec ads1015_events[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#define ADS1015_V_CHAN(_chan, _addr) { \
|
||||
/*
|
||||
* Compile-time check whether _fitbits can accommodate up to _testbits
|
||||
* bits. Returns _fitbits on success, fails to compile otherwise.
|
||||
*
|
||||
* The test works such that it multiplies constant _fitbits by constant
|
||||
* double-negation of size of a non-empty structure, i.e. it multiplies
|
||||
* constant _fitbits by constant 1 in each successful compilation case.
|
||||
* The non-empty structure may contain C11 _Static_assert(), make use of
|
||||
* this and place the kernel variant of static assert in there, so that
|
||||
* it performs the compile-time check for _testbits <= _fitbits. Note
|
||||
* that it is not possible to directly use static_assert in compound
|
||||
* statements, hence this convoluted construct.
|
||||
*/
|
||||
#define FIT_CHECK(_testbits, _fitbits) \
|
||||
( \
|
||||
(_fitbits) * \
|
||||
!!sizeof(struct { \
|
||||
static_assert((_testbits) <= (_fitbits)); \
|
||||
int pad; \
|
||||
}) \
|
||||
)
|
||||
|
||||
#define ADS1015_V_CHAN(_chan, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.indexed = 1, \
|
||||
.address = _addr, \
|
||||
@ -142,20 +187,23 @@ static const struct iio_event_spec ads1015_events[] = {
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
||||
BIT(IIO_CHAN_INFO_SCALE) | \
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
|
||||
.info_mask_shared_by_all_available = \
|
||||
BIT(IIO_CHAN_INFO_SCALE) | \
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
|
||||
.scan_index = _addr, \
|
||||
.scan_type = { \
|
||||
.sign = 's', \
|
||||
.realbits = 12, \
|
||||
.storagebits = 16, \
|
||||
.shift = 4, \
|
||||
.realbits = (_realbits), \
|
||||
.storagebits = FIT_CHECK((_realbits) + (_shift), 16), \
|
||||
.shift = (_shift), \
|
||||
.endianness = IIO_CPU, \
|
||||
}, \
|
||||
.event_spec = ads1015_events, \
|
||||
.num_event_specs = ARRAY_SIZE(ads1015_events), \
|
||||
.event_spec = (_event_spec), \
|
||||
.num_event_specs = (_num_event_specs), \
|
||||
.datasheet_name = "AIN"#_chan, \
|
||||
}
|
||||
|
||||
#define ADS1015_V_DIFF_CHAN(_chan, _chan2, _addr) { \
|
||||
#define ADS1015_V_DIFF_CHAN(_chan, _chan2, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.differential = 1, \
|
||||
.indexed = 1, \
|
||||
@ -165,58 +213,19 @@ static const struct iio_event_spec ads1015_events[] = {
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
||||
BIT(IIO_CHAN_INFO_SCALE) | \
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
|
||||
.scan_index = _addr, \
|
||||
.scan_type = { \
|
||||
.sign = 's', \
|
||||
.realbits = 12, \
|
||||
.storagebits = 16, \
|
||||
.shift = 4, \
|
||||
.endianness = IIO_CPU, \
|
||||
}, \
|
||||
.event_spec = ads1015_events, \
|
||||
.num_event_specs = ARRAY_SIZE(ads1015_events), \
|
||||
.datasheet_name = "AIN"#_chan"-AIN"#_chan2, \
|
||||
}
|
||||
|
||||
#define ADS1115_V_CHAN(_chan, _addr) { \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.indexed = 1, \
|
||||
.address = _addr, \
|
||||
.channel = _chan, \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
||||
.info_mask_shared_by_all_available = \
|
||||
BIT(IIO_CHAN_INFO_SCALE) | \
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
|
||||
.scan_index = _addr, \
|
||||
.scan_type = { \
|
||||
.sign = 's', \
|
||||
.realbits = 16, \
|
||||
.storagebits = 16, \
|
||||
.realbits = (_realbits), \
|
||||
.storagebits = FIT_CHECK((_realbits) + (_shift), 16), \
|
||||
.shift = (_shift), \
|
||||
.endianness = IIO_CPU, \
|
||||
}, \
|
||||
.event_spec = ads1015_events, \
|
||||
.num_event_specs = ARRAY_SIZE(ads1015_events), \
|
||||
.datasheet_name = "AIN"#_chan, \
|
||||
}
|
||||
|
||||
#define ADS1115_V_DIFF_CHAN(_chan, _chan2, _addr) { \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.differential = 1, \
|
||||
.indexed = 1, \
|
||||
.address = _addr, \
|
||||
.channel = _chan, \
|
||||
.channel2 = _chan2, \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
||||
BIT(IIO_CHAN_INFO_SCALE) | \
|
||||
BIT(IIO_CHAN_INFO_SAMP_FREQ), \
|
||||
.scan_index = _addr, \
|
||||
.scan_type = { \
|
||||
.sign = 's', \
|
||||
.realbits = 16, \
|
||||
.storagebits = 16, \
|
||||
.endianness = IIO_CPU, \
|
||||
}, \
|
||||
.event_spec = ads1015_events, \
|
||||
.num_event_specs = ARRAY_SIZE(ads1015_events), \
|
||||
.event_spec = (_event_spec), \
|
||||
.num_event_specs = (_num_event_specs), \
|
||||
.datasheet_name = "AIN"#_chan"-AIN"#_chan2, \
|
||||
}
|
||||
|
||||
@ -245,7 +254,7 @@ struct ads1015_data {
|
||||
unsigned int comp_mode;
|
||||
struct ads1015_thresh_data thresh_data[ADS1015_CHANNELS];
|
||||
|
||||
unsigned int *data_rate;
|
||||
const struct ads1015_chip_data *chip;
|
||||
/*
|
||||
* Set to true when the ADC is switched to the continuous-conversion
|
||||
* mode and exits from a power-down state. This flag is used to avoid
|
||||
@ -273,49 +282,91 @@ static void ads1015_event_channel_disable(struct ads1015_data *data, int chan)
|
||||
data->event_channel = ADS1015_CHANNELS;
|
||||
}
|
||||
|
||||
static bool ads1015_is_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case ADS1015_CFG_REG:
|
||||
case ADS1015_LO_THRESH_REG:
|
||||
case ADS1015_HI_THRESH_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
static const struct regmap_range ads1015_writeable_ranges[] = {
|
||||
regmap_reg_range(ADS1015_CFG_REG, ADS1015_HI_THRESH_REG),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table ads1015_writeable_table = {
|
||||
.yes_ranges = ads1015_writeable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(ads1015_writeable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config ads1015_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 16,
|
||||
.max_register = ADS1015_HI_THRESH_REG,
|
||||
.writeable_reg = ads1015_is_writeable_reg,
|
||||
.wr_table = &ads1015_writeable_table,
|
||||
};
|
||||
|
||||
static const struct regmap_range tla2024_writeable_ranges[] = {
|
||||
regmap_reg_range(ADS1015_CFG_REG, ADS1015_CFG_REG),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table tla2024_writeable_table = {
|
||||
.yes_ranges = tla2024_writeable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(tla2024_writeable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config tla2024_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 16,
|
||||
.max_register = ADS1015_CFG_REG,
|
||||
.wr_table = &tla2024_writeable_table,
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec ads1015_channels[] = {
|
||||
ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1),
|
||||
ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3),
|
||||
ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3),
|
||||
ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3),
|
||||
ADS1015_V_CHAN(0, ADS1015_AIN0),
|
||||
ADS1015_V_CHAN(1, ADS1015_AIN1),
|
||||
ADS1015_V_CHAN(2, ADS1015_AIN2),
|
||||
ADS1015_V_CHAN(3, ADS1015_AIN3),
|
||||
ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 12, 4,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 12, 4,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 12, 4,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 12, 4,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_CHAN(0, ADS1015_AIN0, 12, 4,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_CHAN(1, ADS1015_AIN1, 12, 4,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_CHAN(2, ADS1015_AIN2, 12, 4,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_CHAN(3, ADS1015_AIN3, 12, 4,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP),
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec ads1115_channels[] = {
|
||||
ADS1115_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1),
|
||||
ADS1115_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3),
|
||||
ADS1115_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3),
|
||||
ADS1115_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3),
|
||||
ADS1115_V_CHAN(0, ADS1015_AIN0),
|
||||
ADS1115_V_CHAN(1, ADS1015_AIN1),
|
||||
ADS1115_V_CHAN(2, ADS1015_AIN2),
|
||||
ADS1115_V_CHAN(3, ADS1015_AIN3),
|
||||
ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 16, 0,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 16, 0,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 16, 0,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 16, 0,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_CHAN(0, ADS1015_AIN0, 16, 0,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_CHAN(1, ADS1015_AIN1, 16, 0,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_CHAN(2, ADS1015_AIN2, 16, 0,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
ADS1015_V_CHAN(3, ADS1015_AIN3, 16, 0,
|
||||
ads1015_events, ARRAY_SIZE(ads1015_events)),
|
||||
IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP),
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec tla2024_channels[] = {
|
||||
ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 12, 4, NULL, 0),
|
||||
ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 12, 4, NULL, 0),
|
||||
ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 12, 4, NULL, 0),
|
||||
ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 12, 4, NULL, 0),
|
||||
ADS1015_V_CHAN(0, ADS1015_AIN0, 12, 4, NULL, 0),
|
||||
ADS1015_V_CHAN(1, ADS1015_AIN1, 12, 4, NULL, 0),
|
||||
ADS1015_V_CHAN(2, ADS1015_AIN2, 12, 4, NULL, 0),
|
||||
ADS1015_V_CHAN(3, ADS1015_AIN3, 12, 4, NULL, 0),
|
||||
IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP),
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ads1015_set_power_state(struct ads1015_data *data, bool on)
|
||||
{
|
||||
@ -344,6 +395,7 @@ static int ads1015_set_power_state(struct ads1015_data *data, bool on)
|
||||
static
|
||||
int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val)
|
||||
{
|
||||
const int *data_rate = data->chip->data_rate;
|
||||
int ret, pga, dr, dr_old, conv_time;
|
||||
unsigned int old, mask, cfg;
|
||||
|
||||
@ -378,8 +430,8 @@ int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val)
|
||||
}
|
||||
if (data->conv_invalid) {
|
||||
dr_old = (old & ADS1015_CFG_DR_MASK) >> ADS1015_CFG_DR_SHIFT;
|
||||
conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr_old]);
|
||||
conv_time += DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]);
|
||||
conv_time = DIV_ROUND_UP(USEC_PER_SEC, data_rate[dr_old]);
|
||||
conv_time += DIV_ROUND_UP(USEC_PER_SEC, data_rate[dr]);
|
||||
conv_time += conv_time / 10; /* 10% internal clock inaccuracy */
|
||||
usleep_range(conv_time, conv_time + 1);
|
||||
data->conv_invalid = false;
|
||||
@ -445,8 +497,8 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++) {
|
||||
if (data->data_rate[i] == rate) {
|
||||
for (i = 0; i < data->chip->data_rate_len; i++) {
|
||||
if (data->chip->data_rate[i] == rate) {
|
||||
data->channel_data[chan].data_rate = i;
|
||||
return 0;
|
||||
}
|
||||
@ -455,6 +507,32 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int ads1015_read_avail(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
const int **vals, int *type, int *length,
|
||||
long mask)
|
||||
{
|
||||
struct ads1015_data *data = iio_priv(indio_dev);
|
||||
|
||||
if (chan->type != IIO_VOLTAGE)
|
||||
return -EINVAL;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*type = IIO_VAL_FRACTIONAL_LOG2;
|
||||
*vals = data->chip->scale;
|
||||
*length = data->chip->scale_len;
|
||||
return IIO_AVAIL_LIST;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
*type = IIO_VAL_INT;
|
||||
*vals = data->chip->data_rate;
|
||||
*length = data->chip->data_rate_len;
|
||||
return IIO_AVAIL_LIST;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int ads1015_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan, int *val,
|
||||
int *val2, long mask)
|
||||
@ -504,7 +582,7 @@ release_direct:
|
||||
break;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
idx = data->channel_data[chan->address].data_rate;
|
||||
*val = data->data_rate[idx];
|
||||
*val = data->chip->data_rate[idx];
|
||||
ret = IIO_VAL_INT;
|
||||
break;
|
||||
default:
|
||||
@ -564,7 +642,7 @@ static int ads1015_read_event(struct iio_dev *indio_dev,
|
||||
dr = data->channel_data[chan->address].data_rate;
|
||||
comp_queue = data->thresh_data[chan->address].comp_queue;
|
||||
period = ads1015_comp_queue[comp_queue] *
|
||||
USEC_PER_SEC / data->data_rate[dr];
|
||||
USEC_PER_SEC / data->chip->data_rate[dr];
|
||||
|
||||
*val = period / USEC_PER_SEC;
|
||||
*val2 = period % USEC_PER_SEC;
|
||||
@ -586,6 +664,7 @@ static int ads1015_write_event(struct iio_dev *indio_dev,
|
||||
int val2)
|
||||
{
|
||||
struct ads1015_data *data = iio_priv(indio_dev);
|
||||
const int *data_rate = data->chip->data_rate;
|
||||
int realbits = chan->scan_type.realbits;
|
||||
int ret = 0;
|
||||
long long period;
|
||||
@ -611,7 +690,7 @@ static int ads1015_write_event(struct iio_dev *indio_dev,
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ads1015_comp_queue) - 1; i++) {
|
||||
if (period <= ads1015_comp_queue[i] *
|
||||
USEC_PER_SEC / data->data_rate[dr])
|
||||
USEC_PER_SEC / data_rate[dr])
|
||||
break;
|
||||
}
|
||||
data->thresh_data[chan->address].comp_queue = i;
|
||||
@ -802,54 +881,20 @@ static const struct iio_buffer_setup_ops ads1015_buffer_setup_ops = {
|
||||
.validate_scan_mask = &iio_validate_scan_mask_onehot,
|
||||
};
|
||||
|
||||
static IIO_CONST_ATTR_NAMED(ads1015_scale_available, scale_available,
|
||||
"3 2 1 0.5 0.25 0.125");
|
||||
static IIO_CONST_ATTR_NAMED(ads1115_scale_available, scale_available,
|
||||
"0.1875 0.125 0.0625 0.03125 0.015625 0.007813");
|
||||
|
||||
static IIO_CONST_ATTR_NAMED(ads1015_sampling_frequency_available,
|
||||
sampling_frequency_available, "128 250 490 920 1600 2400 3300");
|
||||
static IIO_CONST_ATTR_NAMED(ads1115_sampling_frequency_available,
|
||||
sampling_frequency_available, "8 16 32 64 128 250 475 860");
|
||||
|
||||
static struct attribute *ads1015_attributes[] = {
|
||||
&iio_const_attr_ads1015_scale_available.dev_attr.attr,
|
||||
&iio_const_attr_ads1015_sampling_frequency_available.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group ads1015_attribute_group = {
|
||||
.attrs = ads1015_attributes,
|
||||
};
|
||||
|
||||
static struct attribute *ads1115_attributes[] = {
|
||||
&iio_const_attr_ads1115_scale_available.dev_attr.attr,
|
||||
&iio_const_attr_ads1115_sampling_frequency_available.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group ads1115_attribute_group = {
|
||||
.attrs = ads1115_attributes,
|
||||
};
|
||||
|
||||
static const struct iio_info ads1015_info = {
|
||||
.read_avail = ads1015_read_avail,
|
||||
.read_raw = ads1015_read_raw,
|
||||
.write_raw = ads1015_write_raw,
|
||||
.read_event_value = ads1015_read_event,
|
||||
.write_event_value = ads1015_write_event,
|
||||
.read_event_config = ads1015_read_event_config,
|
||||
.write_event_config = ads1015_write_event_config,
|
||||
.attrs = &ads1015_attribute_group,
|
||||
};
|
||||
|
||||
static const struct iio_info ads1115_info = {
|
||||
static const struct iio_info tla2024_info = {
|
||||
.read_avail = ads1015_read_avail,
|
||||
.read_raw = ads1015_read_raw,
|
||||
.write_raw = ads1015_write_raw,
|
||||
.read_event_value = ads1015_read_event,
|
||||
.write_event_value = ads1015_write_event,
|
||||
.read_event_config = ads1015_read_event_config,
|
||||
.write_event_config = ads1015_write_event_config,
|
||||
.attrs = &ads1115_attribute_group,
|
||||
};
|
||||
|
||||
static int ads1015_client_get_channels_config(struct i2c_client *client)
|
||||
@ -932,12 +977,18 @@ static int ads1015_set_conv_mode(struct ads1015_data *data, int mode)
|
||||
static int ads1015_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
const struct ads1015_chip_data *chip;
|
||||
struct iio_dev *indio_dev;
|
||||
struct ads1015_data *data;
|
||||
int ret;
|
||||
enum chip_ids chip;
|
||||
int i;
|
||||
|
||||
chip = device_get_match_data(&client->dev);
|
||||
if (!chip)
|
||||
chip = (const struct ads1015_chip_data *)id->driver_data;
|
||||
if (!chip)
|
||||
return dev_err_probe(&client->dev, -EINVAL, "Unknown chip\n");
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
@ -950,28 +1001,12 @@ static int ads1015_probe(struct i2c_client *client,
|
||||
indio_dev->name = ADS1015_DRV_NAME;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
chip = (uintptr_t)device_get_match_data(&client->dev);
|
||||
if (chip == ADSXXXX)
|
||||
chip = id->driver_data;
|
||||
switch (chip) {
|
||||
case ADS1015:
|
||||
indio_dev->channels = ads1015_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(ads1015_channels);
|
||||
indio_dev->info = &ads1015_info;
|
||||
data->data_rate = (unsigned int *) &ads1015_data_rate;
|
||||
break;
|
||||
case ADS1115:
|
||||
indio_dev->channels = ads1115_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(ads1115_channels);
|
||||
indio_dev->info = &ads1115_info;
|
||||
data->data_rate = (unsigned int *) &ads1115_data_rate;
|
||||
break;
|
||||
default:
|
||||
dev_err(&client->dev, "Unknown chip %d\n", chip);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
indio_dev->channels = chip->channels;
|
||||
indio_dev->num_channels = chip->num_channels;
|
||||
indio_dev->info = chip->info;
|
||||
data->chip = chip;
|
||||
data->event_channel = ADS1015_CHANNELS;
|
||||
|
||||
/*
|
||||
* Set default lower and upper threshold to min and max value
|
||||
* respectively.
|
||||
@ -986,7 +1021,9 @@ static int ads1015_probe(struct i2c_client *client,
|
||||
/* we need to keep this ABI the same as used by hwmon ADS1015 driver */
|
||||
ads1015_get_channels_config(client);
|
||||
|
||||
data->regmap = devm_regmap_init_i2c(client, &ads1015_regmap_config);
|
||||
data->regmap = devm_regmap_init_i2c(client, chip->has_comparator ?
|
||||
&ads1015_regmap_config :
|
||||
&tla2024_regmap_config);
|
||||
if (IS_ERR(data->regmap)) {
|
||||
dev_err(&client->dev, "Failed to allocate register map\n");
|
||||
return PTR_ERR(data->regmap);
|
||||
@ -1000,7 +1037,7 @@ static int ads1015_probe(struct i2c_client *client,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (client->irq) {
|
||||
if (client->irq && chip->has_comparator) {
|
||||
unsigned long irq_trig =
|
||||
irqd_get_trigger_type(irq_get_irq_data(client->irq));
|
||||
unsigned int cfg_comp_mask = ADS1015_CFG_COMP_QUE_MASK |
|
||||
@ -1099,22 +1136,51 @@ static const struct dev_pm_ops ads1015_pm_ops = {
|
||||
ads1015_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
static const struct ads1015_chip_data ads1015_data = {
|
||||
.channels = ads1015_channels,
|
||||
.num_channels = ARRAY_SIZE(ads1015_channels),
|
||||
.info = &ads1015_info,
|
||||
.data_rate = ads1015_data_rate,
|
||||
.data_rate_len = ARRAY_SIZE(ads1015_data_rate),
|
||||
.scale = ads1015_scale,
|
||||
.scale_len = ARRAY_SIZE(ads1015_scale),
|
||||
.has_comparator = true,
|
||||
};
|
||||
|
||||
static const struct ads1015_chip_data ads1115_data = {
|
||||
.channels = ads1115_channels,
|
||||
.num_channels = ARRAY_SIZE(ads1115_channels),
|
||||
.info = &ads1015_info,
|
||||
.data_rate = ads1115_data_rate,
|
||||
.data_rate_len = ARRAY_SIZE(ads1115_data_rate),
|
||||
.scale = ads1115_scale,
|
||||
.scale_len = ARRAY_SIZE(ads1115_scale),
|
||||
.has_comparator = true,
|
||||
};
|
||||
|
||||
static const struct ads1015_chip_data tla2024_data = {
|
||||
.channels = tla2024_channels,
|
||||
.num_channels = ARRAY_SIZE(tla2024_channels),
|
||||
.info = &tla2024_info,
|
||||
.data_rate = ads1015_data_rate,
|
||||
.data_rate_len = ARRAY_SIZE(ads1015_data_rate),
|
||||
.scale = ads1015_scale,
|
||||
.scale_len = ARRAY_SIZE(ads1015_scale),
|
||||
.has_comparator = false,
|
||||
};
|
||||
|
||||
static const struct i2c_device_id ads1015_id[] = {
|
||||
{"ads1015", ADS1015},
|
||||
{"ads1115", ADS1115},
|
||||
{ "ads1015", (kernel_ulong_t)&ads1015_data },
|
||||
{ "ads1115", (kernel_ulong_t)&ads1115_data },
|
||||
{ "tla2024", (kernel_ulong_t)&tla2024_data },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ads1015_id);
|
||||
|
||||
static const struct of_device_id ads1015_of_match[] = {
|
||||
{
|
||||
.compatible = "ti,ads1015",
|
||||
.data = (void *)ADS1015
|
||||
},
|
||||
{
|
||||
.compatible = "ti,ads1115",
|
||||
.data = (void *)ADS1115
|
||||
},
|
||||
{ .compatible = "ti,ads1015", .data = &ads1015_data },
|
||||
{ .compatible = "ti,ads1115", .data = &ads1115_data },
|
||||
{ .compatible = "ti,tla2024", .data = &tla2024_data },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ads1015_of_match);
|
||||
|
@ -508,6 +508,7 @@ MODULE_DEVICE_TABLE(of, ads8688_of_match);
|
||||
static struct spi_driver ads8688_driver = {
|
||||
.driver = {
|
||||
.name = "ads8688",
|
||||
.of_match_table = ads8688_of_match,
|
||||
},
|
||||
.probe = ads8688_probe,
|
||||
.remove = ads8688_remove,
|
||||
|
@ -376,9 +376,7 @@ static int tiadc_iio_buffered_hardware_setup(struct device *dev,
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
setup_ops);
|
||||
ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, setup_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -8,7 +8,6 @@ menu "Analog Front Ends"
|
||||
|
||||
config IIO_RESCALE
|
||||
tristate "IIO rescale"
|
||||
depends on OF || COMPILE_TEST
|
||||
help
|
||||
Say yes here to build support for the IIO rescaling
|
||||
that handles voltage dividers, current sense shunts and
|
||||
|
@ -10,9 +10,8 @@
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/gcd.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
@ -536,7 +535,7 @@ static int rescale_probe(struct platform_device *pdev)
|
||||
|
||||
rescale = iio_priv(indio_dev);
|
||||
|
||||
rescale->cfg = of_device_get_match_data(dev);
|
||||
rescale->cfg = device_get_match_data(dev);
|
||||
rescale->numerator = 1;
|
||||
rescale->denominator = 1;
|
||||
rescale->offset = 0;
|
||||
|
@ -259,8 +259,6 @@ static struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev)
|
||||
* devm_iio_kfifo_buffer_setup_ext - Allocate a kfifo buffer & attach it to an IIO device
|
||||
* @dev: Device object to which to attach the life-time of this kfifo buffer
|
||||
* @indio_dev: The device the buffer should be attached to
|
||||
* @mode_flags: The mode flags for this buffer (INDIO_BUFFER_SOFTWARE and/or
|
||||
* INDIO_BUFFER_TRIGGERED).
|
||||
* @setup_ops: The setup_ops required to configure the HW part of the buffer (optional)
|
||||
* @buffer_attrs: Extra sysfs buffer attributes for this IIO buffer
|
||||
*
|
||||
@ -271,22 +269,16 @@ 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,
|
||||
int mode_flags,
|
||||
const struct iio_buffer_setup_ops *setup_ops,
|
||||
const struct attribute **buffer_attrs)
|
||||
{
|
||||
struct iio_buffer *buffer;
|
||||
|
||||
if (!mode_flags)
|
||||
return -EINVAL;
|
||||
|
||||
buffer = devm_iio_kfifo_allocate(dev);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
mode_flags &= kfifo_access_funcs.modes;
|
||||
|
||||
indio_dev->modes |= mode_flags;
|
||||
indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
|
||||
indio_dev->setup_ops = setup_ops;
|
||||
|
||||
buffer->attrs = buffer_attrs;
|
||||
|
@ -333,8 +333,7 @@ int cros_ec_sensors_core_init(struct platform_device *pdev,
|
||||
* We can not use trigger here, as events are generated
|
||||
* as soon as sample_frequency is set.
|
||||
*/
|
||||
ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE, NULL,
|
||||
ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev, NULL,
|
||||
cros_ec_sensor_fifo_attributes);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -413,7 +412,7 @@ static ssize_t cros_ec_sensors_calibrate(struct iio_dev *indio_dev,
|
||||
int ret, i;
|
||||
bool calibrate;
|
||||
|
||||
ret = strtobool(buf, &calibrate);
|
||||
ret = kstrtobool(buf, &calibrate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!calibrate)
|
||||
|
@ -686,7 +686,6 @@ static int scmi_iio_dev_probe(struct scmi_device *sdev)
|
||||
|
||||
err = devm_iio_kfifo_buffer_setup(&scmi_iio_dev->dev,
|
||||
scmi_iio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&scmi_iio_buffer_ops);
|
||||
if (err < 0) {
|
||||
dev_err(dev,
|
||||
|
@ -331,12 +331,11 @@ static int ssp_parse_dataframe(struct ssp_data *data, char *dataframe, int len)
|
||||
/* threaded irq */
|
||||
int ssp_irq_msg(struct ssp_data *data)
|
||||
{
|
||||
bool found = false;
|
||||
char *buffer;
|
||||
u8 msg_type;
|
||||
int ret;
|
||||
u16 length, msg_options;
|
||||
struct ssp_msg *msg, *n;
|
||||
struct ssp_msg *msg = NULL, *iter, *n;
|
||||
|
||||
ret = spi_read(data->spi, data->header_buffer, SSP_HEADER_BUFFER_SIZE);
|
||||
if (ret < 0) {
|
||||
@ -362,15 +361,15 @@ int ssp_irq_msg(struct ssp_data *data)
|
||||
* received with no order
|
||||
*/
|
||||
mutex_lock(&data->pending_lock);
|
||||
list_for_each_entry_safe(msg, n, &data->pending_list, list) {
|
||||
if (msg->options == msg_options) {
|
||||
list_del(&msg->list);
|
||||
found = true;
|
||||
list_for_each_entry_safe(iter, n, &data->pending_list, list) {
|
||||
if (iter->options == msg_options) {
|
||||
list_del(&iter->list);
|
||||
msg = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (!msg) {
|
||||
/*
|
||||
* here can be implemented dead messages handling
|
||||
* but the slave should not send such ones - it is to
|
||||
|
@ -71,16 +71,18 @@ st_sensors_match_odr_error:
|
||||
|
||||
int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)
|
||||
{
|
||||
int err;
|
||||
int err = 0;
|
||||
struct st_sensor_odr_avl odr_out = {0, 0};
|
||||
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||
|
||||
mutex_lock(&sdata->odr_lock);
|
||||
|
||||
if (!sdata->sensor_settings->odr.mask)
|
||||
return 0;
|
||||
goto unlock_mutex;
|
||||
|
||||
err = st_sensors_match_odr(sdata->sensor_settings, odr, &odr_out);
|
||||
if (err < 0)
|
||||
goto st_sensors_match_odr_error;
|
||||
goto unlock_mutex;
|
||||
|
||||
if ((sdata->sensor_settings->odr.addr ==
|
||||
sdata->sensor_settings->pw.addr) &&
|
||||
@ -103,7 +105,9 @@ int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)
|
||||
if (err >= 0)
|
||||
sdata->odr = odr_out.hz;
|
||||
|
||||
st_sensors_match_odr_error:
|
||||
unlock_mutex:
|
||||
mutex_unlock(&sdata->odr_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_NS(st_sensors_set_odr, IIO_ST_SENSORS);
|
||||
@ -361,6 +365,8 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
|
||||
struct st_sensors_platform_data *of_pdata;
|
||||
int err = 0;
|
||||
|
||||
mutex_init(&sdata->odr_lock);
|
||||
|
||||
/* If OF/DT pdata exists, it will take precedence of anything else */
|
||||
of_pdata = st_sensors_dev_probe(indio_dev->dev.parent, pdata);
|
||||
if (IS_ERR(of_pdata))
|
||||
@ -549,26 +555,28 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
|
||||
int err;
|
||||
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
|
||||
err = -EBUSY;
|
||||
err = iio_device_claim_direct_mode(indio_dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mutex_lock(&sdata->odr_lock);
|
||||
|
||||
err = st_sensors_set_enable(indio_dev, true);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
} else {
|
||||
err = st_sensors_set_enable(indio_dev, true);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
msleep((sdata->sensor_settings->bootime * 1000) / sdata->odr);
|
||||
err = st_sensors_read_axis_data(indio_dev, ch, val);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
msleep((sdata->sensor_settings->bootime * 1000) / sdata->odr);
|
||||
err = st_sensors_read_axis_data(indio_dev, ch, val);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
*val = *val >> ch->scan_type.shift;
|
||||
*val = *val >> ch->scan_type.shift;
|
||||
|
||||
err = st_sensors_set_enable(indio_dev, false);
|
||||
|
||||
err = st_sensors_set_enable(indio_dev, false);
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&sdata->odr_lock);
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -641,7 +649,6 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
for (i = 0; i < ST_SENSORS_ODR_LIST_MAX; i++) {
|
||||
if (sdata->sensor_settings->odr.odr_avl[i].hz == 0)
|
||||
break;
|
||||
@ -649,7 +656,6 @@ ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
|
||||
sdata->sensor_settings->odr.odr_avl[i].hz);
|
||||
}
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
buf[len - 1] = '\n';
|
||||
|
||||
return len;
|
||||
@ -663,7 +669,6 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
for (i = 0; i < ST_SENSORS_FULLSCALE_AVL_MAX; i++) {
|
||||
if (sdata->sensor_settings->fs.fs_avl[i].num == 0)
|
||||
break;
|
||||
@ -673,7 +678,6 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ", q, r);
|
||||
}
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
buf[len - 1] = '\n';
|
||||
|
||||
return len;
|
||||
|
@ -285,7 +285,6 @@ config CIO_DAC
|
||||
|
||||
config DPOT_DAC
|
||||
tristate "DAC emulation using a DPOT"
|
||||
depends on OF
|
||||
help
|
||||
Say yes here to build support for DAC emulation using a digital
|
||||
potentiometer.
|
||||
@ -305,7 +304,7 @@ config DS4424
|
||||
config LPC18XX_DAC
|
||||
tristate "NXP LPC18xx DAC driver"
|
||||
depends on ARCH_LPC18XX || COMPILE_TEST
|
||||
depends on OF && HAS_IOMEM
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
Say yes here to build support for NXP LPC18XX DAC.
|
||||
|
||||
@ -442,7 +441,6 @@ config TI_DAC7612
|
||||
|
||||
config VF610_DAC
|
||||
tristate "Vybrid vf610 DAC driver"
|
||||
depends on OF
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
Say yes here to support Vybrid board digital-to-analog converter.
|
||||
|
@ -288,7 +288,7 @@ static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
bool pwr_down;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &pwr_down);
|
||||
ret = kstrtobool(buf, &pwr_down);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -284,7 +284,7 @@ static ssize_t ad5360_write_dac_powerdown(struct device *dev,
|
||||
bool pwr_down;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &pwr_down);
|
||||
ret = kstrtobool(buf, &pwr_down);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -96,7 +96,7 @@ static ssize_t ad5380_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
bool pwr_down;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &pwr_down);
|
||||
ret = kstrtobool(buf, &pwr_down);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -114,7 +114,7 @@ static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
bool powerdown;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &powerdown);
|
||||
ret = kstrtobool(buf, &powerdown);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -182,7 +182,7 @@ static ssize_t ad5504_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
int ret;
|
||||
struct ad5504_state *st = iio_priv(indio_dev);
|
||||
|
||||
ret = strtobool(buf, &pwr_down);
|
||||
ret = kstrtobool(buf, &pwr_down);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -129,7 +129,7 @@ static ssize_t ad5624r_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
int ret;
|
||||
struct ad5624r_state *st = iio_priv(indio_dev);
|
||||
|
||||
ret = strtobool(buf, &pwr_down);
|
||||
ret = kstrtobool(buf, &pwr_down);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -73,7 +73,7 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
unsigned int val, ref_bit_msk;
|
||||
u8 shift, address = 0;
|
||||
|
||||
ret = strtobool(buf, &readin);
|
||||
ret = kstrtobool(buf, &readin);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -502,7 +502,7 @@ static ssize_t ad5755_write_powerdown(struct iio_dev *indio_dev, uintptr_t priv,
|
||||
bool pwr_down;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &pwr_down);
|
||||
ret = kstrtobool(buf, &pwr_down);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -188,7 +188,7 @@ static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
int ret;
|
||||
struct ad5791_state *st = iio_priv(indio_dev);
|
||||
|
||||
ret = strtobool(buf, &pwr_down);
|
||||
ret = kstrtobool(buf, &pwr_down);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -77,7 +77,7 @@ static ssize_t ad7303_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
bool pwr_down;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &pwr_down);
|
||||
ret = kstrtobool(buf, &pwr_down);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
@ -149,7 +150,7 @@ static ssize_t ltc2632_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
int ret;
|
||||
struct ltc2632_state *st = iio_priv(indio_dev);
|
||||
|
||||
ret = strtobool(buf, &pwr_down);
|
||||
ret = kstrtobool(buf, &pwr_down);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -362,8 +363,7 @@ static int ltc2632_probe(struct spi_device *spi)
|
||||
}
|
||||
}
|
||||
|
||||
indio_dev->name = dev_of_node(&spi->dev) ? dev_of_node(&spi->dev)->name
|
||||
: spi_get_device_id(spi)->name;
|
||||
indio_dev->name = fwnode_get_name(dev_fwnode(&spi->dev)) ?: spi_get_device_id(spi)->name;
|
||||
indio_dev->info = <c2632_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->channels = chip_info->channels;
|
||||
@ -469,7 +469,7 @@ MODULE_DEVICE_TABLE(of, ltc2632_of_match);
|
||||
static struct spi_driver ltc2632_driver = {
|
||||
.driver = {
|
||||
.name = "ltc2632",
|
||||
.of_match_table = of_match_ptr(ltc2632_of_match),
|
||||
.of_match_table = ltc2632_of_match,
|
||||
},
|
||||
.probe = ltc2632_probe,
|
||||
.remove = ltc2632_remove,
|
||||
|
@ -703,21 +703,20 @@ static int ltc2688_tgp_clk_setup(struct ltc2688_state *st,
|
||||
struct ltc2688_chan *chan,
|
||||
struct fwnode_handle *node, int tgp)
|
||||
{
|
||||
struct device *dev = &st->spi->dev;
|
||||
unsigned long rate;
|
||||
struct clk *clk;
|
||||
int ret, f;
|
||||
|
||||
clk = devm_get_clk_from_child(&st->spi->dev, to_of_node(node), NULL);
|
||||
clk = devm_get_clk_from_child(dev, to_of_node(node), NULL);
|
||||
if (IS_ERR(clk))
|
||||
return dev_err_probe(&st->spi->dev, PTR_ERR(clk),
|
||||
"failed to get tgp clk.\n");
|
||||
return dev_err_probe(dev, PTR_ERR(clk), "failed to get tgp clk.\n");
|
||||
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (ret)
|
||||
return dev_err_probe(&st->spi->dev, ret,
|
||||
"failed to enable tgp clk.\n");
|
||||
return dev_err_probe(dev, ret, "failed to enable tgp clk.\n");
|
||||
|
||||
ret = devm_add_action_or_reset(&st->spi->dev, ltc2688_clk_disable, clk);
|
||||
ret = devm_add_action_or_reset(dev, ltc2688_clk_disable, clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -858,6 +857,7 @@ static int ltc2688_channel_config(struct ltc2688_state *st)
|
||||
|
||||
static int ltc2688_setup(struct ltc2688_state *st, struct regulator *vref)
|
||||
{
|
||||
struct device *dev = &st->spi->dev;
|
||||
struct gpio_desc *gpio;
|
||||
int ret;
|
||||
|
||||
@ -865,10 +865,9 @@ static int ltc2688_setup(struct ltc2688_state *st, struct regulator *vref)
|
||||
* If we have a reset pin, use that to reset the board, If not, use
|
||||
* the reset bit.
|
||||
*/
|
||||
gpio = devm_gpiod_get_optional(&st->spi->dev, "clr", GPIOD_OUT_HIGH);
|
||||
gpio = devm_gpiod_get_optional(dev, "clr", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(gpio))
|
||||
return dev_err_probe(&st->spi->dev, PTR_ERR(gpio),
|
||||
"Failed to get reset gpio");
|
||||
return dev_err_probe(dev, PTR_ERR(gpio), "Failed to get reset gpio");
|
||||
if (gpio) {
|
||||
usleep_range(1000, 1200);
|
||||
/* bring device out of reset */
|
||||
@ -887,7 +886,7 @@ static int ltc2688_setup(struct ltc2688_state *st, struct regulator *vref)
|
||||
* Duplicate the default channel configuration as it can change during
|
||||
* @ltc2688_channel_config()
|
||||
*/
|
||||
st->iio_chan = devm_kmemdup(&st->spi->dev, ltc2688_channels,
|
||||
st->iio_chan = devm_kmemdup(dev, ltc2688_channels,
|
||||
sizeof(ltc2688_channels), GFP_KERNEL);
|
||||
if (!st->iio_chan)
|
||||
return -ENOMEM;
|
||||
|
@ -116,7 +116,7 @@ static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
bool powerdown;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &powerdown);
|
||||
ret = kstrtobool(buf, &powerdown);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -80,7 +80,7 @@ static ssize_t mcp4725_store_eeprom(struct device *dev,
|
||||
bool state;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &state);
|
||||
ret = kstrtobool(buf, &state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -178,7 +178,7 @@ static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev,
|
||||
bool state;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &state);
|
||||
ret = kstrtobool(buf, &state);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -220,7 +220,7 @@ static ssize_t stm32_dac_write_powerdown(struct iio_dev *indio_dev,
|
||||
bool powerdown;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &powerdown);
|
||||
ret = kstrtobool(buf, &powerdown);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -133,7 +133,7 @@ static ssize_t ti_dac_write_powerdown(struct iio_dev *indio_dev,
|
||||
bool powerdown;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &powerdown);
|
||||
ret = kstrtobool(buf, &powerdown);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -179,7 +179,7 @@ static ssize_t dac5571_write_powerdown(struct iio_dev *indio_dev,
|
||||
bool powerdown;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &powerdown);
|
||||
ret = kstrtobool(buf, &powerdown);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -123,7 +123,7 @@ static ssize_t ti_dac_write_powerdown(struct iio_dev *indio_dev,
|
||||
u8 power;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &powerdown);
|
||||
ret = kstrtobool(buf, &powerdown);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -575,10 +575,9 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)
|
||||
*/
|
||||
|
||||
swd = kzalloc(sizeof(*swd), GFP_KERNEL);
|
||||
if (!swd) {
|
||||
ret = -ENOMEM;
|
||||
goto error_kzalloc;
|
||||
}
|
||||
if (!swd)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/*
|
||||
* Allocate an IIO device.
|
||||
*
|
||||
@ -590,7 +589,7 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)
|
||||
indio_dev = iio_device_alloc(parent, sizeof(*st));
|
||||
if (!indio_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto error_ret;
|
||||
goto error_free_swd;
|
||||
}
|
||||
|
||||
st = iio_priv(indio_dev);
|
||||
@ -616,6 +615,10 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)
|
||||
* indio_dev->name = spi_get_device_id(spi)->name;
|
||||
*/
|
||||
indio_dev->name = kstrdup(name, GFP_KERNEL);
|
||||
if (!indio_dev->name) {
|
||||
ret = -ENOMEM;
|
||||
goto error_free_device;
|
||||
}
|
||||
|
||||
/* Provide description of available channels */
|
||||
indio_dev->channels = iio_dummy_channels;
|
||||
@ -632,7 +635,7 @@ static struct iio_sw_device *iio_dummy_probe(const char *name)
|
||||
|
||||
ret = iio_simple_dummy_events_register(indio_dev);
|
||||
if (ret < 0)
|
||||
goto error_free_device;
|
||||
goto error_free_name;
|
||||
|
||||
ret = iio_simple_dummy_configure_buffer(indio_dev);
|
||||
if (ret < 0)
|
||||
@ -649,11 +652,12 @@ error_unconfigure_buffer:
|
||||
iio_simple_dummy_unconfigure_buffer(indio_dev);
|
||||
error_unregister_events:
|
||||
iio_simple_dummy_events_unregister(indio_dev);
|
||||
error_free_name:
|
||||
kfree(indio_dev->name);
|
||||
error_free_device:
|
||||
iio_device_free(indio_dev);
|
||||
error_ret:
|
||||
error_free_swd:
|
||||
kfree(swd);
|
||||
error_kzalloc:
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
|
@ -516,7 +516,7 @@ static ssize_t ad9523_store(struct device *dev,
|
||||
bool state;
|
||||
int ret;
|
||||
|
||||
ret = strtobool(buf, &state);
|
||||
ret = kstrtobool(buf, &state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
@ -822,7 +822,6 @@ static int fxas21002c_trigger_probe(struct fxas21002c_data *data)
|
||||
{
|
||||
struct device *dev = regmap_get_device(data->regmap);
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct device_node *np = indio_dev->dev.of_node;
|
||||
unsigned long irq_trig;
|
||||
bool irq_open_drain;
|
||||
int irq1;
|
||||
@ -831,8 +830,7 @@ static int fxas21002c_trigger_probe(struct fxas21002c_data *data)
|
||||
if (!data->irq)
|
||||
return 0;
|
||||
|
||||
irq1 = of_irq_get_byname(np, "INT1");
|
||||
|
||||
irq1 = fwnode_irq_get_byname(dev_fwnode(dev), "INT1");
|
||||
if (irq1 == data->irq) {
|
||||
dev_info(dev, "using interrupt line INT1\n");
|
||||
ret = regmap_field_write(data->regmap_fields[F_INT_CFG_DRDY],
|
||||
@ -843,7 +841,7 @@ static int fxas21002c_trigger_probe(struct fxas21002c_data *data)
|
||||
|
||||
dev_info(dev, "using interrupt line INT2\n");
|
||||
|
||||
irq_open_drain = of_property_read_bool(np, "drive-open-drain");
|
||||
irq_open_drain = device_property_read_bool(dev, "drive-open-drain");
|
||||
|
||||
data->dready_trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
|
||||
indio_dev->name,
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
@ -1050,6 +1051,7 @@ static const struct iio_trigger_ops mpu3050_trigger_ops = {
|
||||
static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq)
|
||||
{
|
||||
struct mpu3050 *mpu3050 = iio_priv(indio_dev);
|
||||
struct device *dev = mpu3050->dev;
|
||||
unsigned long irq_trig;
|
||||
int ret;
|
||||
|
||||
@ -1061,8 +1063,7 @@ static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Check if IRQ is open drain */
|
||||
if (of_property_read_bool(mpu3050->dev->of_node, "drive-open-drain"))
|
||||
mpu3050->irq_opendrain = true;
|
||||
mpu3050->irq_opendrain = device_property_read_bool(dev, "drive-open-drain");
|
||||
|
||||
irq_trig = irqd_get_trigger_type(irq_get_irq_data(irq));
|
||||
/*
|
||||
@ -1118,13 +1119,12 @@ static int mpu3050_trigger_probe(struct iio_dev *indio_dev, int irq)
|
||||
mpu3050->trig->name,
|
||||
mpu3050->trig);
|
||||
if (ret) {
|
||||
dev_err(mpu3050->dev,
|
||||
"can't get IRQ %d, error %d\n", irq, ret);
|
||||
dev_err(dev, "can't get IRQ %d, error %d\n", irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
mpu3050->irq = irq;
|
||||
mpu3050->trig->dev.parent = mpu3050->dev;
|
||||
mpu3050->trig->dev.parent = dev;
|
||||
mpu3050->trig->ops = &mpu3050_trigger_ops;
|
||||
iio_trigger_set_drvdata(mpu3050->trig, indio_dev);
|
||||
|
||||
@ -1263,7 +1263,7 @@ err_power_down:
|
||||
}
|
||||
EXPORT_SYMBOL(mpu3050_common_probe);
|
||||
|
||||
int mpu3050_common_remove(struct device *dev)
|
||||
void mpu3050_common_remove(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct mpu3050 *mpu3050 = iio_priv(indio_dev);
|
||||
@ -1276,8 +1276,6 @@ int mpu3050_common_remove(struct device *dev)
|
||||
free_irq(mpu3050->irq, mpu3050);
|
||||
iio_device_unregister(indio_dev);
|
||||
mpu3050_power_down(mpu3050);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mpu3050_common_remove);
|
||||
|
||||
|
@ -86,7 +86,9 @@ static int mpu3050_i2c_remove(struct i2c_client *client)
|
||||
if (mpu3050->i2cmux)
|
||||
i2c_mux_del_adapters(mpu3050->i2cmux);
|
||||
|
||||
return mpu3050_common_remove(&client->dev);
|
||||
mpu3050_common_remove(&client->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -91,7 +91,7 @@ int mpu3050_common_probe(struct device *dev,
|
||||
struct regmap *map,
|
||||
int irq,
|
||||
const char *name);
|
||||
int mpu3050_common_remove(struct device *dev);
|
||||
void mpu3050_common_remove(struct device *dev);
|
||||
|
||||
/* PM ops */
|
||||
extern const struct dev_pm_ops mpu3050_dev_pm_ops;
|
||||
|
@ -113,7 +113,6 @@ static int ssp_gyro_probe(struct platform_device *pdev)
|
||||
indio_dev->available_scan_masks = ssp_gyro_scan_mask;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(&pdev->dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&ssp_gyro_buffer_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -406,24 +406,17 @@ read_error:
|
||||
static int st_gyro_write_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan, int val, int val2, long mask)
|
||||
{
|
||||
int err;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
|
||||
break;
|
||||
return st_sensors_set_fullscale_by_gain(indio_dev, val2);
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
if (val2)
|
||||
return -EINVAL;
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
err = st_sensors_set_odr(indio_dev, val);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return err;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
return st_sensors_set_odr(indio_dev, val);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
|
||||
|
@ -433,7 +433,6 @@ static int max30100_probe(struct i2c_client *client,
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&max30100_buffer_setup_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -542,7 +542,6 @@ static int max30102_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&max30102_buffer_setup_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -7,14 +7,16 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/math.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/lcm.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/swab.h>
|
||||
#include <linux/crc32.h>
|
||||
|
||||
@ -1119,6 +1121,7 @@ static irqreturn_t adis16480_trigger_handler(int irq, void *p)
|
||||
struct iio_dev *indio_dev = pf->indio_dev;
|
||||
struct adis16480 *st = iio_priv(indio_dev);
|
||||
struct adis *adis = &st->adis;
|
||||
struct device *dev = &adis->spi->dev;
|
||||
int ret, bit, offset, i = 0;
|
||||
__be16 *buffer;
|
||||
u32 crc;
|
||||
@ -1130,7 +1133,7 @@ static irqreturn_t adis16480_trigger_handler(int irq, void *p)
|
||||
adis->tx[1] = 0;
|
||||
ret = spi_write(adis->spi, adis->tx, 2);
|
||||
if (ret) {
|
||||
dev_err(&adis->spi->dev, "Failed to change device page: %d\n", ret);
|
||||
dev_err(dev, "Failed to change device page: %d\n", ret);
|
||||
adis_dev_unlock(adis);
|
||||
goto irq_done;
|
||||
}
|
||||
@ -1140,7 +1143,7 @@ static irqreturn_t adis16480_trigger_handler(int irq, void *p)
|
||||
|
||||
ret = spi_sync(adis->spi, &adis->msg);
|
||||
if (ret) {
|
||||
dev_err(&adis->spi->dev, "Failed to read data: %d\n", ret);
|
||||
dev_err(dev, "Failed to read data: %d\n", ret);
|
||||
adis_dev_unlock(adis);
|
||||
goto irq_done;
|
||||
}
|
||||
@ -1168,14 +1171,14 @@ static irqreturn_t adis16480_trigger_handler(int irq, void *p)
|
||||
}
|
||||
|
||||
if (offset == 4) {
|
||||
dev_err(&adis->spi->dev, "Invalid burst data\n");
|
||||
dev_err(dev, "Invalid burst data\n");
|
||||
goto irq_done;
|
||||
}
|
||||
|
||||
crc = be16_to_cpu(buffer[offset + 16]) << 16 | be16_to_cpu(buffer[offset + 15]);
|
||||
valid = adis16480_validate_crc((u16 *)&buffer[offset], 15, crc);
|
||||
if (!valid) {
|
||||
dev_err(&adis->spi->dev, "Invalid crc\n");
|
||||
dev_err(dev, "Invalid crc\n");
|
||||
goto irq_done;
|
||||
}
|
||||
|
||||
@ -1214,12 +1217,12 @@ static const struct iio_info adis16480_info = {
|
||||
static int adis16480_stop_device(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct adis16480 *st = iio_priv(indio_dev);
|
||||
struct device *dev = &st->adis.spi->dev;
|
||||
int ret;
|
||||
|
||||
ret = adis_write_reg_16(&st->adis, ADIS16480_REG_SLP_CNT, BIT(9));
|
||||
if (ret)
|
||||
dev_err(&indio_dev->dev,
|
||||
"Could not power down device: %d\n", ret);
|
||||
dev_err(dev, "Could not power down device: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1239,9 +1242,10 @@ static int adis16480_enable_irq(struct adis *adis, bool enable)
|
||||
return __adis_write_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL, val);
|
||||
}
|
||||
|
||||
static int adis16480_config_irq_pin(struct device_node *of_node,
|
||||
struct adis16480 *st)
|
||||
static int adis16480_config_irq_pin(struct adis16480 *st)
|
||||
{
|
||||
struct device *dev = &st->adis.spi->dev;
|
||||
struct fwnode_handle *fwnode = dev_fwnode(dev);
|
||||
struct irq_data *desc;
|
||||
enum adis16480_int_pin pin;
|
||||
unsigned int irq_type;
|
||||
@ -1250,7 +1254,7 @@ static int adis16480_config_irq_pin(struct device_node *of_node,
|
||||
|
||||
desc = irq_get_irq_data(st->adis.spi->irq);
|
||||
if (!desc) {
|
||||
dev_err(&st->adis.spi->dev, "Could not find IRQ %d\n", irq);
|
||||
dev_err(dev, "Could not find IRQ %d\n", irq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1267,7 +1271,7 @@ static int adis16480_config_irq_pin(struct device_node *of_node,
|
||||
*/
|
||||
pin = ADIS16480_PIN_DIO1;
|
||||
for (i = 0; i < ARRAY_SIZE(adis16480_int_pin_names); i++) {
|
||||
irq = of_irq_get_byname(of_node, adis16480_int_pin_names[i]);
|
||||
irq = fwnode_irq_get_byname(fwnode, adis16480_int_pin_names[i]);
|
||||
if (irq > 0) {
|
||||
pin = i;
|
||||
break;
|
||||
@ -1287,23 +1291,22 @@ static int adis16480_config_irq_pin(struct device_node *of_node,
|
||||
} else if (irq_type == IRQ_TYPE_EDGE_FALLING) {
|
||||
val |= ADIS16480_DRDY_POL(0);
|
||||
} else {
|
||||
dev_err(&st->adis.spi->dev,
|
||||
"Invalid interrupt type 0x%x specified\n", irq_type);
|
||||
dev_err(dev, "Invalid interrupt type 0x%x specified\n", irq_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Write the data ready configuration to the FNCTIO_CTRL register */
|
||||
return adis_write_reg_16(&st->adis, ADIS16480_REG_FNCTIO_CTRL, val);
|
||||
}
|
||||
|
||||
static int adis16480_of_get_ext_clk_pin(struct adis16480 *st,
|
||||
struct device_node *of_node)
|
||||
static int adis16480_fw_get_ext_clk_pin(struct adis16480 *st)
|
||||
{
|
||||
struct device *dev = &st->adis.spi->dev;
|
||||
const char *ext_clk_pin;
|
||||
enum adis16480_int_pin pin;
|
||||
int i;
|
||||
|
||||
pin = ADIS16480_PIN_DIO2;
|
||||
if (of_property_read_string(of_node, "adi,ext-clk-pin", &ext_clk_pin))
|
||||
if (device_property_read_string(dev, "adi,ext-clk-pin", &ext_clk_pin))
|
||||
goto clk_input_not_found;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(adis16480_int_pin_names); i++) {
|
||||
@ -1312,15 +1315,13 @@ static int adis16480_of_get_ext_clk_pin(struct adis16480 *st,
|
||||
}
|
||||
|
||||
clk_input_not_found:
|
||||
dev_info(&st->adis.spi->dev,
|
||||
"clk input line not specified, using DIO2\n");
|
||||
dev_info(dev, "clk input line not specified, using DIO2\n");
|
||||
return pin;
|
||||
}
|
||||
|
||||
static int adis16480_ext_clk_config(struct adis16480 *st,
|
||||
struct device_node *of_node,
|
||||
bool enable)
|
||||
static int adis16480_ext_clk_config(struct adis16480 *st, bool enable)
|
||||
{
|
||||
struct device *dev = &st->adis.spi->dev;
|
||||
unsigned int mode, mask;
|
||||
enum adis16480_int_pin pin;
|
||||
uint16_t val;
|
||||
@ -1330,16 +1331,14 @@ static int adis16480_ext_clk_config(struct adis16480 *st,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pin = adis16480_of_get_ext_clk_pin(st, of_node);
|
||||
pin = adis16480_fw_get_ext_clk_pin(st);
|
||||
/*
|
||||
* Each DIOx pin supports only one function at a time. When a single pin
|
||||
* has two assignments, the enable bit for a lower priority function
|
||||
* automatically resets to zero (disabling the lower priority function).
|
||||
*/
|
||||
if (pin == ADIS16480_DRDY_SEL(val))
|
||||
dev_warn(&st->adis.spi->dev,
|
||||
"DIO%x pin supports only one function at a time\n",
|
||||
pin + 1);
|
||||
dev_warn(dev, "DIO%x pin supports only one function at a time\n", pin + 1);
|
||||
|
||||
mode = ADIS16480_SYNC_EN(enable) | ADIS16480_SYNC_SEL(pin);
|
||||
mask = ADIS16480_SYNC_EN_MSK | ADIS16480_SYNC_SEL_MSK;
|
||||
@ -1361,31 +1360,27 @@ static int adis16480_ext_clk_config(struct adis16480 *st,
|
||||
|
||||
static int adis16480_get_ext_clocks(struct adis16480 *st)
|
||||
{
|
||||
st->clk_mode = ADIS16480_CLK_INT;
|
||||
st->ext_clk = devm_clk_get(&st->adis.spi->dev, "sync");
|
||||
if (!IS_ERR_OR_NULL(st->ext_clk)) {
|
||||
struct device *dev = &st->adis.spi->dev;
|
||||
|
||||
st->ext_clk = devm_clk_get_optional(dev, "sync");
|
||||
if (IS_ERR(st->ext_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(st->ext_clk), "failed to get ext clk\n");
|
||||
if (st->ext_clk) {
|
||||
st->clk_mode = ADIS16480_CLK_SYNC;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (PTR_ERR(st->ext_clk) != -ENOENT) {
|
||||
dev_err(&st->adis.spi->dev, "failed to get ext clk\n");
|
||||
return PTR_ERR(st->ext_clk);
|
||||
}
|
||||
|
||||
if (st->chip_info->has_pps_clk_mode) {
|
||||
st->ext_clk = devm_clk_get(&st->adis.spi->dev, "pps");
|
||||
if (!IS_ERR_OR_NULL(st->ext_clk)) {
|
||||
st->ext_clk = devm_clk_get_optional(dev, "pps");
|
||||
if (IS_ERR(st->ext_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(st->ext_clk), "failed to get ext clk\n");
|
||||
if (st->ext_clk) {
|
||||
st->clk_mode = ADIS16480_CLK_PPS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (PTR_ERR(st->ext_clk) != -ENOENT) {
|
||||
dev_err(&st->adis.spi->dev, "failed to get ext clk\n");
|
||||
return PTR_ERR(st->ext_clk);
|
||||
}
|
||||
}
|
||||
|
||||
st->clk_mode = ADIS16480_CLK_INT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1404,11 +1399,12 @@ static int adis16480_probe(struct spi_device *spi)
|
||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
const struct adis_data *adis16480_data;
|
||||
irq_handler_t trigger_handler = NULL;
|
||||
struct device *dev = &spi->dev;
|
||||
struct iio_dev *indio_dev;
|
||||
struct adis16480 *st;
|
||||
int ret;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
|
||||
if (indio_dev == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1432,13 +1428,12 @@ static int adis16480_probe(struct spi_device *spi)
|
||||
return ret;
|
||||
|
||||
if (st->chip_info->has_sleep_cnt) {
|
||||
ret = devm_add_action_or_reset(&spi->dev, adis16480_stop,
|
||||
indio_dev);
|
||||
ret = devm_add_action_or_reset(dev, adis16480_stop, indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = adis16480_config_irq_pin(spi->dev.of_node, st);
|
||||
ret = adis16480_config_irq_pin(st);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1446,12 +1441,12 @@ static int adis16480_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!IS_ERR_OR_NULL(st->ext_clk)) {
|
||||
ret = adis16480_ext_clk_config(st, spi->dev.of_node, true);
|
||||
if (st->ext_clk) {
|
||||
ret = adis16480_ext_clk_config(st, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(&spi->dev, adis16480_clk_disable, st->ext_clk);
|
||||
ret = devm_add_action_or_reset(dev, adis16480_clk_disable, st->ext_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1484,7 +1479,7 @@ static int adis16480_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_iio_device_register(&spi->dev, indio_dev);
|
||||
ret = devm_iio_device_register(dev, indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -11,10 +11,9 @@
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <linux/iio/iio.h>
|
||||
@ -525,17 +524,6 @@ static const struct iio_info bmi160_info = {
|
||||
.attrs = &bmi160_attrs_group,
|
||||
};
|
||||
|
||||
static const char *bmi160_match_acpi_device(struct device *dev)
|
||||
{
|
||||
const struct acpi_device_id *id;
|
||||
|
||||
id = acpi_match_device(dev->driver->acpi_match_table, dev);
|
||||
if (!id)
|
||||
return NULL;
|
||||
|
||||
return dev_name(dev);
|
||||
}
|
||||
|
||||
static int bmi160_write_conf_reg(struct regmap *regmap, unsigned int reg,
|
||||
unsigned int mask, unsigned int bits,
|
||||
unsigned int write_usleep)
|
||||
@ -647,18 +635,18 @@ int bmi160_enable_irq(struct regmap *regmap, bool enable)
|
||||
}
|
||||
EXPORT_SYMBOL(bmi160_enable_irq);
|
||||
|
||||
static int bmi160_get_irq(struct device_node *of_node, enum bmi160_int_pin *pin)
|
||||
static int bmi160_get_irq(struct fwnode_handle *fwnode, enum bmi160_int_pin *pin)
|
||||
{
|
||||
int irq;
|
||||
|
||||
/* Use INT1 if possible, otherwise fall back to INT2. */
|
||||
irq = of_irq_get_byname(of_node, "INT1");
|
||||
irq = fwnode_irq_get_byname(fwnode, "INT1");
|
||||
if (irq > 0) {
|
||||
*pin = BMI160_PIN_INT1;
|
||||
return irq;
|
||||
}
|
||||
|
||||
irq = of_irq_get_byname(of_node, "INT2");
|
||||
irq = fwnode_irq_get_byname(fwnode, "INT2");
|
||||
if (irq > 0)
|
||||
*pin = BMI160_PIN_INT2;
|
||||
|
||||
@ -688,7 +676,7 @@ static int bmi160_config_device_irq(struct iio_dev *indio_dev, int irq_type,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
open_drain = of_property_read_bool(dev->of_node, "drive-open-drain");
|
||||
open_drain = device_property_read_bool(dev, "drive-open-drain");
|
||||
|
||||
return bmi160_config_pin(data->regmap, pin, open_drain, irq_mask,
|
||||
BMI160_NORMAL_WRITE_USLEEP);
|
||||
@ -872,9 +860,6 @@ int bmi160_core_probe(struct device *dev, struct regmap *regmap,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!name && ACPI_HANDLE(dev))
|
||||
name = bmi160_match_acpi_device(dev);
|
||||
|
||||
indio_dev->channels = bmi160_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(bmi160_channels);
|
||||
indio_dev->name = name;
|
||||
@ -887,7 +872,7 @@ int bmi160_core_probe(struct device *dev, struct regmap *regmap,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
irq = bmi160_get_irq(dev->of_node, &int_pin);
|
||||
irq = bmi160_get_irq(dev_fwnode(dev), &int_pin);
|
||||
if (irq > 0) {
|
||||
ret = bmi160_setup_irq(indio_dev, irq, int_pin);
|
||||
if (ret)
|
||||
|
@ -8,10 +8,9 @@
|
||||
* - 0x68 if SDO is pulled to GND
|
||||
* - 0x69 if SDO is pulled to VDDIO
|
||||
*/
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "bmi160.h"
|
||||
@ -20,7 +19,7 @@ static int bmi160_i2c_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
const char *name = NULL;
|
||||
const char *name;
|
||||
|
||||
regmap = devm_regmap_init_i2c(client, &bmi160_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
@ -31,6 +30,8 @@ static int bmi160_i2c_probe(struct i2c_client *client,
|
||||
|
||||
if (id)
|
||||
name = id->name;
|
||||
else
|
||||
name = dev_name(&client->dev);
|
||||
|
||||
return bmi160_core_probe(&client->dev, regmap, name, false);
|
||||
}
|
||||
@ -47,19 +48,17 @@ static const struct acpi_device_id bmi160_acpi_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id bmi160_of_match[] = {
|
||||
{ .compatible = "bosch,bmi160" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bmi160_of_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver bmi160_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "bmi160_i2c",
|
||||
.acpi_match_table = ACPI_PTR(bmi160_acpi_match),
|
||||
.of_match_table = of_match_ptr(bmi160_of_match),
|
||||
.acpi_match_table = bmi160_acpi_match,
|
||||
.of_match_table = bmi160_of_match,
|
||||
},
|
||||
.probe = bmi160_i2c_probe,
|
||||
.id_table = bmi160_i2c_id,
|
||||
|
@ -5,9 +5,8 @@
|
||||
* Copyright (c) 2016, Intel Corporation.
|
||||
*
|
||||
*/
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
@ -17,6 +16,7 @@ static int bmi160_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
const struct spi_device_id *id = spi_get_device_id(spi);
|
||||
const char *name;
|
||||
|
||||
regmap = devm_regmap_init_spi(spi, &bmi160_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
@ -24,7 +24,13 @@ static int bmi160_spi_probe(struct spi_device *spi)
|
||||
regmap);
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
return bmi160_core_probe(&spi->dev, regmap, id->name, true);
|
||||
|
||||
if (id)
|
||||
name = id->name;
|
||||
else
|
||||
name = dev_name(&spi->dev);
|
||||
|
||||
return bmi160_core_probe(&spi->dev, regmap, name, true);
|
||||
}
|
||||
|
||||
static const struct spi_device_id bmi160_spi_id[] = {
|
||||
@ -39,20 +45,18 @@ static const struct acpi_device_id bmi160_acpi_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id bmi160_of_match[] = {
|
||||
{ .compatible = "bosch,bmi160" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bmi160_of_match);
|
||||
#endif
|
||||
|
||||
static struct spi_driver bmi160_spi_driver = {
|
||||
.probe = bmi160_spi_probe,
|
||||
.id_table = bmi160_spi_id,
|
||||
.driver = {
|
||||
.acpi_match_table = ACPI_PTR(bmi160_acpi_match),
|
||||
.of_match_table = of_match_ptr(bmi160_of_match),
|
||||
.acpi_match_table = bmi160_acpi_match,
|
||||
.of_match_table = bmi160_of_match,
|
||||
.name = "bmi160_spi",
|
||||
},
|
||||
};
|
||||
|
@ -731,7 +731,6 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st)
|
||||
indio_dev->available_scan_masks = inv_icm42600_accel_scan_masks;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&inv_icm42600_buffer_ops);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
@ -743,7 +743,6 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st)
|
||||
indio_dev->setup_ops = &inv_icm42600_buffer_ops;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&inv_icm42600_buffer_ops);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
@ -16,7 +16,7 @@ config INV_MPU6050_I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports the Invensense MPU6050/9150,
|
||||
MPU6500/6515/6880/9250/9255, ICM20608/20609/20689, ICM20602/ICM20690
|
||||
MPU6500/6515/6880/9250/9255, ICM20608(D)/20609/20689, ICM20602/ICM20690
|
||||
and IAM20680 motion tracking devices over I2C.
|
||||
This driver can be built as a module. The module will be called
|
||||
inv-mpu6050-i2c.
|
||||
@ -28,7 +28,7 @@ config INV_MPU6050_SPI
|
||||
select REGMAP_SPI
|
||||
help
|
||||
This driver supports the Invensense MPU6000,
|
||||
MPU6500/6515/6880/9250/9255, ICM20608/20609/20689, ICM20602/ICM20690
|
||||
MPU6500/6515/6880/9250/9255, ICM20608(D)/20609/20689, ICM20602/ICM20690
|
||||
and IAM20680 motion tracking devices over SPI.
|
||||
This driver can be built as a module. The module will be called
|
||||
inv-mpu6050-spi.
|
||||
|
@ -217,6 +217,15 @@ static const struct inv_mpu6050_hw hw_info[] = {
|
||||
.temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
|
||||
.startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
|
||||
},
|
||||
{
|
||||
.whoami = INV_ICM20608D_WHOAMI_VALUE,
|
||||
.name = "ICM20608D",
|
||||
.reg = ®_set_6500,
|
||||
.config = &chip_config_6500,
|
||||
.fifo_size = 512,
|
||||
.temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE},
|
||||
.startup_time = {INV_MPU6500_GYRO_STARTUP_TIME, INV_MPU6500_ACCEL_STARTUP_TIME},
|
||||
},
|
||||
{
|
||||
.whoami = INV_ICM20609_WHOAMI_VALUE,
|
||||
.name = "ICM20609",
|
||||
|
@ -29,6 +29,7 @@ static bool inv_mpu_i2c_aux_bus(struct device *dev)
|
||||
|
||||
switch (st->chip_type) {
|
||||
case INV_ICM20608:
|
||||
case INV_ICM20608D:
|
||||
case INV_ICM20609:
|
||||
case INV_ICM20689:
|
||||
case INV_ICM20602:
|
||||
@ -182,6 +183,7 @@ static const struct i2c_device_id inv_mpu_id[] = {
|
||||
{"mpu9250", INV_MPU9250},
|
||||
{"mpu9255", INV_MPU9255},
|
||||
{"icm20608", INV_ICM20608},
|
||||
{"icm20608d", INV_ICM20608D},
|
||||
{"icm20609", INV_ICM20609},
|
||||
{"icm20689", INV_ICM20689},
|
||||
{"icm20602", INV_ICM20602},
|
||||
@ -225,6 +227,10 @@ static const struct of_device_id inv_of_match[] = {
|
||||
.compatible = "invensense,icm20608",
|
||||
.data = (void *)INV_ICM20608
|
||||
},
|
||||
{
|
||||
.compatible = "invensense,icm20608d",
|
||||
.data = (void *)INV_ICM20608D
|
||||
},
|
||||
{
|
||||
.compatible = "invensense,icm20609",
|
||||
.data = (void *)INV_ICM20609
|
||||
|
@ -76,6 +76,7 @@ enum inv_devices {
|
||||
INV_MPU9250,
|
||||
INV_MPU9255,
|
||||
INV_ICM20608,
|
||||
INV_ICM20608D,
|
||||
INV_ICM20609,
|
||||
INV_ICM20689,
|
||||
INV_ICM20602,
|
||||
@ -394,6 +395,7 @@ struct inv_mpu6050_state {
|
||||
#define INV_MPU9255_WHOAMI_VALUE 0x73
|
||||
#define INV_MPU6515_WHOAMI_VALUE 0x74
|
||||
#define INV_ICM20608_WHOAMI_VALUE 0xAF
|
||||
#define INV_ICM20608D_WHOAMI_VALUE 0xAE
|
||||
#define INV_ICM20609_WHOAMI_VALUE 0xA6
|
||||
#define INV_ICM20689_WHOAMI_VALUE 0x98
|
||||
#define INV_ICM20602_WHOAMI_VALUE 0x12
|
||||
|
@ -73,6 +73,7 @@ static const struct spi_device_id inv_mpu_id[] = {
|
||||
{"mpu9250", INV_MPU9250},
|
||||
{"mpu9255", INV_MPU9255},
|
||||
{"icm20608", INV_ICM20608},
|
||||
{"icm20608d", INV_ICM20608D},
|
||||
{"icm20609", INV_ICM20609},
|
||||
{"icm20689", INV_ICM20689},
|
||||
{"icm20602", INV_ICM20602},
|
||||
@ -112,6 +113,10 @@ static const struct of_device_id inv_of_match[] = {
|
||||
.compatible = "invensense,icm20608",
|
||||
.data = (void *)INV_ICM20608
|
||||
},
|
||||
{
|
||||
.compatible = "invensense,icm20608d",
|
||||
.data = (void *)INV_ICM20608D
|
||||
},
|
||||
{
|
||||
.compatible = "invensense,icm20609",
|
||||
.data = (void *)INV_ICM20609
|
||||
|
@ -11,9 +11,9 @@ 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, lsm6dsr, lsm6ds3tr-c,
|
||||
ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop, the accelerometer/gyroscope
|
||||
of lsm9ds1 and lsm6dst.
|
||||
ism330dlc, lsm6dso, lsm6dsox, asm330lhh, asm330lhhx, lsm6dsr,
|
||||
lsm6ds3tr-c, ism330dhcx, lsm6dsrx, lsm6ds0, lsm6dsop,
|
||||
the accelerometer/gyroscope of lsm9ds1 and lsm6dst.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called st_lsm6dsx.
|
||||
|
@ -31,6 +31,7 @@
|
||||
#define ST_LSM6DSRX_DEV_NAME "lsm6dsrx"
|
||||
#define ST_LSM6DST_DEV_NAME "lsm6dst"
|
||||
#define ST_LSM6DSOP_DEV_NAME "lsm6dsop"
|
||||
#define ST_ASM330LHHX_DEV_NAME "asm330lhhx"
|
||||
|
||||
enum st_lsm6dsx_hw_id {
|
||||
ST_LSM6DS3_ID,
|
||||
@ -49,6 +50,7 @@ enum st_lsm6dsx_hw_id {
|
||||
ST_LSM6DSRX_ID,
|
||||
ST_LSM6DST_ID,
|
||||
ST_LSM6DSOP_ID,
|
||||
ST_ASM330LHHX_ID,
|
||||
ST_LSM6DSX_MAX_ID,
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,8 @@
|
||||
* (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/LSM6DSR/LSM6DSRX/ISM330DHCX/LSM6DST/LSM6DSOP:
|
||||
* LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/LSM6DSRX/ISM330DHCX/
|
||||
* LSM6DST/LSM6DSOP:
|
||||
* 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).
|
||||
@ -746,7 +747,6 @@ int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw)
|
||||
continue;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(hw->dev, hw->iio_devs[i],
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&st_lsm6dsx_buffer_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -26,7 +26,7 @@
|
||||
* - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
|
||||
* - FIFO size: 4KB
|
||||
*
|
||||
* - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP:
|
||||
* - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP:
|
||||
* - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416,
|
||||
* 833
|
||||
* - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
|
||||
@ -786,6 +786,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
|
||||
.hw_id = ST_LSM6DST_ID,
|
||||
.name = ST_LSM6DST_DEV_NAME,
|
||||
.wai = 0x6d,
|
||||
}, {
|
||||
.hw_id = ST_ASM330LHHX_ID,
|
||||
.name = ST_ASM330LHHX_DEV_NAME,
|
||||
.wai = 0x6b,
|
||||
},
|
||||
},
|
||||
.channels = {
|
||||
|
@ -101,6 +101,10 @@ static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
|
||||
.compatible = "st,lsm6dsop",
|
||||
.data = (void *)ST_LSM6DSOP_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,asm330lhhx",
|
||||
.data = (void *)ST_ASM330LHHX_ID,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
|
||||
@ -122,6 +126,7 @@ static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
|
||||
{ ST_LSM6DSRX_DEV_NAME, ST_LSM6DSRX_ID },
|
||||
{ ST_LSM6DST_DEV_NAME, ST_LSM6DST_ID },
|
||||
{ ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID },
|
||||
{ ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
|
||||
|
@ -101,6 +101,10 @@ static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
|
||||
.compatible = "st,lsm6dsop",
|
||||
.data = (void *)ST_LSM6DSOP_ID,
|
||||
},
|
||||
{
|
||||
.compatible = "st,asm330lhhx",
|
||||
.data = (void *)ST_ASM330LHHX_ID,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
|
||||
@ -122,6 +126,7 @@ static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
|
||||
{ ST_LSM6DSRX_DEV_NAME, ST_LSM6DSRX_ID },
|
||||
{ ST_LSM6DST_DEV_NAME, ST_LSM6DST_ID },
|
||||
{ ST_LSM6DSOP_DEV_NAME, ST_LSM6DSOP_ID },
|
||||
{ ST_ASM330LHHX_DEV_NAME, ST_ASM330LHHX_ID },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
|
||||
|
@ -510,7 +510,7 @@ static ssize_t iio_scan_el_store(struct device *dev,
|
||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||
struct iio_buffer *buffer = this_attr->buffer;
|
||||
|
||||
ret = strtobool(buf, &state);
|
||||
ret = kstrtobool(buf, &state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
@ -557,7 +557,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
|
||||
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
|
||||
bool state;
|
||||
|
||||
ret = strtobool(buf, &state);
|
||||
ret = kstrtobool(buf, &state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -915,7 +915,7 @@ static int iio_verify_update(struct iio_dev *indio_dev,
|
||||
if (scan_mask == NULL)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
scan_mask = compound_mask;
|
||||
scan_mask = compound_mask;
|
||||
}
|
||||
|
||||
config->scan_bytes = iio_compute_scan_bytes(indio_dev,
|
||||
@ -1059,13 +1059,13 @@ static int iio_enable_buffers(struct iio_dev *indio_dev,
|
||||
struct iio_device_config *config)
|
||||
{
|
||||
struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
|
||||
struct iio_buffer *buffer;
|
||||
struct iio_buffer *buffer, *tmp = NULL;
|
||||
int ret;
|
||||
|
||||
indio_dev->active_scan_mask = config->scan_mask;
|
||||
indio_dev->scan_timestamp = config->scan_timestamp;
|
||||
indio_dev->scan_bytes = config->scan_bytes;
|
||||
indio_dev->currentmode = config->mode;
|
||||
iio_dev_opaque->currentmode = config->mode;
|
||||
|
||||
iio_update_demux(indio_dev);
|
||||
|
||||
@ -1097,11 +1097,13 @@ static int iio_enable_buffers(struct iio_dev *indio_dev,
|
||||
|
||||
list_for_each_entry(buffer, &iio_dev_opaque->buffer_list, buffer_list) {
|
||||
ret = iio_buffer_enable(buffer, indio_dev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
tmp = buffer;
|
||||
goto err_disable_buffers;
|
||||
}
|
||||
}
|
||||
|
||||
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
|
||||
if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) {
|
||||
ret = iio_trigger_attach_poll_func(indio_dev->trig,
|
||||
indio_dev->pollfunc);
|
||||
if (ret)
|
||||
@ -1120,11 +1122,12 @@ static int iio_enable_buffers(struct iio_dev *indio_dev,
|
||||
return 0;
|
||||
|
||||
err_detach_pollfunc:
|
||||
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
|
||||
if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) {
|
||||
iio_trigger_detach_poll_func(indio_dev->trig,
|
||||
indio_dev->pollfunc);
|
||||
}
|
||||
err_disable_buffers:
|
||||
buffer = list_prepare_entry(tmp, &iio_dev_opaque->buffer_list, buffer_list);
|
||||
list_for_each_entry_continue_reverse(buffer, &iio_dev_opaque->buffer_list,
|
||||
buffer_list)
|
||||
iio_buffer_disable(buffer, indio_dev);
|
||||
@ -1132,7 +1135,7 @@ err_run_postdisable:
|
||||
if (indio_dev->setup_ops->postdisable)
|
||||
indio_dev->setup_ops->postdisable(indio_dev);
|
||||
err_undo_config:
|
||||
indio_dev->currentmode = INDIO_DIRECT_MODE;
|
||||
iio_dev_opaque->currentmode = INDIO_DIRECT_MODE;
|
||||
indio_dev->active_scan_mask = NULL;
|
||||
|
||||
return ret;
|
||||
@ -1162,7 +1165,7 @@ static int iio_disable_buffers(struct iio_dev *indio_dev)
|
||||
ret = ret2;
|
||||
}
|
||||
|
||||
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
|
||||
if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) {
|
||||
iio_trigger_detach_poll_func(indio_dev->trig,
|
||||
indio_dev->pollfunc);
|
||||
}
|
||||
@ -1181,7 +1184,7 @@ static int iio_disable_buffers(struct iio_dev *indio_dev)
|
||||
|
||||
iio_free_scan_mask(indio_dev, indio_dev->active_scan_mask);
|
||||
indio_dev->active_scan_mask = NULL;
|
||||
indio_dev->currentmode = INDIO_DIRECT_MODE;
|
||||
iio_dev_opaque->currentmode = INDIO_DIRECT_MODE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1300,7 +1303,7 @@ static ssize_t iio_buffer_store_enable(struct device *dev,
|
||||
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
|
||||
bool inlist;
|
||||
|
||||
ret = strtobool(buf, &requested_state);
|
||||
ret = kstrtobool(buf, &requested_state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -1629,6 +1632,19 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
|
||||
if (channels[i].scan_index < 0)
|
||||
continue;
|
||||
|
||||
/* Verify that sample bits fit into storage */
|
||||
if (channels[i].scan_type.storagebits <
|
||||
channels[i].scan_type.realbits +
|
||||
channels[i].scan_type.shift) {
|
||||
dev_err(&indio_dev->dev,
|
||||
"Channel %d storagebits (%d) < shifted realbits (%d + %d)\n",
|
||||
i, channels[i].scan_type.storagebits,
|
||||
channels[i].scan_type.realbits,
|
||||
channels[i].scan_type.shift);
|
||||
ret = -EINVAL;
|
||||
goto error_cleanup_dynamic;
|
||||
}
|
||||
|
||||
ret = iio_buffer_add_channel_sysfs(indio_dev, buffer,
|
||||
&channels[i]);
|
||||
if (ret < 0)
|
||||
@ -1649,7 +1665,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
|
||||
}
|
||||
|
||||
attrn = buffer_attrcount + scan_el_attrcount + ARRAY_SIZE(iio_buffer_attrs);
|
||||
attr = kcalloc(attrn + 1, sizeof(* attr), GFP_KERNEL);
|
||||
attr = kcalloc(attrn + 1, sizeof(*attr), GFP_KERNEL);
|
||||
if (!attr) {
|
||||
ret = -ENOMEM;
|
||||
goto error_free_scan_mask;
|
||||
|
@ -184,6 +184,20 @@ int iio_device_id(struct iio_dev *indio_dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iio_device_id);
|
||||
|
||||
/**
|
||||
* iio_buffer_enabled() - helper function to test if the buffer is enabled
|
||||
* @indio_dev: IIO device structure for device
|
||||
*/
|
||||
bool iio_buffer_enabled(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
|
||||
|
||||
return iio_dev_opaque->currentmode
|
||||
& (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE |
|
||||
INDIO_BUFFER_SOFTWARE);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iio_buffer_enabled);
|
||||
|
||||
/**
|
||||
* iio_sysfs_match_string_with_gaps - matches given string in an array with gaps
|
||||
* @array: array of strings
|
||||
@ -892,8 +906,7 @@ static int __iio_str_to_fixpoint(const char *str, int fract_mult,
|
||||
} else if (*str == '\n') {
|
||||
if (*(str + 1) == '\0')
|
||||
break;
|
||||
else
|
||||
return -EINVAL;
|
||||
return -EINVAL;
|
||||
} else if (!strncmp(str, " dB", sizeof(" dB") - 1) && scale_db) {
|
||||
/* Ignore the dB suffix */
|
||||
str += sizeof(" dB") - 1;
|
||||
@ -1894,20 +1907,22 @@ static const struct iio_buffer_setup_ops noop_ring_setup_ops;
|
||||
int __iio_device_register(struct iio_dev *indio_dev, struct module *this_mod)
|
||||
{
|
||||
struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
|
||||
const char *label;
|
||||
struct fwnode_handle *fwnode;
|
||||
int ret;
|
||||
|
||||
if (!indio_dev->info)
|
||||
return -EINVAL;
|
||||
|
||||
iio_dev_opaque->driver_module = this_mod;
|
||||
/* If the calling driver did not initialize of_node, do it here */
|
||||
if (!indio_dev->dev.of_node && indio_dev->dev.parent)
|
||||
indio_dev->dev.of_node = indio_dev->dev.parent->of_node;
|
||||
|
||||
label = of_get_property(indio_dev->dev.of_node, "label", NULL);
|
||||
if (label)
|
||||
indio_dev->label = label;
|
||||
/* If the calling driver did not initialize firmware node, do it here */
|
||||
if (dev_fwnode(&indio_dev->dev))
|
||||
fwnode = dev_fwnode(&indio_dev->dev);
|
||||
else
|
||||
fwnode = dev_fwnode(indio_dev->dev.parent);
|
||||
device_set_node(&indio_dev->dev, fwnode);
|
||||
|
||||
fwnode_property_read_string(fwnode, "label", &indio_dev->label);
|
||||
|
||||
ret = iio_check_unique_scan_index(indio_dev);
|
||||
if (ret < 0)
|
||||
@ -2059,6 +2074,19 @@ void iio_device_release_direct_mode(struct iio_dev *indio_dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iio_device_release_direct_mode);
|
||||
|
||||
/**
|
||||
* iio_device_get_current_mode() - helper function providing read-only access to
|
||||
* the opaque @currentmode variable
|
||||
* @indio_dev: IIO device structure for device
|
||||
*/
|
||||
int iio_device_get_current_mode(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev);
|
||||
|
||||
return iio_dev_opaque->currentmode;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(iio_device_get_current_mode);
|
||||
|
||||
subsys_initcall(iio_init);
|
||||
module_exit(iio_exit);
|
||||
|
||||
|
@ -274,7 +274,7 @@ static ssize_t iio_ev_state_store(struct device *dev,
|
||||
int ret;
|
||||
bool val;
|
||||
|
||||
ret = strtobool(buf, &val);
|
||||
ret = kstrtobool(buf, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -444,7 +444,7 @@ static ssize_t iio_trigger_write_current(struct device *dev,
|
||||
int ret;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
|
||||
if (iio_dev_opaque->currentmode == INDIO_BUFFER_TRIGGERED) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
@ -155,7 +155,6 @@ config CM3323
|
||||
|
||||
config CM3605
|
||||
tristate "Capella CM3605 ambient light and proximity sensor"
|
||||
depends on OF
|
||||
help
|
||||
Say Y here if you want to build a driver for Capella CM3605
|
||||
ambient light and short range proximity sensor.
|
||||
|
@ -1003,7 +1003,6 @@ static int apds9960_probe(struct i2c_client *client,
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev,
|
||||
INDIO_BUFFER_SOFTWARE,
|
||||
&apds9960_buffer_setup_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -106,6 +106,7 @@ struct stk3310_data {
|
||||
struct mutex lock;
|
||||
bool als_enabled;
|
||||
bool ps_enabled;
|
||||
uint32_t ps_near_level;
|
||||
u64 timestamp;
|
||||
struct regmap *regmap;
|
||||
struct regmap_field *reg_state;
|
||||
@ -135,6 +136,25 @@ static const struct iio_event_spec stk3310_events[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static ssize_t stk3310_read_near_level(struct iio_dev *indio_dev,
|
||||
uintptr_t priv,
|
||||
const struct iio_chan_spec *chan,
|
||||
char *buf)
|
||||
{
|
||||
struct stk3310_data *data = iio_priv(indio_dev);
|
||||
|
||||
return sprintf(buf, "%u\n", data->ps_near_level);
|
||||
}
|
||||
|
||||
static const struct iio_chan_spec_ext_info stk3310_ext_info[] = {
|
||||
{
|
||||
.name = "nearlevel",
|
||||
.shared = IIO_SEPARATE,
|
||||
.read = stk3310_read_near_level,
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec stk3310_channels[] = {
|
||||
{
|
||||
.type = IIO_LIGHT,
|
||||
@ -151,6 +171,7 @@ static const struct iio_chan_spec stk3310_channels[] = {
|
||||
BIT(IIO_CHAN_INFO_INT_TIME),
|
||||
.event_spec = stk3310_events,
|
||||
.num_event_specs = ARRAY_SIZE(stk3310_events),
|
||||
.ext_info = stk3310_ext_info,
|
||||
}
|
||||
};
|
||||
|
||||
@ -581,6 +602,10 @@ static int stk3310_probe(struct i2c_client *client,
|
||||
data = iio_priv(indio_dev);
|
||||
data->client = client;
|
||||
i2c_set_clientdata(client, indio_dev);
|
||||
|
||||
device_property_read_u32(&client->dev, "proximity-near-level",
|
||||
&data->ps_near_level);
|
||||
|
||||
mutex_init(&data->lock);
|
||||
|
||||
ret = stk3310_regmap_init(data);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user