summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iio/accel/Kconfig12
-rw-r--r--drivers/iio/accel/adis16201.c2
-rw-r--r--drivers/iio/accel/adis16209.c2
-rw-r--r--drivers/iio/accel/adxl313_core.c11
-rw-r--r--drivers/iio/accel/adxl345_core.c32
-rw-r--r--drivers/iio/accel/adxl372.c314
-rw-r--r--drivers/iio/accel/adxl372.h20
-rw-r--r--drivers/iio/accel/adxl372_i2c.c17
-rw-r--r--drivers/iio/accel/adxl372_spi.c17
-rw-r--r--drivers/iio/accel/adxl380.c4
-rw-r--r--drivers/iio/accel/bmc150-accel-core.c4
-rw-r--r--drivers/iio/accel/sca3000.c215
-rw-r--r--drivers/iio/adc/Kconfig33
-rw-r--r--drivers/iio/adc/Makefile1
-rw-r--r--drivers/iio/adc/ad4030.c618
-rw-r--r--drivers/iio/adc/ad4062.c12
-rw-r--r--drivers/iio/adc/ad4080.c46
-rw-r--r--drivers/iio/adc/ad4170-4.c6
-rw-r--r--drivers/iio/adc/ad7173.c3
-rw-r--r--drivers/iio/adc/ad7192.c3
-rw-r--r--drivers/iio/adc/ad7266.c6
-rw-r--r--drivers/iio/adc/ad7380.c53
-rw-r--r--drivers/iio/adc/ad7768-1.c221
-rw-r--r--drivers/iio/adc/ad7793.c3
-rw-r--r--drivers/iio/adc/ad7887.c2
-rw-r--r--drivers/iio/adc/ad7923.c4
-rw-r--r--drivers/iio/adc/ad9467.c95
-rw-r--r--drivers/iio/adc/ad_sigma_delta.c6
-rw-r--r--drivers/iio/adc/ade9000.c13
-rw-r--r--drivers/iio/adc/adi-axi-adc.c5
-rw-r--r--drivers/iio/adc/aspeed_adc.c72
-rw-r--r--drivers/iio/adc/at91-sama5d2_adc.c5
-rw-r--r--drivers/iio/adc/at91_adc.c12
-rw-r--r--drivers/iio/adc/cpcap-adc.c15
-rw-r--r--drivers/iio/adc/fsl-imx25-gcq.c2
-rw-r--r--drivers/iio/adc/ina2xx-adc.c65
-rw-r--r--drivers/iio/adc/ltc2309.c81
-rw-r--r--drivers/iio/adc/max11410.c4
-rw-r--r--drivers/iio/adc/max1363.c87
-rw-r--r--drivers/iio/adc/mcp3564.c2
-rw-r--r--drivers/iio/adc/men_z188_adc.c2
-rw-r--r--drivers/iio/adc/meson_saradc.c21
-rw-r--r--drivers/iio/adc/mt6359-auxadc.c2
-rw-r--r--drivers/iio/adc/nau7802.c3
-rw-r--r--drivers/iio/adc/npcm_adc.c2
-rw-r--r--drivers/iio/adc/nxp-sar-adc.c3
-rw-r--r--drivers/iio/adc/pac1921.c2
-rw-r--r--drivers/iio/adc/pac1934.c2
-rw-r--r--drivers/iio/adc/palmas_gpadc.c8
-rw-r--r--drivers/iio/adc/qcom-spmi-adc5-gen3.c860
-rw-r--r--drivers/iio/adc/rohm-bd79124.c4
-rw-r--r--drivers/iio/adc/sd_adc_modulator.c1
-rw-r--r--drivers/iio/adc/spear_adc.c2
-rw-r--r--drivers/iio/adc/stm32-adc-core.c2
-rw-r--r--drivers/iio/adc/stm32-adc.c2
-rw-r--r--drivers/iio/adc/sun20i-gpadc-iio.c2
-rw-r--r--drivers/iio/adc/ti-ads1015.c1
-rw-r--r--drivers/iio/adc/ti-ads1119.c3
-rw-r--r--drivers/iio/adc/ti-ads7950.c183
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c6
-rw-r--r--drivers/iio/adc/twl4030-madc.c2
-rw-r--r--drivers/iio/adc/twl6030-gpadc.c2
-rw-r--r--drivers/iio/addac/ad74413r.c9
-rw-r--r--drivers/iio/amplifiers/Kconfig8
-rw-r--r--drivers/iio/amplifiers/ad8366.c405
-rw-r--r--drivers/iio/amplifiers/ada4250.c2
-rw-r--r--drivers/iio/buffer/industrialio-hw-consumer.c11
-rw-r--r--drivers/iio/buffer/kfifo_buf.c41
-rw-r--r--drivers/iio/cdc/ad7150.c2
-rw-r--r--drivers/iio/cdc/ad7746.c2
-rw-r--r--drivers/iio/chemical/bme680_core.c2
-rw-r--r--drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c2
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-attributes.c2
-rw-r--r--drivers/iio/common/inv_sensors/inv_sensors_timestamp.c4
-rw-r--r--drivers/iio/common/ms_sensors/ms_sensors_i2c.c2
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_core.c11
-rw-r--r--drivers/iio/dac/Kconfig1
-rw-r--r--drivers/iio/dac/ad5360.c29
-rw-r--r--drivers/iio/dac/ad7293.c31
-rw-r--r--drivers/iio/dac/adi-axi-dac.c3
-rw-r--r--drivers/iio/dac/ds4424.c373
-rw-r--r--drivers/iio/dac/ltc2632.c353
-rw-r--r--drivers/iio/dac/max5522.c22
-rw-r--r--drivers/iio/dac/ti-dac5571.c1
-rw-r--r--drivers/iio/filter/admv8818.c60
-rw-r--r--drivers/iio/frequency/ad9523.c110
-rw-r--r--drivers/iio/frequency/adf4350.c10
-rw-r--r--drivers/iio/frequency/adf4377.c56
-rw-r--r--drivers/iio/frequency/admv1013.c104
-rw-r--r--drivers/iio/frequency/admv1014.c89
-rw-r--r--drivers/iio/frequency/admv4420.c37
-rw-r--r--drivers/iio/frequency/adrf6780.c60
-rw-r--r--drivers/iio/gyro/hid-sensor-gyro-3d.c6
-rw-r--r--drivers/iio/humidity/hdc2010.c1
-rw-r--r--drivers/iio/imu/bmi323/bmi323_core.c1
-rw-r--r--drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c2
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c2
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c1
-rw-r--r--drivers/iio/industrialio-backend.c22
-rw-r--r--drivers/iio/industrialio-event.c1
-rw-r--r--drivers/iio/industrialio-trigger.c33
-rw-r--r--drivers/iio/light/Kconfig2
-rw-r--r--drivers/iio/light/acpi-als.c42
-rw-r--r--drivers/iio/light/apds9160.c2
-rw-r--r--drivers/iio/light/apds9306.c4
-rw-r--r--drivers/iio/light/as73211.c3
-rw-r--r--drivers/iio/light/gp2ap020a00f.c310
-rw-r--r--drivers/iio/light/ltr390.c2
-rw-r--r--drivers/iio/light/ltr501.c6
-rw-r--r--drivers/iio/light/opt3001.c2
-rw-r--r--drivers/iio/light/tsl2772.c2
-rw-r--r--drivers/iio/light/vcnl4000.c131
-rw-r--r--drivers/iio/light/zopt2201.c45
-rw-r--r--drivers/iio/magnetometer/ak8974.c2
-rw-r--r--drivers/iio/magnetometer/ak8975.c6
-rw-r--r--drivers/iio/magnetometer/bmc150_magn.c145
-rw-r--r--drivers/iio/magnetometer/si7210.c21
-rw-r--r--drivers/iio/magnetometer/yamaha-yas530.c2
-rw-r--r--drivers/iio/pressure/bmp280-spi.c2
-rw-r--r--drivers/iio/pressure/hsc030pa.c2
-rw-r--r--drivers/iio/pressure/hsc030pa_i2c.c7
-rw-r--r--drivers/iio/pressure/rohm-bm1390.c2
-rw-r--r--drivers/iio/pressure/zpa2326.c2
-rw-r--r--drivers/iio/proximity/Kconfig15
-rw-r--r--drivers/iio/proximity/Makefile1
-rw-r--r--drivers/iio/proximity/hx9023s.c5
-rw-r--r--drivers/iio/proximity/sx9324.c2
-rw-r--r--drivers/iio/proximity/vl53l1x-i2c.c756
-rw-r--r--drivers/iio/resolver/ad2s1210.c6
-rw-r--r--drivers/iio/temperature/ltc2983.c4
-rw-r--r--drivers/iio/test/iio-test-gts.c2
-rw-r--r--drivers/staging/iio/adc/ad7816.c16
-rw-r--r--drivers/staging/iio/frequency/ad9834.c20
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c28
134 files changed, 4762 insertions, 1986 deletions
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 3d3f8d8673dd..4094299e2ed8 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -158,24 +158,24 @@ config ADXL372
select IIO_TRIGGERED_BUFFER
config ADXL372_SPI
- tristate "Analog Devices ADXL372 3-Axis Accelerometer SPI Driver"
+ tristate "Analog Devices ADXL371/ADXL372 3-Axis Accelerometer SPI Driver"
depends on SPI
select ADXL372
select REGMAP_SPI
help
- Say yes here to add support for the Analog Devices ADXL372 triaxial
- acceleration sensor.
+ Say yes here to add support for the Analog Devices ADXL371/ADXL372
+ triaxial acceleration sensor.
To compile this driver as a module, choose M here: the
module will be called adxl372_spi.
config ADXL372_I2C
- tristate "Analog Devices ADXL372 3-Axis Accelerometer I2C Driver"
+ tristate "Analog Devices ADXL371/ADXL372 3-Axis Accelerometer I2C Driver"
depends on I2C
select ADXL372
select REGMAP_I2C
help
- Say yes here to add support for the Analog Devices ADXL372 triaxial
- acceleration sensor.
+ Say yes here to add support for the Analog Devices ADXL371/ADXL372
+ triaxial acceleration sensor.
To compile this driver as a module, choose M here: the
module will be called adxl372_i2c.
diff --git a/drivers/iio/accel/adis16201.c b/drivers/iio/accel/adis16201.c
index 5127e58eebc7..ba0f97944c6d 100644
--- a/drivers/iio/accel/adis16201.c
+++ b/drivers/iio/accel/adis16201.c
@@ -147,7 +147,7 @@ static int adis16201_read_raw(struct iio_dev *indio_dev,
/*
* The raw ADC value is 1278 when the temperature
* is 25 degrees and the scale factor per milli
- * degree celcius is -470.
+ * degree Celsius is -470.
*/
*val = 25000 / -470 - 1278;
return IIO_VAL_INT;
diff --git a/drivers/iio/accel/adis16209.c b/drivers/iio/accel/adis16209.c
index 41ffd92f27fd..04e169f221c4 100644
--- a/drivers/iio/accel/adis16209.c
+++ b/drivers/iio/accel/adis16209.c
@@ -186,7 +186,7 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
/*
* The raw ADC value is 0x4FE when the temperature
* is 45 degrees and the scale factor per milli
- * degree celcius is -470.
+ * degree Celsius is -470.
*/
*val = 25000 / -470 - 0x4FE;
return IIO_VAL_INT;
diff --git a/drivers/iio/accel/adxl313_core.c b/drivers/iio/accel/adxl313_core.c
index 9f5d4d2cb325..084037c89ad3 100644
--- a/drivers/iio/accel/adxl313_core.c
+++ b/drivers/iio/accel/adxl313_core.c
@@ -8,6 +8,7 @@
*/
#include <linux/bitfield.h>
+#include <linux/cleanup.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/overflow.h>
@@ -356,19 +357,15 @@ static int adxl313_read_axis(struct adxl313_data *data,
{
int ret;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
ret = regmap_bulk_read(data->regmap,
ADXL313_REG_DATA_AXIS(chan->address),
&data->transf_buf, sizeof(data->transf_buf));
if (ret)
- goto unlock_ret;
-
- ret = le16_to_cpu(data->transf_buf);
+ return ret;
-unlock_ret:
- mutex_unlock(&data->lock);
- return ret;
+ return le16_to_cpu(data->transf_buf);
}
static int adxl313_read_freq_avail(struct iio_dev *indio_dev,
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 78e3f799ecc1..6c9080d88c60 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c
@@ -213,6 +213,7 @@ static const struct iio_event_spec adxl345_events[] = {
.dir = IIO_EV_DIR_RISING,
.mask_shared_by_type =
BIT(IIO_EV_INFO_ENABLE) |
+ BIT(IIO_EV_INFO_SCALE) |
BIT(IIO_EV_INFO_VALUE),
},
{
@@ -221,6 +222,7 @@ static const struct iio_event_spec adxl345_events[] = {
.dir = IIO_EV_DIR_RISING,
.mask_shared_by_type =
BIT(IIO_EV_INFO_ENABLE) |
+ BIT(IIO_EV_INFO_SCALE) |
BIT(IIO_EV_INFO_VALUE),
},
{
@@ -228,14 +230,19 @@ static const struct iio_event_spec adxl345_events[] = {
.type = IIO_EV_TYPE_GESTURE,
.dir = IIO_EV_DIR_SINGLETAP,
.mask_separate = BIT(IIO_EV_INFO_ENABLE),
- .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
+ .mask_shared_by_type =
+ BIT(IIO_EV_INFO_SCALE) |
+ BIT(IIO_EV_INFO_VALUE) |
BIT(IIO_EV_INFO_TIMEOUT),
},
{
/* double tap */
.type = IIO_EV_TYPE_GESTURE,
.dir = IIO_EV_DIR_DOUBLETAP,
- .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |
+ .mask_shared_by_type =
+ BIT(IIO_EV_INFO_ENABLE) |
+ BIT(IIO_EV_INFO_SCALE) |
+ BIT(IIO_EV_INFO_VALUE) |
BIT(IIO_EV_INFO_RESET_TIMEOUT) |
BIT(IIO_EV_INFO_TAP2_MIN_DELAY),
},
@@ -274,6 +281,7 @@ static const struct iio_event_spec adxl345_fake_chan_events[] = {
.dir = IIO_EV_DIR_FALLING,
.mask_separate = BIT(IIO_EV_INFO_ENABLE),
.mask_shared_by_type =
+ BIT(IIO_EV_INFO_SCALE) |
BIT(IIO_EV_INFO_VALUE) |
BIT(IIO_EV_INFO_PERIOD),
},
@@ -283,6 +291,7 @@ static const struct iio_event_spec adxl345_fake_chan_events[] = {
.dir = IIO_EV_DIR_FALLING,
.mask_separate = BIT(IIO_EV_INFO_ENABLE),
.mask_shared_by_type =
+ BIT(IIO_EV_INFO_SCALE) |
BIT(IIO_EV_INFO_VALUE) |
BIT(IIO_EV_INFO_PERIOD),
},
@@ -1341,6 +1350,16 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev,
unsigned int tap_threshold;
int ret;
+ /*
+ * The event threshold LSB is fixed at 62.5 mg/LSB
+ * 0.0625 * 9.80665 = 0.612915625 m/s^2
+ */
+ if (info == IIO_EV_INFO_SCALE) {
+ *val = 0;
+ *val2 = 612915;
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+
switch (type) {
case IIO_EV_TYPE_MAG:
return adxl345_read_mag_value(st, dir, info,
@@ -1355,12 +1374,6 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev,
case IIO_EV_TYPE_GESTURE:
switch (info) {
case IIO_EV_INFO_VALUE:
- /*
- * The scale factor would be 62.5mg/LSB (i.e. 0xFF = 16g) but
- * not applied here. In context of this general purpose sensor,
- * what imports is rather signal intensity than the absolute
- * measured g value.
- */
ret = regmap_read(st->regmap, ADXL345_REG_THRESH_TAP,
&tap_threshold);
if (ret)
@@ -1401,6 +1414,9 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev,
if (ret)
return ret;
+ if (info == IIO_EV_INFO_SCALE)
+ return -EINVAL;
+
switch (type) {
case IIO_EV_TYPE_MAG:
ret = adxl345_write_mag_value(st, dir, info,
diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c
index 28a8793a53b6..545a21e5a308 100644
--- a/drivers/iio/accel/adxl372.c
+++ b/drivers/iio/accel/adxl372.c
@@ -1,12 +1,13 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * ADXL372 3-Axis Digital Accelerometer core driver
+ * ADXL371/ADXL372 3-Axis Digital Accelerometer core driver
*
* Copyright 2018 Analog Devices Inc.
*/
#include <linux/bitfield.h>
#include <linux/bitops.h>
+#include <linux/cleanup.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
@@ -180,6 +181,16 @@ enum adxl372_odr {
ADXL372_ODR_1600HZ,
ADXL372_ODR_3200HZ,
ADXL372_ODR_6400HZ,
+ ADXL372_ODR_NUM
+};
+
+enum adxl371_odr {
+ ADXL371_ODR_320HZ,
+ ADXL371_ODR_640HZ,
+ ADXL371_ODR_1280HZ,
+ ADXL371_ODR_2560HZ,
+ ADXL371_ODR_5120HZ,
+ ADXL371_ODR_NUM
};
enum adxl372_bandwidth {
@@ -214,14 +225,67 @@ enum adxl372_fifo_mode {
ADXL372_FIFO_OLD_SAVED
};
-static const int adxl372_samp_freq_tbl[5] = {
- 400, 800, 1600, 3200, 6400,
+static const int adxl372_samp_freq_tbl[ADXL372_ODR_NUM] = {
+ [ADXL372_ODR_400HZ] = 400,
+ [ADXL372_ODR_800HZ] = 800,
+ [ADXL372_ODR_1600HZ] = 1600,
+ [ADXL372_ODR_3200HZ] = 3200,
+ [ADXL372_ODR_6400HZ] = 6400,
+};
+
+static const int adxl372_bw_freq_tbl[ADXL372_ODR_NUM] = {
+ [ADXL372_BW_200HZ] = 200,
+ [ADXL372_BW_400HZ] = 400,
+ [ADXL372_BW_800HZ] = 800,
+ [ADXL372_BW_1600HZ] = 1600,
+ [ADXL372_BW_3200HZ] = 3200,
+};
+
+static const int adxl371_samp_freq_tbl[ADXL371_ODR_NUM] = {
+ [ADXL371_ODR_320HZ] = 320,
+ [ADXL371_ODR_640HZ] = 640,
+ [ADXL371_ODR_1280HZ] = 1280,
+ [ADXL371_ODR_2560HZ] = 2560,
+ [ADXL371_ODR_5120HZ] = 5120,
};
-static const int adxl372_bw_freq_tbl[5] = {
- 200, 400, 800, 1600, 3200,
+static const int adxl371_bw_freq_tbl[ADXL371_ODR_NUM] = {
+ [ADXL371_ODR_320HZ] = 160,
+ [ADXL371_ODR_640HZ] = 320,
+ [ADXL371_ODR_1280HZ] = 640,
+ [ADXL371_ODR_2560HZ] = 1280,
+ [ADXL371_ODR_5120HZ] = 2560,
};
+const struct adxl372_chip_info adxl371_chip_info = {
+ .name = "adxl371",
+ .samp_freq_tbl = adxl371_samp_freq_tbl,
+ .bw_freq_tbl = adxl371_bw_freq_tbl,
+ .num_freqs = ARRAY_SIZE(adxl371_samp_freq_tbl),
+ .act_time_scale_us = 4125,
+ .act_time_scale_low_us = 8250,
+ .inact_time_scale_ms = 16,
+ .inact_time_scale_low_ms = 32,
+ .max_odr = ADXL371_ODR_5120HZ,
+ /* Silicon erratum (er001) causes FIFO data misalignment on ADXL371 */
+ .fifo_supported = false,
+};
+EXPORT_SYMBOL_NS_GPL(adxl371_chip_info, "IIO_ADXL372");
+
+const struct adxl372_chip_info adxl372_chip_info = {
+ .name = "adxl372",
+ .samp_freq_tbl = adxl372_samp_freq_tbl,
+ .bw_freq_tbl = adxl372_bw_freq_tbl,
+ .num_freqs = ARRAY_SIZE(adxl372_samp_freq_tbl),
+ .act_time_scale_us = 3300,
+ .act_time_scale_low_us = 6600,
+ .inact_time_scale_ms = 13,
+ .inact_time_scale_low_ms = 26,
+ .max_odr = ADXL372_ODR_6400HZ,
+ .fifo_supported = true,
+};
+EXPORT_SYMBOL_NS_GPL(adxl372_chip_info, "IIO_ADXL372");
+
struct adxl372_axis_lookup {
unsigned int bits;
enum adxl372_fifo_format fifo_format;
@@ -257,8 +321,12 @@ static const struct iio_event_spec adxl372_events[] = {
.modified = 1, \
.channel2 = IIO_MOD_##axis, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
- BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ .info_mask_shared_by_type = \
+ BIT(IIO_CHAN_INFO_SCALE) | \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
+ .info_mask_shared_by_type_available = \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
.scan_index = index, \
.scan_type = { \
@@ -279,6 +347,7 @@ static const struct iio_chan_spec adxl372_channels[] = {
};
struct adxl372_state {
+ const struct adxl372_chip_info *chip_info;
int irq;
struct device *dev;
struct regmap *regmap;
@@ -336,18 +405,14 @@ static ssize_t adxl372_write_threshold_value(struct iio_dev *indio_dev, unsigned
struct adxl372_state *st = iio_priv(indio_dev);
int ret;
- mutex_lock(&st->threshold_m);
+ guard(mutex)(&st->threshold_m);
+
ret = regmap_write(st->regmap, addr, ADXL372_THRESH_VAL_H_SEL(threshold));
if (ret < 0)
- goto unlock;
-
- ret = regmap_update_bits(st->regmap, addr + 1, GENMASK(7, 5),
- ADXL372_THRESH_VAL_L_SEL(threshold) << 5);
-
-unlock:
- mutex_unlock(&st->threshold_m);
+ return ret;
- return ret;
+ return regmap_update_bits(st->regmap, addr + 1, GENMASK(7, 5),
+ ADXL372_THRESH_VAL_L_SEL(threshold) << 5);
}
static int adxl372_read_axis(struct adxl372_state *st, u8 addr)
@@ -471,13 +536,14 @@ static int adxl372_set_activity_time_ms(struct adxl372_state *st,
int ret;
/*
- * 3.3 ms per code is the scale factor of the TIME_ACT register for
- * ODR = 6400 Hz. It is 6.6 ms per code for ODR = 3200 Hz and below.
+ * The scale factor of the TIME_ACT register depends on the ODR.
+ * A higher scale factor is used at the maximum ODR and a lower
+ * one at all other rates.
*/
- if (st->odr == ADXL372_ODR_6400HZ)
- scale_factor = 3300;
+ if (st->odr == st->chip_info->max_odr)
+ scale_factor = st->chip_info->act_time_scale_us;
else
- scale_factor = 6600;
+ scale_factor = st->chip_info->act_time_scale_low_us;
reg_val = DIV_ROUND_CLOSEST(act_time_ms * 1000, scale_factor);
@@ -501,13 +567,14 @@ static int adxl372_set_inactivity_time_ms(struct adxl372_state *st,
int ret;
/*
- * 13 ms per code is the scale factor of the TIME_INACT register for
- * ODR = 6400 Hz. It is 26 ms per code for ODR = 3200 Hz and below.
+ * The scale factor of the TIME_INACT register depends on the ODR.
+ * A higher scale factor is used at the maximum ODR and a lower
+ * one at all other rates.
*/
- if (st->odr == ADXL372_ODR_6400HZ)
- scale_factor = 13;
+ if (st->odr == st->chip_info->max_odr)
+ scale_factor = st->chip_info->inact_time_scale_ms;
else
- scale_factor = 26;
+ scale_factor = st->chip_info->inact_time_scale_low_ms;
res = DIV_ROUND_CLOSEST(inact_time_ms, scale_factor);
reg_val_h = (res >> 8) & 0xFF;
@@ -717,7 +784,7 @@ static int adxl372_setup(struct adxl372_state *st)
if (ret < 0)
return ret;
- ret = adxl372_set_odr(st, ADXL372_ODR_6400HZ);
+ ret = adxl372_set_odr(st, st->chip_info->max_odr);
if (ret < 0)
return ret;
@@ -777,10 +844,10 @@ static int adxl372_read_raw(struct iio_dev *indio_dev,
*val2 = ADXL372_USCALE;
return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_SAMP_FREQ:
- *val = adxl372_samp_freq_tbl[st->odr];
+ *val = st->chip_info->samp_freq_tbl[st->odr];
return IIO_VAL_INT;
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
- *val = adxl372_bw_freq_tbl[st->bw];
+ *val = st->chip_info->bw_freq_tbl[st->bw];
return IIO_VAL_INT;
}
@@ -796,23 +863,17 @@ static int adxl372_write_raw(struct iio_dev *indio_dev,
switch (info) {
case IIO_CHAN_INFO_SAMP_FREQ:
- odr_index = adxl372_find_closest_match(adxl372_samp_freq_tbl,
- ARRAY_SIZE(adxl372_samp_freq_tbl),
- val);
+ odr_index = adxl372_find_closest_match(st->chip_info->samp_freq_tbl,
+ st->chip_info->num_freqs,
+ val);
ret = adxl372_set_odr(st, odr_index);
if (ret < 0)
return ret;
- /*
- * The timer period depends on the ODR selected.
- * At 3200 Hz and below, it is 6.6 ms; at 6400 Hz, it is 3.3 ms
- */
+ /* Recalculate activity time as the timer period depends on ODR */
ret = adxl372_set_activity_time_ms(st, st->act_time_ms);
if (ret < 0)
return ret;
- /*
- * The timer period depends on the ODR selected.
- * At 3200 Hz and below, it is 26 ms; at 6400 Hz, it is 13 ms
- */
+ /* Recalculate inactivity time as the timer period depends on ODR */
ret = adxl372_set_inactivity_time_ms(st, st->inact_time_ms);
if (ret < 0)
return ret;
@@ -825,9 +886,9 @@ static int adxl372_write_raw(struct iio_dev *indio_dev,
return ret;
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
- bw_index = adxl372_find_closest_match(adxl372_bw_freq_tbl,
- ARRAY_SIZE(adxl372_bw_freq_tbl),
- val);
+ bw_index = adxl372_find_closest_match(st->chip_info->bw_freq_tbl,
+ st->chip_info->num_freqs,
+ val);
return adxl372_set_bandwidth(st, bw_index);
default:
return -EINVAL;
@@ -957,24 +1018,6 @@ static int adxl372_write_event_config(struct iio_dev *indio_dev, const struct ii
return adxl372_set_interrupts(st, st->int1_bitmask, 0);
}
-static ssize_t adxl372_show_filter_freq_avail(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct adxl372_state *st = iio_priv(indio_dev);
- int i;
- size_t len = 0;
-
- for (i = 0; i <= st->odr; i++)
- len += scnprintf(buf + len, PAGE_SIZE - len,
- "%d ", adxl372_bw_freq_tbl[i]);
-
- buf[len - 1] = '\n';
-
- return len;
-}
-
static ssize_t adxl372_get_fifo_enabled(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -1142,25 +1185,38 @@ static const struct iio_trigger_ops adxl372_peak_data_trigger_ops = {
.set_trigger_state = adxl372_peak_dready_trig_set_state,
};
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("400 800 1600 3200 6400");
-static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available,
- 0444, adxl372_show_filter_freq_avail, NULL, 0);
-
-static struct attribute *adxl372_attributes[] = {
- &iio_const_attr_sampling_frequency_available.dev_attr.attr,
- &iio_dev_attr_in_accel_filter_low_pass_3db_frequency_available.dev_attr.attr,
- NULL,
-};
+static int adxl372_read_avail(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ const int **vals, int *type, int *length,
+ long mask)
+{
+ struct adxl372_state *st = iio_priv(indio_dev);
-static const struct attribute_group adxl372_attrs_group = {
- .attrs = adxl372_attributes,
-};
+ switch (mask) {
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *vals = st->chip_info->samp_freq_tbl;
+ *type = IIO_VAL_INT;
+ *length = st->chip_info->num_freqs;
+ return IIO_AVAIL_LIST;
+ case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ *vals = st->chip_info->bw_freq_tbl;
+ *type = IIO_VAL_INT;
+ /*
+ * Bandwidth cannot exceed half the sampling frequency
+ * (Nyquist), so limit available values based on current ODR.
+ */
+ *length = st->odr + 1;
+ return IIO_AVAIL_LIST;
+ default:
+ return -EINVAL;
+ }
+}
static const struct iio_info adxl372_info = {
.validate_trigger = &adxl372_validate_trigger,
- .attrs = &adxl372_attrs_group,
.read_raw = adxl372_read_raw,
.write_raw = adxl372_write_raw,
+ .read_avail = adxl372_read_avail,
.read_event_config = adxl372_read_event_config,
.write_event_config = adxl372_write_event_config,
.read_event_value = adxl372_read_event_value,
@@ -1175,8 +1231,57 @@ bool adxl372_readable_noinc_reg(struct device *dev, unsigned int reg)
}
EXPORT_SYMBOL_NS_GPL(adxl372_readable_noinc_reg, "IIO_ADXL372");
+static int adxl372_buffer_setup(struct iio_dev *indio_dev)
+{
+ struct adxl372_state *st = iio_priv(indio_dev);
+ struct device *dev = st->dev;
+ int ret;
+
+ ret = devm_iio_triggered_buffer_setup_ext(dev, indio_dev, NULL,
+ adxl372_trigger_handler,
+ IIO_BUFFER_DIRECTION_IN,
+ &adxl372_buffer_ops,
+ adxl372_fifo_attributes);
+ if (ret)
+ return ret;
+
+ if (!st->irq)
+ return 0;
+
+ st->dready_trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
+ indio_dev->name,
+ iio_device_id(indio_dev));
+ if (!st->dready_trig)
+ return -ENOMEM;
+
+ st->peak_datardy_trig = devm_iio_trigger_alloc(dev, "%s-dev%d-peak",
+ indio_dev->name,
+ iio_device_id(indio_dev));
+ if (!st->peak_datardy_trig)
+ return -ENOMEM;
+
+ st->dready_trig->ops = &adxl372_trigger_ops;
+ st->peak_datardy_trig->ops = &adxl372_peak_data_trigger_ops;
+ iio_trigger_set_drvdata(st->dready_trig, indio_dev);
+ iio_trigger_set_drvdata(st->peak_datardy_trig, indio_dev);
+ ret = devm_iio_trigger_register(dev, st->dready_trig);
+ if (ret)
+ return ret;
+
+ ret = devm_iio_trigger_register(dev, st->peak_datardy_trig);
+ if (ret)
+ return ret;
+
+ indio_dev->trig = iio_trigger_get(st->dready_trig);
+
+ return devm_request_irq(dev, st->irq,
+ iio_trigger_generic_data_rdy_poll,
+ IRQF_TRIGGER_RISING | IRQF_NO_THREAD,
+ indio_dev->name, st->dready_trig);
+}
+
int adxl372_probe(struct device *dev, struct regmap *regmap,
- int irq, const char *name)
+ int irq, const struct adxl372_chip_info *chip_info)
{
struct iio_dev *indio_dev;
struct adxl372_state *st;
@@ -1192,15 +1297,21 @@ int adxl372_probe(struct device *dev, struct regmap *regmap,
st->dev = dev;
st->regmap = regmap;
st->irq = irq;
+ st->chip_info = chip_info;
mutex_init(&st->threshold_m);
indio_dev->channels = adxl372_channels;
indio_dev->num_channels = ARRAY_SIZE(adxl372_channels);
- indio_dev->available_scan_masks = adxl372_channel_masks;
- indio_dev->name = name;
+ indio_dev->name = chip_info->name;
indio_dev->info = &adxl372_info;
- indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
+
+ if (chip_info->fifo_supported) {
+ indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
+ indio_dev->available_scan_masks = adxl372_channel_masks;
+ } else {
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ }
ret = adxl372_setup(st);
if (ret < 0) {
@@ -1208,48 +1319,8 @@ int adxl372_probe(struct device *dev, struct regmap *regmap,
return ret;
}
- ret = devm_iio_triggered_buffer_setup_ext(dev,
- indio_dev, NULL,
- adxl372_trigger_handler,
- IIO_BUFFER_DIRECTION_IN,
- &adxl372_buffer_ops,
- adxl372_fifo_attributes);
- if (ret < 0)
- return ret;
-
- if (st->irq) {
- st->dready_trig = devm_iio_trigger_alloc(dev,
- "%s-dev%d",
- indio_dev->name,
- iio_device_id(indio_dev));
- if (st->dready_trig == NULL)
- return -ENOMEM;
-
- st->peak_datardy_trig = devm_iio_trigger_alloc(dev,
- "%s-dev%d-peak",
- indio_dev->name,
- iio_device_id(indio_dev));
- if (!st->peak_datardy_trig)
- return -ENOMEM;
-
- st->dready_trig->ops = &adxl372_trigger_ops;
- st->peak_datardy_trig->ops = &adxl372_peak_data_trigger_ops;
- iio_trigger_set_drvdata(st->dready_trig, indio_dev);
- iio_trigger_set_drvdata(st->peak_datardy_trig, indio_dev);
- ret = devm_iio_trigger_register(dev, st->dready_trig);
- if (ret < 0)
- return ret;
-
- ret = devm_iio_trigger_register(dev, st->peak_datardy_trig);
- if (ret < 0)
- return ret;
-
- indio_dev->trig = iio_trigger_get(st->dready_trig);
-
- ret = devm_request_irq(dev, st->irq,
- iio_trigger_generic_data_rdy_poll,
- IRQF_TRIGGER_RISING | IRQF_NO_THREAD,
- indio_dev->name, st->dready_trig);
+ if (chip_info->fifo_supported) {
+ ret = adxl372_buffer_setup(indio_dev);
if (ret < 0)
return ret;
}
@@ -1259,5 +1330,6 @@ int adxl372_probe(struct device *dev, struct regmap *regmap,
EXPORT_SYMBOL_NS_GPL(adxl372_probe, "IIO_ADXL372");
MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
-MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer driver");
+MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADXL371/ADXL372 3-axis accelerometer driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/iio/accel/adxl372.h b/drivers/iio/accel/adxl372.h
index 80a0aa9714fc..353a8b3a9d76 100644
--- a/drivers/iio/accel/adxl372.h
+++ b/drivers/iio/accel/adxl372.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * ADXL372 3-Axis Digital Accelerometer
+ * ADXL371/ADXL372 3-Axis Digital Accelerometer
*
* Copyright 2018 Analog Devices Inc.
*/
@@ -10,8 +10,24 @@
#define ADXL372_REVID 0x03
+struct adxl372_chip_info {
+ const char *name;
+ const int *samp_freq_tbl;
+ const int *bw_freq_tbl;
+ unsigned int num_freqs;
+ unsigned int act_time_scale_us;
+ unsigned int act_time_scale_low_us;
+ unsigned int inact_time_scale_ms;
+ unsigned int inact_time_scale_low_ms;
+ unsigned int max_odr;
+ bool fifo_supported;
+};
+
+extern const struct adxl372_chip_info adxl371_chip_info;
+extern const struct adxl372_chip_info adxl372_chip_info;
+
int adxl372_probe(struct device *dev, struct regmap *regmap,
- int irq, const char *name);
+ int irq, const struct adxl372_chip_info *chip_info);
bool adxl372_readable_noinc_reg(struct device *dev, unsigned int reg);
#endif /* _ADXL372_H_ */
diff --git a/drivers/iio/accel/adxl372_i2c.c b/drivers/iio/accel/adxl372_i2c.c
index 186d4fe9a556..ca2cabf24938 100644
--- a/drivers/iio/accel/adxl372_i2c.c
+++ b/drivers/iio/accel/adxl372_i2c.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * ADXL372 3-Axis Digital Accelerometer I2C driver
+ * ADXL371/ADXL372 3-Axis Digital Accelerometer I2C driver
*
* Copyright 2018 Analog Devices Inc.
*/
@@ -20,11 +20,13 @@ static const struct regmap_config adxl372_regmap_config = {
static int adxl372_i2c_probe(struct i2c_client *client)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(client);
+ const struct adxl372_chip_info *chip_info;
struct regmap *regmap;
unsigned int regval;
int ret;
+ chip_info = i2c_get_match_data(client);
+
regmap = devm_regmap_init_i2c(client, &adxl372_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
@@ -38,17 +40,19 @@ static int adxl372_i2c_probe(struct i2c_client *client)
dev_warn(&client->dev,
"I2C might not work properly with other devices on the bus");
- return adxl372_probe(&client->dev, regmap, client->irq, id->name);
+ return adxl372_probe(&client->dev, regmap, client->irq, chip_info);
}
static const struct i2c_device_id adxl372_i2c_id[] = {
- { "adxl372" },
+ { "adxl371", (kernel_ulong_t)&adxl371_chip_info },
+ { "adxl372", (kernel_ulong_t)&adxl372_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, adxl372_i2c_id);
static const struct of_device_id adxl372_of_match[] = {
- { .compatible = "adi,adxl372" },
+ { .compatible = "adi,adxl371", .data = &adxl371_chip_info },
+ { .compatible = "adi,adxl372", .data = &adxl372_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, adxl372_of_match);
@@ -65,6 +69,7 @@ static struct i2c_driver adxl372_i2c_driver = {
module_i2c_driver(adxl372_i2c_driver);
MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
-MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer I2C driver");
+MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADXL371/ADXL372 3-axis accelerometer I2C driver");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("IIO_ADXL372");
diff --git a/drivers/iio/accel/adxl372_spi.c b/drivers/iio/accel/adxl372_spi.c
index 39941b519c3b..1f9c1544e547 100644
--- a/drivers/iio/accel/adxl372_spi.c
+++ b/drivers/iio/accel/adxl372_spi.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * ADXL372 3-Axis Digital Accelerometer SPI driver
+ * ADXL371/ADXL372 3-Axis Digital Accelerometer SPI driver
*
* Copyright 2018 Analog Devices Inc.
*/
@@ -22,24 +22,28 @@ static const struct regmap_config adxl372_spi_regmap_config = {
static int adxl372_spi_probe(struct spi_device *spi)
{
- const struct spi_device_id *id = spi_get_device_id(spi);
+ const struct adxl372_chip_info *chip_info;
struct regmap *regmap;
+ chip_info = spi_get_device_match_data(spi);
+
regmap = devm_regmap_init_spi(spi, &adxl372_spi_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
- return adxl372_probe(&spi->dev, regmap, spi->irq, id->name);
+ return adxl372_probe(&spi->dev, regmap, spi->irq, chip_info);
}
static const struct spi_device_id adxl372_spi_id[] = {
- { "adxl372", 0 },
+ { "adxl371", (kernel_ulong_t)&adxl371_chip_info },
+ { "adxl372", (kernel_ulong_t)&adxl372_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, adxl372_spi_id);
static const struct of_device_id adxl372_of_match[] = {
- { .compatible = "adi,adxl372" },
+ { .compatible = "adi,adxl371", .data = &adxl371_chip_info },
+ { .compatible = "adi,adxl372", .data = &adxl372_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, adxl372_of_match);
@@ -56,6 +60,7 @@ static struct spi_driver adxl372_spi_driver = {
module_spi_driver(adxl372_spi_driver);
MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
-MODULE_DESCRIPTION("Analog Devices ADXL372 3-axis accelerometer SPI driver");
+MODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>");
+MODULE_DESCRIPTION("Analog Devices ADXL371/ADXL372 3-axis accelerometer SPI driver");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("IIO_ADXL372");
diff --git a/drivers/iio/accel/adxl380.c b/drivers/iio/accel/adxl380.c
index 8fab2fdbe147..2fc838a234c9 100644
--- a/drivers/iio/accel/adxl380.c
+++ b/drivers/iio/accel/adxl380.c
@@ -31,7 +31,7 @@
#define ADXL319_ID_VAL 382
#define ADXL380_DEVID_AD_REG 0x00
-#define ADLX380_PART_ID_REG 0x02
+#define ADXL380_PART_ID_REG 0x02
#define ADXL380_X_DATA_H_REG 0x15
#define ADXL380_Y_DATA_H_REG 0x17
@@ -1878,7 +1878,7 @@ static int adxl380_setup(struct iio_dev *indio_dev)
if (reg_val != ADXL380_DEVID_AD_VAL)
dev_warn(st->dev, "Unknown chip id %x\n", reg_val);
- ret = regmap_bulk_read(st->regmap, ADLX380_PART_ID_REG,
+ ret = regmap_bulk_read(st->regmap, ADXL380_PART_ID_REG,
&st->transf_buf, 2);
if (ret)
return ret;
diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c
index 42ccf0316ce5..2398eb7e12cd 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -851,7 +851,7 @@ static ssize_t bmc150_accel_get_fifo_watermark(struct device *dev,
wm = data->watermark;
mutex_unlock(&data->mutex);
- return sprintf(buf, "%d\n", wm);
+ return sysfs_emit(buf, "%d\n", wm);
}
static ssize_t bmc150_accel_get_fifo_state(struct device *dev,
@@ -866,7 +866,7 @@ static ssize_t bmc150_accel_get_fifo_state(struct device *dev,
state = data->fifo_mode;
mutex_unlock(&data->mutex);
- return sprintf(buf, "%d\n", state);
+ return sysfs_emit(buf, "%d\n", state);
}
static const struct iio_mount_matrix *
diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c
index 4a827be439a2..573831199bba 100644
--- a/drivers/iio/accel/sca3000.c
+++ b/drivers/iio/accel/sca3000.c
@@ -7,6 +7,7 @@
* See industrialio/accels/sca3000.h for comments.
*/
+#include <linux/cleanup.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/device.h>
@@ -171,6 +172,7 @@ struct sca3000_state {
/**
* struct sca3000_chip_info - model dependent parameters
+ * @name: name of the chip
* @scale: scale * 10^-6
* @temp_output: some devices have temperature sensors.
* @measurement_mode_freq: normal mode sampling frequency
@@ -193,6 +195,7 @@ struct sca3000_state {
* sca3000 variant.
**/
struct sca3000_chip_info {
+ const char *name;
unsigned int scale;
bool temp_output;
int measurement_mode_freq;
@@ -207,69 +210,59 @@ struct sca3000_chip_info {
int mot_det_mult_y[7];
};
-enum sca3000_variant {
- d01,
- e02,
- e04,
- e05,
+static const struct sca3000_chip_info sca3000_chip_info_d01 = {
+ .name = "sca3000_d01",
+ .scale = 7357,
+ .temp_output = true,
+ .measurement_mode_freq = 250,
+ .measurement_mode_3db_freq = 45,
+ .option_mode_1 = SCA3000_OP_MODE_BYPASS,
+ .option_mode_1_freq = 250,
+ .option_mode_1_3db_freq = 70,
+ .mot_det_mult_xz = { 50, 100, 200, 350, 650, 1300 },
+ .mot_det_mult_y = { 50, 100, 150, 250, 450, 850, 1750 },
};
-/*
- * Note where option modes are not defined, the chip simply does not
- * support any.
- * Other chips in the sca3000 series use i2c and are not included here.
- *
- * Some of these devices are only listed in the family data sheet and
- * do not actually appear to be available.
- */
-static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = {
- [d01] = {
- .scale = 7357,
- .temp_output = true,
- .measurement_mode_freq = 250,
- .measurement_mode_3db_freq = 45,
- .option_mode_1 = SCA3000_OP_MODE_BYPASS,
- .option_mode_1_freq = 250,
- .option_mode_1_3db_freq = 70,
- .mot_det_mult_xz = {50, 100, 200, 350, 650, 1300},
- .mot_det_mult_y = {50, 100, 150, 250, 450, 850, 1750},
- },
- [e02] = {
- .scale = 9810,
- .measurement_mode_freq = 125,
- .measurement_mode_3db_freq = 40,
- .option_mode_1 = SCA3000_OP_MODE_NARROW,
- .option_mode_1_freq = 63,
- .option_mode_1_3db_freq = 11,
- .mot_det_mult_xz = {100, 150, 300, 550, 1050, 2050},
- .mot_det_mult_y = {50, 100, 200, 350, 700, 1350, 2700},
- },
- [e04] = {
- .scale = 19620,
- .measurement_mode_freq = 100,
- .measurement_mode_3db_freq = 38,
- .option_mode_1 = SCA3000_OP_MODE_NARROW,
- .option_mode_1_freq = 50,
- .option_mode_1_3db_freq = 9,
- .option_mode_2 = SCA3000_OP_MODE_WIDE,
- .option_mode_2_freq = 400,
- .option_mode_2_3db_freq = 70,
- .mot_det_mult_xz = {200, 300, 600, 1100, 2100, 4100},
- .mot_det_mult_y = {100, 200, 400, 7000, 1400, 2700, 54000},
- },
- [e05] = {
- .scale = 61313,
- .measurement_mode_freq = 200,
- .measurement_mode_3db_freq = 60,
- .option_mode_1 = SCA3000_OP_MODE_NARROW,
- .option_mode_1_freq = 50,
- .option_mode_1_3db_freq = 9,
- .option_mode_2 = SCA3000_OP_MODE_WIDE,
- .option_mode_2_freq = 400,
- .option_mode_2_3db_freq = 75,
- .mot_det_mult_xz = {600, 900, 1700, 3200, 6100, 11900},
- .mot_det_mult_y = {300, 600, 1200, 2000, 4100, 7800, 15600},
- },
+static const struct sca3000_chip_info sca3000_chip_info_e02 = {
+ .name = "sca3000_e02",
+ .scale = 9810,
+ .measurement_mode_freq = 125,
+ .measurement_mode_3db_freq = 40,
+ .option_mode_1 = SCA3000_OP_MODE_NARROW,
+ .option_mode_1_freq = 63,
+ .option_mode_1_3db_freq = 11,
+ .mot_det_mult_xz = { 100, 150, 300, 550, 1050, 2050 },
+ .mot_det_mult_y = { 50, 100, 200, 350, 700, 1350, 2700 },
+};
+
+static const struct sca3000_chip_info sca3000_chip_info_e04 = {
+ .name = "sca3000_e04",
+ .scale = 19620,
+ .measurement_mode_freq = 100,
+ .measurement_mode_3db_freq = 38,
+ .option_mode_1 = SCA3000_OP_MODE_NARROW,
+ .option_mode_1_freq = 50,
+ .option_mode_1_3db_freq = 9,
+ .option_mode_2 = SCA3000_OP_MODE_WIDE,
+ .option_mode_2_freq = 400,
+ .option_mode_2_3db_freq = 70,
+ .mot_det_mult_xz = { 200, 300, 600, 1100, 2100, 4100 },
+ .mot_det_mult_y = { 100, 200, 400, 7000, 1400, 2700, 54000 },
+};
+
+static const struct sca3000_chip_info sca3000_chip_info_e05 = {
+ .name = "sca3000_e05",
+ .scale = 61313,
+ .measurement_mode_freq = 200,
+ .measurement_mode_3db_freq = 60,
+ .option_mode_1 = SCA3000_OP_MODE_NARROW,
+ .option_mode_1_freq = 50,
+ .option_mode_1_3db_freq = 9,
+ .option_mode_2 = SCA3000_OP_MODE_WIDE,
+ .option_mode_2_freq = 400,
+ .option_mode_2_3db_freq = 75,
+ .mot_det_mult_xz = { 600, 900, 1700, 3200, 6100, 11900 },
+ .mot_det_mult_y = { 300, 600, 1200, 2000, 4100, 7800, 15600 },
};
static int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val)
@@ -1435,24 +1428,42 @@ static const struct iio_info sca3000_info = {
.write_event_config = &sca3000_write_event_config,
};
-static int sca3000_probe(struct spi_device *spi)
+static void sca3000_stop_all_interrupts(void *data)
{
+ struct iio_dev *indio_dev = data;
+ struct sca3000_state *st = iio_priv(indio_dev);
int ret;
+
+ guard(mutex)(&st->lock);
+
+ ret = sca3000_read_data_short(st, SCA3000_REG_INT_MASK_ADDR, 1);
+ if (ret)
+ return;
+
+ sca3000_write_reg(st, SCA3000_REG_INT_MASK_ADDR,
+ (st->rx[0] &
+ ~(SCA3000_REG_INT_MASK_RING_THREE_QUARTER |
+ SCA3000_REG_INT_MASK_RING_HALF |
+ SCA3000_REG_INT_MASK_ALL_INTS)));
+}
+
+static int sca3000_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
struct sca3000_state *st;
struct iio_dev *indio_dev;
+ int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
- spi_set_drvdata(spi, indio_dev);
st->us = spi;
mutex_init(&st->lock);
- st->info = &sca3000_spi_chip_info_tbl[spi_get_device_id(spi)
- ->driver_data];
+ st->info = spi_get_device_match_data(spi);
- indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->name = st->info->name;
indio_dev->info = &sca3000_info;
if (st->info->temp_output) {
indio_dev->channels = sca3000_channels_with_temp;
@@ -1464,78 +1475,39 @@ static int sca3000_probe(struct spi_device *spi)
}
indio_dev->modes = INDIO_DIRECT_MODE;
- ret = devm_iio_kfifo_buffer_setup(&spi->dev, indio_dev,
- &sca3000_ring_setup_ops);
+ ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, &sca3000_ring_setup_ops);
if (ret)
return ret;
if (spi->irq) {
- ret = request_threaded_irq(spi->irq,
- NULL,
- &sca3000_event_handler,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- "sca3000",
- indio_dev);
+ ret = devm_request_threaded_irq(dev, spi->irq, NULL,
+ &sca3000_event_handler,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "sca3000",
+ indio_dev);
if (ret)
return ret;
}
ret = sca3000_clean_setup(st);
if (ret)
- goto error_free_irq;
+ return ret;
ret = sca3000_print_rev(indio_dev);
if (ret)
- goto error_free_irq;
-
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_free_irq;
-
- return 0;
-
-error_free_irq:
- if (spi->irq)
- free_irq(spi->irq, indio_dev);
-
- return ret;
-}
-
-static int sca3000_stop_all_interrupts(struct sca3000_state *st)
-{
- int ret;
+ return ret;
- mutex_lock(&st->lock);
- ret = sca3000_read_data_short(st, SCA3000_REG_INT_MASK_ADDR, 1);
+ ret = devm_add_action_or_reset(dev, sca3000_stop_all_interrupts, indio_dev);
if (ret)
- goto error_ret;
- ret = sca3000_write_reg(st, SCA3000_REG_INT_MASK_ADDR,
- (st->rx[0] &
- ~(SCA3000_REG_INT_MASK_RING_THREE_QUARTER |
- SCA3000_REG_INT_MASK_RING_HALF |
- SCA3000_REG_INT_MASK_ALL_INTS)));
-error_ret:
- mutex_unlock(&st->lock);
- return ret;
-}
-
-static void sca3000_remove(struct spi_device *spi)
-{
- struct iio_dev *indio_dev = spi_get_drvdata(spi);
- struct sca3000_state *st = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
+ return ret;
- /* Must ensure no interrupts can be generated after this! */
- sca3000_stop_all_interrupts(st);
- if (spi->irq)
- free_irq(spi->irq, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id sca3000_id[] = {
- {"sca3000_d01", d01},
- {"sca3000_e02", e02},
- {"sca3000_e04", e04},
- {"sca3000_e05", e05},
+ { "sca3000_d01", (kernel_ulong_t)&sca3000_chip_info_d01 },
+ { "sca3000_e02", (kernel_ulong_t)&sca3000_chip_info_e02 },
+ { "sca3000_e04", (kernel_ulong_t)&sca3000_chip_info_e04 },
+ { "sca3000_e05", (kernel_ulong_t)&sca3000_chip_info_e05 },
{ }
};
MODULE_DEVICE_TABLE(spi, sca3000_id);
@@ -1545,7 +1517,6 @@ static struct spi_driver sca3000_driver = {
.name = "sca3000",
},
.probe = sca3000_probe,
- .remove = sca3000_remove,
.id_table = sca3000_id,
};
module_spi_driver(sca3000_driver);
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 60038ae8dfc4..a9dedbb8eb46 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -60,9 +60,14 @@ config AD4030
tristate "Analog Devices AD4030 ADC Driver"
depends on SPI
depends on GPIOLIB
+ depends on PWM
select REGMAP
select IIO_BUFFER
+ select IIO_BUFFER_DMA
+ select IIO_BUFFER_DMAENGINE
select IIO_TRIGGERED_BUFFER
+ select SPI_OFFLOAD
+ select SPI_OFFLOAD_TRIGGER_PWM
help
Say yes here to build support for Analog Devices AD4030 and AD4630 high speed
SPI analog to digital converters (ADC).
@@ -413,8 +418,10 @@ config AD7768_1
select REGMAP_SPI
select RATIONAL
select IIO_BUFFER
+ select IIO_BUFFER_DMAENGINE
select IIO_TRIGGER
select IIO_TRIGGERED_BUFFER
+ select SPI_OFFLOAD
help
Say yes here to build support for Analog Devices AD7768-1 SPI
simultaneously sampling sigma-delta analog to digital converter (ADC).
@@ -1366,6 +1373,32 @@ config QCOM_SPMI_ADC5
To compile this driver as a module, choose M here: the module will
be called qcom-spmi-adc5.
+config QCOM_SPMI_ADC5_GEN3
+ tristate "Qualcomm Technologies Inc. SPMI PMIC5 GEN3 ADC"
+ depends on SPMI && THERMAL
+ select REGMAP_SPMI
+ select QCOM_VADC_COMMON
+ select AUXILIARY_BUS
+ help
+ IIO Voltage PMIC5 Gen3 ADC driver for Qualcomm Technologies Inc.
+
+ The driver supports reading multiple channels. The ADC is a 16-bit
+ sigma-delta ADC. The hardware supports calibrated results for
+ conversion requests and clients include reading phone power supply
+ voltage, on board system thermistors connected to the PMIC ADC,
+ PMIC die temperature, charger temperature, battery current, USB
+ voltage input and voltage signals connected to supported PMIC GPIO
+ pins. The hardware supports internal pull-up for thermistors and can
+ choose between a 30k, 100k or 400k ohm pull up using the ADC channels.
+
+ In addition, the same driver supports ADC thermal monitoring devices
+ too. They appear as thermal zones with multiple trip points. A thermal
+ client sets threshold temperature for both warm and cool trips and
+ gets updated when a threshold is reached.
+
+ To compile this driver as a module, choose M here: the module will
+ be called qcom-spmi-adc5-gen3.
+
config RCAR_GYRO_ADC
tristate "Renesas R-Car GyroADC driver"
depends on ARCH_RCAR_GEN2 || COMPILE_TEST
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index c76550415ff1..097357d146ba 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -116,6 +116,7 @@ obj-$(CONFIG_PAC1934) += pac1934.o
obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o
obj-$(CONFIG_QCOM_SPMI_ADC5) += qcom-spmi-adc5.o
+obj-$(CONFIG_QCOM_SPMI_ADC5_GEN3) += qcom-spmi-adc5-gen3.o
obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
obj-$(CONFIG_QCOM_SPMI_RRADC) += qcom-spmi-rradc.o
obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
diff --git a/drivers/iio/adc/ad4030.c b/drivers/iio/adc/ad4030.c
index 68446db9bef1..9c5f19321e3b 100644
--- a/drivers/iio/adc/ad4030.c
+++ b/drivers/iio/adc/ad4030.c
@@ -14,15 +14,26 @@
*/
#include <linux/bitfield.h>
+#include <linux/cleanup.h>
#include <linux/clk.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/trigger_consumer.h>
-#include <linux/iio/triggered_buffer.h>
+#include <linux/dmaengine.h>
+#include <linux/limits.h>
+#include <linux/log2.h>
+#include <linux/math64.h>
+#include <linux/minmax.h>
+#include <linux/pwm.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include <linux/spi/offload/consumer.h>
#include <linux/spi/spi.h>
#include <linux/unaligned.h>
#include <linux/units.h>
+#include <linux/types.h>
+
+#include <linux/iio/buffer-dmaengine.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
#define AD4030_REG_INTERFACE_CONFIG_A 0x00
#define AD4030_REG_INTERFACE_CONFIG_A_SW_RESET (BIT(0) | BIT(7))
@@ -37,6 +48,8 @@
#define AD4030_REG_CHIP_GRADE_AD4630_24_GRADE 0x00
#define AD4030_REG_CHIP_GRADE_AD4632_16_GRADE 0x05
#define AD4030_REG_CHIP_GRADE_AD4632_24_GRADE 0x02
+#define AD4030_REG_CHIP_GRADE_ADAQ4216_GRADE 0x1E
+#define AD4030_REG_CHIP_GRADE_ADAQ4224_GRADE 0x1C
#define AD4030_REG_CHIP_GRADE_MASK_CHIP_GRADE GENMASK(7, 3)
#define AD4030_REG_SCRATCH_PAD 0x0A
#define AD4030_REG_SPI_REVISION 0x0B
@@ -111,6 +124,12 @@
#define AD4632_TCYC_NS 2000
#define AD4632_TCYC_ADJUSTED_NS (AD4632_TCYC_NS - AD4030_TCNVL_NS)
#define AD4030_TRESET_COM_DELAY_MS 750
+/* Datasheet says 9.8ns, so use the closest integer value */
+#define AD4030_TQUIET_CNV_DELAY_NS 10
+
+/* HARDWARE_GAIN */
+#define ADAQ4616_PGA_PINS 2
+#define ADAQ4616_PGA_GAIN_MAX_NANO (NANO * 2 / 3)
enum ad4030_out_mode {
AD4030_OUT_DATA_MD_DIFF,
@@ -132,15 +151,35 @@ enum {
AD4030_SCAN_TYPE_AVG,
};
+/*
+ * Gains computed as fractions of 1000 so they can be expressed by integers.
+ */
+static const int adaq4216_hw_gains_vpv[] = {
+ 1 * MILLI / 3, /* 0.333 */
+ 5 * MILLI / 9, /* 0.555 */
+ 20 * MILLI / 9, /* 0.2222 */
+ 20 * MILLI / 3, /* 0.6666 */
+};
+
+static const int adaq4216_hw_gains_frac[][2] = {
+ { 1, 3 }, /* 1/3 V/V gain */
+ { 5, 9 }, /* 5/9 V/V gain */
+ { 20, 9 }, /* 20/9 V/V gain */
+ { 20, 3 }, /* 20/3 V/V gain */
+};
+
struct ad4030_chip_info {
const char *name;
const unsigned long *available_masks;
const struct iio_chan_spec channels[AD4030_MAX_IIO_CHANNEL_NB];
+ const struct iio_chan_spec offload_channels[AD4030_MAX_IIO_CHANNEL_NB];
u8 grade;
u8 precision_bits;
+ bool has_pga;
/* Number of hardware channels */
int num_voltage_inputs;
unsigned int tcyc_ns;
+ unsigned int max_sample_rate_hz;
};
struct ad4030_state {
@@ -153,6 +192,18 @@ struct ad4030_state {
int offset_avail[3];
unsigned int avg_log2;
enum ad4030_out_mode mode;
+ /* Offload sampling */
+ struct spi_transfer offload_xfer;
+ struct spi_message offload_msg;
+ struct spi_offload *offload;
+ struct spi_offload_trigger *offload_trigger;
+ struct spi_offload_trigger_config offload_trigger_config;
+ struct pwm_device *cnv_trigger;
+ size_t scale_avail_size;
+ struct pwm_waveform cnv_wf;
+ unsigned int scale_avail[ARRAY_SIZE(adaq4216_hw_gains_vpv)][2];
+ struct gpio_descs *pga_gpios;
+ unsigned int pga_index;
/*
* DMA (thus cache coherency maintenance) requires the transfer buffers
@@ -209,8 +260,9 @@ struct ad4030_state {
* - voltage0-voltage1
* - voltage2-voltage3
*/
-#define AD4030_CHAN_DIFF(_idx, _scan_type) { \
+#define __AD4030_CHAN_DIFF(_idx, _scan_type, _offload, _pga) { \
.info_mask_shared_by_all = \
+ (_offload ? BIT(IIO_CHAN_INFO_SAMP_FREQ) : 0) | \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.info_mask_shared_by_all_available = \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
@@ -219,6 +271,7 @@ struct ad4030_state {
BIT(IIO_CHAN_INFO_CALIBBIAS) | \
BIT(IIO_CHAN_INFO_RAW), \
.info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBBIAS) | \
+ (_pga ? BIT(IIO_CHAN_INFO_SCALE) : 0) | \
BIT(IIO_CHAN_INFO_CALIBSCALE), \
.type = IIO_VOLTAGE, \
.indexed = 1, \
@@ -232,10 +285,33 @@ struct ad4030_state {
.num_ext_scan_type = ARRAY_SIZE(_scan_type), \
}
+#define AD4030_CHAN_DIFF(_idx, _scan_type) \
+ __AD4030_CHAN_DIFF(_idx, _scan_type, 0, 0)
+
+#define AD4030_OFFLOAD_CHAN_DIFF(_idx, _scan_type) \
+ __AD4030_CHAN_DIFF(_idx, _scan_type, 1, 0)
+
+#define ADAQ4216_CHAN_DIFF(_idx, _scan_type) \
+ __AD4030_CHAN_DIFF(_idx, _scan_type, 0, 1)
+
+#define ADAQ4216_OFFLOAD_CHAN_DIFF(_idx, _scan_type) \
+ __AD4030_CHAN_DIFF(_idx, _scan_type, 1, 1)
+
+/*
+ * AD4030 can average over 2^N samples, where N = 1, 2, 3, ..., 16.
+ * We use N = 0 to mean no sample averaging.
+ */
static const int ad4030_average_modes[] = {
- 1, 2, 4, 8, 16, 32, 64, 128,
- 256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
- 65536,
+ BIT(0), /* No sampling average */
+ BIT(1), BIT(2), BIT(3), BIT(4),
+ BIT(5), BIT(6), BIT(7), BIT(8),
+ BIT(9), BIT(10), BIT(11), BIT(12),
+ BIT(13), BIT(14), BIT(15), BIT(16),
+};
+
+static const struct spi_offload_config ad4030_offload_config = {
+ .capability_flags = SPI_OFFLOAD_CAP_TRIGGER |
+ SPI_OFFLOAD_CAP_RX_STREAM_DMA,
};
static int ad4030_enter_config_mode(struct ad4030_state *st)
@@ -377,6 +453,65 @@ static const struct regmap_config ad4030_regmap_config = {
.max_register = AD4030_REG_DIG_ERR,
};
+static void ad4030_fill_scale_avail(struct ad4030_state *st)
+{
+ unsigned int mag_bits, int_part, fract_part;
+ u64 range;
+
+ /*
+ * The maximum precision of differential channels is retrieved from the
+ * chip properties. The output code of differential channels is in two's
+ * complement format (i.e. signed), so the MSB is the sign bit and only
+ * (precision_bits - 1) bits express voltage magnitude.
+ */
+ mag_bits = st->chip->precision_bits - 1;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(adaq4216_hw_gains_frac); i++) {
+ range = mult_frac(st->vref_uv, adaq4216_hw_gains_frac[i][1],
+ adaq4216_hw_gains_frac[i][0]);
+ /*
+ * If range were in mV, we would multiply it by NANO below.
+ * Though, range is in µV so multiply it by MICRO only so the
+ * result after right shift and division scales output codes to
+ * millivolts.
+ */
+ int_part = div_u64_rem((range * MICRO) >> mag_bits, NANO, &fract_part);
+ st->scale_avail[i][0] = int_part;
+ st->scale_avail[i][1] = fract_part;
+ }
+}
+
+static int ad4030_set_pga_gain(struct ad4030_state *st)
+{
+ DECLARE_BITMAP(bitmap, ADAQ4616_PGA_PINS) = { };
+
+ bitmap_write(bitmap, st->pga_index, 0, ADAQ4616_PGA_PINS);
+
+ return gpiod_multi_set_value_cansleep(st->pga_gpios, bitmap);
+}
+
+static int ad4030_set_pga(struct iio_dev *indio_dev, int gain_int, int gain_fract)
+{
+ struct ad4030_state *st = iio_priv(indio_dev);
+ unsigned int mag_bits = st->chip->precision_bits - 1;
+ unsigned int tmp;
+ u64 gain_nano;
+
+ if (!st->pga_gpios)
+ return -EINVAL;
+
+ gain_nano = gain_int * NANO + gain_fract;
+ if (!in_range(gain_nano, 1, ADAQ4616_PGA_GAIN_MAX_NANO))
+ return -EINVAL;
+
+ tmp = DIV_ROUND_CLOSEST_ULL(gain_nano << mag_bits, NANO);
+ gain_nano = DIV_ROUND_CLOSEST(st->vref_uv, tmp);
+ st->pga_index = find_closest(gain_nano, adaq4216_hw_gains_vpv,
+ ARRAY_SIZE(adaq4216_hw_gains_vpv));
+
+ return ad4030_set_pga_gain(st);
+}
+
static int ad4030_get_chan_scale(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
@@ -389,6 +524,13 @@ static int ad4030_get_chan_scale(struct iio_dev *indio_dev,
if (IS_ERR(scan_type))
return PTR_ERR(scan_type);
+ /* The LSB of the 8-bit common-mode data is always vref/256. */
+ if (st->chip->has_pga && scan_type->realbits != 8) {
+ *val = st->scale_avail[st->pga_index][0];
+ *val2 = st->scale_avail[st->pga_index][1];
+ return IIO_VAL_INT_PLUS_NANO;
+ }
+
if (chan->differential)
*val = (st->vref_uv * 2) / MILLI;
else
@@ -451,6 +593,102 @@ static int ad4030_get_chan_calibbias(struct iio_dev *indio_dev,
}
}
+static void ad4030_get_sampling_freq(struct ad4030_state *st, int *freq)
+{
+ struct spi_offload_trigger_config *config = &st->offload_trigger_config;
+
+ /*
+ * Conversion data is fetched from the device when the offload transfer
+ * is triggered. Thus, provide the SPI offload trigger frequency as the
+ * sampling frequency.
+ */
+ *freq = config->periodic.frequency_hz;
+}
+
+static int ad4030_update_conversion_rate(struct ad4030_state *st,
+ unsigned int freq_hz, unsigned int avg_log2)
+{
+ struct spi_offload_trigger_config *config = &st->offload_trigger_config;
+ unsigned int offload_period_ns, cnv_rate_hz;
+ struct pwm_waveform cnv_wf = { };
+ u64 target = AD4030_TCNVH_NS;
+ u64 offload_offset_ns;
+ int ret;
+
+ /*
+ * When averaging/oversampling over N samples, we fire the offload
+ * trigger once at every N pulses of the CNV signal. Conversely, the CNV
+ * signal needs to be N times faster than the offload trigger. Take that
+ * into account to correctly re-evaluate both the PWM waveform connected
+ * to CNV and the SPI offload trigger.
+ */
+ cnv_rate_hz = freq_hz << avg_log2;
+
+ cnv_wf.period_length_ns = DIV_ROUND_CLOSEST(NSEC_PER_SEC, cnv_rate_hz);
+ /*
+ * The datasheet lists a minimum time of 9.8 ns, but no maximum. If the
+ * rounded PWM's value is less than 10, increase the target value by 10
+ * and attempt to round the waveform again, until the value is at least
+ * 10 ns. Use a separate variable to represent the target in case the
+ * rounding is severe enough to keep putting the first few results under
+ * the minimum 10ns condition checked by the while loop.
+ */
+ do {
+ cnv_wf.duty_length_ns = target;
+ ret = pwm_round_waveform_might_sleep(st->cnv_trigger, &cnv_wf);
+ if (ret)
+ return ret;
+ target += AD4030_TCNVH_NS;
+ } while (cnv_wf.duty_length_ns < AD4030_TCNVH_NS);
+
+ /*
+ * The CNV waveform period (period_length_ns) might get rounded down by
+ * pwm_round_waveform_might_sleep(). Check the resultant PWM period
+ * is not smaller than the minimum data conversion cycle time.
+ */
+ if (!in_range(cnv_wf.period_length_ns, AD4030_TCYC_NS, INT_MAX))
+ return -EINVAL;
+
+ offload_period_ns = DIV_ROUND_CLOSEST(NSEC_PER_SEC, freq_hz);
+
+ config->periodic.frequency_hz = DIV_ROUND_UP(HZ_PER_GHZ, offload_period_ns);
+
+ /*
+ * The hardware does the capture on zone 2 (when SPI trigger PWM
+ * is used). This means that the SPI trigger signal should happen at
+ * tsync + tquiet_con_delay being tsync the conversion signal period
+ * and tquiet_con_delay 9.8ns. Hence set the PWM phase accordingly.
+ *
+ * The PWM waveform API only supports nanosecond resolution right now,
+ * so round this setting to the closest available value.
+ */
+ offload_offset_ns = AD4030_TQUIET_CNV_DELAY_NS;
+ do {
+ config->periodic.offset_ns = offload_offset_ns;
+ ret = spi_offload_trigger_validate(st->offload_trigger, config);
+ if (ret)
+ return ret;
+ offload_offset_ns += AD4030_TQUIET_CNV_DELAY_NS;
+ } while (config->periodic.offset_ns < AD4030_TQUIET_CNV_DELAY_NS);
+
+ st->cnv_wf = cnv_wf;
+
+ return 0;
+}
+
+static int ad4030_set_sampling_freq(struct iio_dev *indio_dev, int freq_hz)
+{
+ struct ad4030_state *st = iio_priv(indio_dev);
+
+ if (freq_hz == 0)
+ return -EINVAL;
+
+ if (!in_range(freq_hz, 0, st->chip->max_sample_rate_hz))
+ return -ERANGE;
+
+ return ad4030_update_conversion_rate(st, freq_hz, st->avg_log2);
+}
+
static int ad4030_set_chan_calibscale(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int gain_int,
@@ -510,11 +748,30 @@ static int ad4030_set_avg_frame_len(struct iio_dev *dev, int avg_val)
struct ad4030_state *st = iio_priv(dev);
unsigned int avg_log2 = ilog2(avg_val);
unsigned int last_avg_idx = ARRAY_SIZE(ad4030_average_modes) - 1;
+ int freq_hz;
int ret;
if (avg_val < 0 || avg_val > ad4030_average_modes[last_avg_idx])
return -EINVAL;
+ if (st->offload_trigger) {
+ /*
+ * The sample averaging and sampling frequency configurations
+ * are mutually dependent on each other. That's because the
+ * effective data sample rate is fCNV / 2^N, where N is the
+ * number of samples being averaged.
+ *
+ * When SPI offload is supported and we have control over the
+ * sample rate, the conversion start signal (CNV) and the SPI
+ * offload trigger frequencies must be re-evaluated so data is
+ * fetched only after 'avg_val' conversions.
+ */
+ ad4030_get_sampling_freq(st, &freq_hz);
+ ret = ad4030_update_conversion_rate(st, freq_hz, avg_log2);
+ if (ret)
+ return ret;
+ }
+
ret = regmap_write(st->regmap, AD4030_REG_AVG,
AD4030_REG_AVG_MASK_AVG_SYNC |
FIELD_PREP(AD4030_REG_AVG_MASK_AVG_VAL, avg_log2));
@@ -623,7 +880,7 @@ static int ad4030_conversion(struct iio_dev *indio_dev)
/* Add one byte if we are using a differential + common byte mode */
bytes_to_read += (st->mode == AD4030_OUT_DATA_MD_24_DIFF_8_COM ||
st->mode == AD4030_OUT_DATA_MD_16_DIFF_8_COM) ? 1 : 0;
- /* Mulitiply by the number of hardware channels */
+ /* Multiply by the number of hardware channels */
bytes_to_read *= st->chip->num_voltage_inputs;
for (i = 0; i < cnv_nb; i++) {
@@ -742,6 +999,15 @@ static int ad4030_read_avail(struct iio_dev *indio_dev,
*length = ARRAY_SIZE(ad4030_average_modes);
return IIO_AVAIL_LIST;
+ case IIO_CHAN_INFO_SCALE:
+ if (st->scale_avail_size == 1)
+ *vals = (int *)st->scale_avail[st->pga_index];
+ else
+ *vals = (int *)st->scale_avail;
+ *length = st->scale_avail_size * 2; /* print int and nano part */
+ *type = IIO_VAL_INT_PLUS_NANO;
+ return IIO_AVAIL_LIST;
+
default:
return -EINVAL;
}
@@ -767,6 +1033,10 @@ static int ad4030_read_raw_dispatch(struct iio_dev *indio_dev,
*val = BIT(st->avg_log2);
return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ ad4030_get_sampling_freq(st, val);
+ return IIO_VAL_INT;
+
default:
return -EINVAL;
}
@@ -807,6 +1077,12 @@ static int ad4030_write_raw_dispatch(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
return ad4030_set_avg_frame_len(indio_dev, val);
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ return ad4030_set_sampling_freq(indio_dev, val);
+
+ case IIO_CHAN_INFO_SCALE:
+ return ad4030_set_pga(indio_dev, val, val2);
+
default:
return -EINVAL;
}
@@ -828,6 +1104,17 @@ static int ad4030_write_raw(struct iio_dev *indio_dev,
return ret;
}
+static int ad4030_write_raw_get_fmt(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, long mask)
+{
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+}
+
static int ad4030_reg_access(struct iio_dev *indio_dev, unsigned int reg,
unsigned int writeval, unsigned int *readval)
{
@@ -874,6 +1161,7 @@ static const struct iio_info ad4030_iio_info = {
.read_avail = ad4030_read_avail,
.read_raw = ad4030_read_raw,
.write_raw = ad4030_write_raw,
+ .write_raw_get_fmt = &ad4030_write_raw_get_fmt,
.debugfs_reg_access = ad4030_reg_access,
.read_label = ad4030_read_label,
.get_current_scan_type = ad4030_get_current_scan_type,
@@ -896,6 +1184,86 @@ static const struct iio_buffer_setup_ops ad4030_buffer_setup_ops = {
.validate_scan_mask = ad4030_validate_scan_mask,
};
+static void ad4030_prepare_offload_msg(struct iio_dev *indio_dev)
+{
+ struct ad4030_state *st = iio_priv(indio_dev);
+ u8 offload_bpw;
+
+ if (st->mode == AD4030_OUT_DATA_MD_30_AVERAGED_DIFF)
+ offload_bpw = 32;
+ else
+ offload_bpw = st->chip->precision_bits;
+
+ st->offload_xfer.bits_per_word = offload_bpw;
+ st->offload_xfer.len = spi_bpw_to_bytes(offload_bpw);
+ st->offload_xfer.offload_flags = SPI_OFFLOAD_XFER_RX_STREAM;
+ spi_message_init_with_transfers(&st->offload_msg, &st->offload_xfer, 1);
+}
+
+static int ad4030_offload_buffer_postenable(struct iio_dev *indio_dev)
+{
+ struct ad4030_state *st = iio_priv(indio_dev);
+ unsigned int reg_modes;
+ int ret;
+
+ /*
+ * When data from 2 analog input channels is output through a single
+ * bus line (interleaved mode (LANE_MD == 0b11)) and gets pushed through
+ * DMA, extra hardware is required to do the de-interleaving. While we
+ * don't support such hardware configurations, disallow interleaved mode
+ * when using SPI offload.
+ */
+ ret = regmap_read(st->regmap, AD4030_REG_MODES, &reg_modes);
+ if (ret)
+ return ret;
+
+ if (st->chip->num_voltage_inputs > 1 &&
+ FIELD_GET(AD4030_REG_MODES_MASK_LANE_MODE, reg_modes) == AD4030_LANE_MD_INTERLEAVED)
+ return -EINVAL;
+
+ ad4030_prepare_offload_msg(indio_dev);
+ st->offload_msg.offload = st->offload;
+ ret = spi_optimize_message(st->spi, &st->offload_msg);
+ if (ret)
+ return ret;
+
+ ret = pwm_set_waveform_might_sleep(st->cnv_trigger, &st->cnv_wf, false);
+ if (ret)
+ goto out_unoptimize;
+
+ ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
+ &st->offload_trigger_config);
+ if (ret)
+ goto out_pwm_disable;
+
+ return 0;
+
+out_pwm_disable:
+ pwm_disable(st->cnv_trigger);
+out_unoptimize:
+ spi_unoptimize_message(&st->offload_msg);
+
+ return ret;
+}
+
+static int ad4030_offload_buffer_predisable(struct iio_dev *indio_dev)
+{
+ struct ad4030_state *st = iio_priv(indio_dev);
+
+ spi_offload_trigger_disable(st->offload, st->offload_trigger);
+
+ pwm_disable(st->cnv_trigger);
+
+ spi_unoptimize_message(&st->offload_msg);
+
+ return 0;
+}
+
+static const struct iio_buffer_setup_ops ad4030_offload_buffer_setup_ops = {
+ .postenable = &ad4030_offload_buffer_postenable,
+ .predisable = &ad4030_offload_buffer_predisable,
+};
+
static int ad4030_regulators_get(struct ad4030_state *st)
{
struct device *dev = &st->spi->dev;
@@ -965,6 +1333,24 @@ static int ad4030_detect_chip_info(const struct ad4030_state *st)
return 0;
}
+static int ad4030_pwm_get(struct ad4030_state *st)
+{
+ struct device *dev = &st->spi->dev;
+
+ st->cnv_trigger = devm_pwm_get(dev, NULL);
+ if (IS_ERR(st->cnv_trigger))
+ return dev_err_probe(dev, PTR_ERR(st->cnv_trigger),
+ "Failed to get CNV PWM\n");
+
+ /*
+ * Preemptively disable the PWM, since we only want to enable it with
+ * the buffer.
+ */
+ pwm_disable(st->cnv_trigger);
+
+ return 0;
+}
+
static int ad4030_config(struct ad4030_state *st)
{
int ret;
@@ -992,6 +1378,51 @@ static int ad4030_config(struct ad4030_state *st)
return 0;
}
+static int ad4030_spi_offload_setup(struct iio_dev *indio_dev,
+ struct ad4030_state *st)
+{
+ struct device *dev = &st->spi->dev;
+ struct dma_chan *rx_dma;
+
+ indio_dev->setup_ops = &ad4030_offload_buffer_setup_ops;
+
+ st->offload_trigger = devm_spi_offload_trigger_get(dev, st->offload,
+ SPI_OFFLOAD_TRIGGER_PERIODIC);
+ if (IS_ERR(st->offload_trigger))
+ return dev_err_probe(dev, PTR_ERR(st->offload_trigger),
+ "failed to get offload trigger\n");
+
+ st->offload_trigger_config.type = SPI_OFFLOAD_TRIGGER_PERIODIC;
+
+ rx_dma = devm_spi_offload_rx_stream_request_dma_chan(dev, st->offload);
+ if (IS_ERR(rx_dma))
+ return dev_err_probe(dev, PTR_ERR(rx_dma),
+ "failed to get offload RX DMA\n");
+
+ return devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev, rx_dma,
+ IIO_BUFFER_DIRECTION_IN);
+}
+
+static int ad4030_setup_pga(struct device *dev, struct iio_dev *indio_dev,
+ struct ad4030_state *st)
+{
+ /* Setup GPIOs for PGA control */
+ st->pga_gpios = devm_gpiod_get_array(dev, "pga", GPIOD_OUT_LOW);
+ if (IS_ERR(st->pga_gpios))
+ return dev_err_probe(dev, PTR_ERR(st->pga_gpios),
+ "Failed to get PGA gpios.\n");
+
+ if (st->pga_gpios->ndescs != ADAQ4616_PGA_PINS)
+ return dev_err_probe(dev, -EINVAL,
+ "Expected %d GPIOs for PGA control.\n",
+ ADAQ4616_PGA_PINS);
+
+ st->scale_avail_size = ARRAY_SIZE(adaq4216_hw_gains_vpv);
+ st->pga_index = 0;
+
+ return 0;
+}
+
static int ad4030_probe(struct spi_device *spi)
{
struct device *dev = &spi->dev;
@@ -1034,6 +1465,14 @@ static int ad4030_probe(struct spi_device *spi)
if (ret)
return ret;
+ if (st->chip->has_pga) {
+ ret = ad4030_setup_pga(dev, indio_dev, st);
+ if (ret)
+ return ret;
+
+ ad4030_fill_scale_avail(st);
+ }
+
ret = ad4030_config(st);
if (ret)
return ret;
@@ -1043,24 +1482,58 @@ static int ad4030_probe(struct spi_device *spi)
return dev_err_probe(dev, PTR_ERR(st->cnv_gpio),
"Failed to get cnv gpio\n");
- /*
- * One hardware channel is split in two software channels when using
- * common byte mode. Add one more channel for the timestamp.
- */
- indio_dev->num_channels = 2 * st->chip->num_voltage_inputs + 1;
indio_dev->name = st->chip->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &ad4030_iio_info;
- indio_dev->channels = st->chip->channels;
indio_dev->available_scan_masks = st->chip->available_masks;
- ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
- iio_pollfunc_store_time,
- ad4030_trigger_handler,
- &ad4030_buffer_setup_ops);
- if (ret)
- return dev_err_probe(dev, ret,
- "Failed to setup triggered buffer\n");
+ st->offload = devm_spi_offload_get(dev, spi, &ad4030_offload_config);
+ ret = PTR_ERR_OR_ZERO(st->offload);
+ /* Fall back to low speed usage when no SPI offload is available. */
+ if (ret == -ENODEV) {
+ /*
+ * One hardware channel is split in two software channels when
+ * using common byte mode. Add one more channel for the timestamp.
+ */
+ indio_dev->num_channels = 2 * st->chip->num_voltage_inputs + 1;
+ indio_dev->channels = st->chip->channels;
+
+ ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
+ iio_pollfunc_store_time,
+ ad4030_trigger_handler,
+ &ad4030_buffer_setup_ops);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to setup triggered buffer\n");
+ } else if (ret) {
+ return dev_err_probe(dev, ret, "failed to get offload\n");
+ } else {
+ /*
+ * Offloaded SPI transfers can't support software timestamp so
+ * no additional timestamp channel is added.
+ */
+ indio_dev->num_channels = st->chip->num_voltage_inputs;
+ indio_dev->channels = st->chip->offload_channels;
+ ret = ad4030_spi_offload_setup(indio_dev, st);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to setup SPI offload\n");
+
+ ret = ad4030_pwm_get(st);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get PWM\n");
+
+ /*
+ * Start with a slower sampling rate so there is some room for
+ * adjusting the sample averaging and the sampling frequency
+ * without hitting the maximum conversion rate.
+ */
+ ret = ad4030_update_conversion_rate(st, st->chip->max_sample_rate_hz >> 4,
+ st->avg_log2);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to set offload samp freq\n");
+ }
return devm_iio_device_register(dev, indio_dev);
}
@@ -1098,11 +1571,28 @@ static const struct iio_scan_type ad4030_24_scan_types[] = {
},
};
-static const struct iio_scan_type ad4030_16_scan_types[] = {
+static const struct iio_scan_type ad4030_24_offload_scan_types[] = {
[AD4030_SCAN_TYPE_NORMAL] = {
.sign = 's',
+ .realbits = 24,
.storagebits = 32,
+ .shift = 0,
+ .endianness = IIO_CPU,
+ },
+ [AD4030_SCAN_TYPE_AVG] = {
+ .sign = 's',
+ .realbits = 30,
+ .storagebits = 32,
+ .shift = 2,
+ .endianness = IIO_CPU,
+ },
+};
+
+static const struct iio_scan_type ad4030_16_scan_types[] = {
+ [AD4030_SCAN_TYPE_NORMAL] = {
+ .sign = 's',
.realbits = 16,
+ .storagebits = 32,
.shift = 16,
.endianness = IIO_BE,
},
@@ -1115,6 +1605,23 @@ static const struct iio_scan_type ad4030_16_scan_types[] = {
}
};
+static const struct iio_scan_type ad4030_16_offload_scan_types[] = {
+ [AD4030_SCAN_TYPE_NORMAL] = {
+ .sign = 's',
+ .realbits = 16,
+ .storagebits = 32,
+ .shift = 0,
+ .endianness = IIO_CPU,
+ },
+ [AD4030_SCAN_TYPE_AVG] = {
+ .sign = 's',
+ .realbits = 30,
+ .storagebits = 32,
+ .shift = 2,
+ .endianness = IIO_CPU,
+ },
+};
+
static const struct ad4030_chip_info ad4030_24_chip_info = {
.name = "ad4030-24",
.available_masks = ad4030_channel_masks,
@@ -1123,10 +1630,14 @@ static const struct ad4030_chip_info ad4030_24_chip_info = {
AD4030_CHAN_CMO(1, 0),
IIO_CHAN_SOFT_TIMESTAMP(2),
},
+ .offload_channels = {
+ AD4030_OFFLOAD_CHAN_DIFF(0, ad4030_24_offload_scan_types),
+ },
.grade = AD4030_REG_CHIP_GRADE_AD4030_24_GRADE,
.precision_bits = 24,
.num_voltage_inputs = 1,
.tcyc_ns = AD4030_TCYC_ADJUSTED_NS,
+ .max_sample_rate_hz = 2 * HZ_PER_MHZ,
};
static const struct ad4030_chip_info ad4630_16_chip_info = {
@@ -1139,10 +1650,15 @@ static const struct ad4030_chip_info ad4630_16_chip_info = {
AD4030_CHAN_CMO(3, 1),
IIO_CHAN_SOFT_TIMESTAMP(4),
},
+ .offload_channels = {
+ AD4030_OFFLOAD_CHAN_DIFF(0, ad4030_16_offload_scan_types),
+ AD4030_OFFLOAD_CHAN_DIFF(1, ad4030_16_offload_scan_types),
+ },
.grade = AD4030_REG_CHIP_GRADE_AD4630_16_GRADE,
.precision_bits = 16,
.num_voltage_inputs = 2,
.tcyc_ns = AD4030_TCYC_ADJUSTED_NS,
+ .max_sample_rate_hz = 2 * HZ_PER_MHZ,
};
static const struct ad4030_chip_info ad4630_24_chip_info = {
@@ -1155,10 +1671,15 @@ static const struct ad4030_chip_info ad4630_24_chip_info = {
AD4030_CHAN_CMO(3, 1),
IIO_CHAN_SOFT_TIMESTAMP(4),
},
+ .offload_channels = {
+ AD4030_OFFLOAD_CHAN_DIFF(0, ad4030_24_offload_scan_types),
+ AD4030_OFFLOAD_CHAN_DIFF(1, ad4030_24_offload_scan_types),
+ },
.grade = AD4030_REG_CHIP_GRADE_AD4630_24_GRADE,
.precision_bits = 24,
.num_voltage_inputs = 2,
.tcyc_ns = AD4030_TCYC_ADJUSTED_NS,
+ .max_sample_rate_hz = 2 * HZ_PER_MHZ,
};
static const struct ad4030_chip_info ad4632_16_chip_info = {
@@ -1171,10 +1692,15 @@ static const struct ad4030_chip_info ad4632_16_chip_info = {
AD4030_CHAN_CMO(3, 1),
IIO_CHAN_SOFT_TIMESTAMP(4),
},
+ .offload_channels = {
+ AD4030_OFFLOAD_CHAN_DIFF(0, ad4030_16_offload_scan_types),
+ AD4030_OFFLOAD_CHAN_DIFF(1, ad4030_16_offload_scan_types),
+ },
.grade = AD4030_REG_CHIP_GRADE_AD4632_16_GRADE,
.precision_bits = 16,
.num_voltage_inputs = 2,
.tcyc_ns = AD4632_TCYC_ADJUSTED_NS,
+ .max_sample_rate_hz = 500 * HZ_PER_KHZ,
};
static const struct ad4030_chip_info ad4632_24_chip_info = {
@@ -1187,10 +1713,53 @@ static const struct ad4030_chip_info ad4632_24_chip_info = {
AD4030_CHAN_CMO(3, 1),
IIO_CHAN_SOFT_TIMESTAMP(4),
},
+ .offload_channels = {
+ AD4030_OFFLOAD_CHAN_DIFF(0, ad4030_24_offload_scan_types),
+ AD4030_OFFLOAD_CHAN_DIFF(1, ad4030_24_offload_scan_types),
+ },
.grade = AD4030_REG_CHIP_GRADE_AD4632_24_GRADE,
.precision_bits = 24,
.num_voltage_inputs = 2,
.tcyc_ns = AD4632_TCYC_ADJUSTED_NS,
+ .max_sample_rate_hz = 500 * HZ_PER_KHZ,
+};
+
+static const struct ad4030_chip_info adaq4216_chip_info = {
+ .name = "adaq4216",
+ .available_masks = ad4030_channel_masks,
+ .channels = {
+ ADAQ4216_CHAN_DIFF(0, ad4030_16_scan_types),
+ AD4030_CHAN_CMO(1, 0),
+ IIO_CHAN_SOFT_TIMESTAMP(2),
+ },
+ .offload_channels = {
+ ADAQ4216_OFFLOAD_CHAN_DIFF(0, ad4030_16_offload_scan_types),
+ },
+ .grade = AD4030_REG_CHIP_GRADE_ADAQ4216_GRADE,
+ .precision_bits = 16,
+ .has_pga = true,
+ .num_voltage_inputs = 1,
+ .tcyc_ns = AD4030_TCYC_ADJUSTED_NS,
+ .max_sample_rate_hz = 2 * HZ_PER_MHZ,
+};
+
+static const struct ad4030_chip_info adaq4224_chip_info = {
+ .name = "adaq4224",
+ .available_masks = ad4030_channel_masks,
+ .channels = {
+ ADAQ4216_CHAN_DIFF(0, ad4030_24_scan_types),
+ AD4030_CHAN_CMO(1, 0),
+ IIO_CHAN_SOFT_TIMESTAMP(2),
+ },
+ .offload_channels = {
+ ADAQ4216_OFFLOAD_CHAN_DIFF(0, ad4030_24_offload_scan_types),
+ },
+ .grade = AD4030_REG_CHIP_GRADE_ADAQ4224_GRADE,
+ .precision_bits = 24,
+ .has_pga = true,
+ .num_voltage_inputs = 1,
+ .tcyc_ns = AD4030_TCYC_ADJUSTED_NS,
+ .max_sample_rate_hz = 2 * HZ_PER_MHZ,
};
static const struct spi_device_id ad4030_id_table[] = {
@@ -1199,6 +1768,8 @@ static const struct spi_device_id ad4030_id_table[] = {
{ "ad4630-24", (kernel_ulong_t)&ad4630_24_chip_info },
{ "ad4632-16", (kernel_ulong_t)&ad4632_16_chip_info },
{ "ad4632-24", (kernel_ulong_t)&ad4632_24_chip_info },
+ { "adaq4216", (kernel_ulong_t)&adaq4216_chip_info },
+ { "adaq4224", (kernel_ulong_t)&adaq4224_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ad4030_id_table);
@@ -1209,6 +1780,8 @@ static const struct of_device_id ad4030_of_match[] = {
{ .compatible = "adi,ad4630-24", .data = &ad4630_24_chip_info },
{ .compatible = "adi,ad4632-16", .data = &ad4632_16_chip_info },
{ .compatible = "adi,ad4632-24", .data = &ad4632_24_chip_info },
+ { .compatible = "adi,adaq4216", .data = &adaq4216_chip_info },
+ { .compatible = "adi,adaq4224", .data = &adaq4224_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ad4030_of_match);
@@ -1226,3 +1799,4 @@ module_spi_driver(ad4030_driver);
MODULE_AUTHOR("Esteban Blanc <eblanc@baylibre.com>");
MODULE_DESCRIPTION("Analog Devices AD4630 ADC family driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER");
diff --git a/drivers/iio/adc/ad4062.c b/drivers/iio/adc/ad4062.c
index dd4ad32aa6f5..c864de3b46ba 100644
--- a/drivers/iio/adc/ad4062.c
+++ b/drivers/iio/adc/ad4062.c
@@ -1199,11 +1199,14 @@ static int ad4062_write_event_value(struct iio_dev *indio_dev,
* The AD4062 in burst averaging mode increases realbits from 16-bits to
* 20-bits, increasing the storagebits from 16-bits to 32-bits.
*/
-static inline size_t ad4062_sizeof_storagebits(struct ad4062_state *st)
+static inline int ad4062_sizeof_storagebits(struct ad4062_state *st)
{
const struct iio_scan_type *scan_type =
iio_get_current_scan_type(st->indio_dev, st->chip->channels);
+ if (IS_ERR(scan_type))
+ return PTR_ERR(scan_type);
+
return BITS_TO_BYTES(scan_type->storagebits);
}
@@ -1233,7 +1236,12 @@ static int pm_ad4062_triggered_buffer_postenable(struct ad4062_state *st)
if (ret)
return ret;
- st->conv_sizeof = ad4062_sizeof_storagebits(st);
+ ret = ad4062_sizeof_storagebits(st);
+ if (ret < 0)
+ return ret;
+
+ st->conv_sizeof = ret;
+
st->conv_addr = ad4062_get_conv_addr(st, st->conv_sizeof);
/* CONV_READ requires read to trigger first sample. */
struct i3c_xfer xfer_sample[2] = {
diff --git a/drivers/iio/adc/ad4080.c b/drivers/iio/adc/ad4080.c
index 7cf3b6ed7940..204ad198342b 100644
--- a/drivers/iio/adc/ad4080.c
+++ b/drivers/iio/adc/ad4080.c
@@ -127,10 +127,13 @@
#define AD4080_SPI_READ BIT(7)
#define AD4080_CHIP_ID 0x0050
#define AD4081_CHIP_ID 0x0051
+#define AD4082_CHIP_ID 0x0052
#define AD4083_CHIP_ID 0x0053
#define AD4084_CHIP_ID 0x0054
+#define AD4085_CHIP_ID 0x0055
#define AD4086_CHIP_ID 0x0056
#define AD4087_CHIP_ID 0x0057
+#define AD4088_CHIP_ID 0x0058
#define AD4080_LVDS_CNV_CLK_CNT_MAX 7
@@ -185,7 +188,6 @@ struct ad4080_state {
*/
struct mutex lock;
unsigned int num_lanes;
- unsigned int dec_rate;
unsigned long clk_rate;
enum ad4080_filter_type filter_type;
bool lvds_cnv_en;
@@ -442,14 +444,20 @@ static const struct iio_chan_spec ad4080_channel = AD4080_CHANNEL_DEFINE(20, 32)
static const struct iio_chan_spec ad4081_channel = AD4080_CHANNEL_DEFINE(20, 32);
+static const struct iio_chan_spec ad4082_channel = AD4080_CHANNEL_DEFINE(20, 32);
+
static const struct iio_chan_spec ad4083_channel = AD4080_CHANNEL_DEFINE(16, 16);
static const struct iio_chan_spec ad4084_channel = AD4080_CHANNEL_DEFINE(16, 16);
+static const struct iio_chan_spec ad4085_channel = AD4080_CHANNEL_DEFINE(16, 16);
+
static const struct iio_chan_spec ad4086_channel = AD4080_CHANNEL_DEFINE(14, 16);
static const struct iio_chan_spec ad4087_channel = AD4080_CHANNEL_DEFINE(14, 16);
+static const struct iio_chan_spec ad4088_channel = AD4080_CHANNEL_DEFINE(14, 16);
+
static const struct ad4080_chip_info ad4080_chip_info = {
.name = "ad4080",
.product_id = AD4080_CHIP_ID,
@@ -470,6 +478,16 @@ static const struct ad4080_chip_info ad4081_chip_info = {
.lvds_cnv_clk_cnt_max = 2,
};
+static const struct ad4080_chip_info ad4082_chip_info = {
+ .name = "ad4082",
+ .product_id = AD4082_CHIP_ID,
+ .scale_table = ad4080_scale_table,
+ .num_scales = ARRAY_SIZE(ad4080_scale_table),
+ .num_channels = 1,
+ .channels = &ad4082_channel,
+ .lvds_cnv_clk_cnt_max = 8,
+};
+
static const struct ad4080_chip_info ad4083_chip_info = {
.name = "ad4083",
.product_id = AD4083_CHIP_ID,
@@ -490,6 +508,16 @@ static const struct ad4080_chip_info ad4084_chip_info = {
.lvds_cnv_clk_cnt_max = 2,
};
+static const struct ad4080_chip_info ad4085_chip_info = {
+ .name = "ad4085",
+ .product_id = AD4085_CHIP_ID,
+ .scale_table = ad4080_scale_table,
+ .num_scales = ARRAY_SIZE(ad4080_scale_table),
+ .num_channels = 1,
+ .channels = &ad4085_channel,
+ .lvds_cnv_clk_cnt_max = 8,
+};
+
static const struct ad4080_chip_info ad4086_chip_info = {
.name = "ad4086",
.product_id = AD4086_CHIP_ID,
@@ -510,6 +538,16 @@ static const struct ad4080_chip_info ad4087_chip_info = {
.lvds_cnv_clk_cnt_max = 1,
};
+static const struct ad4080_chip_info ad4088_chip_info = {
+ .name = "ad4088",
+ .product_id = AD4088_CHIP_ID,
+ .scale_table = ad4080_scale_table,
+ .num_scales = ARRAY_SIZE(ad4080_scale_table),
+ .num_channels = 1,
+ .channels = &ad4088_channel,
+ .lvds_cnv_clk_cnt_max = 8,
+};
+
static int ad4080_setup(struct iio_dev *indio_dev)
{
struct ad4080_state *st = iio_priv(indio_dev);
@@ -666,10 +704,13 @@ static int ad4080_probe(struct spi_device *spi)
static const struct spi_device_id ad4080_id[] = {
{ "ad4080", (kernel_ulong_t)&ad4080_chip_info },
{ "ad4081", (kernel_ulong_t)&ad4081_chip_info },
+ { "ad4082", (kernel_ulong_t)&ad4082_chip_info },
{ "ad4083", (kernel_ulong_t)&ad4083_chip_info },
{ "ad4084", (kernel_ulong_t)&ad4084_chip_info },
+ { "ad4085", (kernel_ulong_t)&ad4085_chip_info },
{ "ad4086", (kernel_ulong_t)&ad4086_chip_info },
{ "ad4087", (kernel_ulong_t)&ad4087_chip_info },
+ { "ad4088", (kernel_ulong_t)&ad4088_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ad4080_id);
@@ -677,10 +718,13 @@ MODULE_DEVICE_TABLE(spi, ad4080_id);
static const struct of_device_id ad4080_of_match[] = {
{ .compatible = "adi,ad4080", &ad4080_chip_info },
{ .compatible = "adi,ad4081", &ad4081_chip_info },
+ { .compatible = "adi,ad4082", &ad4082_chip_info },
{ .compatible = "adi,ad4083", &ad4083_chip_info },
{ .compatible = "adi,ad4084", &ad4084_chip_info },
+ { .compatible = "adi,ad4085", &ad4085_chip_info },
{ .compatible = "adi,ad4086", &ad4086_chip_info },
{ .compatible = "adi,ad4087", &ad4087_chip_info },
+ { .compatible = "adi,ad4088", &ad4088_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ad4080_of_match);
diff --git a/drivers/iio/adc/ad4170-4.c b/drivers/iio/adc/ad4170-4.c
index 82205bfae531..77af0e6b2c59 100644
--- a/drivers/iio/adc/ad4170-4.c
+++ b/drivers/iio/adc/ad4170-4.c
@@ -275,9 +275,9 @@ static const unsigned int ad4170_reg_size[] = {
};
enum ad4170_ref_buf {
- AD4170_REF_BUF_PRE, /* Pre-charge referrence buffer */
- AD4170_REF_BUF_FULL, /* Full referrence buffering */
- AD4170_REF_BUF_BYPASS, /* Bypass referrence buffering */
+ AD4170_REF_BUF_PRE, /* Pre-charge reference buffer */
+ AD4170_REF_BUF_FULL, /* Full reference buffering */
+ AD4170_REF_BUF_BYPASS, /* Bypass reference buffering */
};
/* maps adi,positive/negative-reference-buffer property values to enum */
diff --git a/drivers/iio/adc/ad7173.c b/drivers/iio/adc/ad7173.c
index d36612352b44..f76a9e08f39e 100644
--- a/drivers/iio/adc/ad7173.c
+++ b/drivers/iio/adc/ad7173.c
@@ -1763,7 +1763,8 @@ static int ad7173_validate_openwire_ain_inputs(struct ad7173_state *st,
static unsigned int ad7173_calc_openwire_thrsh_raw(struct ad7173_state *st,
struct iio_chan_spec *chan,
struct ad7173_channel *chan_st_priv,
- unsigned int thrsh_mv) {
+ unsigned int thrsh_mv)
+{
unsigned int thrsh_raw;
thrsh_raw =
diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c
index 530e1d307860..8b1664f6b102 100644
--- a/drivers/iio/adc/ad7192.c
+++ b/drivers/iio/adc/ad7192.c
@@ -1402,9 +1402,6 @@ static int ad7192_probe(struct spi_device *spi)
st->int_vref_mv = ret == -ENODEV ? avdd_mv : ret / MILLI;
st->chip_info = spi_get_device_match_data(spi);
- if (!st->chip_info)
- return -ENODEV;
-
indio_dev->name = st->chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = st->chip_info->info;
diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
index 3364ac6c4631..0ef36c249ab8 100644
--- a/drivers/iio/adc/ad7266.c
+++ b/drivers/iio/adc/ad7266.c
@@ -409,10 +409,8 @@ static int ad7266_probe(struct spi_device *spi)
st->gpios[i] = devm_gpiod_get(&spi->dev,
ad7266_gpio_labels[i],
GPIOD_OUT_LOW);
- if (IS_ERR(st->gpios[i])) {
- ret = PTR_ERR(st->gpios[i]);
- return ret;
- }
+ if (IS_ERR(st->gpios[i]))
+ return PTR_ERR(st->gpios[i]);
}
}
} else {
diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
index bfd908deefc0..9f77990a03f9 100644
--- a/drivers/iio/adc/ad7380.c
+++ b/drivers/iio/adc/ad7380.c
@@ -77,8 +77,7 @@
#define AD7380_CONFIG1_REFSEL BIT(1)
#define AD7380_CONFIG1_PMODE BIT(0)
-#define AD7380_CONFIG2_SDO2 GENMASK(9, 8)
-#define AD7380_CONFIG2_SDO BIT(8)
+#define AD7380_CONFIG2_SDO GENMASK(9, 8)
#define AD7380_CONFIG2_RESET GENMASK(7, 0)
#define AD7380_CONFIG2_RESET_SOFT 0x3C
@@ -92,11 +91,6 @@
#define T_CONVERT_X_NS 500 /* xth conversion start time (oversampling) */
#define T_POWERUP_US 5000 /* Power up */
-/*
- * AD738x support several SDO lines to increase throughput, but driver currently
- * supports only 1 SDO line (standard SPI transaction)
- */
-#define AD7380_NUM_SDO_LINES 1
#define AD7380_DEFAULT_GAIN_MILLI 1000
/*
@@ -888,6 +882,8 @@ struct ad7380_state {
bool resolution_boost_enabled;
unsigned int ch;
bool seq;
+ /* How many SDO lines are wired up. */
+ u8 num_sdo_lines;
unsigned int vref_mv;
unsigned int vcm_mv[MAX_NUM_CHANNELS];
unsigned int gain_milli[MAX_NUM_CHANNELS];
@@ -1084,7 +1080,7 @@ static int ad7380_set_ch(struct ad7380_state *st, unsigned int ch)
if (oversampling_ratio > 1)
xfer.delay.value = T_CONVERT_0_NS +
T_CONVERT_X_NS * (oversampling_ratio - 1) *
- st->chip_info->num_simult_channels / AD7380_NUM_SDO_LINES;
+ st->chip_info->num_simult_channels / st->num_sdo_lines;
return spi_sync_transfer(st->spi, &xfer, 1);
}
@@ -1113,7 +1109,7 @@ static int ad7380_update_xfers(struct ad7380_state *st,
if (oversampling_ratio > 1)
t_convert = T_CONVERT_0_NS + T_CONVERT_X_NS *
(oversampling_ratio - 1) *
- st->chip_info->num_simult_channels / AD7380_NUM_SDO_LINES;
+ st->chip_info->num_simult_channels / st->num_sdo_lines;
if (st->seq) {
xfer[0].delay.value = xfer[1].delay.value = t_convert;
@@ -1198,6 +1194,8 @@ static int ad7380_init_offload_msg(struct ad7380_state *st,
xfer->bits_per_word = scan_type->realbits;
xfer->offload_flags = SPI_OFFLOAD_XFER_RX_STREAM;
xfer->len = AD7380_SPI_BYTES(scan_type) * st->chip_info->num_simult_channels;
+ if (st->num_sdo_lines > 1)
+ xfer->multi_lane_mode = SPI_MULTI_LANE_MODE_STRIPE;
spi_message_init_with_transfers(&st->offload_msg, xfer, 1);
st->offload_msg.offload = st->offload;
@@ -1793,6 +1791,7 @@ static const struct iio_info ad7380_info = {
static int ad7380_init(struct ad7380_state *st, bool external_ref_en)
{
+ u32 sdo;
int ret;
/* perform hard reset */
@@ -1815,11 +1814,24 @@ static int ad7380_init(struct ad7380_state *st, bool external_ref_en)
st->ch = 0;
st->seq = false;
- /* SPI 1-wire mode */
+ /* SDO field has an irregular mapping. */
+ switch (st->num_sdo_lines) {
+ case 1:
+ sdo = 1;
+ break;
+ case 2:
+ sdo = 0;
+ break;
+ case 4:
+ sdo = 2;
+ break;
+ default:
+ return -EINVAL;
+ }
+
return regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2,
AD7380_CONFIG2_SDO,
- FIELD_PREP(AD7380_CONFIG2_SDO,
- AD7380_NUM_SDO_LINES));
+ FIELD_PREP(AD7380_CONFIG2_SDO, sdo));
}
static int ad7380_probe_spi_offload(struct iio_dev *indio_dev,
@@ -1842,7 +1854,7 @@ static int ad7380_probe_spi_offload(struct iio_dev *indio_dev,
"failed to get offload trigger\n");
sample_rate = st->chip_info->max_conversion_rate_hz *
- AD7380_NUM_SDO_LINES / st->chip_info->num_simult_channels;
+ st->num_sdo_lines / st->chip_info->num_simult_channels;
st->sample_freq_range[0] = 1; /* min */
st->sample_freq_range[1] = 1; /* step */
@@ -1850,7 +1862,7 @@ static int ad7380_probe_spi_offload(struct iio_dev *indio_dev,
/*
* Starting with a quite low frequency, to allow oversampling x32,
- * user is then reponsible to adjust the frequency for the specific case.
+ * user is then responsible to adjust the frequency for the specific case.
*/
ret = ad7380_set_sample_freq(st, sample_rate / 32);
if (ret)
@@ -1887,6 +1899,13 @@ static int ad7380_probe(struct spi_device *spi)
if (!st->chip_info)
return dev_err_probe(dev, -EINVAL, "missing match data\n");
+ st->num_sdo_lines = spi->num_rx_lanes;
+
+ if (st->num_sdo_lines < 1 || st->num_sdo_lines > st->chip_info->num_simult_channels)
+ return dev_err_probe(dev, -EINVAL,
+ "invalid number of SDO lines (%d)\n",
+ st->num_sdo_lines);
+
ret = devm_regulator_bulk_get_enable(dev, st->chip_info->num_supplies,
st->chip_info->supplies);
@@ -2010,6 +2029,8 @@ static int ad7380_probe(struct spi_device *spi)
st->normal_xfer[0].cs_change_delay.value = st->chip_info->timing_specs->t_csh_ns;
st->normal_xfer[0].cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
st->normal_xfer[1].rx_buf = st->scan_data;
+ if (st->num_sdo_lines > 1)
+ st->normal_xfer[1].multi_lane_mode = SPI_MULTI_LANE_MODE_STRIPE;
spi_message_init_with_transfers(&st->normal_msg, st->normal_xfer,
ARRAY_SIZE(st->normal_xfer));
@@ -2031,6 +2052,10 @@ static int ad7380_probe(struct spi_device *spi)
st->seq_xfer[2].cs_change = 1;
st->seq_xfer[2].cs_change_delay.value = st->chip_info->timing_specs->t_csh_ns;
st->seq_xfer[2].cs_change_delay.unit = SPI_DELAY_UNIT_NSECS;
+ if (st->num_sdo_lines > 1) {
+ st->seq_xfer[2].multi_lane_mode = SPI_MULTI_LANE_MODE_STRIPE;
+ st->seq_xfer[3].multi_lane_mode = SPI_MULTI_LANE_MODE_STRIPE;
+ }
spi_message_init_with_transfers(&st->seq_msg, st->seq_xfer,
ARRAY_SIZE(st->seq_xfer));
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c
index e16dede687d3..73fb734d06b2 100644
--- a/drivers/iio/adc/ad7768-1.c
+++ b/drivers/iio/adc/ad7768-1.c
@@ -25,12 +25,15 @@
#include <linux/regulator/consumer.h>
#include <linux/regulator/driver.h>
#include <linux/sysfs.h>
+#include <linux/spi/offload/consumer.h>
+#include <linux/spi/offload/provider.h>
#include <linux/spi/spi.h>
#include <linux/unaligned.h>
#include <linux/units.h>
#include <linux/util_macros.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/buffer-dmaengine.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
@@ -161,6 +164,8 @@ enum ad7768_filter_regval {
enum ad7768_scan_type {
AD7768_SCAN_TYPE_NORMAL,
AD7768_SCAN_TYPE_HIGH_SPEED,
+ AD7768_SCAN_TYPE_OFFLOAD_NORMAL,
+ AD7768_SCAN_TYPE_OFFLOAD_HIGH_SPEED,
};
enum {
@@ -266,6 +271,18 @@ static const struct iio_scan_type ad7768_scan_type[] = {
.storagebits = 16,
.endianness = IIO_BE,
},
+ [AD7768_SCAN_TYPE_OFFLOAD_NORMAL] = {
+ .sign = 's',
+ .realbits = 24,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ },
+ [AD7768_SCAN_TYPE_OFFLOAD_HIGH_SPEED] = {
+ .sign = 's',
+ .realbits = 16,
+ .storagebits = 32,
+ .endianness = IIO_CPU,
+ },
};
struct ad7768_chip_info {
@@ -283,6 +300,8 @@ struct ad7768_chip_info {
struct ad7768_state {
struct spi_device *spi;
+ struct spi_offload *offload;
+ struct spi_offload_trigger *offload_trigger;
struct regmap *regmap;
struct regmap *regmap24;
int vref_uv;
@@ -290,7 +309,6 @@ struct ad7768_state {
unsigned int vcm_output_sel;
struct clk *mclk;
unsigned int mclk_freq;
- unsigned int mclk_div;
unsigned int oversampling_ratio;
enum ad7768_filter_type filter_type;
unsigned int samp_freq;
@@ -306,6 +324,8 @@ struct ad7768_state {
struct gpio_desc *gpio_reset;
const char *labels[AD7768_MAX_CHANNELS];
struct gpio_chip gpiochip;
+ struct spi_transfer offload_xfer;
+ struct spi_message offload_msg;
const struct ad7768_chip_info *chip;
bool en_spi_sync;
struct mutex pga_lock; /* protect device internal state (PGA) */
@@ -464,13 +484,11 @@ static int ad7768_scan_direct(struct iio_dev *indio_dev)
int readval, ret;
reinit_completion(&st->completion);
-
- ret = ad7768_set_mode(st, AD7768_ONE_SHOT);
- if (ret < 0)
- return ret;
+ enable_irq(st->spi->irq);
ret = wait_for_completion_timeout(&st->completion,
msecs_to_jiffies(1000));
+ disable_irq(st->spi->irq);
if (!ret)
return -ETIMEDOUT;
@@ -487,14 +505,6 @@ static int ad7768_scan_direct(struct iio_dev *indio_dev)
if (st->oversampling_ratio == 8)
readval >>= 8;
- /*
- * Any SPI configuration of the AD7768-1 can only be
- * performed in continuous conversion mode.
- */
- ret = ad7768_set_mode(st, AD7768_CONTINUOUS);
- if (ret < 0)
- return ret;
-
return readval;
}
@@ -1138,6 +1148,10 @@ static int ad7768_get_current_scan_type(const struct iio_dev *indio_dev,
{
struct ad7768_state *st = iio_priv(indio_dev);
+ if (st->offload)
+ return st->oversampling_ratio == 8 ?
+ AD7768_SCAN_TYPE_OFFLOAD_HIGH_SPEED : AD7768_SCAN_TYPE_OFFLOAD_NORMAL;
+
return st->oversampling_ratio == 8 ?
AD7768_SCAN_TYPE_HIGH_SPEED : AD7768_SCAN_TYPE_NORMAL;
}
@@ -1252,6 +1266,10 @@ static int ad7768_setup(struct iio_dev *indio_dev)
return ret;
}
+ ret = ad7768_set_mode(st, AD7768_CONTINUOUS);
+ if (ret)
+ return ret;
+
/* For backwards compatibility, try the adi,sync-in-gpios property */
st->gpio_sync_in = devm_gpiod_get_optional(&st->spi->dev, "adi,sync-in",
GPIOD_OUT_LOW);
@@ -1356,8 +1374,94 @@ static const struct iio_buffer_setup_ops ad7768_buffer_ops = {
.predisable = &ad7768_buffer_predisable,
};
+static int ad7768_offload_buffer_postenable(struct iio_dev *indio_dev)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+ struct spi_offload_trigger_config config = {
+ .type = SPI_OFFLOAD_TRIGGER_DATA_READY,
+ };
+ const struct iio_scan_type *scan_type;
+ unsigned int unused;
+ int ret;
+
+ scan_type = iio_get_current_scan_type(indio_dev, &indio_dev->channels[0]);
+ if (IS_ERR(scan_type))
+ return PTR_ERR(scan_type);
+
+ st->offload_xfer.len = spi_bpw_to_bytes(scan_type->realbits);
+ st->offload_xfer.bits_per_word = scan_type->realbits;
+ st->offload_xfer.offload_flags = SPI_OFFLOAD_XFER_RX_STREAM;
+
+ spi_message_init_with_transfers(&st->offload_msg, &st->offload_xfer, 1);
+ st->offload_msg.offload = st->offload;
+
+ ret = spi_optimize_message(st->spi, &st->offload_msg);
+ if (ret) {
+ dev_err(&st->spi->dev, "failed to prepare offload, err: %d\n", ret);
+ return ret;
+ }
+
+ /*
+ * Write a 1 to the LSB of the INTERFACE_FORMAT register to enter
+ * continuous read mode. Subsequent data reads do not require an
+ * initial 8-bit write to query the ADC_DATA register.
+ */
+ ret = regmap_write(st->regmap, AD7768_REG_INTERFACE_FORMAT, 0x01);
+ if (ret)
+ goto err_unoptimize_message;
+
+ ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
+ &config);
+ if (ret)
+ goto err_exit_continuous_read_mode;
+
+ return 0;
+
+err_exit_continuous_read_mode:
+ regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &unused);
+
+err_unoptimize_message:
+ spi_unoptimize_message(&st->offload_msg);
+
+ return ret;
+}
+
+static int ad7768_offload_buffer_predisable(struct iio_dev *indio_dev)
+{
+ struct ad7768_state *st = iio_priv(indio_dev);
+ unsigned int unused;
+
+ spi_offload_trigger_disable(st->offload, st->offload_trigger);
+ spi_unoptimize_message(&st->offload_msg);
+
+ /*
+ * To exit continuous read mode, perform a single read of the ADC_DATA
+ * reg (0x2C), which allows further configuration of the device.
+ */
+ return regmap_read(st->regmap24, AD7768_REG24_ADC_DATA, &unused);
+}
+
+static const struct iio_buffer_setup_ops ad7768_offload_buffer_ops = {
+ .postenable = ad7768_offload_buffer_postenable,
+ .predisable = ad7768_offload_buffer_predisable,
+};
+
+static int ad7768_set_trigger_state(struct iio_trigger *trig, bool enable)
+{
+ struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+ struct ad7768_state *st = iio_priv(indio_dev);
+
+ if (enable)
+ enable_irq(st->spi->irq);
+ else
+ disable_irq(st->spi->irq);
+
+ return 0;
+}
+
static const struct iio_trigger_ops ad7768_trigger_ops = {
.validate_device = iio_trigger_validate_own_device,
+ .set_trigger_state = ad7768_set_trigger_state,
};
static int ad7768_set_channel_label(struct iio_dev *indio_dev,
@@ -1590,6 +1694,36 @@ static int ad7768_parse_aaf_gain(struct device *dev, struct ad7768_state *st)
return 0;
}
+static bool ad7768_offload_trigger_match(struct spi_offload_trigger *trigger,
+ enum spi_offload_trigger_type type,
+ u64 *args, u32 nargs)
+{
+ if (type != SPI_OFFLOAD_TRIGGER_DATA_READY)
+ return false;
+
+ /* Up to 2 args are allowed, but only 1 is used */
+ if (nargs == 0 || nargs > 2 || args[0] != AD7768_TRIGGER_SOURCE_DRDY)
+ return false;
+
+ return true;
+}
+
+static int ad7768_offload_trigger_request(struct spi_offload_trigger *trigger,
+ enum spi_offload_trigger_type type,
+ u64 *args, u32 nargs)
+{
+ /* Should already be validated by match, but just in case */
+ if (nargs == 0 || nargs > 2)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct spi_offload_trigger_ops ad7768_offload_trigger_ops = {
+ .match = ad7768_offload_trigger_match,
+ .request = ad7768_offload_trigger_request,
+};
+
static const struct ad7768_chip_info ad7768_chip_info = {
.name = "ad7768-1",
.channel_spec = ad7768_channels,
@@ -1627,10 +1761,51 @@ static const struct ad7768_chip_info adaq7769_chip_info = {
.has_variable_aaf = true,
};
+static const struct spi_offload_config ad7768_spi_offload_config = {
+ .capability_flags = SPI_OFFLOAD_CAP_TRIGGER | SPI_OFFLOAD_CAP_RX_STREAM_DMA,
+};
+
+static int ad7768_spi_offload_probe(struct iio_dev *indio_dev,
+ struct ad7768_state *st)
+{
+ struct device *dev = &st->spi->dev;
+ struct spi_offload_trigger_info trigger_info = {
+ .fwnode = dev_fwnode(dev),
+ .ops = &ad7768_offload_trigger_ops,
+ .priv = st,
+ };
+ struct dma_chan *rx_dma;
+ int ret;
+
+ ret = devm_spi_offload_trigger_register(dev, &trigger_info);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register offload trigger\n");
+
+ st->offload_trigger = devm_spi_offload_trigger_get(dev, st->offload,
+ SPI_OFFLOAD_TRIGGER_DATA_READY);
+ if (IS_ERR(st->offload_trigger))
+ return dev_err_probe(dev, PTR_ERR(st->offload_trigger),
+ "failed to get offload trigger\n");
+
+ rx_dma = devm_spi_offload_rx_stream_request_dma_chan(dev, st->offload);
+ if (IS_ERR(rx_dma))
+ return dev_err_probe(dev, PTR_ERR(rx_dma), "failed to get offload RX DMA\n");
+
+ ret = devm_iio_dmaengine_buffer_setup_with_handle(dev, indio_dev, rx_dma,
+ IIO_BUFFER_DIRECTION_IN);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to setup offload RX DMA\n");
+
+ indio_dev->setup_ops = &ad7768_offload_buffer_ops;
+
+ return 0;
+}
+
static int ad7768_probe(struct spi_device *spi)
{
struct ad7768_state *st;
struct iio_dev *indio_dev;
+ struct device *dev = &spi->dev;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
@@ -1721,14 +1896,25 @@ static int ad7768_probe(struct spi_device *spi)
return ret;
ret = devm_request_irq(&spi->dev, spi->irq, &ad7768_interrupt,
- IRQF_TRIGGER_RISING | IRQF_NO_THREAD,
+ IRQF_TRIGGER_RISING | IRQF_NO_THREAD | IRQF_NO_AUTOEN,
indio_dev->name, indio_dev);
if (ret)
return ret;
- ret = ad7768_triggered_buffer_alloc(indio_dev);
- if (ret)
- return ret;
+ st->offload = devm_spi_offload_get(dev, spi, &ad7768_spi_offload_config);
+ ret = PTR_ERR_OR_ZERO(st->offload);
+ if (ret == -ENODEV) {
+ /* If not using SPI offload, fall back to low speed usage */
+ ret = ad7768_triggered_buffer_alloc(indio_dev);
+ if (ret)
+ return ret;
+ } else if (ret) {
+ return dev_err_probe(dev, ret, "failed to get SPI offload\n");
+ } else {
+ ret = ad7768_spi_offload_probe(indio_dev, st);
+ if (ret)
+ return ret;
+ }
return devm_iio_device_register(&spi->dev, indio_dev);
}
@@ -1764,3 +1950,4 @@ module_spi_driver(ad7768_driver);
MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
MODULE_DESCRIPTION("Analog Devices AD7768-1 ADC driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("IIO_DMAENGINE_BUFFER");
diff --git a/drivers/iio/adc/ad7793.c b/drivers/iio/adc/ad7793.c
index ccf18ce48e34..8ff7b70d6632 100644
--- a/drivers/iio/adc/ad7793.c
+++ b/drivers/iio/adc/ad7793.c
@@ -152,7 +152,6 @@ struct ad7793_chip_info {
struct ad7793_state {
const struct ad7793_chip_info *chip_info;
- u16 int_vref_mv;
u16 mode;
u16 conf;
u32 scale_avail[8][2];
@@ -805,7 +804,7 @@ static int ad7793_probe(struct spi_device *spi)
vref_mv = ret / 1000;
} else {
- vref_mv = 1170; /* Build-in ref */
+ vref_mv = 1170; /* Built-in ref */
}
st->chip_info =
diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c
index 87ff95643794..068171d54596 100644
--- a/drivers/iio/adc/ad7887.c
+++ b/drivers/iio/adc/ad7887.c
@@ -104,7 +104,7 @@ static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
{
struct ad7887_state *st = iio_priv(indio_dev);
- /* dummy read: restore default CH0 settin */
+ /* dummy read: restore default CH0 settings */
return spi_sync(st->spi, &st->msg[AD7887_CH0]);
}
diff --git a/drivers/iio/adc/ad7923.c b/drivers/iio/adc/ad7923.c
index 0369151c7db1..acc87d486aa4 100644
--- a/drivers/iio/adc/ad7923.c
+++ b/drivers/iio/adc/ad7923.c
@@ -30,7 +30,7 @@
#define AD7923_PM_MODE_AS (1) /* auto shutdown */
#define AD7923_PM_MODE_FS (2) /* full shutdown */
#define AD7923_PM_MODE_OPS (3) /* normal operation */
-#define AD7923_SEQUENCE_OFF (0) /* no sequence fonction */
+#define AD7923_SEQUENCE_OFF (0) /* no sequence function */
#define AD7923_SEQUENCE_PROTECT (2) /* no interrupt write cycle */
#define AD7923_SEQUENCE_ON (3) /* continuous sequence */
@@ -39,7 +39,7 @@
#define AD7923_CHANNEL_WRITE(channel) ((channel) << 6) /* write channel */
#define AD7923_SEQUENCE_WRITE(sequence) ((((sequence) & 1) << 3) \
+ (((sequence) & 2) << 9))
- /* write sequence fonction */
+ /* write sequence function */
/* left shift for CR : bit 11 transmit in first */
#define AD7923_SHIFT_REGISTER 4
diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
index 022888545580..0bf67437508f 100644
--- a/drivers/iio/adc/ad9467.c
+++ b/drivers/iio/adc/ad9467.c
@@ -176,7 +176,6 @@ struct ad9467_state {
struct clk *clk;
/* used for debugfs */
struct ad9467_chan_test_mode *chan_test;
- unsigned int output_mode;
unsigned int (*scales)[2];
/*
* Times 2 because we may also invert the signal polarity and run the
@@ -925,7 +924,11 @@ static int __ad9467_update_clock(struct ad9467_state *st, long r_clk)
return ret;
guard(mutex)(&st->lock);
- return ad9467_calibrate(st);
+
+ if (iio_backend_has_caps(st->back, IIO_BACKEND_CAP_CALIBRATION))
+ return ad9467_calibrate(st);
+
+ return 0;
}
static int ad9467_write_raw(struct iio_dev *indio_dev,
@@ -1131,12 +1134,15 @@ static ssize_t ad9467_chan_test_mode_read(struct file *file,
len = scnprintf(buf, sizeof(buf), "Running \"%s\" Test:\n\t",
ad9467_test_modes[chan->mode]);
- ret = iio_backend_debugfs_print_chan_status(st->back, chan->idx,
- buf + len,
- sizeof(buf) - len);
- if (ret < 0)
- return ret;
- len += ret;
+ if (iio_backend_has_caps(st->back, IIO_BACKEND_CAP_CALIBRATION)) {
+ ret = iio_backend_debugfs_print_chan_status(st->back,
+ chan->idx,
+ buf + len,
+ sizeof(buf) - len);
+ if (ret < 0)
+ return ret;
+ len += ret;
+ }
} else if (chan->mode == AN877_ADC_TESTMODE_OFF) {
len = scnprintf(buf, sizeof(buf), "No test Running...\n");
} else {
@@ -1175,11 +1181,13 @@ static ssize_t ad9467_chan_test_mode_write(struct file *file,
if (mode == AN877_ADC_TESTMODE_OFF) {
unsigned int out_mode;
- if (chan->mode == AN877_ADC_TESTMODE_PN9_SEQ ||
- chan->mode == AN877_ADC_TESTMODE_PN23_SEQ) {
- ret = ad9467_backend_testmode_off(st, chan->idx);
- if (ret)
- return ret;
+ if (iio_backend_has_caps(st->back, IIO_BACKEND_CAP_CALIBRATION)) {
+ if (chan->mode == AN877_ADC_TESTMODE_PN9_SEQ ||
+ chan->mode == AN877_ADC_TESTMODE_PN23_SEQ) {
+ ret = ad9467_backend_testmode_off(st, chan->idx);
+ if (ret)
+ return ret;
+ }
}
ret = ad9467_testmode_set(st, chan->idx, mode);
@@ -1205,16 +1213,18 @@ static ssize_t ad9467_chan_test_mode_write(struct file *file,
return ret;
/* some patterns have a backend matching monitoring block */
- if (mode == AN877_ADC_TESTMODE_PN9_SEQ) {
- ret = ad9467_backend_testmode_on(st, chan->idx,
+ if (iio_backend_has_caps(st->back, IIO_BACKEND_CAP_CALIBRATION)) {
+ if (mode == AN877_ADC_TESTMODE_PN9_SEQ) {
+ ret = ad9467_backend_testmode_on(st, chan->idx,
IIO_BACKEND_ADI_PRBS_9A);
- if (ret)
- return ret;
- } else if (mode == AN877_ADC_TESTMODE_PN23_SEQ) {
- ret = ad9467_backend_testmode_on(st, chan->idx,
+ if (ret)
+ return ret;
+ } else if (mode == AN877_ADC_TESTMODE_PN23_SEQ) {
+ ret = ad9467_backend_testmode_on(st, chan->idx,
IIO_BACKEND_ADI_PRBS_23A);
- if (ret)
- return ret;
+ if (ret)
+ return ret;
+ }
}
}
@@ -1280,8 +1290,9 @@ static void ad9467_debugfs_init(struct iio_dev *indio_dev)
if (!st->chan_test)
return;
- debugfs_create_file("calibration_table_dump", 0400, d, st,
- &ad9467_calib_table_fops);
+ if (iio_backend_has_caps(st->back, IIO_BACKEND_CAP_CALIBRATION))
+ debugfs_create_file("calibration_table_dump", 0400, d, st,
+ &ad9467_calib_table_fops);
for (chan = 0; chan < st->info->num_channels; chan++) {
snprintf(attr_name, sizeof(attr_name), "in_voltage%u_test_mode",
@@ -1300,12 +1311,13 @@ static void ad9467_debugfs_init(struct iio_dev *indio_dev)
static int ad9467_probe(struct spi_device *spi)
{
+ struct device *dev = &spi->dev;
struct iio_dev *indio_dev;
struct ad9467_state *st;
unsigned int id;
int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@@ -1320,16 +1332,15 @@ static int ad9467_probe(struct spi_device *spi)
if (AD9467_CAN_INVERT(st))
st->calib_map_size *= 2;
- st->clk = devm_clk_get_enabled(&spi->dev, "adc-clk");
+ st->clk = devm_clk_get_enabled(dev, "adc-clk");
if (IS_ERR(st->clk))
return PTR_ERR(st->clk);
- st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown",
- GPIOD_OUT_LOW);
+ st->pwrdown_gpio = devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_LOW);
if (IS_ERR(st->pwrdown_gpio))
return PTR_ERR(st->pwrdown_gpio);
- ret = ad9467_reset(&spi->dev);
+ ret = ad9467_reset(dev);
if (ret)
return ret;
@@ -1339,7 +1350,7 @@ static int ad9467_probe(struct spi_device *spi)
id = ad9467_spi_read(st, AN877_ADC_REG_CHIP_ID);
if (id != st->info->id) {
- dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n",
+ dev_err(dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n",
id, st->info->id);
return -ENODEV;
}
@@ -1356,19 +1367,25 @@ static int ad9467_probe(struct spi_device *spi)
if (ret)
return ret;
- ret = devm_iio_backend_request_buffer(&spi->dev, st->back, indio_dev);
- if (ret)
- return ret;
+ if (iio_backend_has_caps(st->back, IIO_BACKEND_CAP_BUFFER)) {
+ ret = devm_iio_backend_request_buffer(dev, st->back, indio_dev);
+ if (ret)
+ return ret;
+ }
- ret = devm_iio_backend_enable(&spi->dev, st->back);
- if (ret)
- return ret;
+ if (iio_backend_has_caps(st->back, IIO_BACKEND_CAP_ENABLE)) {
+ ret = devm_iio_backend_enable(dev, st->back);
+ if (ret)
+ return ret;
+ }
- ret = ad9467_calibrate(st);
- if (ret)
- return ret;
+ if (iio_backend_has_caps(st->back, IIO_BACKEND_CAP_CALIBRATION)) {
+ ret = ad9467_calibrate(st);
+ 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;
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
index 7852884703b0..a955556f9ec8 100644
--- a/drivers/iio/adc/ad_sigma_delta.c
+++ b/drivers/iio/adc/ad_sigma_delta.c
@@ -51,8 +51,10 @@
*/
void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, u8 comm)
{
- /* Some variants use the lower two bits of the communications register
- * to select the channel */
+ /*
+ * Some variants use the lower two bits of the communications register
+ * to select the channel.
+ */
sigma_delta->comm = comm & AD_SD_COMM_CHAN_MASK;
}
EXPORT_SYMBOL_NS_GPL(ad_sd_set_comm, "IIO_AD_SIGMA_DELTA");
diff --git a/drivers/iio/adc/ade9000.c b/drivers/iio/adc/ade9000.c
index db085dc5e526..c9c21fa4a28b 100644
--- a/drivers/iio/adc/ade9000.c
+++ b/drivers/iio/adc/ade9000.c
@@ -218,9 +218,6 @@
#define ADE9000_ST1_ERROR1_BIT BIT(29)
#define ADE9000_ST1_ERROR2_BIT BIT(30)
#define ADE9000_ST1_ERROR3_BIT BIT(31)
-#define ADE9000_ST_ERROR \
- (ADE9000_ST1_ERROR0 | ADE9000_ST1_ERROR1 | \
- ADE9000_ST1_ERROR2 | ADE9000_ST1_ERROR3)
#define ADE9000_ST1_CROSSING_FIRST 6
#define ADE9000_ST1_CROSSING_DEPTH 25
@@ -283,7 +280,6 @@ enum ade9000_wfb_cfg {
#define ADE9000_PHASE_C_POS_BIT BIT(6)
#define ADE9000_MAX_PHASE_NR 3
-#define AD9000_CHANNELS_PER_PHASE 10
/*
* Calculate register address for multi-phase device.
@@ -1549,7 +1545,7 @@ static int ade9000_buffer_postdisable(struct iio_dev *indio_dev)
ret = regmap_clear_bits(st->regmap, ADE9000_REG_MASK0, interrupts);
if (ret) {
- dev_err(dev, "Post-disable update maks0 fail\n");
+ dev_err(dev, "Post-disable update mask0 fail\n");
return ret;
}
@@ -1589,10 +1585,9 @@ static int ade9000_reset(struct ade9000_state *st)
/* Only wait for completion if IRQ1 is available to signal reset done */
if (fwnode_irq_get_byname(dev_fwnode(dev), "irq1") >= 0) {
if (!wait_for_completion_timeout(&st->reset_completion,
- msecs_to_jiffies(1000))) {
- dev_err(dev, "Reset timeout after 1s\n");
- return -ETIMEDOUT;
- }
+ msecs_to_jiffies(1000)))
+ return dev_err_probe(dev, -ETIMEDOUT,
+ "Reset timeout after 1s\n");
}
/* If no IRQ available, reset is already complete after the 50ms delay above */
diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
index 5f445e0de9ea..ced0a2321ecf 100644
--- a/drivers/iio/adc/adi-axi-adc.c
+++ b/drivers/iio/adc/adi-axi-adc.c
@@ -621,6 +621,8 @@ static const struct iio_backend_ops adi_axi_adc_ops = {
static const struct iio_backend_info adi_axi_adc_generic = {
.name = "axi-adc",
.ops = &adi_axi_adc_ops,
+ .caps = IIO_BACKEND_CAP_CALIBRATION | IIO_BACKEND_CAP_BUFFER |
+ IIO_BACKEND_CAP_ENABLE,
};
static const struct iio_backend_ops adi_ad485x_ops = {
@@ -645,6 +647,8 @@ static const struct iio_backend_ops adi_ad485x_ops = {
static const struct iio_backend_info axi_ad485x = {
.name = "axi-ad485x",
.ops = &adi_ad485x_ops,
+ .caps = IIO_BACKEND_CAP_CALIBRATION | IIO_BACKEND_CAP_BUFFER |
+ IIO_BACKEND_CAP_ENABLE,
};
static const struct iio_backend_ops adi_ad408x_ops = {
@@ -665,6 +669,7 @@ static const struct iio_backend_ops adi_ad408x_ops = {
static const struct iio_backend_info axi_ad408x = {
.name = "axi-ad408x",
.ops = &adi_ad408x_ops,
+ .caps = IIO_BACKEND_CAP_BUFFER | IIO_BACKEND_CAP_ENABLE,
};
static int adi_axi_adc_probe(struct platform_device *pdev)
diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c
index 4be44c524b4d..9b828a3c91da 100644
--- a/drivers/iio/adc/aspeed_adc.c
+++ b/drivers/iio/adc/aspeed_adc.c
@@ -75,6 +75,8 @@
#define ASPEED_ADC_INIT_POLLING_TIME 500
#define ASPEED_ADC_INIT_TIMEOUT 500000
+/* Battery sensing is typically on the last channel */
+#define ASPEED_ADC_BATTERY_CHANNEL 7
/*
* When the sampling rate is too high, the ADC may not have enough charging
* time, resulting in a low voltage value. Thus, the default uses a slow
@@ -121,6 +123,31 @@ struct aspeed_adc_data {
struct adc_gain battery_mode_gain;
};
+/*
+ * Enable multiple consecutive channels starting from channel 0.
+ * This creates a bitmask for channels 0 to (num_channels - 1).
+ * For example: num_channels=3 creates mask 0x0007 (channels 0,1,2)
+ */
+static inline u32 aspeed_adc_channels_mask(unsigned int num_channels)
+{
+ if (num_channels > 16)
+ return GENMASK(15, 0);
+
+ return BIT(num_channels) - 1;
+}
+
+static inline unsigned int aspeed_adc_get_active_channels(const struct aspeed_adc_data *data)
+{
+ /*
+ * For controllers with battery sensing capability, the last channel
+ * is reserved for battery sensing and should not be included in
+ * normal channel operations.
+ */
+ if (data->model_data->bat_sense_sup)
+ return data->model_data->num_channels - 1;
+ return data->model_data->num_channels;
+}
+
#define ASPEED_CHAN(_idx, _data_reg_addr) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
@@ -236,10 +263,10 @@ static int aspeed_adc_compensation(struct iio_dev *indio_dev)
ASPEED_ADC_CTRL_CHANNEL_ENABLE(0),
data->base + ASPEED_REG_ENGINE_CONTROL);
/*
- * After enable compensating sensing mode need to wait some time for ADC stable
- * Experiment result is 1ms.
+ * After enable compensating sensing mode need to wait some time for the
+ * ADC stablize. Experiment result is 1ms.
*/
- mdelay(1);
+ fsleep(1000);
for (index = 0; index < 16; index++) {
/*
@@ -285,31 +312,48 @@ static int aspeed_adc_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
- if (data->battery_sensing && chan->channel == 7) {
- adc_engine_control_reg_val =
- readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+ adc_engine_control_reg_val = readl(data->base + ASPEED_REG_ENGINE_CONTROL);
+ /*
+ * For battery sensing capable controllers, we need to enable
+ * the specific channel before reading. This is required because
+ * the battery channel may not be enabled by default.
+ */
+ if (data->model_data->bat_sense_sup &&
+ chan->channel == ASPEED_ADC_BATTERY_CHANNEL) {
+ u32 ctrl_reg = adc_engine_control_reg_val & ~ASPEED_ADC_CTRL_CHANNEL;
+
+ ctrl_reg |= ASPEED_ADC_CTRL_CHANNEL_ENABLE(chan->channel);
+ writel(ctrl_reg, data->base + ASPEED_REG_ENGINE_CONTROL);
+ /*
+ * After enable a new channel need to wait some time for ADC stable
+ * Experiment result is 1ms.
+ */
+ fsleep(1000);
+ }
+
+ if (data->battery_sensing && chan->channel == ASPEED_ADC_BATTERY_CHANNEL) {
writel(adc_engine_control_reg_val |
FIELD_PREP(ASPEED_ADC_CH7_MODE,
ASPEED_ADC_CH7_BAT) |
ASPEED_ADC_BAT_SENSING_ENABLE,
data->base + ASPEED_REG_ENGINE_CONTROL);
/*
- * After enable battery sensing mode need to wait some time for adc stable
+ * After enable battery sensing mode need to wait some time for ADC stable
* Experiment result is 1ms.
*/
- mdelay(1);
+ fsleep(1000);
*val = readw(data->base + chan->address);
*val = (*val * data->battery_mode_gain.mult) /
data->battery_mode_gain.div;
- /* Restore control register value */
- writel(adc_engine_control_reg_val,
- data->base + ASPEED_REG_ENGINE_CONTROL);
} else
*val = readw(data->base + chan->address);
+ /* Restore control register value */
+ writel(adc_engine_control_reg_val,
+ data->base + ASPEED_REG_ENGINE_CONTROL);
return IIO_VAL_INT;
case IIO_CHAN_INFO_OFFSET:
- if (data->battery_sensing && chan->channel == 7)
+ if (data->battery_sensing && chan->channel == ASPEED_ADC_BATTERY_CHANNEL)
*val = (data->cv * data->battery_mode_gain.mult) /
data->battery_mode_gain.div;
else
@@ -610,7 +654,9 @@ static int aspeed_adc_probe(struct platform_device *pdev)
/* Start all channels in normal mode. */
adc_engine_control_reg_val =
readl(data->base + ASPEED_REG_ENGINE_CONTROL);
- adc_engine_control_reg_val |= ASPEED_ADC_CTRL_CHANNEL;
+ FIELD_MODIFY(ASPEED_ADC_CTRL_CHANNEL, &adc_engine_control_reg_val,
+ aspeed_adc_channels_mask(aspeed_adc_get_active_channels(data)));
+
writel(adc_engine_control_reg_val,
data->base + ASPEED_REG_ENGINE_CONTROL);
diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index aa4ba3f5a506..255970b2e747 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -2259,7 +2259,7 @@ static int at91_adc_temp_sensor_init(struct at91_adc_state *st,
return 0;
/* Get the calibration data from NVMEM. */
- temp_calib = devm_nvmem_cell_get(dev, "temperature_calib");
+ temp_calib = nvmem_cell_get(dev, "temperature_calib");
if (IS_ERR(temp_calib)) {
ret = PTR_ERR(temp_calib);
if (ret != -ENOENT)
@@ -2268,6 +2268,7 @@ static int at91_adc_temp_sensor_init(struct at91_adc_state *st,
}
buf = nvmem_cell_read(temp_calib, &len);
+ nvmem_cell_put(temp_calib);
if (IS_ERR(buf)) {
dev_err(dev, "Failed to read calibration data!\n");
return PTR_ERR(buf);
@@ -2507,7 +2508,7 @@ static int at91_adc_suspend(struct device *dev)
at91_adc_buffer_postdisable(indio_dev);
/*
- * Do a sofware reset of the ADC before we go to suspend.
+ * Do a software reset of the ADC before we go to suspend.
* this will ensure that all pins are free from being muxed by the ADC
* and can be used by for other devices.
* Otherwise, ADC will hog them and we can't go to suspend mode.
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
index 920dd9ffd27a..6e1930f7c65d 100644
--- a/drivers/iio/adc/at91_adc.c
+++ b/drivers/iio/adc/at91_adc.c
@@ -171,7 +171,7 @@ struct at91_adc_trigger {
};
/**
- * struct at91_adc_reg_desc - Various informations relative to registers
+ * struct at91_adc_reg_desc - Various information relative to registers
* @channel_base: Base offset for the channel data registers
* @drdy_mask: Mask of the DRDY field in the relevant registers
* (Interruptions registers mostly)
@@ -231,7 +231,7 @@ struct at91_adc_state {
struct iio_trigger **trig;
bool use_external;
u32 vref_mv;
- u32 res; /* resolution used for convertions */
+ u32 res; /* resolution used for conversions */
wait_queue_head_t wq_data_avail;
const struct at91_adc_caps *caps;
@@ -304,7 +304,7 @@ static void handle_adc_eoc_trigger(int irq, struct iio_dev *idev)
}
}
-static int at91_ts_sample(struct iio_dev *idev)
+static void at91_ts_sample(struct iio_dev *idev)
{
struct at91_adc_state *st = iio_priv(idev);
unsigned int xscale, yscale, reg, z1, z2;
@@ -323,7 +323,7 @@ static int at91_ts_sample(struct iio_dev *idev)
xscale = (reg >> 16) & xyz_mask;
if (xscale == 0) {
dev_err(&idev->dev, "Error: xscale == 0!\n");
- return -1;
+ return;
}
x /= xscale;
@@ -334,7 +334,7 @@ static int at91_ts_sample(struct iio_dev *idev)
yscale = (reg >> 16) & xyz_mask;
if (yscale == 0) {
dev_err(&idev->dev, "Error: yscale == 0!\n");
- return -1;
+ return;
}
y /= yscale;
@@ -363,8 +363,6 @@ static int at91_ts_sample(struct iio_dev *idev)
} else {
dev_dbg(&idev->dev, "pressure too low: not reporting\n");
}
-
- return 0;
}
static irqreturn_t at91_adc_rl_interrupt(int irq, void *private)
diff --git a/drivers/iio/adc/cpcap-adc.c b/drivers/iio/adc/cpcap-adc.c
index d9ee2ea116a7..f6f72efcc6ed 100644
--- a/drivers/iio/adc/cpcap-adc.c
+++ b/drivers/iio/adc/cpcap-adc.c
@@ -934,6 +934,17 @@ static const struct cpcap_adc_ato mapphone_adc = {
.atox_ps_factor_out = 0,
};
+static const struct cpcap_adc_ato mot_adc = {
+ .ato_in = 0x0300,
+ .atox_in = 0,
+ .adc_ps_factor_in = 0x0200,
+ .atox_ps_factor_in = 0,
+ .ato_out = 0x0780,
+ .atox_out = 0,
+ .adc_ps_factor_out = 0x0600,
+ .atox_ps_factor_out = 0,
+};
+
static const struct of_device_id cpcap_adc_id_table[] = {
{
.compatible = "motorola,cpcap-adc",
@@ -942,6 +953,10 @@ static const struct of_device_id cpcap_adc_id_table[] = {
.compatible = "motorola,mapphone-cpcap-adc",
.data = &mapphone_adc,
},
+ {
+ .compatible = "motorola,mot-cpcap-adc",
+ .data = &mot_adc,
+ },
{ }
};
MODULE_DEVICE_TABLE(of, cpcap_adc_id_table);
diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
index f8c220f6a7b4..e6268f7ac400 100644
--- a/drivers/iio/adc/fsl-imx25-gcq.c
+++ b/drivers/iio/adc/fsl-imx25-gcq.c
@@ -47,7 +47,7 @@ struct mx25_gcq_priv {
* of register writes, then a wait for a completion callback,
* and finally a register read, during which userspace could issue
* another read request. This lock protects a read access from
- * ocurring before another one has finished.
+ * occurring before another one has finished.
*/
struct mutex lock;
};
diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c
index 857e1b69d6cd..dd37109a008a 100644
--- a/drivers/iio/adc/ina2xx-adc.c
+++ b/drivers/iio/adc/ina2xx-adc.c
@@ -121,7 +121,7 @@ static const struct regmap_config ina2xx_regmap_config = {
.volatile_reg = ina2xx_is_volatile_reg,
};
-enum ina2xx_ids { ina219, ina226 };
+enum ina2xx_ids { ina219, ina226, ina236 };
struct ina2xx_config {
const char *name;
@@ -175,6 +175,16 @@ static const struct ina2xx_config ina2xx_config[] = {
.power_lsb_factor = 25,
.chip_id = ina226,
},
+ [ina236] = {
+ .name = "ina236",
+ .config_default = INA226_CONFIG_DEFAULT,
+ .calibration_value = 2048,
+ .shunt_voltage_lsb = 2500,
+ .bus_voltage_shift = 0,
+ .bus_voltage_lsb = 1600,
+ .power_lsb_factor = 32,
+ .chip_id = ina236,
+ },
};
static int ina2xx_read_raw(struct iio_dev *indio_dev,
@@ -499,20 +509,26 @@ static int ina2xx_write_raw(struct iio_dev *indio_dev,
break;
case IIO_CHAN_INFO_INT_TIME:
- if (chip->config->chip_id == ina226) {
+ switch (chip->config->chip_id) {
+ case ina226:
+ case ina236:
if (chan->address == INA2XX_SHUNT_VOLTAGE)
ret = ina226_set_int_time_vshunt(chip, val2,
&tmp);
else
ret = ina226_set_int_time_vbus(chip, val2,
&tmp);
- } else {
+ break;
+ case ina219:
if (chan->address == INA2XX_SHUNT_VOLTAGE)
ret = ina219_set_int_time_vshunt(chip, val2,
&tmp);
else
ret = ina219_set_int_time_vbus(chip, val2,
&tmp);
+ break;
+ default:
+ ret = -EINVAL;
}
break;
@@ -727,19 +743,27 @@ static int ina2xx_conversion_ready(struct iio_dev *indio_dev)
* For now, we do an extra read of the MASK_ENABLE register (INA226)
* resp. the BUS_VOLTAGE register (INA219).
*/
- if (chip->config->chip_id == ina226) {
+ switch (chip->config->chip_id) {
+ case ina226:
+ case ina236:
ret = regmap_read(chip->regmap,
INA226_MASK_ENABLE, &alert);
+ if (ret < 0)
+ return ret;
+
alert &= INA226_CVRF;
- } else {
+ break;
+ case ina219:
ret = regmap_read(chip->regmap,
INA2XX_BUS_VOLTAGE, &alert);
+ if (ret < 0)
+ return ret;
alert &= INA219_CNVR;
+ break;
+ default:
+ return -EINVAL;
}
- if (ret < 0)
- return ret;
-
return !!alert;
}
@@ -998,16 +1022,22 @@ static int ina2xx_probe(struct i2c_client *client)
/* Patch the current config register with default. */
val = chip->config->config_default;
- if (type == ina226) {
+ switch (type) {
+ case ina226:
+ case ina236:
ina226_set_average(chip, INA226_DEFAULT_AVG, &val);
ina226_set_int_time_vbus(chip, INA226_DEFAULT_IT, &val);
ina226_set_int_time_vshunt(chip, INA226_DEFAULT_IT, &val);
- } else {
+ break;
+ case ina219:
chip->avg = 1;
ina219_set_int_time_vbus(chip, INA219_DEFAULT_IT, &val);
ina219_set_int_time_vshunt(chip, INA219_DEFAULT_IT, &val);
ina219_set_vbus_range_denom(chip, INA219_DEFAULT_BRNG, &val);
ina219_set_vshunt_pga_gain(chip, INA219_DEFAULT_PGA, &val);
+ break;
+ default:
+ return -EINVAL;
}
ret = ina2xx_init(chip, val);
@@ -1017,14 +1047,20 @@ static int ina2xx_probe(struct i2c_client *client)
}
indio_dev->modes = INDIO_DIRECT_MODE;
- if (type == ina226) {
+ switch (type) {
+ case ina226:
+ case ina236:
indio_dev->channels = ina226_channels;
indio_dev->num_channels = ARRAY_SIZE(ina226_channels);
indio_dev->info = &ina226_info;
- } else {
+ break;
+ case ina219:
indio_dev->channels = ina219_channels;
indio_dev->num_channels = ARRAY_SIZE(ina219_channels);
indio_dev->info = &ina219_info;
+ break;
+ default:
+ return -EINVAL;
}
indio_dev->name = id ? id->name : chip->config->name;
@@ -1057,6 +1093,7 @@ static const struct i2c_device_id ina2xx_id[] = {
{ "ina226", ina226 },
{ "ina230", ina226 },
{ "ina231", ina226 },
+ { "ina236", ina236 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ina2xx_id);
@@ -1082,6 +1119,10 @@ static const struct of_device_id ina2xx_of_match[] = {
.compatible = "ti,ina231",
.data = (void *)ina226
},
+ {
+ .compatible = "ti,ina236",
+ .data = (void *)ina236
+ },
{ }
};
MODULE_DEVICE_TABLE(of, ina2xx_of_match);
diff --git a/drivers/iio/adc/ltc2309.c b/drivers/iio/adc/ltc2309.c
index 5f0d947d0615..316256edf150 100644
--- a/drivers/iio/adc/ltc2309.c
+++ b/drivers/iio/adc/ltc2309.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
/*
+ * The LTC2305 is a 2-Channel, 12-Bit SAR ADC with an I2C Interface.
* The LTC2309 is an 8-Channel, 12-Bit SAR ADC with an I2C Interface.
*
* Datasheet:
+ * https://www.analog.com/media/en/technical-documentation/data-sheets/23015fb.pdf
* https://www.analog.com/media/en/technical-documentation/data-sheets/2309fd.pdf
*
* Copyright (c) 2023, Liam Beguin <liambeguin@gmail.com>
@@ -41,23 +43,30 @@ struct ltc2309 {
};
/* Order matches expected channel address, See datasheet Table 1. */
+enum ltc2305_channels {
+ LTC2305_CH0_CH1 = 0x0,
+ LTC2305_CH1_CH0 = 0x4,
+ LTC2305_CH0 = 0x8,
+ LTC2305_CH1 = 0xc,
+};
+
enum ltc2309_channels {
- LTC2309_CH0_CH1 = 0,
- LTC2309_CH2_CH3,
- LTC2309_CH4_CH5,
- LTC2309_CH6_CH7,
- LTC2309_CH1_CH0,
- LTC2309_CH3_CH2,
- LTC2309_CH5_CH4,
- LTC2309_CH7_CH6,
- LTC2309_CH0,
- LTC2309_CH2,
- LTC2309_CH4,
- LTC2309_CH6,
- LTC2309_CH1,
- LTC2309_CH3,
- LTC2309_CH5,
- LTC2309_CH7,
+ LTC2309_CH0_CH1 = 0x0,
+ LTC2309_CH2_CH3 = 0x1,
+ LTC2309_CH4_CH5 = 0x2,
+ LTC2309_CH6_CH7 = 0x3,
+ LTC2309_CH1_CH0 = 0x4,
+ LTC2309_CH3_CH2 = 0x5,
+ LTC2309_CH5_CH4 = 0x6,
+ LTC2309_CH7_CH6 = 0x7,
+ LTC2309_CH0 = 0x8,
+ LTC2309_CH2 = 0x9,
+ LTC2309_CH4 = 0xa,
+ LTC2309_CH6 = 0xb,
+ LTC2309_CH1 = 0xc,
+ LTC2309_CH3 = 0xd,
+ LTC2309_CH5 = 0xe,
+ LTC2309_CH7 = 0xf,
};
#define LTC2309_CHAN(_chan, _addr) { \
@@ -80,6 +89,13 @@ enum ltc2309_channels {
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
}
+static const struct iio_chan_spec ltc2305_channels[] = {
+ LTC2309_CHAN(0, LTC2305_CH0),
+ LTC2309_CHAN(1, LTC2305_CH1),
+ LTC2309_DIFF_CHAN(0, 1, LTC2305_CH0_CH1),
+ LTC2309_DIFF_CHAN(1, 0, LTC2305_CH1_CH0),
+};
+
static const struct iio_chan_spec ltc2309_channels[] = {
LTC2309_CHAN(0, LTC2309_CH0),
LTC2309_CHAN(1, LTC2309_CH1),
@@ -99,6 +115,24 @@ static const struct iio_chan_spec ltc2309_channels[] = {
LTC2309_DIFF_CHAN(7, 6, LTC2309_CH7_CH6),
};
+struct ltc2309_chip_info {
+ const char *name;
+ const struct iio_chan_spec *channels;
+ int num_channels;
+};
+
+static const struct ltc2309_chip_info ltc2305_chip_info = {
+ .name = "ltc2305",
+ .channels = ltc2305_channels,
+ .num_channels = ARRAY_SIZE(ltc2305_channels),
+};
+
+static const struct ltc2309_chip_info ltc2309_chip_info = {
+ .name = "ltc2309",
+ .channels = ltc2309_channels,
+ .num_channels = ARRAY_SIZE(ltc2309_channels),
+};
+
static int ltc2309_read_raw_channel(struct ltc2309 *ltc2309,
unsigned long address, int *val)
{
@@ -158,6 +192,7 @@ static const struct iio_info ltc2309_info = {
static int ltc2309_probe(struct i2c_client *client)
{
+ const struct ltc2309_chip_info *chip_info;
struct iio_dev *indio_dev;
struct ltc2309 *ltc2309;
int ret;
@@ -167,13 +202,15 @@ static int ltc2309_probe(struct i2c_client *client)
return -ENOMEM;
ltc2309 = iio_priv(indio_dev);
+ chip_info = i2c_get_match_data(client);
+
ltc2309->dev = &indio_dev->dev;
ltc2309->client = client;
- indio_dev->name = "ltc2309";
+ indio_dev->name = chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->channels = ltc2309_channels;
- indio_dev->num_channels = ARRAY_SIZE(ltc2309_channels);
+ indio_dev->channels = chip_info->channels;
+ indio_dev->num_channels = chip_info->num_channels;
indio_dev->info = &ltc2309_info;
ret = devm_regulator_get_enable_read_voltage(&client->dev, "vref");
@@ -189,13 +226,15 @@ static int ltc2309_probe(struct i2c_client *client)
}
static const struct of_device_id ltc2309_of_match[] = {
- { .compatible = "lltc,ltc2309" },
+ { .compatible = "lltc,ltc2305", .data = &ltc2305_chip_info },
+ { .compatible = "lltc,ltc2309", .data = &ltc2309_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ltc2309_of_match);
static const struct i2c_device_id ltc2309_id[] = {
- { "ltc2309" },
+ { "ltc2305", (kernel_ulong_t)&ltc2305_chip_info },
+ { "ltc2309", (kernel_ulong_t)&ltc2309_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc2309_id);
diff --git a/drivers/iio/adc/max11410.c b/drivers/iio/adc/max11410.c
index 511b2f14dfaf..69351f4f10bb 100644
--- a/drivers/iio/adc/max11410.c
+++ b/drivers/iio/adc/max11410.c
@@ -912,8 +912,8 @@ static int max11410_self_calibrate(struct max11410_state *st)
static int max11410_probe(struct spi_device *spi)
{
- const char *vrefp_regs[] = { "vref0p", "vref1p", "vref2p" };
- const char *vrefn_regs[] = { "vref0n", "vref1n", "vref2n" };
+ static const char * const vrefp_regs[] = { "vref0p", "vref1p", "vref2p" };
+ static const char * const vrefn_regs[] = { "vref0n", "vref1n", "vref2n" };
struct device *dev = &spi->dev;
struct max11410_state *st;
struct iio_dev *indio_dev;
diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c
index 9dd547e62b6c..4d0b79cfeb27 100644
--- a/drivers/iio/adc/max1363.c
+++ b/drivers/iio/adc/max1363.c
@@ -121,7 +121,7 @@ enum max1363_modes {
};
/**
- * struct max1363_chip_info - chip specifc information
+ * struct max1363_chip_info - chip specific information
* @info: iio core function callbacks structure
* @channels: channel specification
* @num_channels: number of channels
@@ -149,7 +149,6 @@ struct max1363_chip_info {
* @configbyte: cache of current device config byte
* @chip_info: chip model specific constants, available modes, etc.
* @current_mode: the scan mode of this chip
- * @requestedmask: a valid requested set of channels
* @lock: lock to ensure state is consistent
* @monitor_on: whether monitor mode is enabled
* @monitor_speed: parameter corresponding to device monitor speed setting
@@ -169,7 +168,6 @@ struct max1363_state {
u8 configbyte;
const struct max1363_chip_info *chip_info;
const struct max1363_mode *current_mode;
- u32 requestedmask;
struct mutex lock;
/* Using monitor modes and buffer at the same time is
@@ -637,48 +635,51 @@ static const enum max1363_modes max11644_mode_list[] = {
static const struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10);
static const struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12);
-enum { max1361,
- max1362,
- max1363,
- max1364,
- max1036,
- max1037,
- max1038,
- max1039,
- max1136,
- max1137,
- max1138,
- max1139,
- max1236,
- max1237,
- max1238,
- max1239,
- max11600,
- max11601,
- max11602,
- max11603,
- max11604,
- max11605,
- max11606,
- max11607,
- max11608,
- max11609,
- max11610,
- max11611,
- max11612,
- max11613,
- max11614,
- max11615,
- max11616,
- max11617,
- max11644,
- max11645,
- max11646,
- max11647
+enum {
+ max1361,
+ max1362,
+ max1363,
+ max1364,
+ max1036,
+ max1037,
+ max1038,
+ max1039,
+ max1136,
+ max1137,
+ max1138,
+ max1139,
+ max1236,
+ max1237,
+ max1238,
+ max1239,
+ max11600,
+ max11601,
+ max11602,
+ max11603,
+ max11604,
+ max11605,
+ max11606,
+ max11607,
+ max11608,
+ max11609,
+ max11610,
+ max11611,
+ max11612,
+ max11613,
+ max11614,
+ max11615,
+ max11616,
+ max11617,
+ max11644,
+ max11645,
+ max11646,
+ max11647,
};
-static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600,
- 8300, 4200, 2000, 1000 };
+static const int max1363_monitor_speeds[] = {
+ 133000, 665000, 33300, 16600,
+ 8300, 4200, 2000, 1000,
+};
static ssize_t max1363_monitor_show_freq(struct device *dev,
struct device_attribute *attr,
diff --git a/drivers/iio/adc/mcp3564.c b/drivers/iio/adc/mcp3564.c
index fcdf13f49c48..36675563829e 100644
--- a/drivers/iio/adc/mcp3564.c
+++ b/drivers/iio/adc/mcp3564.c
@@ -349,7 +349,7 @@ struct mcp3564_chip_info {
* struct mcp3564_state - working data for a ADC device
* @chip_info: chip specific data
* @spi: SPI device structure
- * @vref_mv: voltage reference value in miliVolts
+ * @vref_mv: voltage reference value in millivolts
* @lock: synchronize access to driver's state members
* @dev_addr: hardware device address
* @oversampling: the index inside oversampling list of the ADC
diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c
index 90919d282e7b..5bd334ec5655 100644
--- a/drivers/iio/adc/men_z188_adc.c
+++ b/drivers/iio/adc/men_z188_adc.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * MEN 16z188 Analog to Digial Converter
+ * MEN 16z188 Analog to Digital Converter
*
* Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
* Author: Johannes Thumshirn <johannes.thumshirn@men.de>
diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c
index 47cd350498a0..23991a3612bd 100644
--- a/drivers/iio/adc/meson_saradc.c
+++ b/drivers/iio/adc/meson_saradc.c
@@ -792,7 +792,7 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
size_t read_len;
int ret;
- temperature_calib = devm_nvmem_cell_get(dev, "temperature_calib");
+ temperature_calib = nvmem_cell_get(dev, "temperature_calib");
if (IS_ERR(temperature_calib)) {
ret = PTR_ERR(temperature_calib);
@@ -806,13 +806,9 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
return dev_err_probe(dev, ret, "failed to get temperature_calib cell\n");
}
- priv->tsc_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "amlogic,hhi-sysctrl");
- if (IS_ERR(priv->tsc_regmap))
- return dev_err_probe(dev, PTR_ERR(priv->tsc_regmap),
- "failed to get amlogic,hhi-sysctrl regmap\n");
-
read_len = MESON_SAR_ADC_EFUSE_BYTES;
buf = nvmem_cell_read(temperature_calib, &read_len);
+ nvmem_cell_put(temperature_calib);
if (IS_ERR(buf))
return dev_err_probe(dev, PTR_ERR(buf), "failed to read temperature_calib cell\n");
if (read_len != MESON_SAR_ADC_EFUSE_BYTES) {
@@ -820,6 +816,11 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
return dev_err_probe(dev, -EINVAL, "invalid read size of temperature_calib cell\n");
}
+ priv->tsc_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "amlogic,hhi-sysctrl");
+ if (IS_ERR(priv->tsc_regmap))
+ return dev_err_probe(dev, PTR_ERR(priv->tsc_regmap),
+ "failed to get amlogic,hhi-sysctrl regmap\n");
+
trimming_bits = priv->param->temperature_trimming_bits;
trimming_mask = BIT(trimming_bits) - 1;
@@ -1313,6 +1314,11 @@ static const struct meson_sar_adc_data meson_sar_adc_g12a_data = {
.name = "meson-g12a-saradc",
};
+static const struct meson_sar_adc_data meson_sar_adc_s4_data = {
+ .param = &meson_sar_adc_g12a_param,
+ .name = "meson-s4-saradc",
+};
+
static const struct of_device_id meson_sar_adc_of_match[] = {
{
.compatible = "amlogic,meson8-saradc",
@@ -1341,6 +1347,9 @@ static const struct of_device_id meson_sar_adc_of_match[] = {
}, {
.compatible = "amlogic,meson-g12a-saradc",
.data = &meson_sar_adc_g12a_data,
+ }, {
+ .compatible = "amlogic,meson-s4-saradc",
+ .data = &meson_sar_adc_s4_data,
},
{ }
};
diff --git a/drivers/iio/adc/mt6359-auxadc.c b/drivers/iio/adc/mt6359-auxadc.c
index f426a289e867..6b9ed9b1fde2 100644
--- a/drivers/iio/adc/mt6359-auxadc.c
+++ b/drivers/iio/adc/mt6359-auxadc.c
@@ -322,7 +322,7 @@ static const struct mtk_pmic_auxadc_chan mt6359_auxadc_ch_desc[] = {
MTK_PMIC_ADC_CHAN(BATADC, PMIC_AUXADC_RQST0, 0, PMIC_AUXADC_IMP1, 15, 128, 7, 2),
MTK_PMIC_ADC_CHAN(BAT_TEMP, PMIC_AUXADC_RQST0, 3, PMIC_AUXADC_IMP1, 15, 8, 5, 2),
MTK_PMIC_ADC_CHAN(CHIP_TEMP, PMIC_AUXADC_RQST0, 4, PMIC_AUXADC_IMP1, 15, 8, 1, 1),
- MTK_PMIC_ADC_CHAN(ACCDET, PMIC_AUXADC_RQST0, 5, PMIC_AUXADC_IMP1, 15 ,8, 1, 1),
+ MTK_PMIC_ADC_CHAN(ACCDET, PMIC_AUXADC_RQST0, 5, PMIC_AUXADC_IMP1, 15, 8, 1, 1),
MTK_PMIC_ADC_CHAN(VDCXO, PMIC_AUXADC_RQST0, 6, PMIC_AUXADC_IMP1, 15, 8, 3, 2),
MTK_PMIC_ADC_CHAN(TSX_TEMP, PMIC_AUXADC_RQST0, 7, PMIC_AUXADC_IMP1, 15, 128, 1, 1),
MTK_PMIC_ADC_CHAN(HPOFS_CAL, PMIC_AUXADC_RQST0, 9, PMIC_AUXADC_IMP1, 15, 256, 1, 1),
diff --git a/drivers/iio/adc/nau7802.c b/drivers/iio/adc/nau7802.c
index 458544cb8ee4..970afb27b839 100644
--- a/drivers/iio/adc/nau7802.c
+++ b/drivers/iio/adc/nau7802.c
@@ -55,7 +55,6 @@ struct nau7802_state {
struct mutex data_lock;
u32 vref_mv;
u32 conversion_count;
- u32 min_conversions;
u8 sample_rate;
u32 scale_avail[8];
struct completion value_ok;
@@ -257,7 +256,7 @@ static int nau7802_read_poll(struct iio_dev *indio_dev,
/*
* Because there is actually only one ADC for both channels, we have to
* wait for enough conversions to happen before getting a significant
- * value when changing channels and the values are far appart.
+ * value when changing channels and the values are far apart.
*/
do {
ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c
index c8283873cdee..ddabb9600d46 100644
--- a/drivers/iio/adc/npcm_adc.c
+++ b/drivers/iio/adc/npcm_adc.c
@@ -38,7 +38,7 @@ struct npcm_adc {
* read access from userspace. Reading a raw value requires a sequence
* of register writes, then a wait for a event and finally a register
* read, during which userspace could issue another read request.
- * This lock protects a read access from ocurring before another one
+ * This lock protects a read access from occurring before another one
* has finished.
*/
struct mutex lock;
diff --git a/drivers/iio/adc/nxp-sar-adc.c b/drivers/iio/adc/nxp-sar-adc.c
index 9efa883c277d..a6e4888a8464 100644
--- a/drivers/iio/adc/nxp-sar-adc.c
+++ b/drivers/iio/adc/nxp-sar-adc.c
@@ -247,7 +247,8 @@ static inline void nxp_sar_adc_calibration_start(void __iomem *base)
static inline int nxp_sar_adc_calibration_wait(void __iomem *base)
{
- u32 msr, ret;
+ u32 msr;
+ int ret;
ret = readl_poll_timeout(NXP_SAR_ADC_MSR(base), msr,
!FIELD_GET(NXP_SAR_ADC_MSR_CALBUSY, msr),
diff --git a/drivers/iio/adc/pac1921.c b/drivers/iio/adc/pac1921.c
index a0227b57f238..bce7185953ec 100644
--- a/drivers/iio/adc/pac1921.c
+++ b/drivers/iio/adc/pac1921.c
@@ -856,7 +856,7 @@ static ssize_t pac1921_format_scale_avail(const int (*const scales_tbl)[2],
/*
* Read available scales for a specific channel
*
- * NOTE: using extended info insted of iio.read_avail() because access to
+ * NOTE: using extended info instead of iio.read_avail() because access to
* current scales must be locked as they depend on shunt resistor which may
* change runtime. Caller of iio.read_avail() would access the table unlocked
* instead.
diff --git a/drivers/iio/adc/pac1934.c b/drivers/iio/adc/pac1934.c
index 712b5e9caba6..23055405a6e0 100644
--- a/drivers/iio/adc/pac1934.c
+++ b/drivers/iio/adc/pac1934.c
@@ -1351,7 +1351,7 @@ static int pac1934_prep_iio_channels(struct pac1934_chip_info *info, struct iio_
dyn_ch_struct = devm_kzalloc(dev, channel_size, GFP_KERNEL);
if (!dyn_ch_struct)
- return -EINVAL;
+ return -ENOMEM;
tmp_data = dyn_ch_struct;
diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c
index 3f433064618e..f777986a6aba 100644
--- a/drivers/iio/adc/palmas_gpadc.c
+++ b/drivers/iio/adc/palmas_gpadc.c
@@ -105,7 +105,7 @@ struct palmas_gpadc_thresholds {
* of register writes, then a wait for a completion callback,
* and finally a register read, during which userspace could issue
* another read request. This lock protects a read access from
- * ocurring before another one has finished.
+ * occurring before another one has finished.
*
* This is the palmas_gpadc structure to store run-time information
* and pointers for this driver instance.
@@ -521,16 +521,16 @@ static int palmas_gpadc_get_low_threshold_raw(struct palmas_gpadc *adc,
val = (val * 1000) / adc->adc_info[adc_chan].gain;
- if (adc->adc_info[adc_chan].is_uncalibrated) {
+ if (adc->adc_info[adc_chan].is_uncalibrated) {
/* 2% worse */
min_gain_error -= 20;
min_offset_error = -36;
- } else {
+ } else {
val = (val * adc->adc_info[adc_chan].gain_error -
adc->adc_info[adc_chan].offset) /
1000;
min_offset_error = -2;
- }
+ }
return palmas_gpadc_threshold_with_tolerance(val,
min_INL,
diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c
new file mode 100644
index 000000000000..f8168a14b907
--- /dev/null
+++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c
@@ -0,0 +1,860 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/cleanup.h>
+#include <linux/completion.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/device/devres.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/iio/adc/qcom-adc5-gen3-common.h>
+#include <linux/iio/iio.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+#include <linux/unaligned.h>
+
+#define ADC5_GEN3_VADC_SDAM 0x0
+
+struct adc5_chip;
+
+/**
+ * struct adc5_channel_prop - ADC channel structure
+ * @common_props: structure with ADC channel properties (common to TM usage).
+ * @adc_tm: indicates TM type if the channel is used for TM measurements.
+ * @chip: pointer to top-level ADC device structure.
+ */
+struct adc5_channel_prop {
+ struct adc5_channel_common_prop common_props;
+ int adc_tm;
+ struct adc5_chip *chip;
+};
+
+/**
+ * struct adc5_chip - ADC private structure.
+ * @dev: SPMI ADC5 Gen3 device.
+ * @dev_data: Top-level ADC device data.
+ * @nchannels: number of ADC channels.
+ * @chan_props: array of ADC channel properties.
+ * @iio_chans: array of IIO channels specification.
+ * @complete: ADC result notification after interrupt is received.
+ * @lock: ADC lock for access to the peripheral, to prevent concurrent
+ * requests from multiple clients.
+ * @data: software configuration data.
+ * @n_tm_channels: number of ADC channels used for TM measurements.
+ * @handler: TM callback to be called for threshold violation interrupt
+ * on first SDAM.
+ * @tm_aux: pointer to auxiliary TM device.
+ */
+struct adc5_chip {
+ struct device *dev;
+ struct adc5_device_data dev_data;
+ unsigned int nchannels;
+ struct adc5_channel_prop *chan_props;
+ struct iio_chan_spec *iio_chans;
+ struct completion complete;
+ struct mutex lock;
+ const struct adc5_data *data;
+ unsigned int n_tm_channels;
+ void (*handler)(struct auxiliary_device *tm_aux);
+ struct auxiliary_device *tm_aux;
+};
+
+int adc5_gen3_read(struct adc5_device_data *adc, unsigned int sdam_index,
+ u16 offset, u8 *data, int len)
+{
+ return regmap_bulk_read(adc->regmap,
+ adc->base[sdam_index].base_addr + offset,
+ data, len);
+}
+EXPORT_SYMBOL_NS_GPL(adc5_gen3_read, "QCOM_SPMI_ADC5_GEN3");
+
+int adc5_gen3_write(struct adc5_device_data *adc, unsigned int sdam_index,
+ u16 offset, u8 *data, int len)
+{
+ return regmap_bulk_write(adc->regmap,
+ adc->base[sdam_index].base_addr + offset,
+ data, len);
+}
+EXPORT_SYMBOL_NS_GPL(adc5_gen3_write, "QCOM_SPMI_ADC5_GEN3");
+
+static int adc5_gen3_read_voltage_data(struct adc5_chip *adc, u16 *data)
+{
+ u8 rslt[2];
+ int ret;
+
+ ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
+ ADC5_GEN3_CH_DATA0(0), rslt, sizeof(rslt));
+ if (ret)
+ return ret;
+
+ *data = get_unaligned_le16(rslt);
+
+ if (*data == ADC5_USR_DATA_CHECK) {
+ dev_err(adc->dev, "Invalid data:%#x\n", *data);
+ return -EINVAL;
+ }
+
+ dev_dbg(adc->dev, "voltage raw code:%#x\n", *data);
+
+ return 0;
+}
+
+void adc5_gen3_update_dig_param(struct adc5_channel_common_prop *prop, u8 *data)
+{
+ /* Update calibration select and decimation ratio select */
+ *data &= ~(ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK | ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK);
+ *data |= FIELD_PREP(ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK, prop->cal_method);
+ *data |= FIELD_PREP(ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK, prop->decimation);
+}
+EXPORT_SYMBOL_NS_GPL(adc5_gen3_update_dig_param, "QCOM_SPMI_ADC5_GEN3");
+
+#define ADC5_GEN3_READ_CONFIG_REGS 7
+
+static int adc5_gen3_configure(struct adc5_chip *adc,
+ struct adc5_channel_common_prop *prop)
+{
+ u8 buf[ADC5_GEN3_READ_CONFIG_REGS];
+ u8 conv_req = 0;
+ int ret;
+
+ ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM, ADC5_GEN3_SID,
+ buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ /* Write SID */
+ buf[0] = FIELD_PREP(ADC5_GEN3_SID_MASK, prop->sid);
+
+ /*
+ * Use channel 0 by default for immediate conversion and to indicate
+ * there is an actual conversion request
+ */
+ buf[1] = ADC5_GEN3_CHAN_CONV_REQ | 0;
+
+ buf[2] = ADC5_GEN3_TIME_IMMEDIATE;
+
+ /* Digital param selection */
+ adc5_gen3_update_dig_param(prop, &buf[3]);
+
+ /* Update fast average sample value */
+ buf[4] = FIELD_PREP(ADC5_GEN3_FAST_AVG_CTL_SAMPLES_MASK,
+ prop->avg_samples) | ADC5_GEN3_FAST_AVG_CTL_EN;
+
+ /* Select ADC channel */
+ buf[5] = prop->channel;
+
+ /* Select HW settle delay for channel */
+ buf[6] = FIELD_PREP(ADC5_GEN3_HW_SETTLE_DELAY_MASK,
+ prop->hw_settle_time_us);
+
+ reinit_completion(&adc->complete);
+
+ ret = adc5_gen3_write(&adc->dev_data, ADC5_GEN3_VADC_SDAM, ADC5_GEN3_SID,
+ buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ conv_req = ADC5_GEN3_CONV_REQ_REQ;
+ return adc5_gen3_write(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
+ ADC5_GEN3_CONV_REQ, &conv_req, sizeof(conv_req));
+}
+
+/*
+ * Worst case delay from PBS in readying handshake bit can be up to 15ms, when
+ * PBS is busy running other simultaneous transactions, while in the best case,
+ * it is already ready at this point. Assigning polling delay and retry count
+ * accordingly.
+ */
+
+#define ADC5_GEN3_HS_DELAY_US 100
+#define ADC5_GEN3_HS_RETRY_COUNT 150
+
+int adc5_gen3_poll_wait_hs(struct adc5_device_data *adc,
+ unsigned int sdam_index)
+{
+ u8 conv_req = ADC5_GEN3_CONV_REQ_REQ;
+ int ret, count;
+ u8 status = 0;
+
+ for (count = 0; count < ADC5_GEN3_HS_RETRY_COUNT; count++) {
+ ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_HS, &status, sizeof(status));
+ if (ret)
+ return ret;
+
+ if (status == ADC5_GEN3_HS_READY) {
+ ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_CONV_REQ,
+ &conv_req, sizeof(conv_req));
+ if (ret)
+ return ret;
+
+ if (!conv_req)
+ return 0;
+ }
+
+ fsleep(ADC5_GEN3_HS_DELAY_US);
+ }
+
+ pr_err("Setting HS ready bit timed out, sdam_index:%d, status:%#x\n",
+ sdam_index, status);
+ return -ETIMEDOUT;
+}
+EXPORT_SYMBOL_NS_GPL(adc5_gen3_poll_wait_hs, "QCOM_SPMI_ADC5_GEN3");
+
+int adc5_gen3_status_clear(struct adc5_device_data *adc,
+ int sdam_index, u16 offset, u8 *val, int len)
+{
+ u8 value;
+ int ret;
+
+ ret = adc5_gen3_write(adc, sdam_index, offset, val, len);
+ if (ret)
+ return ret;
+
+ /* To indicate conversion request is only to clear a status */
+ value = 0;
+ ret = adc5_gen3_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &value,
+ sizeof(value));
+ if (ret)
+ return ret;
+
+ value = ADC5_GEN3_CONV_REQ_REQ;
+ return adc5_gen3_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &value,
+ sizeof(value));
+}
+EXPORT_SYMBOL_NS_GPL(adc5_gen3_status_clear, "QCOM_SPMI_ADC5_GEN3");
+
+/*
+ * Worst case delay from PBS for conversion time can be up to 500ms, when PBS
+ * has timed out twice, once for the initial attempt and once for a retry of
+ * the same transaction.
+ */
+
+#define ADC5_GEN3_CONV_TIMEOUT_MS 501
+
+static int adc5_gen3_do_conversion(struct adc5_chip *adc,
+ struct adc5_channel_common_prop *prop,
+ u16 *data_volt)
+{
+ unsigned long rc;
+ int ret;
+ u8 val;
+
+ guard(mutex)(&adc->lock);
+ ret = adc5_gen3_poll_wait_hs(&adc->dev_data, ADC5_GEN3_VADC_SDAM);
+ if (ret)
+ return ret;
+
+ ret = adc5_gen3_configure(adc, prop);
+ if (ret) {
+ dev_err(adc->dev, "ADC configure failed with %d\n", ret);
+ return ret;
+ }
+
+ /* No support for polling mode at present */
+ rc = wait_for_completion_timeout(&adc->complete,
+ msecs_to_jiffies(ADC5_GEN3_CONV_TIMEOUT_MS));
+ if (!rc) {
+ dev_err(adc->dev, "Reading ADC channel %s timed out\n",
+ prop->label);
+ return -ETIMEDOUT;
+ }
+
+ ret = adc5_gen3_read_voltage_data(adc, data_volt);
+ if (ret)
+ return ret;
+
+ val = BIT(0);
+ return adc5_gen3_status_clear(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
+ ADC5_GEN3_EOC_CLR, &val, 1);
+}
+
+static irqreturn_t adc5_gen3_isr(int irq, void *dev_id)
+{
+ struct adc5_chip *adc = dev_id;
+ struct device *dev = adc->dev;
+ struct auxiliary_device *adev;
+ u8 status, eoc_status, val;
+ u8 tm_status[2];
+ int ret;
+
+ ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
+ ADC5_GEN3_STATUS1, &status, sizeof(status));
+ if (ret) {
+ dev_err(dev, "adc read status1 failed with %d\n", ret);
+ return IRQ_HANDLED;
+ }
+
+ ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
+ ADC5_GEN3_EOC_STS, &eoc_status, sizeof(eoc_status));
+ if (ret) {
+ dev_err(dev, "adc read eoc status failed with %d\n", ret);
+ return IRQ_HANDLED;
+ }
+
+ if (status & ADC5_GEN3_STATUS1_CONV_FAULT) {
+ dev_err_ratelimited(dev,
+ "Unexpected conversion fault, status:%#x, eoc_status:%#x\n",
+ status, eoc_status);
+ val = ADC5_GEN3_CONV_ERR_CLR_REQ;
+ adc5_gen3_status_clear(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
+ ADC5_GEN3_CONV_ERR_CLR, &val, 1);
+ return IRQ_HANDLED;
+ }
+
+ /* CHAN0 is the preconfigured channel for immediate conversion */
+ if (eoc_status & ADC5_GEN3_EOC_CHAN_0)
+ complete(&adc->complete);
+
+ ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
+ ADC5_GEN3_TM_HIGH_STS, tm_status, sizeof(tm_status));
+ if (ret) {
+ dev_err(dev, "adc read TM status failed with %d\n", ret);
+ return IRQ_HANDLED;
+ }
+
+ dev_dbg(dev, "Interrupt status:%#x, EOC status:%#x, high:%#x, low:%#x\n",
+ status, eoc_status, tm_status[0], tm_status[1]);
+
+ if (tm_status[0] || tm_status[1]) {
+ adev = adc->tm_aux;
+ if (!adev || !adev->dev.driver) {
+ dev_err(dev, "adc_tm auxiliary device not initialized\n");
+ return IRQ_HANDLED;
+ }
+
+ adc->handler(adev);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int adc5_gen3_fwnode_xlate(struct iio_dev *indio_dev,
+ const struct fwnode_reference_args *iiospec)
+{
+ struct adc5_chip *adc = iio_priv(indio_dev);
+ int i, v_channel;
+
+ for (i = 0; i < adc->nchannels; i++) {
+ v_channel = ADC5_GEN3_V_CHAN(adc->chan_props[i].common_props);
+ if (v_channel == iiospec->args[0])
+ return i;
+ }
+
+ return -ENOENT;
+}
+
+static int adc5_gen3_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, int *val,
+ int *val2, long mask)
+{
+ struct adc5_chip *adc = iio_priv(indio_dev);
+ struct adc5_channel_common_prop *prop;
+ u16 adc_code_volt;
+ int ret;
+
+ prop = &adc->chan_props[chan->address].common_props;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_PROCESSED:
+ ret = adc5_gen3_do_conversion(adc, prop, &adc_code_volt);
+ if (ret)
+ return ret;
+
+ ret = qcom_adc5_hw_scale(prop->scale_fn_type, prop->prescale,
+ adc->data, adc_code_volt, val);
+ if (ret)
+ return ret;
+
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int adc5_gen3_read_label(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan, char *label)
+{
+ struct adc5_chip *adc = iio_priv(indio_dev);
+ struct adc5_channel_prop *prop;
+
+ prop = &adc->chan_props[chan->address];
+ return sprintf(label, "%s\n", prop->common_props.label);
+}
+
+static const struct iio_info adc5_gen3_info = {
+ .read_raw = adc5_gen3_read_raw,
+ .read_label = adc5_gen3_read_label,
+ .fwnode_xlate = adc5_gen3_fwnode_xlate,
+};
+
+struct adc5_channels {
+ unsigned int prescale_index;
+ enum iio_chan_type type;
+ long info_mask;
+ enum vadc_scale_fn_type scale_fn_type;
+};
+
+/* In these definitions, _pre refers to an index into adc5_prescale_ratios. */
+#define ADC5_CHAN(_type, _mask, _pre, _scale) \
+ { \
+ .prescale_index = _pre, \
+ .type = _type, \
+ .info_mask = _mask, \
+ .scale_fn_type = _scale, \
+ }, \
+
+#define ADC5_CHAN_TEMP(_pre, _scale) \
+ ADC5_CHAN(IIO_TEMP, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale) \
+
+#define ADC5_CHAN_VOLT(_pre, _scale) \
+ ADC5_CHAN(IIO_VOLTAGE, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale) \
+
+#define ADC5_CHAN_CUR(_pre, _scale) \
+ ADC5_CHAN(IIO_CURRENT, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale) \
+
+static const struct adc5_channels adc5_gen3_chans_pmic[ADC5_MAX_CHANNEL] = {
+ [ADC5_GEN3_REF_GND] = ADC5_CHAN_VOLT(0, SCALE_HW_CALIB_DEFAULT)
+ [ADC5_GEN3_1P25VREF] = ADC5_CHAN_VOLT(0, SCALE_HW_CALIB_DEFAULT)
+ [ADC5_GEN3_VPH_PWR] = ADC5_CHAN_VOLT(1, SCALE_HW_CALIB_DEFAULT)
+ [ADC5_GEN3_VBAT_SNS_QBG] = ADC5_CHAN_VOLT(1, SCALE_HW_CALIB_DEFAULT)
+ [ADC5_GEN3_USB_SNS_V_16] = ADC5_CHAN_TEMP(8, SCALE_HW_CALIB_DEFAULT)
+ [ADC5_GEN3_VIN_DIV16_MUX] = ADC5_CHAN_TEMP(8, SCALE_HW_CALIB_DEFAULT)
+ [ADC5_GEN3_DIE_TEMP] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_PMIC_THERM_PM7)
+ [ADC5_GEN3_AMUX1_THM_100K_PU] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC5_GEN3_AMUX2_THM_100K_PU] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC5_GEN3_AMUX3_THM_100K_PU] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC5_GEN3_AMUX4_THM_100K_PU] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC5_GEN3_AMUX5_THM_100K_PU] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC5_GEN3_AMUX6_THM_100K_PU] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC5_GEN3_AMUX1_GPIO_100K_PU] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC5_GEN3_AMUX2_GPIO_100K_PU] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC5_GEN3_AMUX3_GPIO_100K_PU] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+ [ADC5_GEN3_AMUX4_GPIO_100K_PU] = ADC5_CHAN_TEMP(0,
+ SCALE_HW_CALIB_THERM_100K_PU_PM7)
+};
+
+static int adc5_gen3_get_fw_channel_data(struct adc5_chip *adc,
+ struct adc5_channel_prop *prop,
+ struct fwnode_handle *fwnode)
+{
+ const char *name = fwnode_get_name(fwnode);
+ const struct adc5_data *data = adc->data;
+ struct device *dev = adc->dev;
+ const char *channel_name;
+ u32 chan, value, sid;
+ u32 varr[2];
+ int ret;
+
+ ret = fwnode_property_read_u32(fwnode, "reg", &chan);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "invalid channel number %s\n",
+ name);
+
+ /*
+ * Value read from "reg" is virtual channel number
+ * virtual channel number = sid << 8 | channel number
+ */
+ sid = FIELD_GET(ADC5_GEN3_VIRTUAL_SID_MASK, chan);
+ chan = FIELD_GET(ADC5_GEN3_CHANNEL_MASK, chan);
+
+ if (chan > ADC5_MAX_CHANNEL)
+ return dev_err_probe(dev, -EINVAL,
+ "%s invalid channel number %d\n",
+ name, chan);
+
+ prop->common_props.channel = chan;
+ prop->common_props.sid = sid;
+
+ if (!adc->data->adc_chans[chan].info_mask)
+ return dev_err_probe(dev, -EINVAL, "Channel %#x not supported\n", chan);
+
+ channel_name = name;
+ fwnode_property_read_string(fwnode, "label", &channel_name);
+ prop->common_props.label = channel_name;
+
+ value = data->decimation[ADC5_DECIMATION_DEFAULT];
+ fwnode_property_read_u32(fwnode, "qcom,decimation", &value);
+ ret = qcom_adc5_decimation_from_dt(value, data->decimation);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "%#x invalid decimation %d\n",
+ chan, value);
+ prop->common_props.decimation = ret;
+
+ prop->common_props.prescale = adc->data->adc_chans[chan].prescale_index;
+ ret = fwnode_property_read_u32_array(fwnode, "qcom,pre-scaling", varr, 2);
+ if (!ret) {
+ ret = qcom_adc5_prescaling_from_dt(varr[0], varr[1]);
+ if (ret < 0)
+ return dev_err_probe(dev, ret,
+ "%#x invalid pre-scaling <%d %d>\n",
+ chan, varr[0], varr[1]);
+ prop->common_props.prescale = ret;
+ }
+
+ value = data->hw_settle_1[VADC_DEF_HW_SETTLE_TIME];
+ fwnode_property_read_u32(fwnode, "qcom,hw-settle-time", &value);
+ ret = qcom_adc5_hw_settle_time_from_dt(value, data->hw_settle_1);
+ if (ret < 0)
+ return dev_err_probe(dev, ret,
+ "%#x invalid hw-settle-time %d us\n",
+ chan, value);
+ prop->common_props.hw_settle_time_us = ret;
+
+ value = BIT(VADC_DEF_AVG_SAMPLES);
+ fwnode_property_read_u32(fwnode, "qcom,avg-samples", &value);
+ ret = qcom_adc5_avg_samples_from_dt(value);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "%#x invalid avg-samples %d\n",
+ chan, value);
+ prop->common_props.avg_samples = ret;
+
+ if (fwnode_property_read_bool(fwnode, "qcom,ratiometric"))
+ prop->common_props.cal_method = ADC5_RATIOMETRIC_CAL;
+ else
+ prop->common_props.cal_method = ADC5_ABSOLUTE_CAL;
+
+ prop->adc_tm = fwnode_property_read_bool(fwnode, "qcom,adc-tm");
+ if (prop->adc_tm) {
+ adc->n_tm_channels++;
+ if (adc->n_tm_channels > (adc->dev_data.num_sdams * 8 - 1))
+ return dev_err_probe(dev, -EINVAL,
+ "Number of TM nodes %u greater than channels supported:%u\n",
+ adc->n_tm_channels,
+ adc->dev_data.num_sdams * 8 - 1);
+ }
+
+ return 0;
+}
+
+static const struct adc5_data adc5_gen3_data_pmic = {
+ .full_scale_code_volt = 0x70e4,
+ .adc_chans = adc5_gen3_chans_pmic,
+ .info = &adc5_gen3_info,
+ .decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
+ { 85, 340, 1360 },
+ .hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
+ { 15, 100, 200, 300,
+ 400, 500, 600, 700,
+ 1000, 2000, 4000, 8000,
+ 16000, 32000, 64000, 128000 },
+};
+
+static const struct of_device_id adc5_match_table[] = {
+ {
+ .compatible = "qcom,spmi-adc5-gen3",
+ .data = &adc5_gen3_data_pmic,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, adc5_match_table);
+
+static int adc5_get_fw_data(struct adc5_chip *adc)
+{
+ const struct adc5_channels *adc_chan;
+ struct adc5_channel_prop *chan_props;
+ struct iio_chan_spec *iio_chan;
+ struct device *dev = adc->dev;
+ unsigned int index = 0;
+ int ret;
+
+ adc->nchannels = device_get_child_node_count(dev);
+ if (!adc->nchannels)
+ return dev_err_probe(dev, -EINVAL, "No ADC channels found\n");
+
+ adc->iio_chans = devm_kcalloc(dev, adc->nchannels,
+ sizeof(*adc->iio_chans), GFP_KERNEL);
+ if (!adc->iio_chans)
+ return -ENOMEM;
+
+ adc->chan_props = devm_kcalloc(dev, adc->nchannels,
+ sizeof(*adc->chan_props), GFP_KERNEL);
+ if (!adc->chan_props)
+ return -ENOMEM;
+
+ chan_props = adc->chan_props;
+ adc->n_tm_channels = 0;
+ iio_chan = adc->iio_chans;
+ adc->data = device_get_match_data(dev);
+
+ device_for_each_child_node_scoped(dev, child) {
+ ret = adc5_gen3_get_fw_channel_data(adc, chan_props, child);
+ if (ret)
+ return ret;
+
+ chan_props->chip = adc;
+ adc_chan = &adc->data->adc_chans[chan_props->common_props.channel];
+ chan_props->common_props.scale_fn_type = adc_chan->scale_fn_type;
+
+ iio_chan->channel = ADC5_GEN3_V_CHAN(chan_props->common_props);
+ iio_chan->info_mask_separate = adc_chan->info_mask;
+ iio_chan->type = adc_chan->type;
+ iio_chan->address = index;
+ iio_chan->indexed = 1;
+ iio_chan++;
+ chan_props++;
+ index++;
+ }
+
+ return 0;
+}
+
+static void adc5_gen3_uninit_aux(void *data)
+{
+ auxiliary_device_uninit(data);
+}
+
+static void adc5_gen3_delete_aux(void *data)
+{
+ auxiliary_device_delete(data);
+}
+
+static void adc5_gen3_aux_device_release(struct device *dev) {}
+
+static int adc5_gen3_add_aux_tm_device(struct adc5_chip *adc)
+{
+ struct tm5_aux_dev_wrapper *aux_device;
+ int i, ret, i_tm = 0;
+
+ aux_device = devm_kzalloc(adc->dev, sizeof(*aux_device), GFP_KERNEL);
+ if (!aux_device)
+ return -ENOMEM;
+
+ aux_device->aux_dev.name = "adc5_tm_gen3";
+ aux_device->aux_dev.dev.parent = adc->dev;
+ aux_device->aux_dev.dev.release = adc5_gen3_aux_device_release;
+
+ aux_device->tm_props = devm_kcalloc(adc->dev, adc->n_tm_channels,
+ sizeof(*aux_device->tm_props),
+ GFP_KERNEL);
+ if (!aux_device->tm_props)
+ return -ENOMEM;
+
+ aux_device->dev_data = &adc->dev_data;
+
+ for (i = 0; i < adc->nchannels; i++) {
+ if (!adc->chan_props[i].adc_tm)
+ continue;
+ aux_device->tm_props[i_tm] = adc->chan_props[i].common_props;
+ i_tm++;
+ }
+
+ device_set_of_node_from_dev(&aux_device->aux_dev.dev, adc->dev);
+
+ aux_device->n_tm_channels = adc->n_tm_channels;
+
+ ret = auxiliary_device_init(&aux_device->aux_dev);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(adc->dev, adc5_gen3_uninit_aux,
+ &aux_device->aux_dev);
+ if (ret)
+ return ret;
+
+ ret = auxiliary_device_add(&aux_device->aux_dev);
+ if (ret)
+ return ret;
+ ret = devm_add_action_or_reset(adc->dev, adc5_gen3_delete_aux,
+ &aux_device->aux_dev);
+ if (ret)
+ return ret;
+
+ adc->tm_aux = &aux_device->aux_dev;
+
+ return 0;
+}
+
+void adc5_gen3_mutex_lock(struct device *dev)
+ __acquires(&adc->lock)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
+ struct adc5_chip *adc = iio_priv(indio_dev);
+
+ mutex_lock(&adc->lock);
+}
+EXPORT_SYMBOL_NS_GPL(adc5_gen3_mutex_lock, "QCOM_SPMI_ADC5_GEN3");
+
+void adc5_gen3_mutex_unlock(struct device *dev)
+ __releases(&adc->lock)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
+ struct adc5_chip *adc = iio_priv(indio_dev);
+
+ mutex_unlock(&adc->lock);
+}
+EXPORT_SYMBOL_NS_GPL(adc5_gen3_mutex_unlock, "QCOM_SPMI_ADC5_GEN3");
+
+int adc5_gen3_get_scaled_reading(struct device *dev,
+ struct adc5_channel_common_prop *common_props,
+ int *val)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
+ struct adc5_chip *adc = iio_priv(indio_dev);
+ u16 adc_code_volt;
+ int ret;
+
+ ret = adc5_gen3_do_conversion(adc, common_props, &adc_code_volt);
+ if (ret)
+ return ret;
+
+ return qcom_adc5_hw_scale(common_props->scale_fn_type,
+ common_props->prescale,
+ adc->data, adc_code_volt, val);
+}
+EXPORT_SYMBOL_NS_GPL(adc5_gen3_get_scaled_reading, "QCOM_SPMI_ADC5_GEN3");
+
+int adc5_gen3_therm_code_to_temp(struct device *dev,
+ struct adc5_channel_common_prop *common_props,
+ u16 code, int *val)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
+ struct adc5_chip *adc = iio_priv(indio_dev);
+
+ return qcom_adc5_hw_scale(common_props->scale_fn_type,
+ common_props->prescale,
+ adc->data, code, val);
+}
+EXPORT_SYMBOL_NS_GPL(adc5_gen3_therm_code_to_temp, "QCOM_SPMI_ADC5_GEN3");
+
+void adc5_gen3_register_tm_event_notifier(struct device *dev,
+ void (*handler)(struct auxiliary_device *))
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
+ struct adc5_chip *adc = iio_priv(indio_dev);
+
+ adc->handler = handler;
+}
+EXPORT_SYMBOL_NS_GPL(adc5_gen3_register_tm_event_notifier, "QCOM_SPMI_ADC5_GEN3");
+
+static int adc5_gen3_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct iio_dev *indio_dev;
+ struct adc5_chip *adc;
+ struct regmap *regmap;
+ int ret, i;
+ u32 *reg;
+
+ regmap = dev_get_regmap(dev->parent, NULL);
+ if (!regmap)
+ return -ENODEV;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ adc = iio_priv(indio_dev);
+ adc->dev_data.regmap = regmap;
+ adc->dev = dev;
+
+ ret = device_property_count_u32(dev, "reg");
+ if (ret < 0)
+ return ret;
+
+ adc->dev_data.num_sdams = ret;
+
+ reg = devm_kcalloc(dev, adc->dev_data.num_sdams, sizeof(u32),
+ GFP_KERNEL);
+ if (!reg)
+ return -ENOMEM;
+
+ ret = device_property_read_u32_array(dev, "reg", reg,
+ adc->dev_data.num_sdams);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to read reg property\n");
+
+ adc->dev_data.base = devm_kcalloc(dev, adc->dev_data.num_sdams,
+ sizeof(*adc->dev_data.base),
+ GFP_KERNEL);
+ if (!adc->dev_data.base)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, indio_dev);
+ init_completion(&adc->complete);
+ ret = devm_mutex_init(dev, &adc->lock);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < adc->dev_data.num_sdams; i++) {
+ adc->dev_data.base[i].base_addr = reg[i];
+
+ ret = platform_get_irq(pdev, i);
+ if (ret < 0)
+ return dev_err_probe(dev, ret,
+ "Getting IRQ %d failed\n", i);
+
+ adc->dev_data.base[i].irq = ret;
+
+ adc->dev_data.base[i].irq_name = devm_kasprintf(dev, GFP_KERNEL,
+ "sdam%d", i);
+ if (!adc->dev_data.base[i].irq_name)
+ return -ENOMEM;
+ }
+
+ ret = devm_request_irq(dev, adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq,
+ adc5_gen3_isr, 0,
+ adc->dev_data.base[ADC5_GEN3_VADC_SDAM].irq_name,
+ adc);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to request SDAM%d irq\n",
+ ADC5_GEN3_VADC_SDAM);
+
+ ret = adc5_get_fw_data(adc);
+ if (ret)
+ return ret;
+
+ if (adc->n_tm_channels > 0) {
+ ret = adc5_gen3_add_aux_tm_device(adc);
+ if (ret)
+ dev_err_probe(dev, ret,
+ "Failed to add auxiliary TM device\n");
+ }
+
+ indio_dev->name = "spmi-adc5-gen3";
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &adc5_gen3_info;
+ indio_dev->channels = adc->iio_chans;
+ indio_dev->num_channels = adc->nchannels;
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+
+static struct platform_driver adc5_gen3_driver = {
+ .driver = {
+ .name = "qcom-spmi-adc5-gen3",
+ .of_match_table = adc5_match_table,
+ },
+ .probe = adc5_gen3_probe,
+};
+module_platform_driver(adc5_gen3_driver);
+
+MODULE_DESCRIPTION("Qualcomm Technologies Inc. PMIC5 Gen3 ADC driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("QCOM_SPMI_ADC5_GEN3");
diff --git a/drivers/iio/adc/rohm-bd79124.c b/drivers/iio/adc/rohm-bd79124.c
index fc0452749b79..40d00bd0cc9d 100644
--- a/drivers/iio/adc/rohm-bd79124.c
+++ b/drivers/iio/adc/rohm-bd79124.c
@@ -75,7 +75,7 @@
/*
* The high limit, low limit and last measurement result are each stored in
- * 2 consequtive registers. 4 bits are in the high bits of the first register
+ * 2 consecutive registers. 4 bits are in the high bits of the first register
* and 8 bits in the next register.
*
* These macros return the address of the first reg for the given channel.
@@ -962,7 +962,7 @@ static int bd79124_hw_init(struct bd79124_data *data)
if (ret)
return ret;
- /* Enable writing the measured values to the regsters */
+ /* Enable writing the measured values to the registers */
ret = regmap_set_bits(data->map, BD79124_REG_GEN_CFG,
BD79124_MSK_STATS_EN);
if (ret)
diff --git a/drivers/iio/adc/sd_adc_modulator.c b/drivers/iio/adc/sd_adc_modulator.c
index 9f7a75168aac..218117c45ec8 100644
--- a/drivers/iio/adc/sd_adc_modulator.c
+++ b/drivers/iio/adc/sd_adc_modulator.c
@@ -77,6 +77,7 @@ static const struct iio_backend_ops sd_backend_ops = {
static const struct iio_backend_info sd_backend_info = {
.name = "sd-modulator",
.ops = &sd_backend_ops,
+ .caps = IIO_BACKEND_CAP_ENABLE,
};
static int iio_sd_mod_register(struct platform_device *pdev)
diff --git a/drivers/iio/adc/spear_adc.c b/drivers/iio/adc/spear_adc.c
index 50b0a607baeb..91995489bb1c 100644
--- a/drivers/iio/adc/spear_adc.c
+++ b/drivers/iio/adc/spear_adc.c
@@ -82,7 +82,7 @@ struct spear_adc_state {
* of register writes, then a wait for a completion callback,
* and finally a register read, during which userspace could issue
* another read request. This lock protects a read access from
- * ocurring before another one has finished.
+ * occurring before another one has finished.
*/
struct mutex lock;
u32 current_clk;
diff --git a/drivers/iio/adc/stm32-adc-core.c b/drivers/iio/adc/stm32-adc-core.c
index e39a4c0db25e..a42d82d61cb8 100644
--- a/drivers/iio/adc/stm32-adc-core.c
+++ b/drivers/iio/adc/stm32-adc-core.c
@@ -227,7 +227,7 @@ static int stm32h7_adc_clk_sel(struct platform_device *pdev,
if (priv->aclk) {
/*
* Asynchronous clock modes (e.g. ckmode == 0)
- * From spec: PLL output musn't exceed max rate
+ * From spec: PLL output mustn't exceed max rate
*/
rate = clk_get_rate(priv->aclk);
if (!rate) {
diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
index 2d7f88459c7c..46106200bb86 100644
--- a/drivers/iio/adc/stm32-adc.c
+++ b/drivers/iio/adc/stm32-adc.c
@@ -1662,7 +1662,7 @@ static irqreturn_t stm32_adc_threaded_isr(int irq, void *data)
/*
* Clear ovr bit to avoid subsequent calls to IRQ handler.
* This requires to stop ADC first. OVR bit state in ISR,
- * is propaged to CSR register by hardware.
+ * is propagated to CSR register by hardware.
*/
adc->cfg->stop_conv(indio_dev);
stm32_adc_irq_clear(indio_dev, regs->isr_ovr.mask);
diff --git a/drivers/iio/adc/sun20i-gpadc-iio.c b/drivers/iio/adc/sun20i-gpadc-iio.c
index e4dfe76e6362..861c14da75ad 100644
--- a/drivers/iio/adc/sun20i-gpadc-iio.c
+++ b/drivers/iio/adc/sun20i-gpadc-iio.c
@@ -55,7 +55,7 @@ struct sun20i_gpadc_iio {
* of register writes, then a wait for a completion callback,
* and finally a register read, during which userspace could issue
* another read request. This lock protects a read access from
- * ocurring before another one has finished.
+ * occurring before another one has finished.
*/
struct mutex lock;
};
diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c
index f2a93c63ca14..c7ffe47449e2 100644
--- a/drivers/iio/adc/ti-ads1015.c
+++ b/drivers/iio/adc/ti-ads1015.c
@@ -231,7 +231,6 @@ static const struct iio_event_spec ads1015_events[] = {
}
struct ads1015_channel_data {
- bool enabled;
unsigned int pga;
unsigned int data_rate;
};
diff --git a/drivers/iio/adc/ti-ads1119.c b/drivers/iio/adc/ti-ads1119.c
index c9cedc59cdcd..1157e606bc64 100644
--- a/drivers/iio/adc/ti-ads1119.c
+++ b/drivers/iio/adc/ti-ads1119.c
@@ -740,8 +740,7 @@ static int ads1119_probe(struct i2c_client *client)
NULL, IRQF_ONESHOT,
"ads1119", indio_dev);
if (ret)
- return dev_err_probe(dev, ret,
- "Failed to allocate irq\n");
+ return ret;
st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
indio_dev->name,
diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c
index bbe1ce577789..4e9359b259fc 100644
--- a/drivers/iio/adc/ti-ads7950.c
+++ b/drivers/iio/adc/ti-ads7950.c
@@ -47,8 +47,6 @@
#define TI_ADS7950_MAX_CHAN 16
#define TI_ADS7950_NUM_GPIOS 4
-#define TI_ADS7950_TIMESTAMP_SIZE (sizeof(int64_t) / sizeof(__be16))
-
/* val = value, dec = left shift, bits = number of bits of the mask */
#define TI_ADS7950_EXTRACT(val, dec, bits) \
(((val) >> (dec)) & ((1 << (bits)) - 1))
@@ -105,8 +103,7 @@ struct ti_ads7950_state {
* DMA (thus cache coherency maintenance) may require the
* transfer buffers to live in their own cache lines.
*/
- u16 rx_buf[TI_ADS7950_MAX_CHAN + 2 + TI_ADS7950_TIMESTAMP_SIZE]
- __aligned(IIO_DMA_MINALIGN);
+ u16 rx_buf[TI_ADS7950_MAX_CHAN + 2] __aligned(IIO_DMA_MINALIGN);
u16 tx_buf[TI_ADS7950_MAX_CHAN + 2];
u16 single_tx;
u16 single_rx;
@@ -118,21 +115,6 @@ struct ti_ads7950_chip_info {
unsigned int num_channels;
};
-enum ti_ads7950_id {
- TI_ADS7950,
- TI_ADS7951,
- TI_ADS7952,
- TI_ADS7953,
- TI_ADS7954,
- TI_ADS7955,
- TI_ADS7956,
- TI_ADS7957,
- TI_ADS7958,
- TI_ADS7959,
- TI_ADS7960,
- TI_ADS7961,
-};
-
#define TI_ADS7950_V_CHAN(index, bits) \
{ \
.type = IIO_VOLTAGE, \
@@ -225,55 +207,64 @@ static DECLARE_TI_ADS7950_8_CHANNELS(ti_ads7959, 8);
static DECLARE_TI_ADS7950_12_CHANNELS(ti_ads7960, 8);
static DECLARE_TI_ADS7950_16_CHANNELS(ti_ads7961, 8);
-static const struct ti_ads7950_chip_info ti_ads7950_chip_info[] = {
- [TI_ADS7950] = {
- .channels = ti_ads7950_channels,
- .num_channels = ARRAY_SIZE(ti_ads7950_channels),
- },
- [TI_ADS7951] = {
- .channels = ti_ads7951_channels,
- .num_channels = ARRAY_SIZE(ti_ads7951_channels),
- },
- [TI_ADS7952] = {
- .channels = ti_ads7952_channels,
- .num_channels = ARRAY_SIZE(ti_ads7952_channels),
- },
- [TI_ADS7953] = {
- .channels = ti_ads7953_channels,
- .num_channels = ARRAY_SIZE(ti_ads7953_channels),
- },
- [TI_ADS7954] = {
- .channels = ti_ads7954_channels,
- .num_channels = ARRAY_SIZE(ti_ads7954_channels),
- },
- [TI_ADS7955] = {
- .channels = ti_ads7955_channels,
- .num_channels = ARRAY_SIZE(ti_ads7955_channels),
- },
- [TI_ADS7956] = {
- .channels = ti_ads7956_channels,
- .num_channels = ARRAY_SIZE(ti_ads7956_channels),
- },
- [TI_ADS7957] = {
- .channels = ti_ads7957_channels,
- .num_channels = ARRAY_SIZE(ti_ads7957_channels),
- },
- [TI_ADS7958] = {
- .channels = ti_ads7958_channels,
- .num_channels = ARRAY_SIZE(ti_ads7958_channels),
- },
- [TI_ADS7959] = {
- .channels = ti_ads7959_channels,
- .num_channels = ARRAY_SIZE(ti_ads7959_channels),
- },
- [TI_ADS7960] = {
- .channels = ti_ads7960_channels,
- .num_channels = ARRAY_SIZE(ti_ads7960_channels),
- },
- [TI_ADS7961] = {
- .channels = ti_ads7961_channels,
- .num_channels = ARRAY_SIZE(ti_ads7961_channels),
- },
+static const struct ti_ads7950_chip_info ti_ads7950_chip_info = {
+ .channels = ti_ads7950_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7950_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7951_chip_info = {
+ .channels = ti_ads7951_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7951_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7952_chip_info = {
+ .channels = ti_ads7952_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7952_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7953_chip_info = {
+ .channels = ti_ads7953_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7953_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7954_chip_info = {
+ .channels = ti_ads7954_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7954_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7955_chip_info = {
+ .channels = ti_ads7955_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7955_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7956_chip_info = {
+ .channels = ti_ads7956_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7956_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7957_chip_info = {
+ .channels = ti_ads7957_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7957_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7958_chip_info = {
+ .channels = ti_ads7958_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7958_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7959_chip_info = {
+ .channels = ti_ads7959_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7959_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7960_chip_info = {
+ .channels = ti_ads7960_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7960_channels),
+};
+
+static const struct ti_ads7950_chip_info ti_ads7961_chip_info = {
+ .channels = ti_ads7961_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7961_channels),
};
/*
@@ -313,8 +304,10 @@ static irqreturn_t ti_ads7950_trigger_handler(int irq, void *p)
if (ret < 0)
goto out;
- iio_push_to_buffers_with_timestamp(indio_dev, &st->rx_buf[2],
- iio_get_time_ns(indio_dev));
+ iio_push_to_buffers_with_ts_unaligned(indio_dev, &st->rx_buf[2],
+ sizeof(*st->rx_buf) *
+ TI_ADS7950_MAX_CHAN,
+ iio_get_time_ns(indio_dev));
out:
mutex_unlock(&st->slock);
@@ -561,7 +554,7 @@ static int ti_ads7950_probe(struct spi_device *spi)
st->spi = spi;
- info = &ti_ads7950_chip_info[spi_get_device_id(spi)->driver_data];
+ info = spi_get_device_match_data(spi);
indio_dev->name = spi_get_device_id(spi)->name;
indio_dev->modes = INDIO_DIRECT_MODE;
@@ -683,35 +676,35 @@ static void ti_ads7950_remove(struct spi_device *spi)
}
static const struct spi_device_id ti_ads7950_id[] = {
- { "ads7950", TI_ADS7950 },
- { "ads7951", TI_ADS7951 },
- { "ads7952", TI_ADS7952 },
- { "ads7953", TI_ADS7953 },
- { "ads7954", TI_ADS7954 },
- { "ads7955", TI_ADS7955 },
- { "ads7956", TI_ADS7956 },
- { "ads7957", TI_ADS7957 },
- { "ads7958", TI_ADS7958 },
- { "ads7959", TI_ADS7959 },
- { "ads7960", TI_ADS7960 },
- { "ads7961", TI_ADS7961 },
+ { "ads7950", (kernel_ulong_t)&ti_ads7950_chip_info },
+ { "ads7951", (kernel_ulong_t)&ti_ads7951_chip_info },
+ { "ads7952", (kernel_ulong_t)&ti_ads7952_chip_info },
+ { "ads7953", (kernel_ulong_t)&ti_ads7953_chip_info },
+ { "ads7954", (kernel_ulong_t)&ti_ads7954_chip_info },
+ { "ads7955", (kernel_ulong_t)&ti_ads7955_chip_info },
+ { "ads7956", (kernel_ulong_t)&ti_ads7956_chip_info },
+ { "ads7957", (kernel_ulong_t)&ti_ads7957_chip_info },
+ { "ads7958", (kernel_ulong_t)&ti_ads7958_chip_info },
+ { "ads7959", (kernel_ulong_t)&ti_ads7959_chip_info },
+ { "ads7960", (kernel_ulong_t)&ti_ads7960_chip_info },
+ { "ads7961", (kernel_ulong_t)&ti_ads7961_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ti_ads7950_id);
static const struct of_device_id ads7950_of_table[] = {
- { .compatible = "ti,ads7950", .data = &ti_ads7950_chip_info[TI_ADS7950] },
- { .compatible = "ti,ads7951", .data = &ti_ads7950_chip_info[TI_ADS7951] },
- { .compatible = "ti,ads7952", .data = &ti_ads7950_chip_info[TI_ADS7952] },
- { .compatible = "ti,ads7953", .data = &ti_ads7950_chip_info[TI_ADS7953] },
- { .compatible = "ti,ads7954", .data = &ti_ads7950_chip_info[TI_ADS7954] },
- { .compatible = "ti,ads7955", .data = &ti_ads7950_chip_info[TI_ADS7955] },
- { .compatible = "ti,ads7956", .data = &ti_ads7950_chip_info[TI_ADS7956] },
- { .compatible = "ti,ads7957", .data = &ti_ads7950_chip_info[TI_ADS7957] },
- { .compatible = "ti,ads7958", .data = &ti_ads7950_chip_info[TI_ADS7958] },
- { .compatible = "ti,ads7959", .data = &ti_ads7950_chip_info[TI_ADS7959] },
- { .compatible = "ti,ads7960", .data = &ti_ads7950_chip_info[TI_ADS7960] },
- { .compatible = "ti,ads7961", .data = &ti_ads7950_chip_info[TI_ADS7961] },
+ { .compatible = "ti,ads7950", .data = &ti_ads7950_chip_info },
+ { .compatible = "ti,ads7951", .data = &ti_ads7951_chip_info },
+ { .compatible = "ti,ads7952", .data = &ti_ads7952_chip_info },
+ { .compatible = "ti,ads7953", .data = &ti_ads7953_chip_info },
+ { .compatible = "ti,ads7954", .data = &ti_ads7954_chip_info },
+ { .compatible = "ti,ads7955", .data = &ti_ads7955_chip_info },
+ { .compatible = "ti,ads7956", .data = &ti_ads7956_chip_info },
+ { .compatible = "ti,ads7957", .data = &ti_ads7957_chip_info },
+ { .compatible = "ti,ads7958", .data = &ti_ads7958_chip_info },
+ { .compatible = "ti,ads7959", .data = &ti_ads7959_chip_info },
+ { .compatible = "ti,ads7960", .data = &ti_ads7960_chip_info },
+ { .compatible = "ti,ads7961", .data = &ti_ads7961_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ads7950_of_table);
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index a1a28584de93..1516dd332f90 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -113,10 +113,10 @@ static void tiadc_step_config(struct iio_dev *indio_dev)
* There are 16 configurable steps and 8 analog input
* lines available which are shared between Touchscreen and ADC.
*
- * Steps forwards i.e. from 0 towards 16 are used by ADC
- * depending on number of input lines needed.
+ * Steps forward, i.e. from 0 towards 16, are used by ADC
+ * depending on the number of input lines needed.
* Channel would represent which analog input
- * needs to be given to ADC to digitalize data.
+ * needs to be given to ADC to digitize data.
*/
for (i = 0; i < adc_dev->channels; i++) {
int chan;
diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c
index fe3b31ec976e..f0274cd74973 100644
--- a/drivers/iio/adc/twl4030-madc.c
+++ b/drivers/iio/adc/twl4030-madc.c
@@ -252,7 +252,7 @@ static const struct s16_fract twl4030_divider_ratios[16] = {
{5, 11}, /* CHANNEL 15 */
};
-/* Conversion table from -3 to 55 degrees Celcius */
+/* Conversion table from -3 to 55 degrees Celsius */
static int twl4030_therm_tbl[] = {
30800, 29500, 28300, 27100,
26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700,
diff --git a/drivers/iio/adc/twl6030-gpadc.c b/drivers/iio/adc/twl6030-gpadc.c
index 3ac774ebf678..7810d6b2b668 100644
--- a/drivers/iio/adc/twl6030-gpadc.c
+++ b/drivers/iio/adc/twl6030-gpadc.c
@@ -416,7 +416,7 @@ static u8 twl6032_channel_to_reg(int channel)
{
/*
* for any prior chosen channel, when the conversion is ready
- * the result is avalable in GPCH0_LSB, GPCH0_MSB.
+ * the result is available in GPCH0_LSB, GPCH0_MSB.
*/
return TWL6032_GPADC_GPCH0_LSB;
diff --git a/drivers/iio/addac/ad74413r.c b/drivers/iio/addac/ad74413r.c
index a20b4d48c5f7..fe930ce5ee30 100644
--- a/drivers/iio/addac/ad74413r.c
+++ b/drivers/iio/addac/ad74413r.c
@@ -839,12 +839,9 @@ static int _ad74413r_get_single_adc_result(struct ad74413r_state *st,
if (ret)
return ret;
- ret = wait_for_completion_timeout(&st->adc_data_completion,
- msecs_to_jiffies(1000));
- if (!ret) {
- ret = -ETIMEDOUT;
- return ret;
- }
+ if (!wait_for_completion_timeout(&st->adc_data_completion,
+ msecs_to_jiffies(1000)))
+ return -ETIMEDOUT;
ret = regmap_read(st->regmap, AD74413R_REG_ADC_RESULT_X(channel),
&uval);
diff --git a/drivers/iio/amplifiers/Kconfig b/drivers/iio/amplifiers/Kconfig
index a8a604863eed..9e24421b5e97 100644
--- a/drivers/iio/amplifiers/Kconfig
+++ b/drivers/iio/amplifiers/Kconfig
@@ -18,7 +18,15 @@ config AD8366
AD8366 Dual-Digital Variable Gain Amplifier (VGA)
ADA4961 BiCMOS RF Digital Gain Amplifier (DGA)
ADL5240 Digitally controlled variable gain amplifier (VGA)
+ ADRF5702: 0.125 dB LSB, 8-Bit, Silicon Digital Attenuator
+ ADRF5703: 0.25 dB LSB, 7-Bit, Silicon Digital Attenuator
+ ADRF5720: 0.5 dB LSB, 6-Bit, Silicon Digital Attenuator
+ ADRF5730: 0.5 dB LSB, 6-Bit, Silicon Digital Attenuator
+ ADRF5731: 2 dB LSB, 4-Bit, Silicon Digital Attenuator
+ HMC271A: 1dB LSB 5-Bit Digital Attenuator SMT
HMC792A 0.25 dB LSB GaAs MMIC 6-Bit Digital Attenuator
+ HMC1018A: 1.0 dB LSB GaAs MMIC 5-BIT Digital Attenuator
+ HMC1019A: 0.5 dB LSB GaAs MMIC 5-BIT Digital Attenuator
HMC1119 0.25 dB LSB, 7-Bit, Silicon Digital Attenuator
To compile this driver as a module, choose M here: the
diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c
index d06ac786501c..bbf41a1fb3a1 100644
--- a/drivers/iio/amplifiers/ad8366.c
+++ b/drivers/iio/amplifiers/ad8366.c
@@ -5,46 +5,52 @@
* AD8366 Dual-Digital Variable Gain Amplifier (VGA)
* ADA4961 BiCMOS RF Digital Gain Amplifier (DGA)
* ADL5240 Digitally controlled variable gain amplifier (VGA)
+ * ADRF5702: 0.125 dB LSB, 8-Bit, Silicon Digital Attenuator, 50 MHz to 20 GHz
+ * ADRF5703: 0.25 dB LSB, 7-Bit, Silicon Digital Attenuator, 9 kHz to 20 GHz
+ * ADRF5720: 0.5 dB LSB, 6-Bit, Silicon Digital Attenuator, 9 kHz to 40 GHz
+ * ADRF5730: 0.5 dB LSB, 6-Bit, Silicon Digital Attenuator, 100 MHz to 40 GHz
+ * ADRF5731: 2 dB LSB, 4-Bit, Silicon Digital Attenuator, 100 MHz to 40 GHz
+ * HMC271A: 1dB LSB 5-Bit Digital Attenuator SMT, 0.7 - 3.7 GHz
* HMC792A 0.25 dB LSB GaAs MMIC 6-Bit Digital Attenuator
+ * HMC1018A: 1.0 dB LSB GaAs MMIC 5-BIT DIGITAL ATTENUATOR, 0.1 - 30 GHz
+ * HMC1019A: 0.5 dB LSB GaAs MMIC 5-BIT DIGITAL ATTENUATOR, 0.1 - 30 GHz
* HMC1119 0.25 dB LSB, 7-Bit, Silicon Digital Attenuator
*
- * Copyright 2012-2019 Analog Devices Inc.
+ * Copyright 2012-2026 Analog Devices Inc.
*/
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/spi/spi.h>
-#include <linux/regulator/consumer.h>
-#include <linux/gpio/consumer.h>
+#include <linux/bitrev.h>
+#include <linux/bits.h>
+#include <linux/dev_printk.h>
#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/math.h>
+#include <linux/minmax.h>
+#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/bitrev.h>
+#include <linux/mutex.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/spi/spi.h>
+#include <linux/types.h>
+#include <linux/unaligned.h>
#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-
-enum ad8366_type {
- ID_AD8366,
- ID_ADA4961,
- ID_ADL5240,
- ID_HMC792,
- ID_HMC1119,
-};
struct ad8366_info {
+ const char *name;
int gain_min;
int gain_max;
+ int gain_step;
+ size_t num_channels;
+ size_t (*pack_code)(const unsigned char *code, size_t num_channels,
+ unsigned char *data);
};
struct ad8366_state {
struct spi_device *spi;
- struct regulator *reg;
struct mutex lock; /* protect sensor state */
- struct gpio_desc *reset_gpio;
unsigned char ch[2];
- enum ad8366_type type;
const struct ad8366_info *info;
/*
* DMA (thus cache coherency maintenance) may require the
@@ -53,60 +59,148 @@ struct ad8366_state {
unsigned char data[2] __aligned(IIO_DMA_MINALIGN);
};
-static const struct ad8366_info ad8366_infos[] = {
- [ID_AD8366] = {
- .gain_min = 4500,
- .gain_max = 20500,
- },
- [ID_ADA4961] = {
- .gain_min = -6000,
- .gain_max = 15000,
- },
- [ID_ADL5240] = {
- .gain_min = -11500,
- .gain_max = 20000,
- },
- [ID_HMC792] = {
- .gain_min = -15750,
- .gain_max = 0,
- },
- [ID_HMC1119] = {
- .gain_min = -31750,
- .gain_max = 0,
- },
-};
+static size_t ad8366_pack_code(const unsigned char *code, size_t num_channels,
+ unsigned char *data)
+{
+ u8 ch_a = bitrev8(code[0]) >> 2;
+ u8 ch_b = bitrev8(code[1]) >> 2;
+
+ put_unaligned_be16((ch_b << 6) | ch_a, &data[0]);
+ return sizeof(__be16);
+}
-static int ad8366_write(struct iio_dev *indio_dev,
- unsigned char ch_a, unsigned char ch_b)
+static size_t adrf5731_pack_code(const unsigned char *code, size_t num_channels,
+ unsigned char *data)
{
- struct ad8366_state *st = iio_priv(indio_dev);
- int ret;
+ data[0] = code[0] << 2;
+ return 1;
+}
- switch (st->type) {
- case ID_AD8366:
- ch_a = bitrev8(ch_a & 0x3F);
- ch_b = bitrev8(ch_b & 0x3F);
+static size_t hmc271_pack_code(const unsigned char *code, size_t num_channels,
+ unsigned char *data)
+{
+ data[0] = bitrev8(code[0]) >> 3;
+ return 1;
+}
- st->data[0] = ch_b >> 4;
- st->data[1] = (ch_b << 4) | (ch_a >> 2);
- break;
- case ID_ADA4961:
- st->data[0] = ch_a & 0x1F;
- break;
- case ID_ADL5240:
- st->data[0] = (ch_a & 0x3F);
- break;
- case ID_HMC792:
- case ID_HMC1119:
- st->data[0] = ch_a;
- break;
- }
+static const struct ad8366_info ad8366_chip_info = {
+ .name = "ad8366",
+ .gain_min = 4500,
+ .gain_max = 20500,
+ .gain_step = 253,
+ .num_channels = 2,
+ .pack_code = ad8366_pack_code,
+};
- ret = spi_write(st->spi, st->data, indio_dev->num_channels);
- if (ret < 0)
- dev_err(&indio_dev->dev, "write failed (%d)", ret);
+static const struct ad8366_info ada4961_chip_info = {
+ .name = "ada4961",
+ .gain_min = -6000,
+ .gain_max = 15000,
+ .gain_step = -1000,
+ .num_channels = 1,
+};
- return ret;
+static const struct ad8366_info adl5240_chip_info = {
+ .name = "adl5240",
+ .gain_min = -11500,
+ .gain_max = 20000,
+ .gain_step = 500,
+ .num_channels = 1,
+};
+
+static const struct ad8366_info adrf5702_chip_info = {
+ .name = "adrf5702",
+ .gain_min = -31875,
+ .gain_max = 0,
+ .gain_step = -125,
+ .num_channels = 1,
+};
+
+static const struct ad8366_info adrf5703_chip_info = {
+ .name = "adrf5703",
+ .gain_min = -31750,
+ .gain_max = 0,
+ .gain_step = -250,
+ .num_channels = 1,
+};
+
+static const struct ad8366_info adrf5720_chip_info = {
+ .name = "adrf5720",
+ .gain_min = -31500,
+ .gain_max = 0,
+ .gain_step = -500,
+ .num_channels = 1,
+};
+
+static const struct ad8366_info adrf5730_chip_info = {
+ .name = "adrf5730",
+ .gain_min = -31500,
+ .gain_max = 0,
+ .gain_step = -500,
+ .num_channels = 1,
+};
+
+static const struct ad8366_info adrf5731_chip_info = {
+ .name = "adrf5731",
+ .gain_min = -30000,
+ .gain_max = 0,
+ .gain_step = -2000,
+ .num_channels = 1,
+ .pack_code = adrf5731_pack_code,
+};
+
+static const struct ad8366_info hmc271_chip_info = {
+ .name = "hmc271a",
+ .gain_min = -31000,
+ .gain_max = 0,
+ .gain_step = 1000,
+ .num_channels = 1,
+ .pack_code = hmc271_pack_code,
+};
+
+static const struct ad8366_info hmc792_chip_info = {
+ .name = "hmc792a",
+ .gain_min = -15750,
+ .gain_max = 0,
+ .gain_step = 250,
+ .num_channels = 1,
+};
+
+static const struct ad8366_info hmc1018_chip_info = {
+ .name = "hmc1018a",
+ .gain_min = -31000,
+ .gain_max = 0,
+ .gain_step = 1000,
+ .num_channels = 1,
+};
+
+static const struct ad8366_info hmc1019_chip_info = {
+ .name = "hmc1019a",
+ .gain_min = -15500,
+ .gain_max = 0,
+ .gain_step = 500,
+ .num_channels = 1,
+};
+
+static const struct ad8366_info hmc1119_chip_info = {
+ .name = "hmc1119",
+ .gain_min = -31750,
+ .gain_max = 0,
+ .gain_step = -250,
+ .num_channels = 1,
+};
+
+static int ad8366_write_code(struct ad8366_state *st)
+{
+ const struct ad8366_info *inf = st->info;
+ size_t len = 1;
+
+ if (inf->pack_code)
+ len = inf->pack_code(st->ch, inf->num_channels, st->data);
+ else
+ st->data[0] = st->ch[0];
+
+ return spi_write(st->spi, st->data, len);
}
static int ad8366_read_raw(struct iio_dev *indio_dev,
@@ -116,6 +210,7 @@ static int ad8366_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad8366_state *st = iio_priv(indio_dev);
+ const struct ad8366_info *inf = st->info;
int ret;
int code, gain = 0;
@@ -123,25 +218,8 @@ static int ad8366_read_raw(struct iio_dev *indio_dev,
switch (m) {
case IIO_CHAN_INFO_HARDWAREGAIN:
code = st->ch[chan->channel];
-
- switch (st->type) {
- case ID_AD8366:
- gain = code * 253 + 4500;
- break;
- case ID_ADA4961:
- gain = 15000 - code * 1000;
- break;
- case ID_ADL5240:
- gain = 20000 - 31500 + code * 500;
- break;
- case ID_HMC792:
- gain = -1 * code * 500;
- break;
- case ID_HMC1119:
- gain = -1 * code * 250;
- break;
- }
-
+ gain = inf->gain_step > 0 ? inf->gain_min : inf->gain_max;
+ gain += inf->gain_step * code;
/* Values in dB */
*val = gain / 1000;
*val2 = (gain % 1000) * 1000;
@@ -176,29 +254,14 @@ static int ad8366_write_raw(struct iio_dev *indio_dev,
if (gain > inf->gain_max || gain < inf->gain_min)
return -EINVAL;
- switch (st->type) {
- case ID_AD8366:
- code = (gain - 4500) / 253;
- break;
- case ID_ADA4961:
- code = (15000 - gain) / 1000;
- break;
- case ID_ADL5240:
- code = ((gain - 500 - 20000) / 500) & 0x3F;
- break;
- case ID_HMC792:
- code = (abs(gain) / 500) & 0x3F;
- break;
- case ID_HMC1119:
- code = (abs(gain) / 250) & 0x7F;
- break;
- }
+ gain -= inf->gain_step > 0 ? inf->gain_min : inf->gain_max;
+ code = DIV_ROUND_CLOSEST(gain, inf->gain_step);
mutex_lock(&st->lock);
switch (mask) {
case IIO_CHAN_INFO_HARDWAREGAIN:
st->ch[chan->channel] = code;
- ret = ad8366_write(indio_dev, st->ch[0], st->ch[1]);
+ ret = ad8366_write_code(st);
break;
default:
ret = -EINVAL;
@@ -239,107 +302,97 @@ static const struct iio_chan_spec ad8366_channels[] = {
AD8366_CHAN(1),
};
-static const struct iio_chan_spec ada4961_channels[] = {
- AD8366_CHAN(0),
-};
-
static int ad8366_probe(struct spi_device *spi)
{
+ struct device *dev = &spi->dev;
+ struct gpio_desc *enable_gpio;
+ struct reset_control *rstc;
struct iio_dev *indio_dev;
struct ad8366_state *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;
st = iio_priv(indio_dev);
- st->reg = devm_regulator_get(&spi->dev, "vcc");
- if (!IS_ERR(st->reg)) {
- ret = regulator_enable(st->reg);
- if (ret)
- return ret;
- }
+ ret = devm_mutex_init(dev, &st->lock);
+ if (ret)
+ return ret;
+
+ ret = devm_regulator_get_enable(dev, "vcc");
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get regulator\n");
- spi_set_drvdata(spi, indio_dev);
- mutex_init(&st->lock);
st->spi = spi;
- st->type = spi_get_device_id(spi)->driver_data;
+ st->info = spi_get_device_match_data(spi);
- switch (st->type) {
- case ID_AD8366:
- indio_dev->channels = ad8366_channels;
- indio_dev->num_channels = ARRAY_SIZE(ad8366_channels);
- break;
- case ID_ADA4961:
- case ID_ADL5240:
- case ID_HMC792:
- case ID_HMC1119:
- st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_HIGH);
- if (IS_ERR(st->reset_gpio)) {
- ret = PTR_ERR(st->reset_gpio);
- goto error_disable_reg;
- }
- indio_dev->channels = ada4961_channels;
- indio_dev->num_channels = ARRAY_SIZE(ada4961_channels);
- break;
- default:
- dev_err(&spi->dev, "Invalid device ID\n");
- ret = -EINVAL;
- goto error_disable_reg;
- }
+ enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
+ if (IS_ERR(enable_gpio))
+ return dev_err_probe(dev, PTR_ERR(enable_gpio),
+ "Failed to get enable GPIO\n");
+
+ rstc = devm_reset_control_get_optional_exclusive_deasserted(dev, NULL);
+ if (IS_ERR(rstc))
+ return dev_err_probe(dev, PTR_ERR(rstc),
+ "Failed to get reset controller\n");
- st->info = &ad8366_infos[st->type];
- indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->name = st->info->name;
indio_dev->info = &ad8366_info;
indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = ad8366_channels;
+ indio_dev->num_channels = st->info->num_channels;
- ret = ad8366_write(indio_dev, 0, 0);
+ ret = ad8366_write_code(st);
if (ret < 0)
- goto error_disable_reg;
-
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_disable_reg;
-
- return 0;
+ return dev_err_probe(dev, ret, "failed to write initial gain\n");
-error_disable_reg:
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
-
- return ret;
-}
-
-static void ad8366_remove(struct spi_device *spi)
-{
- struct iio_dev *indio_dev = spi_get_drvdata(spi);
- struct ad8366_state *st = iio_priv(indio_dev);
- struct regulator *reg = st->reg;
-
- iio_device_unregister(indio_dev);
-
- if (!IS_ERR(reg))
- regulator_disable(reg);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id ad8366_id[] = {
- {"ad8366", ID_AD8366},
- {"ada4961", ID_ADA4961},
- {"adl5240", ID_ADL5240},
- {"hmc792a", ID_HMC792},
- {"hmc1119", ID_HMC1119},
+ { "ad8366", (kernel_ulong_t)&ad8366_chip_info },
+ { "ada4961", (kernel_ulong_t)&ada4961_chip_info },
+ { "adl5240", (kernel_ulong_t)&adl5240_chip_info },
+ { "adrf5702", (kernel_ulong_t)&adrf5702_chip_info },
+ { "adrf5703", (kernel_ulong_t)&adrf5703_chip_info },
+ { "adrf5720", (kernel_ulong_t)&adrf5720_chip_info },
+ { "adrf5730", (kernel_ulong_t)&adrf5730_chip_info },
+ { "adrf5731", (kernel_ulong_t)&adrf5731_chip_info },
+ { "hmc271a", (kernel_ulong_t)&hmc271_chip_info },
+ { "hmc792a", (kernel_ulong_t)&hmc792_chip_info },
+ { "hmc1018a", (kernel_ulong_t)&hmc1018_chip_info },
+ { "hmc1019a", (kernel_ulong_t)&hmc1019_chip_info },
+ { "hmc1119", (kernel_ulong_t)&hmc1119_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ad8366_id);
+static const struct of_device_id ad8366_of_match[] = {
+ { .compatible = "adi,ad8366", .data = &ad8366_chip_info },
+ { .compatible = "adi,ada4961", .data = &ada4961_chip_info },
+ { .compatible = "adi,adl5240", .data = &adl5240_chip_info },
+ { .compatible = "adi,adrf5702", .data = &adrf5702_chip_info },
+ { .compatible = "adi,adrf5703", .data = &adrf5703_chip_info },
+ { .compatible = "adi,adrf5720", .data = &adrf5720_chip_info },
+ { .compatible = "adi,adrf5730", .data = &adrf5730_chip_info },
+ { .compatible = "adi,adrf5731", .data = &adrf5731_chip_info },
+ { .compatible = "adi,hmc271a", .data = &hmc271_chip_info },
+ { .compatible = "adi,hmc792a", .data = &hmc792_chip_info },
+ { .compatible = "adi,hmc1018a", .data = &hmc1018_chip_info },
+ { .compatible = "adi,hmc1019a", .data = &hmc1019_chip_info },
+ { .compatible = "adi,hmc1119", .data = &hmc1119_chip_info },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ad8366_of_match);
+
static struct spi_driver ad8366_driver = {
.driver = {
- .name = KBUILD_MODNAME,
+ .name = KBUILD_MODNAME,
+ .of_match_table = ad8366_of_match,
},
.probe = ad8366_probe,
- .remove = ad8366_remove,
.id_table = ad8366_id,
};
diff --git a/drivers/iio/amplifiers/ada4250.c b/drivers/iio/amplifiers/ada4250.c
index 40f396ea9069..71e361af2074 100644
--- a/drivers/iio/amplifiers/ada4250.c
+++ b/drivers/iio/amplifiers/ada4250.c
@@ -109,7 +109,7 @@ static int ada4250_set_offset_uv(struct iio_dev *indio_dev,
/*
* Compute Range and Voltage per LSB for the Sensor Offset Calibration
- * Example of computation for Range 1 and Range 2 (Curren Bias Set = AVDD):
+ * Example of computation for Range 1 and Range 2 (Current Bias Set = AVDD):
* Range 1 Range 2
* Gain | Max Vos(mV) | LSB(mV) | Max Vos(mV) | LSB(mV) |
* 2 | X1*127 | X1=0.126(AVDD-1) | X1*3*127 | X1*3 |
diff --git a/drivers/iio/buffer/industrialio-hw-consumer.c b/drivers/iio/buffer/industrialio-hw-consumer.c
index cb771ef8eeb3..24d7df603760 100644
--- a/drivers/iio/buffer/industrialio-hw-consumer.c
+++ b/drivers/iio/buffer/industrialio-hw-consumer.c
@@ -28,7 +28,6 @@ struct hw_consumer_buffer {
struct list_head head;
struct iio_dev *indio_dev;
struct iio_buffer buffer;
- long scan_mask[];
};
static struct hw_consumer_buffer *iio_buffer_to_hw_consumer_buffer(
@@ -52,7 +51,6 @@ static const struct iio_buffer_access_funcs iio_hw_buf_access = {
static struct hw_consumer_buffer *iio_hw_consumer_get_buffer(
struct iio_hw_consumer *hwc, struct iio_dev *indio_dev)
{
- unsigned int mask_longs = BITS_TO_LONGS(iio_get_masklength(indio_dev));
struct hw_consumer_buffer *buf;
list_for_each_entry(buf, &hwc->buffers, head) {
@@ -60,13 +58,18 @@ static struct hw_consumer_buffer *iio_hw_consumer_get_buffer(
return buf;
}
- buf = kzalloc_flex(*buf, scan_mask, mask_longs);
+ buf = kzalloc_obj(*buf);
if (!buf)
return NULL;
buf->buffer.access = &iio_hw_buf_access;
buf->indio_dev = indio_dev;
- buf->buffer.scan_mask = buf->scan_mask;
+ buf->buffer.scan_mask = bitmap_zalloc(iio_get_masklength(indio_dev),
+ GFP_KERNEL);
+ if (!buf->buffer.scan_mask) {
+ kfree(buf);
+ return NULL;
+ }
iio_buffer_init(&buf->buffer);
list_add_tail(&buf->head, &hwc->buffers);
diff --git a/drivers/iio/buffer/kfifo_buf.c b/drivers/iio/buffer/kfifo_buf.c
index a6ff9085b8a2..b67ea6468226 100644
--- a/drivers/iio/buffer/kfifo_buf.c
+++ b/drivers/iio/buffer/kfifo_buf.c
@@ -224,35 +224,9 @@ void iio_kfifo_free(struct iio_buffer *r)
}
EXPORT_SYMBOL(iio_kfifo_free);
-static void devm_iio_kfifo_release(struct device *dev, void *res)
+static void devm_iio_kfifo_release(void *buffer)
{
- iio_kfifo_free(*(struct iio_buffer **)res);
-}
-
-/**
- * devm_iio_kfifo_allocate - Resource-managed iio_kfifo_allocate()
- * @dev: Device to allocate kfifo buffer for
- *
- * RETURNS:
- * Pointer to allocated iio_buffer on success, NULL on failure.
- */
-static struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev)
-{
- struct iio_buffer **ptr, *r;
-
- ptr = devres_alloc(devm_iio_kfifo_release, sizeof(*ptr), GFP_KERNEL);
- if (!ptr)
- return NULL;
-
- r = iio_kfifo_allocate();
- if (r) {
- *ptr = r;
- devres_add(dev, ptr);
- } else {
- devres_free(ptr);
- }
-
- return r;
+ iio_kfifo_free(buffer);
}
/**
@@ -262,10 +236,12 @@ static struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev)
* @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
*
- * This function allocates a kfifo buffer via devm_iio_kfifo_allocate() and
+ * This function allocates a kfifo buffer via iio_kfifo_allocate() and
* attaches it to the IIO device via iio_device_attach_buffer().
* This is meant to be a bit of a short-hand/helper function as there are a few
* drivers that seem to do this.
+ *
+ * Return: 0 on success, negative error code on failure.
*/
int devm_iio_kfifo_buffer_setup_ext(struct device *dev,
struct iio_dev *indio_dev,
@@ -273,11 +249,16 @@ int devm_iio_kfifo_buffer_setup_ext(struct device *dev,
const struct iio_dev_attr **buffer_attrs)
{
struct iio_buffer *buffer;
+ int ret;
- buffer = devm_iio_kfifo_allocate(dev);
+ buffer = iio_kfifo_allocate();
if (!buffer)
return -ENOMEM;
+ ret = devm_add_action_or_reset(dev, devm_iio_kfifo_release, buffer);
+ if (ret)
+ return ret;
+
indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
indio_dev->setup_ops = setup_ops;
diff --git a/drivers/iio/cdc/ad7150.c b/drivers/iio/cdc/ad7150.c
index 427d32e398b3..8106a6a83561 100644
--- a/drivers/iio/cdc/ad7150.c
+++ b/drivers/iio/cdc/ad7150.c
@@ -306,7 +306,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
dir);
if (ret)
goto error_ret;
- /* reenable any irq's we disabled whilst changing mode */
+ /* re-enable any IRQs we disabled whilst changing mode */
enable_irq(chip->interrupts[0]);
enable_irq(chip->interrupts[1]);
}
diff --git a/drivers/iio/cdc/ad7746.c b/drivers/iio/cdc/ad7746.c
index 8a306d55c72a..cb97e3c978d8 100644
--- a/drivers/iio/cdc/ad7746.c
+++ b/drivers/iio/cdc/ad7746.c
@@ -606,7 +606,7 @@ static int ad7746_read_channel(struct iio_dev *indio_dev,
return ret;
/*
- * Offset applied internally becaue the _offset userspace interface is
+ * Offset applied internally because the _offset userspace interface is
* needed for the CAP DACs which apply a controllable offset.
*/
*val = get_unaligned_be24(data) - 0x800000;
diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c
index 24e0b59e2fdf..6aeac132394c 100644
--- a/drivers/iio/chemical/bme680_core.c
+++ b/drivers/iio/chemical/bme680_core.c
@@ -807,7 +807,7 @@ static int bme680_read_gas(struct bme680_data *data, int *comp_gas_res)
adc_gas_res = FIELD_GET(BME680_ADC_GAS_RES, gas_regs_val);
/*
- * occurs if either the gas heating duration was insuffient
+ * This may occur if either the gas heating duration was insufficient
* to reach the target heater temperature or the target
* heater temperature was too high for the heater sink to
* reach.
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
index 82cef4a12442..f34e2bbba2d1 100644
--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
@@ -106,7 +106,7 @@ static int cros_ec_sensors_read(struct iio_dev *indio_dev,
switch (st->core.type) {
case MOTIONSENSE_TYPE_ACCEL:
/*
- * EC returns data in g, iio exepects m/s^2.
+ * EC returns data in g, IIO expects m/s^2.
* Do not use IIO_G_TO_M_S_2 to avoid precision loss.
*/
*val = div_s64(val64 * 980665, 10);
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
index a61428bfdce3..c115a72832b2 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -346,7 +346,7 @@ int hid_sensor_write_raw_hyst_rel_value(struct hid_sensor_common *st,
EXPORT_SYMBOL_NS(hid_sensor_write_raw_hyst_rel_value, "IIO_HID");
/*
- * This fuction applies the unit exponent to the scale.
+ * This function applies the unit exponent to the scale.
* For example:
* 9.806650000 ->exp:2-> val0[980]val1[665000000]
* 9.000806000 ->exp:2-> val0[900]val1[80600000]
diff --git a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
index 97526ba87b93..e0b10366ed2b 100644
--- a/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
+++ b/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
@@ -154,7 +154,7 @@ void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
valid = inv_update_chip_period(ts, period);
}
- /* no previous data, compute theoritical value from interrupt */
+ /* no previous data, compute theoretical value from interrupt */
if (ts->timestamp == 0) {
/* elapsed time: sensor period * sensor samples number */
interval = (int64_t)ts->period * (int64_t)sample_nb;
@@ -185,7 +185,7 @@ void inv_sensors_timestamp_apply_odr(struct inv_sensors_timestamp *ts,
/*
* After ODR change the time interval with the previous sample is
- * undertermined (depends when the change occures). So we compute the
+ * undertermined (depends when the change occurs). So we compute the
* timestamp from the current interrupt using the new FIFO period, the
* total number of samples and the current sample numero.
*/
diff --git a/drivers/iio/common/ms_sensors/ms_sensors_i2c.c b/drivers/iio/common/ms_sensors/ms_sensors_i2c.c
index 588470863681..1960a2ce82a8 100644
--- a/drivers/iio/common/ms_sensors/ms_sensors_i2c.c
+++ b/drivers/iio/common/ms_sensors/ms_sensors_i2c.c
@@ -96,7 +96,7 @@ EXPORT_SYMBOL_NS(ms_sensors_read_prom_word, "IIO_MEAS_SPEC_SENSORS");
*
* Generic ADC conversion & read function for Measurement Specialties
* devices.
- * The function will issue conversion command, sleep appopriate delay, and
+ * The function will issue conversion command, sleep appropriate delay, and
* issue command to read ADC.
*
* Return: 0 on success, negative errno otherwise.
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index dac593be5695..dbc5e16fbde4 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -501,14 +501,12 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits +
ch->scan_type.shift, 8);
- outdata = kmalloc(byte_for_channel, GFP_DMA | GFP_KERNEL);
- if (!outdata)
- return -ENOMEM;
+ outdata = sdata->buffer_data;
err = regmap_bulk_read(sdata->regmap, ch->address,
outdata, byte_for_channel);
if (err < 0)
- goto st_sensors_free_memory;
+ return err;
if (byte_for_channel == 1)
*data = (s8)*outdata;
@@ -517,10 +515,7 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
else if (byte_for_channel == 3)
*data = (s32)sign_extend32(get_unaligned_le24(outdata), 23);
-st_sensors_free_memory:
- kfree(outdata);
-
- return err;
+ return 0;
}
int st_sensors_read_info_raw(struct iio_dev *indio_dev,
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index db9f5c711b3d..cd4870b65415 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -408,6 +408,7 @@ config DPOT_DAC
config DS4424
tristate "Maxim Integrated DS4422/DS4424 DAC driver"
depends on I2C
+ select REGMAP_I2C
help
If you say yes here you get support for Maxim chips DS4422, DS4424.
diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c
index bd32fa57b1d7..20316fd568e6 100644
--- a/drivers/iio/dac/ad5360.c
+++ b/drivers/iio/dac/ad5360.c
@@ -206,14 +206,10 @@ static int ad5360_write_unlocked(struct iio_dev *indio_dev,
static int ad5360_write(struct iio_dev *indio_dev, unsigned int cmd,
unsigned int addr, unsigned int val, unsigned int shift)
{
- int ret;
struct ad5360_state *st = iio_priv(indio_dev);
- mutex_lock(&st->lock);
- ret = ad5360_write_unlocked(indio_dev, cmd, addr, val, shift);
- mutex_unlock(&st->lock);
-
- return ret;
+ guard(mutex)(&st->lock);
+ return ad5360_write_unlocked(indio_dev, cmd, addr, val, shift);
}
static int ad5360_read(struct iio_dev *indio_dev, unsigned int type,
@@ -232,7 +228,7 @@ static int ad5360_read(struct iio_dev *indio_dev, unsigned int type,
},
};
- mutex_lock(&st->lock);
+ guard(mutex)(&st->lock);
st->data[0].d32 = cpu_to_be32(AD5360_CMD(AD5360_CMD_SPECIAL_FUNCTION) |
AD5360_ADDR(AD5360_REG_SF_READBACK) |
@@ -240,12 +236,10 @@ static int ad5360_read(struct iio_dev *indio_dev, unsigned int type,
AD5360_READBACK_ADDR(addr));
ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
- if (ret >= 0)
- ret = be32_to_cpu(st->data[1].d32) & 0xffff;
-
- mutex_unlock(&st->lock);
+ if (ret < 0)
+ return ret;
- return ret;
+ return be32_to_cpu(st->data[1].d32) & 0xffff;
}
static ssize_t ad5360_read_dac_powerdown(struct device *dev,
@@ -262,19 +256,14 @@ static int ad5360_update_ctrl(struct iio_dev *indio_dev, unsigned int set,
unsigned int clr)
{
struct ad5360_state *st = iio_priv(indio_dev);
- int ret;
- mutex_lock(&st->lock);
+ guard(mutex)(&st->lock);
st->ctrl |= set;
st->ctrl &= ~clr;
- ret = ad5360_write_unlocked(indio_dev, AD5360_CMD_SPECIAL_FUNCTION,
- AD5360_REG_SF_CTRL, st->ctrl, 0);
-
- mutex_unlock(&st->lock);
-
- return ret;
+ return ad5360_write_unlocked(indio_dev, AD5360_CMD_SPECIAL_FUNCTION,
+ AD5360_REG_SF_CTRL, st->ctrl, 0);
}
static ssize_t ad5360_write_dac_powerdown(struct device *dev,
diff --git a/drivers/iio/dac/ad7293.c b/drivers/iio/dac/ad7293.c
index c3797e40cdd9..df6f126abf05 100644
--- a/drivers/iio/dac/ad7293.c
+++ b/drivers/iio/dac/ad7293.c
@@ -776,27 +776,27 @@ static int ad7293_reset(struct ad7293_state *st)
static int ad7293_properties_parse(struct ad7293_state *st)
{
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
int ret;
- ret = devm_regulator_get_enable(&spi->dev, "avdd");
+ ret = devm_regulator_get_enable(dev, "avdd");
if (ret)
- return dev_err_probe(&spi->dev, ret, "failed to enable AVDD\n");
+ return dev_err_probe(dev, ret, "failed to enable AVDD\n");
- ret = devm_regulator_get_enable(&spi->dev, "vdrive");
+ ret = devm_regulator_get_enable(dev, "vdrive");
if (ret)
- return dev_err_probe(&spi->dev, ret, "failed to enable VDRIVE\n");
+ return dev_err_probe(dev, ret, "failed to enable VDRIVE\n");
- ret = devm_regulator_get_enable_optional(&spi->dev, "vrefin");
+ ret = devm_regulator_get_enable_optional(dev, "vrefin");
if (ret < 0 && ret != -ENODEV)
- return dev_err_probe(&spi->dev, ret, "failed to enable VREFIN\n");
+ return dev_err_probe(dev, ret, "failed to enable VREFIN\n");
st->vrefin_en = ret != -ENODEV;
- st->gpio_reset = devm_gpiod_get_optional(&st->spi->dev, "reset",
+ st->gpio_reset = devm_gpiod_get_optional(dev, "reset",
GPIOD_OUT_HIGH);
if (IS_ERR(st->gpio_reset))
- return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_reset),
+ return dev_err_probe(dev, PTR_ERR(st->gpio_reset),
"failed to get the reset GPIO\n");
return 0;
@@ -806,7 +806,7 @@ static int ad7293_init(struct ad7293_state *st)
{
int ret;
u16 chip_id;
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
ret = ad7293_properties_parse(st);
if (ret)
@@ -821,10 +821,8 @@ static int ad7293_init(struct ad7293_state *st)
if (ret)
return ret;
- if (chip_id != AD7293_CHIP_ID) {
- dev_err(&spi->dev, "Invalid Chip ID.\n");
- return -EINVAL;
- }
+ if (chip_id != AD7293_CHIP_ID)
+ return dev_err_probe(dev, -EINVAL, "Invalid Chip ID.\n");
if (!st->vrefin_en)
return __ad7293_spi_update_bits(st, AD7293_REG_GENERAL,
@@ -845,9 +843,10 @@ static int ad7293_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct ad7293_state *st;
+ struct device *dev = &spi->dev;
int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@@ -867,7 +866,7 @@ static int ad7293_probe(struct spi_device *spi)
if (ret)
return ret;
- return devm_iio_device_register(&spi->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id ad7293_id[] = {
diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c
index 9cc895bbe51a..451fad34e7ee 100644
--- a/drivers/iio/dac/adi-axi-dac.c
+++ b/drivers/iio/dac/adi-axi-dac.c
@@ -114,7 +114,6 @@ struct axi_dac_state {
const struct axi_dac_info *info;
u64 dac_clk;
u32 reg_config;
- bool int_tone;
int dac_clk_rate;
};
@@ -869,11 +868,13 @@ static const struct iio_backend_ops axi_ad3552r_ops = {
static const struct iio_backend_info axi_dac_generic = {
.name = "axi-dac",
.ops = &axi_dac_generic_ops,
+ .caps = IIO_BACKEND_CAP_BUFFER | IIO_BACKEND_CAP_ENABLE,
};
static const struct iio_backend_info axi_ad3552r = {
.name = "axi-ad3552r",
.ops = &axi_ad3552r_ops,
+ .caps = IIO_BACKEND_CAP_BUFFER | IIO_BACKEND_CAP_ENABLE,
};
static const struct regmap_config axi_dac_regmap_config = {
diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c
index c61868f2de31..085f73de3f02 100644
--- a/drivers/iio/dac/ds4424.c
+++ b/drivers/iio/dac/ds4424.c
@@ -5,22 +5,31 @@
* Copyright (C) 2017 Maxim Integrated
*/
+#include <linux/array_size.h>
+#include <linux/bits.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/i2c.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/iio/iio.h>
+#include <linux/time64.h>
+#include <linux/types.h>
+
#include <linux/iio/driver.h>
+#include <linux/iio/iio.h>
#include <linux/iio/machine.h>
#define DS4422_MAX_DAC_CHANNELS 2
#define DS4424_MAX_DAC_CHANNELS 4
+#define DS4424_DAC_MASK GENMASK(6, 0)
+#define DS4404_DAC_MASK GENMASK(4, 0)
+#define DS4424_DAC_SOURCE BIT(7)
+
#define DS4424_DAC_ADDR(chan) ((chan) + 0xf8)
-#define DS4424_SOURCE_I 1
-#define DS4424_SINK_I 0
#define DS4424_CHANNEL(chan) { \
.type = IIO_CURRENT, \
@@ -30,33 +39,61 @@
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
}
-/*
- * DS4424 DAC control register 8 bits
- * [7] 0: to sink; 1: to source
- * [6:0] steps to sink/source
- * bit[7] looks like a sign bit, but the value of the register is
- * not a two's complement code considering the bit[6:0] is a absolute
- * distance from the zero point.
- */
-union ds4424_raw_data {
- struct {
- u8 dx:7;
- u8 source_bit:1;
- };
- u8 bits;
+#define DS4424_CHANNEL_WITH_SCALE(chan) { \
+ .type = IIO_CURRENT, \
+ .indexed = 1, \
+ .output = 1, \
+ .channel = chan, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+}
+
+struct ds4424_chip_info {
+ const char *name;
+ int vref_mV;
+ int scale_denom;
+ u8 result_mask;
+ u8 num_channels;
+};
+
+static const struct ds4424_chip_info ds4402_info = {
+ .name = "ds4402",
+ .vref_mV = 1230,
+ .scale_denom = 4,
+ .result_mask = DS4404_DAC_MASK,
+ .num_channels = DS4422_MAX_DAC_CHANNELS,
+};
+
+static const struct ds4424_chip_info ds4404_info = {
+ .name = "ds4404",
+ .vref_mV = 1230,
+ .scale_denom = 4,
+ .result_mask = DS4404_DAC_MASK,
+ .num_channels = DS4424_MAX_DAC_CHANNELS,
+};
+
+static const struct ds4424_chip_info ds4422_info = {
+ .name = "ds4422",
+ .vref_mV = 976,
+ .scale_denom = 16,
+ .result_mask = DS4424_DAC_MASK,
+ .num_channels = DS4422_MAX_DAC_CHANNELS,
};
-enum ds4424_device_ids {
- ID_DS4422,
- ID_DS4424,
+static const struct ds4424_chip_info ds4424_info = {
+ .name = "ds4424",
+ .vref_mV = 976,
+ .scale_denom = 16,
+ .result_mask = DS4424_DAC_MASK,
+ .num_channels = DS4424_MAX_DAC_CHANNELS,
};
struct ds4424_data {
- struct i2c_client *client;
- struct mutex lock;
- uint8_t save[DS4424_MAX_DAC_CHANNELS];
+ struct regmap *regmap;
struct regulator *vcc_reg;
- uint8_t raw[DS4424_MAX_DAC_CHANNELS];
+ const struct ds4424_chip_info *chip_info;
+ u32 rfs_ohms[DS4424_MAX_DAC_CHANNELS];
+ bool has_rfs;
};
static const struct iio_chan_spec ds4424_channels[] = {
@@ -66,63 +103,114 @@ static const struct iio_chan_spec ds4424_channels[] = {
DS4424_CHANNEL(3),
};
-static int ds4424_get_value(struct iio_dev *indio_dev,
- int *val, int channel)
-{
- struct ds4424_data *data = iio_priv(indio_dev);
- int ret;
+static const struct iio_chan_spec ds4424_channels_with_scale[] = {
+ DS4424_CHANNEL_WITH_SCALE(0),
+ DS4424_CHANNEL_WITH_SCALE(1),
+ DS4424_CHANNEL_WITH_SCALE(2),
+ DS4424_CHANNEL_WITH_SCALE(3),
+};
- mutex_lock(&data->lock);
- ret = i2c_smbus_read_byte_data(data->client, DS4424_DAC_ADDR(channel));
- if (ret < 0)
- goto fail;
+static const struct regmap_range ds44x2_ranges[] = {
+ regmap_reg_range(DS4424_DAC_ADDR(0), DS4424_DAC_ADDR(1)),
+};
- *val = ret;
+static const struct regmap_range ds44x4_ranges[] = {
+ regmap_reg_range(DS4424_DAC_ADDR(0), DS4424_DAC_ADDR(3)),
+};
-fail:
- mutex_unlock(&data->lock);
- return ret;
-}
+static const struct regmap_access_table ds44x2_table = {
+ .yes_ranges = ds44x2_ranges,
+ .n_yes_ranges = ARRAY_SIZE(ds44x2_ranges),
+};
+
+static const struct regmap_access_table ds44x4_table = {
+ .yes_ranges = ds44x4_ranges,
+ .n_yes_ranges = ARRAY_SIZE(ds44x4_ranges),
+};
-static int ds4424_set_value(struct iio_dev *indio_dev,
- int val, struct iio_chan_spec const *chan)
+static const struct regmap_config ds44x2_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .cache_type = REGCACHE_MAPLE,
+ .max_register = DS4424_DAC_ADDR(1),
+ .rd_table = &ds44x2_table,
+ .wr_table = &ds44x2_table,
+};
+
+static const struct regmap_config ds44x4_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .cache_type = REGCACHE_MAPLE,
+ .max_register = DS4424_DAC_ADDR(3),
+ .rd_table = &ds44x4_table,
+ .wr_table = &ds44x4_table,
+};
+
+static int ds4424_init_regmap(struct i2c_client *client,
+ struct iio_dev *indio_dev)
{
struct ds4424_data *data = iio_priv(indio_dev);
+ const struct regmap_config *regmap_config;
+ u8 vals[DS4424_MAX_DAC_CHANNELS];
int ret;
- mutex_lock(&data->lock);
- ret = i2c_smbus_write_byte_data(data->client,
- DS4424_DAC_ADDR(chan->channel), val);
- if (ret < 0)
- goto fail;
-
- data->raw[chan->channel] = val;
-
-fail:
- mutex_unlock(&data->lock);
- return ret;
+ if (indio_dev->num_channels == DS4424_MAX_DAC_CHANNELS)
+ regmap_config = &ds44x4_regmap_config;
+ else
+ regmap_config = &ds44x2_regmap_config;
+
+ data->regmap = devm_regmap_init_i2c(client, regmap_config);
+ if (IS_ERR(data->regmap))
+ return dev_err_probe(&client->dev, PTR_ERR(data->regmap),
+ "Failed to init regmap.\n");
+
+ /*
+ * Prime the cache with the bootloader's configuration.
+ * regmap_bulk_read() will automatically populate the cache with
+ * the values read from the hardware.
+ */
+ ret = regmap_bulk_read(data->regmap, DS4424_DAC_ADDR(0), vals,
+ indio_dev->num_channels);
+ if (ret)
+ return dev_err_probe(&client->dev, ret,
+ "Failed to read hardware values\n");
+
+ return 0;
}
static int ds4424_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
- union ds4424_raw_data raw;
+ struct ds4424_data *data = iio_priv(indio_dev);
+ unsigned int regval;
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
- ret = ds4424_get_value(indio_dev, val, chan->channel);
+ ret = regmap_read(data->regmap, DS4424_DAC_ADDR(chan->channel),
+ &regval);
if (ret < 0) {
- pr_err("%s : ds4424_get_value returned %d\n",
- __func__, ret);
+ dev_err_ratelimited(indio_dev->dev.parent,
+ "Failed to read channel %d: %pe\n",
+ chan->channel, ERR_PTR(ret));
return ret;
}
- raw.bits = *val;
- *val = raw.dx;
- if (raw.source_bit == DS4424_SINK_I)
+
+ *val = regval & data->chip_info->result_mask;
+ if (!(regval & DS4424_DAC_SOURCE))
*val = -*val;
+
return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ if (!data->has_rfs)
+ return -EINVAL;
+
+ /* SCALE is mA/step: mV / Ohm = mA. */
+ *val = data->chip_info->vref_mV;
+ *val2 = data->rfs_ohms[chan->channel] *
+ data->chip_info->scale_denom;
+ return IIO_VAL_FRACTIONAL;
default:
return -EINVAL;
@@ -133,107 +221,131 @@ static int ds4424_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
- union ds4424_raw_data raw;
+ struct ds4424_data *data = iio_priv(indio_dev);
+ unsigned int abs_val;
if (val2 != 0)
return -EINVAL;
switch (mask) {
case IIO_CHAN_INFO_RAW:
- if (val <= S8_MIN || val > S8_MAX)
+ abs_val = abs(val);
+ if (abs_val > data->chip_info->result_mask)
return -EINVAL;
- if (val > 0) {
- raw.source_bit = DS4424_SOURCE_I;
- raw.dx = val;
- } else {
- raw.source_bit = DS4424_SINK_I;
- raw.dx = -val;
- }
+ /*
+ * Currents exiting the IC (Source) are positive. 0 is a valid
+ * value for no current flow; the direction bit (Source vs Sink)
+ * is treated as don't-care by the hardware at 0.
+ */
+ if (val > 0)
+ abs_val |= DS4424_DAC_SOURCE;
- return ds4424_set_value(indio_dev, raw.bits, chan);
+ return regmap_write(data->regmap, DS4424_DAC_ADDR(chan->channel),
+ abs_val);
default:
return -EINVAL;
}
}
-static int ds4424_verify_chip(struct iio_dev *indio_dev)
+static int ds4424_parse_rfs(struct i2c_client *client,
+ struct ds4424_data *data,
+ struct iio_dev *indio_dev)
{
- int ret, val;
+ struct device *dev = &client->dev;
+ int count, ret;
+
+ if (!device_property_present(dev, "maxim,rfs-ohms"))
+ return 0;
+
+ count = device_property_count_u32(dev, "maxim,rfs-ohms");
+ if (count < 0)
+ return dev_err_probe(dev, count, "Failed to count maxim,rfs-ohms entries\n");
+ if (count != indio_dev->num_channels)
+ return dev_err_probe(dev, -EINVAL, "maxim,rfs-ohms must have %u entries\n",
+ indio_dev->num_channels);
+
+ ret = device_property_read_u32_array(dev, "maxim,rfs-ohms",
+ data->rfs_ohms,
+ indio_dev->num_channels);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to read maxim,rfs-ohms property\n");
+
+ for (unsigned int i = 0; i < indio_dev->num_channels; i++) {
+ if (!data->rfs_ohms[i])
+ return dev_err_probe(dev, -EINVAL, "maxim,rfs-ohms entry %u is zero\n", i);
+ }
- ret = ds4424_get_value(indio_dev, &val, 0);
- if (ret < 0)
- dev_err(&indio_dev->dev,
- "%s failed. ret: %d\n", __func__, ret);
+ data->has_rfs = true;
- return ret;
+ return 0;
}
static int ds4424_suspend(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ds4424_data *data = iio_priv(indio_dev);
- int ret = 0;
- int i;
-
- for (i = 0; i < indio_dev->num_channels; i++) {
- data->save[i] = data->raw[i];
- ret = ds4424_set_value(indio_dev, 0,
- &indio_dev->channels[i]);
- if (ret < 0)
- return ret;
+ u8 zero_buf[DS4424_MAX_DAC_CHANNELS] = { };
+ int ret;
+
+ /* Disable all outputs, bypass cache so the '0' isn't saved */
+ regcache_cache_bypass(data->regmap, true);
+ ret = regmap_bulk_write(data->regmap, DS4424_DAC_ADDR(0),
+ zero_buf, indio_dev->num_channels);
+ regcache_cache_bypass(data->regmap, false);
+ if (ret) {
+ dev_err(dev, "Failed to zero outputs: %pe\n", ERR_PTR(ret));
+ return ret;
}
- return ret;
+
+ regcache_cache_only(data->regmap, true);
+ regcache_mark_dirty(data->regmap);
+
+ return 0;
}
static int ds4424_resume(struct device *dev)
{
- struct i2c_client *client = to_i2c_client(dev);
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct ds4424_data *data = iio_priv(indio_dev);
- int ret = 0;
- int i;
- for (i = 0; i < indio_dev->num_channels; i++) {
- ret = ds4424_set_value(indio_dev, data->save[i],
- &indio_dev->channels[i]);
- if (ret < 0)
- return ret;
- }
- return ret;
+ regcache_cache_only(data->regmap, false);
+ return regcache_sync(data->regmap);
}
static DEFINE_SIMPLE_DEV_PM_OPS(ds4424_pm_ops, ds4424_suspend, ds4424_resume);
-static const struct iio_info ds4424_info = {
+static const struct iio_info ds4424_iio_info = {
.read_raw = ds4424_read_raw,
.write_raw = ds4424_write_raw,
};
static int ds4424_probe(struct i2c_client *client)
{
- const struct i2c_device_id *id = i2c_client_get_device_id(client);
+ const struct ds4424_chip_info *chip_info;
struct ds4424_data *data;
struct iio_dev *indio_dev;
int ret;
+ chip_info = i2c_get_match_data(client);
+ if (!chip_info)
+ return -ENODEV;
+
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
- data->client = client;
- indio_dev->name = id->name;
+ indio_dev->name = chip_info->name;
+ data->chip_info = chip_info;
data->vcc_reg = devm_regulator_get(&client->dev, "vcc");
if (IS_ERR(data->vcc_reg))
return dev_err_probe(&client->dev, PTR_ERR(data->vcc_reg),
"Failed to get vcc-supply regulator.\n");
- mutex_init(&data->lock);
ret = regulator_enable(data->vcc_reg);
if (ret < 0) {
dev_err(&client->dev,
@@ -241,28 +353,29 @@ static int ds4424_probe(struct i2c_client *client)
return ret;
}
- usleep_range(1000, 1200);
- ret = ds4424_verify_chip(indio_dev);
- if (ret < 0)
+ /*
+ * The datasheet does not specify a power-up to I2C ready time.
+ * Maintain the existing conservative 1ms delay to ensure the
+ * device is ready for communication.
+ */
+ fsleep(1 * USEC_PER_MSEC);
+
+ indio_dev->num_channels = chip_info->num_channels;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &ds4424_iio_info;
+
+ ret = ds4424_init_regmap(client, indio_dev);
+ if (ret)
goto fail;
- switch (id->driver_data) {
- case ID_DS4422:
- indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;
- break;
- case ID_DS4424:
- indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
- break;
- default:
- dev_err(&client->dev,
- "ds4424: Invalid chip id.\n");
- ret = -ENXIO;
+ ret = ds4424_parse_rfs(client, data, indio_dev);
+ if (ret)
goto fail;
- }
- indio_dev->channels = ds4424_channels;
- indio_dev->modes = INDIO_DIRECT_MODE;
- indio_dev->info = &ds4424_info;
+ if (data->has_rfs)
+ indio_dev->channels = ds4424_channels_with_scale;
+ else
+ indio_dev->channels = ds4424_channels;
ret = iio_device_register(indio_dev);
if (ret < 0) {
@@ -288,16 +401,20 @@ static void ds4424_remove(struct i2c_client *client)
}
static const struct i2c_device_id ds4424_id[] = {
- { "ds4422", ID_DS4422 },
- { "ds4424", ID_DS4424 },
+ { "ds4402", (kernel_ulong_t)&ds4402_info },
+ { "ds4404", (kernel_ulong_t)&ds4404_info },
+ { "ds4422", (kernel_ulong_t)&ds4422_info },
+ { "ds4424", (kernel_ulong_t)&ds4424_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, ds4424_id);
static const struct of_device_id ds4424_of_match[] = {
- { .compatible = "maxim,ds4422" },
- { .compatible = "maxim,ds4424" },
+ { .compatible = "maxim,ds4402", .data = &ds4402_info },
+ { .compatible = "maxim,ds4404", .data = &ds4404_info },
+ { .compatible = "maxim,ds4422", .data = &ds4422_info },
+ { .compatible = "maxim,ds4424", .data = &ds4424_info },
{ }
};
diff --git a/drivers/iio/dac/ltc2632.c b/drivers/iio/dac/ltc2632.c
index 105f939f7e54..d6a3d290e7a8 100644
--- a/drivers/iio/dac/ltc2632.c
+++ b/drivers/iio/dac/ltc2632.c
@@ -48,27 +48,6 @@ struct ltc2632_state {
int vref_mv;
};
-enum ltc2632_supported_device_ids {
- ID_LTC2632L12,
- ID_LTC2632L10,
- ID_LTC2632L8,
- ID_LTC2632H12,
- ID_LTC2632H10,
- ID_LTC2632H8,
- ID_LTC2634L12,
- ID_LTC2634L10,
- ID_LTC2634L8,
- ID_LTC2634H12,
- ID_LTC2634H10,
- ID_LTC2634H8,
- ID_LTC2636L12,
- ID_LTC2636L10,
- ID_LTC2636L8,
- ID_LTC2636H12,
- ID_LTC2636H10,
- ID_LTC2636H8,
-};
-
static int ltc2632_spi_write(struct spi_device *spi,
u8 cmd, u8 addr, u16 val, u8 shift)
{
@@ -79,8 +58,9 @@ static int ltc2632_spi_write(struct spi_device *spi,
* The input shift register is 24 bits wide.
* The next four are the command bits, C3 to C0,
* followed by the 4-bit DAC address, A3 to A0, and then the
- * 12-, 10-, 8-bit data-word. The data-word comprises the 12-,
- * 10-, 8-bit input code followed by 4, 6, or 8 don't care bits.
+ * 16-, 12-, 10-, 8-bit data-word. The data-word comprises the
+ * 16-, 12-, 10-, 8-bit input code followed by 0, 4, 6, or 8
+ * don't care bits.
*/
data = (cmd << 20) | (addr << 16) | (val << shift);
put_unaligned_be24(data, &msg[0]);
@@ -206,101 +186,129 @@ static const struct iio_chan_spec_ext_info ltc2632_ext_info[] = {
LTC2632_CHANNEL(7, _bits), \
}
+static DECLARE_LTC2632_CHANNELS(ltc2632x16, 16);
static DECLARE_LTC2632_CHANNELS(ltc2632x12, 12);
static DECLARE_LTC2632_CHANNELS(ltc2632x10, 10);
static DECLARE_LTC2632_CHANNELS(ltc2632x8, 8);
-static const struct ltc2632_chip_info ltc2632_chip_info_tbl[] = {
- [ID_LTC2632L12] = {
- .channels = ltc2632x12_channels,
- .num_channels = 2,
- .vref_mv = 2500,
- },
- [ID_LTC2632L10] = {
- .channels = ltc2632x10_channels,
- .num_channels = 2,
- .vref_mv = 2500,
- },
- [ID_LTC2632L8] = {
- .channels = ltc2632x8_channels,
- .num_channels = 2,
- .vref_mv = 2500,
- },
- [ID_LTC2632H12] = {
- .channels = ltc2632x12_channels,
- .num_channels = 2,
- .vref_mv = 4096,
- },
- [ID_LTC2632H10] = {
- .channels = ltc2632x10_channels,
- .num_channels = 2,
- .vref_mv = 4096,
- },
- [ID_LTC2632H8] = {
- .channels = ltc2632x8_channels,
- .num_channels = 2,
- .vref_mv = 4096,
- },
- [ID_LTC2634L12] = {
- .channels = ltc2632x12_channels,
- .num_channels = 4,
- .vref_mv = 2500,
- },
- [ID_LTC2634L10] = {
- .channels = ltc2632x10_channels,
- .num_channels = 4,
- .vref_mv = 2500,
- },
- [ID_LTC2634L8] = {
- .channels = ltc2632x8_channels,
- .num_channels = 4,
- .vref_mv = 2500,
- },
- [ID_LTC2634H12] = {
- .channels = ltc2632x12_channels,
- .num_channels = 4,
- .vref_mv = 4096,
- },
- [ID_LTC2634H10] = {
- .channels = ltc2632x10_channels,
- .num_channels = 4,
- .vref_mv = 4096,
- },
- [ID_LTC2634H8] = {
- .channels = ltc2632x8_channels,
- .num_channels = 4,
- .vref_mv = 4096,
- },
- [ID_LTC2636L12] = {
- .channels = ltc2632x12_channels,
- .num_channels = 8,
- .vref_mv = 2500,
- },
- [ID_LTC2636L10] = {
- .channels = ltc2632x10_channels,
- .num_channels = 8,
- .vref_mv = 2500,
- },
- [ID_LTC2636L8] = {
- .channels = ltc2632x8_channels,
- .num_channels = 8,
- .vref_mv = 2500,
- },
- [ID_LTC2636H12] = {
- .channels = ltc2632x12_channels,
- .num_channels = 8,
- .vref_mv = 4096,
- },
- [ID_LTC2636H10] = {
- .channels = ltc2632x10_channels,
- .num_channels = 8,
- .vref_mv = 4096,
- },
- [ID_LTC2636H8] = {
- .channels = ltc2632x8_channels,
- .num_channels = 8,
- .vref_mv = 4096,
- },
+static const struct ltc2632_chip_info ltc2632l12_chip_info = {
+ .channels = ltc2632x12_channels,
+ .num_channels = 2,
+ .vref_mv = 2500,
+};
+
+static const struct ltc2632_chip_info ltc2632l10_chip_info = {
+ .channels = ltc2632x10_channels,
+ .num_channels = 2,
+ .vref_mv = 2500,
+};
+
+static const struct ltc2632_chip_info ltc2632l8_chip_info = {
+ .channels = ltc2632x8_channels,
+ .num_channels = 2,
+ .vref_mv = 2500,
+};
+
+static const struct ltc2632_chip_info ltc2632h12_chip_info = {
+ .channels = ltc2632x12_channels,
+ .num_channels = 2,
+ .vref_mv = 4096,
+};
+
+static const struct ltc2632_chip_info ltc2632h10_chip_info = {
+ .channels = ltc2632x10_channels,
+ .num_channels = 2,
+ .vref_mv = 4096,
+};
+
+static const struct ltc2632_chip_info ltc2632h8_chip_info = {
+ .channels = ltc2632x8_channels,
+ .num_channels = 2,
+ .vref_mv = 4096,
+};
+
+static const struct ltc2632_chip_info ltc2634l12_chip_info = {
+ .channels = ltc2632x12_channels,
+ .num_channels = 4,
+ .vref_mv = 2500,
+};
+
+static const struct ltc2632_chip_info ltc2634l10_chip_info = {
+ .channels = ltc2632x10_channels,
+ .num_channels = 4,
+ .vref_mv = 2500,
+};
+
+static const struct ltc2632_chip_info ltc2634l8_chip_info = {
+ .channels = ltc2632x8_channels,
+ .num_channels = 4,
+ .vref_mv = 2500,
+};
+
+static const struct ltc2632_chip_info ltc2634h12_chip_info = {
+ .channels = ltc2632x12_channels,
+ .num_channels = 4,
+ .vref_mv = 4096,
+};
+
+static const struct ltc2632_chip_info ltc2634h10_chip_info = {
+ .channels = ltc2632x10_channels,
+ .num_channels = 4,
+ .vref_mv = 4096,
+};
+
+static const struct ltc2632_chip_info ltc2634h8_chip_info = {
+ .channels = ltc2632x8_channels,
+ .num_channels = 4,
+ .vref_mv = 4096,
+};
+
+static const struct ltc2632_chip_info ltc2636l12_chip_info = {
+ .channels = ltc2632x12_channels,
+ .num_channels = 8,
+ .vref_mv = 2500,
+};
+
+static const struct ltc2632_chip_info ltc2636l10_chip_info = {
+ .channels = ltc2632x10_channels,
+ .num_channels = 8,
+ .vref_mv = 2500,
+};
+
+static const struct ltc2632_chip_info ltc2636l8_chip_info = {
+ .channels = ltc2632x8_channels,
+ .num_channels = 8,
+ .vref_mv = 2500,
+};
+
+static const struct ltc2632_chip_info ltc2636h12_chip_info = {
+ .channels = ltc2632x12_channels,
+ .num_channels = 8,
+ .vref_mv = 4096,
+};
+
+static const struct ltc2632_chip_info ltc2636h10_chip_info = {
+ .channels = ltc2632x10_channels,
+ .num_channels = 8,
+ .vref_mv = 4096,
+};
+
+static const struct ltc2632_chip_info ltc2636h8_chip_info = {
+ .channels = ltc2632x8_channels,
+ .num_channels = 8,
+ .vref_mv = 4096,
+};
+
+static const struct ltc2632_chip_info ltc2654l16_chip_info = {
+ .channels = ltc2632x16_channels,
+ .num_channels = 4,
+ .vref_mv = 2500,
+};
+
+static const struct ltc2632_chip_info ltc2654h16_chip_info = {
+ .channels = ltc2632x16_channels,
+ .num_channels = 4,
+ .vref_mv = 4096,
};
static int ltc2632_probe(struct spi_device *spi)
@@ -354,84 +362,53 @@ static int ltc2632_probe(struct spi_device *spi)
}
static const struct spi_device_id ltc2632_id[] = {
- { "ltc2632-l12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632L12] },
- { "ltc2632-l10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632L10] },
- { "ltc2632-l8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632L8] },
- { "ltc2632-h12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632H12] },
- { "ltc2632-h10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632H10] },
- { "ltc2632-h8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2632H8] },
- { "ltc2634-l12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2634L12] },
- { "ltc2634-l10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2634L10] },
- { "ltc2634-l8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2634L8] },
- { "ltc2634-h12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2634H12] },
- { "ltc2634-h10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2634H10] },
- { "ltc2634-h8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2634H8] },
- { "ltc2636-l12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636L12] },
- { "ltc2636-l10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636L10] },
- { "ltc2636-l8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636L8] },
- { "ltc2636-h12", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636H12] },
- { "ltc2636-h10", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636H10] },
- { "ltc2636-h8", (kernel_ulong_t)&ltc2632_chip_info_tbl[ID_LTC2636H8] },
+ { "ltc2632-l12", (kernel_ulong_t)&ltc2632l12_chip_info },
+ { "ltc2632-l10", (kernel_ulong_t)&ltc2632l10_chip_info },
+ { "ltc2632-l8", (kernel_ulong_t)&ltc2632l8_chip_info },
+ { "ltc2632-h12", (kernel_ulong_t)&ltc2632h12_chip_info },
+ { "ltc2632-h10", (kernel_ulong_t)&ltc2632h10_chip_info },
+ { "ltc2632-h8", (kernel_ulong_t)&ltc2632h8_chip_info },
+ { "ltc2634-l12", (kernel_ulong_t)&ltc2634l12_chip_info },
+ { "ltc2634-l10", (kernel_ulong_t)&ltc2634l10_chip_info },
+ { "ltc2634-l8", (kernel_ulong_t)&ltc2634l8_chip_info },
+ { "ltc2634-h12", (kernel_ulong_t)&ltc2634h12_chip_info },
+ { "ltc2634-h10", (kernel_ulong_t)&ltc2634h10_chip_info },
+ { "ltc2634-h8", (kernel_ulong_t)&ltc2634h8_chip_info },
+ { "ltc2636-l12", (kernel_ulong_t)&ltc2636l12_chip_info },
+ { "ltc2636-l10", (kernel_ulong_t)&ltc2636l10_chip_info },
+ { "ltc2636-l8", (kernel_ulong_t)&ltc2636l8_chip_info },
+ { "ltc2636-h12", (kernel_ulong_t)&ltc2636h12_chip_info },
+ { "ltc2636-h10", (kernel_ulong_t)&ltc2636h10_chip_info },
+ { "ltc2636-h8", (kernel_ulong_t)&ltc2636h8_chip_info },
+ { "ltc2654-l16", (kernel_ulong_t)&ltc2654l16_chip_info },
+ { "ltc2654-l12", (kernel_ulong_t)&ltc2634l12_chip_info },
+ { "ltc2654-h16", (kernel_ulong_t)&ltc2654h16_chip_info },
+ { "ltc2654-h12", (kernel_ulong_t)&ltc2634h12_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ltc2632_id);
static const struct of_device_id ltc2632_of_match[] = {
- {
- .compatible = "lltc,ltc2632-l12",
- .data = &ltc2632_chip_info_tbl[ID_LTC2632L12]
- }, {
- .compatible = "lltc,ltc2632-l10",
- .data = &ltc2632_chip_info_tbl[ID_LTC2632L10]
- }, {
- .compatible = "lltc,ltc2632-l8",
- .data = &ltc2632_chip_info_tbl[ID_LTC2632L8]
- }, {
- .compatible = "lltc,ltc2632-h12",
- .data = &ltc2632_chip_info_tbl[ID_LTC2632H12]
- }, {
- .compatible = "lltc,ltc2632-h10",
- .data = &ltc2632_chip_info_tbl[ID_LTC2632H10]
- }, {
- .compatible = "lltc,ltc2632-h8",
- .data = &ltc2632_chip_info_tbl[ID_LTC2632H8]
- }, {
- .compatible = "lltc,ltc2634-l12",
- .data = &ltc2632_chip_info_tbl[ID_LTC2634L12]
- }, {
- .compatible = "lltc,ltc2634-l10",
- .data = &ltc2632_chip_info_tbl[ID_LTC2634L10]
- }, {
- .compatible = "lltc,ltc2634-l8",
- .data = &ltc2632_chip_info_tbl[ID_LTC2634L8]
- }, {
- .compatible = "lltc,ltc2634-h12",
- .data = &ltc2632_chip_info_tbl[ID_LTC2634H12]
- }, {
- .compatible = "lltc,ltc2634-h10",
- .data = &ltc2632_chip_info_tbl[ID_LTC2634H10]
- }, {
- .compatible = "lltc,ltc2634-h8",
- .data = &ltc2632_chip_info_tbl[ID_LTC2634H8]
- }, {
- .compatible = "lltc,ltc2636-l12",
- .data = &ltc2632_chip_info_tbl[ID_LTC2636L12]
- }, {
- .compatible = "lltc,ltc2636-l10",
- .data = &ltc2632_chip_info_tbl[ID_LTC2636L10]
- }, {
- .compatible = "lltc,ltc2636-l8",
- .data = &ltc2632_chip_info_tbl[ID_LTC2636L8]
- }, {
- .compatible = "lltc,ltc2636-h12",
- .data = &ltc2632_chip_info_tbl[ID_LTC2636H12]
- }, {
- .compatible = "lltc,ltc2636-h10",
- .data = &ltc2632_chip_info_tbl[ID_LTC2636H10]
- }, {
- .compatible = "lltc,ltc2636-h8",
- .data = &ltc2632_chip_info_tbl[ID_LTC2636H8]
- },
+ { .compatible = "lltc,ltc2632-l12", .data = &ltc2632l12_chip_info },
+ { .compatible = "lltc,ltc2632-l10", .data = &ltc2632l10_chip_info },
+ { .compatible = "lltc,ltc2632-l8", .data = &ltc2632l8_chip_info },
+ { .compatible = "lltc,ltc2632-h12", .data = &ltc2632h12_chip_info },
+ { .compatible = "lltc,ltc2632-h10", .data = &ltc2632h10_chip_info },
+ { .compatible = "lltc,ltc2632-h8", .data = &ltc2632h8_chip_info },
+ { .compatible = "lltc,ltc2634-l12", .data = &ltc2634l12_chip_info },
+ { .compatible = "lltc,ltc2634-l10", .data = &ltc2634l10_chip_info },
+ { .compatible = "lltc,ltc2634-l8", .data = &ltc2634l8_chip_info },
+ { .compatible = "lltc,ltc2634-h12", .data = &ltc2634h12_chip_info },
+ { .compatible = "lltc,ltc2634-h10", .data = &ltc2634h10_chip_info },
+ { .compatible = "lltc,ltc2634-h8", .data = &ltc2634h8_chip_info },
+ { .compatible = "lltc,ltc2636-l12", .data = &ltc2636l12_chip_info },
+ { .compatible = "lltc,ltc2636-l10", .data = &ltc2636l10_chip_info },
+ { .compatible = "lltc,ltc2636-l8", .data = &ltc2636l8_chip_info },
+ { .compatible = "lltc,ltc2636-h12", .data = &ltc2636h12_chip_info },
+ { .compatible = "lltc,ltc2636-h10", .data = &ltc2636h10_chip_info },
+ { .compatible = "lltc,ltc2636-h8", .data = &ltc2636h8_chip_info },
+ { .compatible = "lltc,ltc2654-l16", .data = &ltc2654l16_chip_info },
+ { .compatible = "lltc,ltc2654-h16", .data = &ltc2654h16_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ltc2632_of_match);
@@ -447,5 +424,5 @@ static struct spi_driver ltc2632_driver = {
module_spi_driver(ltc2632_driver);
MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>");
-MODULE_DESCRIPTION("LTC2632 DAC SPI driver");
+MODULE_DESCRIPTION("LTC2632 and similar DAC SPI driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/dac/max5522.c b/drivers/iio/dac/max5522.c
index 1b8fe6b8d26e..b52a9cc1da79 100644
--- a/drivers/iio/dac/max5522.c
+++ b/drivers/iio/dac/max5522.c
@@ -14,6 +14,7 @@
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
+#include <linux/units.h>
#include <linux/iio/iio.h>
@@ -34,7 +35,7 @@ struct max5522_state {
struct regmap *regmap;
const struct max5522_chip_info *chip_info;
unsigned short dac_cache[2];
- struct regulator *vrefin_reg;
+ int vref_mV;
};
#define MAX5522_CHANNEL(chan) { \
@@ -79,17 +80,13 @@ static int max5522_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long info)
{
struct max5522_state *state = iio_priv(indio_dev);
- int ret;
switch (info) {
case IIO_CHAN_INFO_RAW:
*val = state->dac_cache[chan->channel];
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- ret = regulator_get_voltage(state->vrefin_reg);
- if (ret < 0)
- return -EINVAL;
- *val = ret / 1000;
+ *val = state->vref_mV;
*val2 = 10;
return IIO_VAL_FRACTIONAL_LOG2;
default:
@@ -147,16 +144,11 @@ static int max5522_spi_probe(struct spi_device *spi)
if (!state->chip_info)
return -EINVAL;
- state->vrefin_reg = devm_regulator_get(&spi->dev, "vrefin");
- if (IS_ERR(state->vrefin_reg))
- return dev_err_probe(&spi->dev, PTR_ERR(state->vrefin_reg),
- "Vrefin regulator not specified\n");
-
- ret = regulator_enable(state->vrefin_reg);
- if (ret) {
+ ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vrefin");
+ if (ret < 0)
return dev_err_probe(&spi->dev, ret,
- "Failed to enable vref regulators\n");
- }
+ "Failed to get vrefin regulator\n");
+ state->vref_mV = ret / (MICRO / MILLI);
state->regmap = devm_regmap_init_spi(spi, &max5522_regmap_config);
diff --git a/drivers/iio/dac/ti-dac5571.c b/drivers/iio/dac/ti-dac5571.c
index bdc3f94aef98..455d61fc3f13 100644
--- a/drivers/iio/dac/ti-dac5571.c
+++ b/drivers/iio/dac/ti-dac5571.c
@@ -45,7 +45,6 @@ static const struct dac5571_spec dac5571_spec[] = {
struct dac5571_data {
struct i2c_client *client;
- int id;
struct mutex lock;
struct regulator *vref;
u16 val[4];
diff --git a/drivers/iio/filter/admv8818.c b/drivers/iio/filter/admv8818.c
index 19f823446cda..a4984b867248 100644
--- a/drivers/iio/filter/admv8818.c
+++ b/drivers/iio/filter/admv8818.c
@@ -657,56 +657,49 @@ static void admv8818_clk_disable(void *data)
static int admv8818_init(struct admv8818_state *st)
{
int ret;
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
unsigned int chip_id;
ret = regmap_write(st->regmap, ADMV8818_REG_SPI_CONFIG_A,
ADMV8818_SOFTRESET_N_MSK | ADMV8818_SOFTRESET_MSK);
- if (ret) {
- dev_err(&spi->dev, "ADMV8818 Soft Reset failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "ADMV8818 Soft Reset failed.\n");
ret = regmap_write(st->regmap, ADMV8818_REG_SPI_CONFIG_A,
ADMV8818_SDOACTIVE_N_MSK | ADMV8818_SDOACTIVE_MSK);
- if (ret) {
- dev_err(&spi->dev, "ADMV8818 SDO Enable failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "ADMV8818 SDO Enable failed.\n");
ret = regmap_read(st->regmap, ADMV8818_REG_CHIPTYPE, &chip_id);
- if (ret) {
- dev_err(&spi->dev, "ADMV8818 Chip ID read failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "ADMV8818 Chip ID read failed.\n");
- if (chip_id != 0x1) {
- dev_err(&spi->dev, "ADMV8818 Invalid Chip ID.\n");
- return -EINVAL;
- }
+ if (chip_id != 0x1)
+ return dev_err_probe(dev, -EINVAL,
+ "ADMV8818 Invalid Chip ID.\n");
ret = regmap_update_bits(st->regmap, ADMV8818_REG_SPI_CONFIG_B,
ADMV8818_SINGLE_INSTRUCTION_MSK,
FIELD_PREP(ADMV8818_SINGLE_INSTRUCTION_MSK, 1));
- if (ret) {
- dev_err(&spi->dev, "ADMV8818 Single Instruction failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "ADMV8818 Single Instruction failed.\n");
if (st->clkin)
return admv8818_rfin_band_select(st);
- else
- return 0;
+
+ return 0;
}
static int admv8818_clk_setup(struct admv8818_state *st)
{
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
int ret;
- st->clkin = devm_clk_get_optional(&spi->dev, "rf_in");
+ st->clkin = devm_clk_get_optional(dev, "rf_in");
if (IS_ERR(st->clkin))
- return dev_err_probe(&spi->dev, PTR_ERR(st->clkin),
+ return dev_err_probe(dev, PTR_ERR(st->clkin),
"failed to get the input clock\n");
else if (!st->clkin)
return 0;
@@ -715,7 +708,7 @@ static int admv8818_clk_setup(struct admv8818_state *st)
if (ret)
return ret;
- ret = devm_add_action_or_reset(&spi->dev, admv8818_clk_disable, st);
+ ret = devm_add_action_or_reset(dev, admv8818_clk_disable, st);
if (ret)
return ret;
@@ -724,16 +717,16 @@ static int admv8818_clk_setup(struct admv8818_state *st)
if (ret < 0)
return ret;
- return devm_add_action_or_reset(&spi->dev, admv8818_clk_notifier_unreg, st);
+ return devm_add_action_or_reset(dev, admv8818_clk_notifier_unreg, st);
}
static int admv8818_read_properties(struct admv8818_state *st)
{
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
u32 mhz;
int ret;
- ret = device_property_read_u32(&spi->dev, "adi,lpf-margin-mhz", &mhz);
+ ret = device_property_read_u32(dev, "adi,lpf-margin-mhz", &mhz);
if (ret == 0)
st->lpf_margin_hz = (u64)mhz * HZ_PER_MHZ;
else if (ret == -EINVAL)
@@ -742,7 +735,7 @@ static int admv8818_read_properties(struct admv8818_state *st)
return ret;
- ret = device_property_read_u32(&spi->dev, "adi,hpf-margin-mhz", &mhz);
+ ret = device_property_read_u32(dev, "adi,hpf-margin-mhz", &mhz);
if (ret == 0)
st->hpf_margin_hz = (u64)mhz * HZ_PER_MHZ;
else if (ret == -EINVAL)
@@ -758,9 +751,10 @@ static int admv8818_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
struct regmap *regmap;
struct admv8818_state *st;
+ struct device *dev = &spi->dev;
int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@@ -792,7 +786,7 @@ static int admv8818_probe(struct spi_device *spi)
if (ret)
return ret;
- return devm_iio_device_register(&spi->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id admv8818_id[] = {
diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c
index 63c485e9e44c..ea4d2763564a 100644
--- a/drivers/iio/frequency/ad9523.c
+++ b/drivers/iio/frequency/ad9523.c
@@ -167,9 +167,9 @@
/* AD9523_CHANNEL_CLOCK_DIST */
#define AD9523_CLK_DIST_DIV_PHASE(x) (((x) & 0x3F) << 18)
-#define AD9523_CLK_DIST_DIV_PHASE_REV(x) ((ret >> 18) & 0x3F)
+#define AD9523_CLK_DIST_DIV_PHASE_REV(x) (((x) >> 18) & 0x3F)
#define AD9523_CLK_DIST_DIV(x) ((((x) - 1) & 0x3FF) << 8)
-#define AD9523_CLK_DIST_DIV_REV(x) (((ret >> 8) & 0x3FF) + 1)
+#define AD9523_CLK_DIST_DIV_REV(x) ((((x) >> 8) & 0x3FF) + 1)
#define AD9523_CLK_DIST_INV_DIV_OUTPUT_EN (1 << 7)
#define AD9523_CLK_DIST_IGNORE_SYNC_EN (1 << 6)
#define AD9523_CLK_DIST_PWR_DOWN_EN (1 << 5)
@@ -558,55 +558,35 @@ static ssize_t ad9523_show(struct device *dev,
return ret;
}
-static IIO_DEVICE_ATTR(pll1_locked, S_IRUGO,
- ad9523_show,
- NULL,
- AD9523_STAT_PLL1_LD);
-
-static IIO_DEVICE_ATTR(pll2_locked, S_IRUGO,
- ad9523_show,
- NULL,
- AD9523_STAT_PLL2_LD);
-
-static IIO_DEVICE_ATTR(pll1_reference_clk_a_present, S_IRUGO,
- ad9523_show,
- NULL,
- AD9523_STAT_REFA);
-
-static IIO_DEVICE_ATTR(pll1_reference_clk_b_present, S_IRUGO,
- ad9523_show,
- NULL,
- AD9523_STAT_REFB);
-
-static IIO_DEVICE_ATTR(pll1_reference_clk_test_present, S_IRUGO,
- ad9523_show,
- NULL,
- AD9523_STAT_REF_TEST);
-
-static IIO_DEVICE_ATTR(vcxo_clk_present, S_IRUGO,
- ad9523_show,
- NULL,
- AD9523_STAT_VCXO);
-
-static IIO_DEVICE_ATTR(pll2_feedback_clk_present, S_IRUGO,
- ad9523_show,
- NULL,
- AD9523_STAT_PLL2_FB_CLK);
-
-static IIO_DEVICE_ATTR(pll2_reference_clk_present, S_IRUGO,
- ad9523_show,
- NULL,
- AD9523_STAT_PLL2_REF_CLK);
-
-static IIO_DEVICE_ATTR(sync_dividers, S_IWUSR,
- NULL,
- ad9523_store,
- AD9523_SYNC);
-
-static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR,
- NULL,
- ad9523_store,
- AD9523_EEPROM);
+static IIO_DEVICE_ATTR(pll1_locked, 0444, ad9523_show, NULL,
+ AD9523_STAT_PLL1_LD);
+
+static IIO_DEVICE_ATTR(pll2_locked, 0444, ad9523_show, NULL,
+ AD9523_STAT_PLL2_LD);
+
+static IIO_DEVICE_ATTR(pll1_reference_clk_a_present, 0444, ad9523_show, NULL,
+ AD9523_STAT_REFA);
+
+static IIO_DEVICE_ATTR(pll1_reference_clk_b_present, 0444, ad9523_show, NULL,
+ AD9523_STAT_REFB);
+
+static IIO_DEVICE_ATTR(pll1_reference_clk_test_present, 0444, ad9523_show, NULL,
+ AD9523_STAT_REF_TEST);
+
+static IIO_DEVICE_ATTR(vcxo_clk_present, 0444, ad9523_show, NULL,
+ AD9523_STAT_VCXO);
+
+static IIO_DEVICE_ATTR(pll2_feedback_clk_present, 0444, ad9523_show, NULL,
+ AD9523_STAT_PLL2_FB_CLK);
+
+static IIO_DEVICE_ATTR(pll2_reference_clk_present, 0444, ad9523_show, NULL,
+ AD9523_STAT_PLL2_REF_CLK);
+
+static IIO_DEVICE_ATTR(sync_dividers, 0200, NULL, ad9523_store,
+ AD9523_SYNC);
+
+static IIO_DEVICE_ATTR(store_eeprom, 0200, NULL, ad9523_store,
+ AD9523_EEPROM);
static struct attribute *ad9523_attributes[] = {
&iio_dev_attr_sync_dividers.dev_attr.attr,
@@ -797,8 +777,7 @@ static int ad9523_setup(struct iio_dev *indio_dev)
return ret;
ret = ad9523_write(indio_dev, AD9523_PLL1_CHARGE_PUMP_CTRL,
- AD9523_PLL1_CHARGE_PUMP_CURRENT_nA(pdata->
- pll1_charge_pump_current_nA) |
+ AD9523_PLL1_CHARGE_PUMP_CURRENT_nA(pdata->pll1_charge_pump_current_nA) |
AD9523_PLL1_CHARGE_PUMP_MODE_NORMAL |
AD9523_PLL1_BACKLASH_PW_MIN);
if (ret < 0)
@@ -842,8 +821,7 @@ static int ad9523_setup(struct iio_dev *indio_dev)
*/
ret = ad9523_write(indio_dev, AD9523_PLL2_CHARGE_PUMP,
- AD9523_PLL2_CHARGE_PUMP_CURRENT_nA(pdata->
- pll2_charge_pump_current_nA));
+ AD9523_PLL2_CHARGE_PUMP_CURRENT_nA(pdata->pll2_charge_pump_current_nA));
if (ret < 0)
return ret;
@@ -970,17 +948,17 @@ static int ad9523_setup(struct iio_dev *indio_dev)
static int ad9523_probe(struct spi_device *spi)
{
- struct ad9523_platform_data *pdata = dev_get_platdata(&spi->dev);
+ struct device *dev = &spi->dev;
+ struct ad9523_platform_data *pdata;
struct iio_dev *indio_dev;
struct ad9523_state *st;
int ret;
- if (!pdata) {
- dev_err(&spi->dev, "no platform data?\n");
- return -EINVAL;
- }
+ pdata = dev_get_platdata(dev);
+ if (!pdata)
+ return dev_err_probe(dev, -EINVAL, "no platform data?\n");
- 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;
@@ -988,16 +966,16 @@ static int ad9523_probe(struct spi_device *spi)
mutex_init(&st->lock);
- ret = devm_regulator_get_enable(&spi->dev, "vcc");
+ ret = devm_regulator_get_enable(dev, "vcc");
if (ret)
return ret;
- st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown",
+ st->pwrdown_gpio = devm_gpiod_get_optional(dev, "powerdown",
GPIOD_OUT_HIGH);
if (IS_ERR(st->pwrdown_gpio))
return PTR_ERR(st->pwrdown_gpio);
- st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
+ st->reset_gpio = devm_gpiod_get_optional(dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(st->reset_gpio))
return PTR_ERR(st->reset_gpio);
@@ -1007,7 +985,7 @@ static int ad9523_probe(struct spi_device *spi)
gpiod_direction_output(st->reset_gpio, 1);
}
- st->sync_gpio = devm_gpiod_get_optional(&spi->dev, "sync",
+ st->sync_gpio = devm_gpiod_get_optional(dev, "sync",
GPIOD_OUT_HIGH);
if (IS_ERR(st->sync_gpio))
return PTR_ERR(st->sync_gpio);
@@ -1027,7 +1005,7 @@ static int ad9523_probe(struct spi_device *spi)
if (ret < 0)
return ret;
- return devm_iio_device_register(&spi->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id ad9523_id[] = {
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c
index ed1741165f55..6bbb6a8dd9d0 100644
--- a/drivers/iio/frequency/adf4350.c
+++ b/drivers/iio/frequency/adf4350.c
@@ -152,10 +152,10 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq)
st->r4_rf_div_sel = 0;
/*
- * !\TODO: The below computation is making sure we get a power of 2
- * shift (st->r4_rf_div_sel) so that freq becomes higher or equal to
- * ADF4350_MIN_VCO_FREQ. This might be simplified with fls()/fls_long()
- * and friends.
+ * NOTE: This iteratively shifts freq by a power of 2
+ * (st->r4_rf_div_sel) to meet or exceed ADF4350_MIN_VCO_FREQ.
+ * A constant-time approach using fls_long() was attempted but
+ * deemed more complex without meaningful benefit for init code.
*/
while (freq < ADF4350_MIN_VCO_FREQ) {
freq <<= 1;
@@ -607,7 +607,7 @@ static int adf4350_probe(struct spi_device *spi)
if (dev_fwnode(&spi->dev)) {
pdata = adf4350_parse_dt(&spi->dev);
if (pdata == NULL)
- return -EINVAL;
+ return -ENOMEM;
} else {
pdata = dev_get_platdata(&spi->dev);
}
diff --git a/drivers/iio/frequency/adf4377.c b/drivers/iio/frequency/adf4377.c
index 8e2da218d48a..ff6077e29c73 100644
--- a/drivers/iio/frequency/adf4377.c
+++ b/drivers/iio/frequency/adf4377.c
@@ -706,23 +706,20 @@ static void adf4377_gpio_init(struct adf4377_state *st)
static int adf4377_init(struct adf4377_state *st)
{
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
int ret;
adf4377_gpio_init(st);
ret = adf4377_soft_reset(st);
- if (ret) {
- dev_err(&spi->dev, "Failed to soft reset.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to soft reset.\n");
ret = regmap_multi_reg_write(st->regmap, adf4377_reg_defaults,
ARRAY_SIZE(adf4377_reg_defaults));
- if (ret) {
- dev_err(&spi->dev, "Failed to set default registers.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to set default registers.\n");
ret = regmap_update_bits(st->regmap, 0x00,
ADF4377_0000_SDO_ACTIVE_MSK | ADF4377_0000_SDO_ACTIVE_R_MSK,
@@ -730,10 +727,9 @@ static int adf4377_init(struct adf4377_state *st)
ADF4377_0000_SDO_ACTIVE_SPI_4W) |
FIELD_PREP(ADF4377_0000_SDO_ACTIVE_R_MSK,
ADF4377_0000_SDO_ACTIVE_SPI_4W));
- if (ret) {
- dev_err(&spi->dev, "Failed to set 4-Wire Operation.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to set 4-Wire Operation.\n");
st->clkin_freq = clk_get_rate(st->clkin);
@@ -747,10 +743,9 @@ static int adf4377_init(struct adf4377_state *st)
FIELD_PREP(ADF4377_001A_PD_PFDCP_MSK, 0) |
FIELD_PREP(ADF4377_001A_PD_CLKOUT1_MSK, 0) |
FIELD_PREP(ADF4377_001A_PD_CLKOUT2_MSK, 0));
- if (ret) {
- dev_err(&spi->dev, "Failed to set power down registers.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to set power down registers.\n");
/* Set Mux Output */
ret = regmap_update_bits(st->regmap, 0x1D,
@@ -882,35 +877,35 @@ static const struct iio_chan_spec adf4377_channels[] = {
static int adf4377_properties_parse(struct adf4377_state *st)
{
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
int ret;
- st->clkin = devm_clk_get_enabled(&spi->dev, "ref_in");
+ st->clkin = devm_clk_get_enabled(dev, "ref_in");
if (IS_ERR(st->clkin))
- return dev_err_probe(&spi->dev, PTR_ERR(st->clkin),
+ return dev_err_probe(dev, PTR_ERR(st->clkin),
"failed to get the reference input clock\n");
- st->gpio_ce = devm_gpiod_get_optional(&st->spi->dev, "chip-enable",
+ st->gpio_ce = devm_gpiod_get_optional(dev, "chip-enable",
GPIOD_OUT_LOW);
if (IS_ERR(st->gpio_ce))
- return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_ce),
+ return dev_err_probe(dev, PTR_ERR(st->gpio_ce),
"failed to get the CE GPIO\n");
- st->gpio_enclk1 = devm_gpiod_get_optional(&st->spi->dev, "clk1-enable",
+ st->gpio_enclk1 = devm_gpiod_get_optional(dev, "clk1-enable",
GPIOD_OUT_LOW);
if (IS_ERR(st->gpio_enclk1))
- return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_enclk1),
+ return dev_err_probe(dev, PTR_ERR(st->gpio_enclk1),
"failed to get the CE GPIO\n");
if (st->chip_info->has_gpio_enclk2) {
- st->gpio_enclk2 = devm_gpiod_get_optional(&st->spi->dev, "clk2-enable",
+ st->gpio_enclk2 = devm_gpiod_get_optional(dev, "clk2-enable",
GPIOD_OUT_LOW);
if (IS_ERR(st->gpio_enclk2))
- return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_enclk2),
+ return dev_err_probe(dev, PTR_ERR(st->gpio_enclk2),
"failed to get the CE GPIO\n");
}
- ret = device_property_match_property_string(&spi->dev, "adi,muxout-select",
+ ret = device_property_match_property_string(dev, "adi,muxout-select",
adf4377_muxout_modes,
ARRAY_SIZE(adf4377_muxout_modes));
if (ret >= 0)
@@ -1055,9 +1050,10 @@ static int adf4377_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
struct regmap *regmap;
struct adf4377_state *st;
+ struct device *dev = &spi->dev;
int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@@ -1080,7 +1076,7 @@ static int adf4377_probe(struct spi_device *spi)
return ret;
st->nb.notifier_call = adf4377_freq_change;
- ret = devm_clk_notifier_register(&spi->dev, st->clkin, &st->nb);
+ ret = devm_clk_notifier_register(dev, st->clkin, &st->nb);
if (ret)
return ret;
@@ -1097,7 +1093,7 @@ static int adf4377_probe(struct spi_device *spi)
indio_dev->num_channels = ARRAY_SIZE(adf4377_channels);
}
- return devm_iio_device_register(&spi->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id adf4377_id[] = {
diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c
index d8e8d541990f..b852378b3f68 100644
--- a/drivers/iio/frequency/admv1013.c
+++ b/drivers/iio/frequency/admv1013.c
@@ -85,9 +85,9 @@ enum {
};
enum {
- ADMV1013_SE_MODE_POS = 6,
- ADMV1013_SE_MODE_NEG = 9,
- ADMV1013_SE_MODE_DIFF = 12
+ ADMV1013_SE_MODE_POS,
+ ADMV1013_SE_MODE_NEG,
+ ADMV1013_SE_MODE_DIFF,
};
struct admv1013_state {
@@ -441,7 +441,7 @@ static int admv1013_init(struct admv1013_state *st, int vcm_uv)
{
int ret;
unsigned int data;
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
/* Perform a software reset */
ret = __admv1013_spi_update_bits(st, ADMV1013_REG_SPI_CONTROL,
@@ -461,19 +461,30 @@ static int admv1013_init(struct admv1013_state *st, int vcm_uv)
return ret;
data = FIELD_GET(ADMV1013_CHIP_ID_MSK, data);
- if (data != ADMV1013_CHIP_ID) {
- dev_err(&spi->dev, "Invalid Chip ID.\n");
- return -EINVAL;
- }
+ if (data != ADMV1013_CHIP_ID)
+ return dev_err_probe(dev, -EINVAL, "Invalid Chip ID.\n");
ret = __admv1013_spi_write(st, ADMV1013_REG_VVA_TEMP_COMP, 0xE700);
if (ret)
return ret;
- data = FIELD_PREP(ADMV1013_QUAD_SE_MODE_MSK, st->quad_se_mode);
+ switch (st->quad_se_mode) {
+ case ADMV1013_SE_MODE_POS:
+ data = 6;
+ break;
+ case ADMV1013_SE_MODE_NEG:
+ data = 9;
+ break;
+ case ADMV1013_SE_MODE_DIFF:
+ data = 12;
+ break;
+ default:
+ return -EINVAL;
+ }
ret = __admv1013_spi_update_bits(st, ADMV1013_REG_QUAD,
- ADMV1013_QUAD_SE_MODE_MSK, data);
+ ADMV1013_QUAD_SE_MODE_MSK,
+ FIELD_PREP(ADMV1013_QUAD_SE_MODE_MSK, data));
if (ret)
return ret;
@@ -514,43 +525,39 @@ static void admv1013_powerdown(void *data)
admv1013_spi_update_bits(data, ADMV1013_REG_ENABLE, enable_reg_msk, enable_reg);
}
+static const char * const admv1013_input_modes[] = {
+ [ADMV1013_IQ_MODE] = "iq",
+ [ADMV1013_IF_MODE] = "if",
+};
+
+static const char * const admv1013_quad_se_modes[] = {
+ [ADMV1013_SE_MODE_POS] = "se-pos",
+ [ADMV1013_SE_MODE_NEG] = "se-neg",
+ [ADMV1013_SE_MODE_DIFF] = "diff",
+};
+
static int admv1013_properties_parse(struct admv1013_state *st)
{
int ret;
- const char *str;
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
- st->det_en = device_property_read_bool(&spi->dev, "adi,detector-enable");
+ st->det_en = device_property_read_bool(dev, "adi,detector-enable");
- ret = device_property_read_string(&spi->dev, "adi,input-mode", &str);
- if (ret)
- st->input_mode = ADMV1013_IQ_MODE;
+ ret = device_property_match_property_string(dev, "adi,input-mode",
+ admv1013_input_modes,
+ ARRAY_SIZE(admv1013_input_modes));
+ st->input_mode = ret >= 0 ? ret : ADMV1013_IQ_MODE;
- if (!strcmp(str, "iq"))
- st->input_mode = ADMV1013_IQ_MODE;
- else if (!strcmp(str, "if"))
- st->input_mode = ADMV1013_IF_MODE;
- else
- return -EINVAL;
+ ret = device_property_match_property_string(dev, "adi,quad-se-mode",
+ admv1013_quad_se_modes,
+ ARRAY_SIZE(admv1013_quad_se_modes));
+ st->quad_se_mode = ret >= 0 ? ret : ADMV1013_SE_MODE_DIFF;
- ret = device_property_read_string(&spi->dev, "adi,quad-se-mode", &str);
- if (ret)
- st->quad_se_mode = ADMV1013_SE_MODE_DIFF;
-
- if (!strcmp(str, "diff"))
- st->quad_se_mode = ADMV1013_SE_MODE_DIFF;
- else if (!strcmp(str, "se-pos"))
- st->quad_se_mode = ADMV1013_SE_MODE_POS;
- else if (!strcmp(str, "se-neg"))
- st->quad_se_mode = ADMV1013_SE_MODE_NEG;
- else
- return -EINVAL;
-
- ret = devm_regulator_bulk_get_enable(&st->spi->dev,
+ ret = devm_regulator_bulk_get_enable(dev,
ARRAY_SIZE(admv1013_vcc_regs),
admv1013_vcc_regs);
if (ret) {
- dev_err_probe(&spi->dev, ret,
+ dev_err_probe(dev, ret,
"Failed to request VCC regulators\n");
return ret;
}
@@ -562,9 +569,10 @@ static int admv1013_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct admv1013_state *st;
+ struct device *dev = &spi->dev;
int ret, vcm_uv;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@@ -581,36 +589,34 @@ static int admv1013_probe(struct spi_device *spi)
if (ret)
return ret;
- ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vcm");
+ ret = devm_regulator_get_enable_read_voltage(dev, "vcm");
if (ret < 0)
- return dev_err_probe(&spi->dev, ret,
+ return dev_err_probe(dev, ret,
"failed to get the common-mode voltage\n");
vcm_uv = ret;
- st->clkin = devm_clk_get_enabled(&spi->dev, "lo_in");
+ st->clkin = devm_clk_get_enabled(dev, "lo_in");
if (IS_ERR(st->clkin))
- return dev_err_probe(&spi->dev, PTR_ERR(st->clkin),
+ return dev_err_probe(dev, PTR_ERR(st->clkin),
"failed to get the LO input clock\n");
st->nb.notifier_call = admv1013_freq_change;
- ret = devm_clk_notifier_register(&spi->dev, st->clkin, &st->nb);
+ ret = devm_clk_notifier_register(dev, st->clkin, &st->nb);
if (ret)
return ret;
mutex_init(&st->lock);
ret = admv1013_init(st, vcm_uv);
- if (ret) {
- dev_err(&spi->dev, "admv1013 init failed\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "admv1013 init failed\n");
- ret = devm_add_action_or_reset(&spi->dev, admv1013_powerdown, st);
+ ret = devm_add_action_or_reset(dev, admv1013_powerdown, st);
if (ret)
return ret;
- return devm_iio_device_register(&spi->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id admv1013_id[] = {
diff --git a/drivers/iio/frequency/admv1014.c b/drivers/iio/frequency/admv1014.c
index 7a8f92ec80a2..25e8cd8135ad 100644
--- a/drivers/iio/frequency/admv1014.c
+++ b/drivers/iio/frequency/admv1014.c
@@ -610,15 +610,14 @@ static int admv1014_init(struct admv1014_state *st)
{
unsigned int chip_id, enable_reg, enable_reg_msk;
struct spi_device *spi = st->spi;
+ struct device *dev = &spi->dev;
int ret;
ret = regulator_bulk_enable(ADMV1014_NUM_REGULATORS, st->regulators);
- if (ret) {
- dev_err(&spi->dev, "Failed to enable regulators");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable regulators");
- ret = devm_add_action_or_reset(&spi->dev, admv1014_reg_disable, st->regulators);
+ ret = devm_add_action_or_reset(dev, admv1014_reg_disable, st->regulators);
if (ret)
return ret;
@@ -626,16 +625,16 @@ static int admv1014_init(struct admv1014_state *st)
if (ret)
return ret;
- ret = devm_add_action_or_reset(&spi->dev, admv1014_clk_disable, st->clkin);
+ ret = devm_add_action_or_reset(dev, admv1014_clk_disable, st->clkin);
if (ret)
return ret;
st->nb.notifier_call = admv1014_freq_change;
- ret = devm_clk_notifier_register(&spi->dev, st->clkin, &st->nb);
+ ret = devm_clk_notifier_register(dev, st->clkin, &st->nb);
if (ret)
return ret;
- ret = devm_add_action_or_reset(&spi->dev, admv1014_powerdown, st);
+ ret = devm_add_action_or_reset(dev, admv1014_powerdown, st);
if (ret)
return ret;
@@ -643,55 +642,47 @@ static int admv1014_init(struct admv1014_state *st)
ret = __admv1014_spi_update_bits(st, ADMV1014_REG_SPI_CONTROL,
ADMV1014_SPI_SOFT_RESET_MSK,
FIELD_PREP(ADMV1014_SPI_SOFT_RESET_MSK, 1));
- if (ret) {
- dev_err(&spi->dev, "ADMV1014 SPI software reset failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "ADMV1014 SPI software reset failed.\n");
ret = __admv1014_spi_update_bits(st, ADMV1014_REG_SPI_CONTROL,
ADMV1014_SPI_SOFT_RESET_MSK,
FIELD_PREP(ADMV1014_SPI_SOFT_RESET_MSK, 0));
- if (ret) {
- dev_err(&spi->dev, "ADMV1014 SPI software reset disable failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "ADMV1014 SPI software reset disable failed.\n");
ret = __admv1014_spi_write(st, ADMV1014_REG_VVA_TEMP_COMP, 0x727C);
- if (ret) {
- dev_err(&spi->dev, "Writing default Temperature Compensation value failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Writing default Temperature Compensation value failed.\n");
ret = __admv1014_spi_read(st, ADMV1014_REG_SPI_CONTROL, &chip_id);
if (ret)
return ret;
chip_id = FIELD_GET(ADMV1014_CHIP_ID_MSK, chip_id);
- if (chip_id != ADMV1014_CHIP_ID) {
- dev_err(&spi->dev, "Invalid Chip ID.\n");
- return -EINVAL;
- }
+ if (chip_id != ADMV1014_CHIP_ID)
+ return dev_err_probe(dev, -EINVAL, "Invalid Chip ID.\n");
ret = __admv1014_spi_update_bits(st, ADMV1014_REG_QUAD,
ADMV1014_QUAD_SE_MODE_MSK,
FIELD_PREP(ADMV1014_QUAD_SE_MODE_MSK,
st->quad_se_mode));
- if (ret) {
- dev_err(&spi->dev, "Writing Quad SE Mode failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Writing Quad SE Mode failed.\n");
ret = admv1014_update_quad_filters(st);
- if (ret) {
- dev_err(&spi->dev, "Update Quad Filters failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Update Quad Filters failed.\n");
ret = admv1014_update_vcm_settings(st);
- if (ret) {
- dev_err(&spi->dev, "Update VCM Settings failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Update VCM Settings failed.\n");
enable_reg_msk = ADMV1014_P1DB_COMPENSATION_MSK |
ADMV1014_IF_AMP_PD_MSK |
@@ -712,13 +703,14 @@ static int admv1014_properties_parse(struct admv1014_state *st)
{
unsigned int i;
struct spi_device *spi = st->spi;
+ struct device *dev = &spi->dev;
int ret;
- st->det_en = device_property_read_bool(&spi->dev, "adi,detector-enable");
+ st->det_en = device_property_read_bool(dev, "adi,detector-enable");
- st->p1db_comp = device_property_read_bool(&spi->dev, "adi,p1db-compensation-enable");
+ st->p1db_comp = device_property_read_bool(dev, "adi,p1db-compensation-enable");
- ret = device_property_match_property_string(&spi->dev, "adi,input-mode",
+ ret = device_property_match_property_string(dev, "adi,input-mode",
input_mode_names,
ARRAY_SIZE(input_mode_names));
if (ret >= 0)
@@ -726,7 +718,7 @@ static int admv1014_properties_parse(struct admv1014_state *st)
else
st->input_mode = ADMV1014_IQ_MODE;
- ret = device_property_match_property_string(&spi->dev, "adi,quad-se-mode",
+ ret = device_property_match_property_string(dev, "adi,quad-se-mode",
quad_se_mode_names,
ARRAY_SIZE(quad_se_mode_names));
if (ret >= 0)
@@ -737,16 +729,14 @@ static int admv1014_properties_parse(struct admv1014_state *st)
for (i = 0; i < ADMV1014_NUM_REGULATORS; ++i)
st->regulators[i].supply = admv1014_reg_name[i];
- ret = devm_regulator_bulk_get(&st->spi->dev, ADMV1014_NUM_REGULATORS,
+ ret = devm_regulator_bulk_get(dev, ADMV1014_NUM_REGULATORS,
st->regulators);
- if (ret) {
- dev_err(&spi->dev, "Failed to request regulators");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to request regulators");
- st->clkin = devm_clk_get(&spi->dev, "lo_in");
+ st->clkin = devm_clk_get(dev, "lo_in");
if (IS_ERR(st->clkin))
- return dev_err_probe(&spi->dev, PTR_ERR(st->clkin),
+ return dev_err_probe(dev, PTR_ERR(st->clkin),
"failed to get the LO input clock\n");
return 0;
@@ -756,9 +746,10 @@ static int admv1014_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct admv1014_state *st;
+ struct device *dev = &spi->dev;
int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@@ -787,7 +778,7 @@ static int admv1014_probe(struct spi_device *spi)
if (ret)
return ret;
- return devm_iio_device_register(&spi->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id admv1014_id[] = {
diff --git a/drivers/iio/frequency/admv4420.c b/drivers/iio/frequency/admv4420.c
index 3ae462b4f5c9..618511eddfb1 100644
--- a/drivers/iio/frequency/admv4420.c
+++ b/drivers/iio/frequency/admv4420.c
@@ -243,7 +243,7 @@ static int admv4420_calc_parameters(struct admv4420_state *st)
st->n_counter.n_counter = 1;
}
if (!sol_found)
- return -1;
+ return -EINVAL;
st->n_counter.int_val = div_u64_rem(st->n_counter.n_counter, 10, &st->n_counter.frac_val);
st->n_counter.mod_val = 10;
@@ -279,10 +279,9 @@ static int admv4420_setup(struct iio_dev *indio_dev)
if (ret)
return ret;
- if (val != ADMV4420_SCRATCH_PAD_VAL_1) {
- dev_err(dev, "Failed ADMV4420 to read/write scratchpad %x ", val);
- return -EIO;
- }
+ if (val != ADMV4420_SCRATCH_PAD_VAL_1)
+ return dev_err_probe(dev, -EIO,
+ "Failed ADMV4420 to read/write scratchpad %x\n", val);
ret = regmap_write(st->regmap,
ADMV4420_SCRATCHPAD,
@@ -294,10 +293,9 @@ static int admv4420_setup(struct iio_dev *indio_dev)
if (ret)
return ret;
- if (val != ADMV4420_SCRATCH_PAD_VAL_2) {
- dev_err(dev, "Failed to read/write scratchpad %x ", val);
- return -EIO;
- }
+ if (val != ADMV4420_SCRATCH_PAD_VAL_2)
+ return dev_err_probe(dev, -EIO,
+ "Failed to read/write scratchpad %x\n", val);
st->mux_sel = ADMV4420_LOCK_DTCT;
st->lo_freq_hz = ADMV4420_DEFAULT_LO_FREQ_HZ;
@@ -305,10 +303,10 @@ static int admv4420_setup(struct iio_dev *indio_dev)
admv4420_fw_parse(st);
ret = admv4420_calc_parameters(st);
- if (ret) {
- dev_err(dev, "Failed calc parameters for %lld ", st->vco_freq_hz);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed calc parameters for %llu\n",
+ st->vco_freq_hz);
ret = regmap_write(st->regmap, ADMV4420_R_DIV_L,
FIELD_GET(0xFF, st->ref_block.divider));
@@ -344,18 +342,19 @@ static int admv4420_setup(struct iio_dev *indio_dev)
static int admv4420_probe(struct spi_device *spi)
{
+ struct device *dev = &spi->dev;
struct iio_dev *indio_dev;
struct admv4420_state *st;
struct regmap *regmap;
int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
regmap = devm_regmap_init_spi(spi, &admv4420_regmap_config);
if (IS_ERR(regmap))
- return dev_err_probe(&spi->dev, PTR_ERR(regmap),
+ return dev_err_probe(dev, PTR_ERR(regmap),
"Failed to initializing spi regmap\n");
st = iio_priv(indio_dev);
@@ -368,12 +367,10 @@ static int admv4420_probe(struct spi_device *spi)
indio_dev->num_channels = ARRAY_SIZE(admv4420_channels);
ret = admv4420_setup(indio_dev);
- if (ret) {
- dev_err(&spi->dev, "Setup ADMV4420 failed (%d)\n", ret);
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "Setup ADMV4420 failed\n");
- return devm_iio_device_register(&spi->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct of_device_id admv4420_of_match[] = {
diff --git a/drivers/iio/frequency/adrf6780.c b/drivers/iio/frequency/adrf6780.c
index a7a21f929970..257fd31a0b0e 100644
--- a/drivers/iio/frequency/adrf6780.c
+++ b/drivers/iio/frequency/adrf6780.c
@@ -346,23 +346,21 @@ static const struct iio_chan_spec adrf6780_channels[] = {
static int adrf6780_reset(struct adrf6780_state *st)
{
int ret;
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
ret = __adrf6780_spi_update_bits(st, ADRF6780_REG_CONTROL,
ADRF6780_SOFT_RESET_MSK,
FIELD_PREP(ADRF6780_SOFT_RESET_MSK, 1));
- if (ret) {
- dev_err(&spi->dev, "ADRF6780 SPI software reset failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "ADRF6780 SPI software reset failed.\n");
ret = __adrf6780_spi_update_bits(st, ADRF6780_REG_CONTROL,
ADRF6780_SOFT_RESET_MSK,
FIELD_PREP(ADRF6780_SOFT_RESET_MSK, 0));
- if (ret) {
- dev_err(&spi->dev, "ADRF6780 SPI software reset disable failed.\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "ADRF6780 SPI software reset disable failed.\n");
return 0;
}
@@ -371,7 +369,7 @@ static int adrf6780_init(struct adrf6780_state *st)
{
int ret;
unsigned int chip_id, enable_reg, enable_reg_msk;
- struct spi_device *spi = st->spi;
+ struct device *dev = &st->spi->dev;
/* Perform a software reset */
ret = adrf6780_reset(st);
@@ -383,10 +381,9 @@ static int adrf6780_init(struct adrf6780_state *st)
return ret;
chip_id = FIELD_GET(ADRF6780_CHIP_ID_MSK, chip_id);
- if (chip_id != ADRF6780_CHIP_ID) {
- dev_err(&spi->dev, "ADRF6780 Invalid Chip ID.\n");
- return -EINVAL;
- }
+ if (chip_id != ADRF6780_CHIP_ID)
+ return dev_err_probe(dev, -EINVAL,
+ "ADRF6780 Invalid Chip ID.\n");
enable_reg_msk = ADRF6780_VGA_BUFFER_EN_MSK |
ADRF6780_DETECTOR_EN_MSK |
@@ -426,18 +423,18 @@ static int adrf6780_init(struct adrf6780_state *st)
static void adrf6780_properties_parse(struct adrf6780_state *st)
{
- struct spi_device *spi = st->spi;
-
- st->vga_buff_en = device_property_read_bool(&spi->dev, "adi,vga-buff-en");
- st->lo_buff_en = device_property_read_bool(&spi->dev, "adi,lo-buff-en");
- st->if_mode_en = device_property_read_bool(&spi->dev, "adi,if-mode-en");
- st->iq_mode_en = device_property_read_bool(&spi->dev, "adi,iq-mode-en");
- st->lo_x2_en = device_property_read_bool(&spi->dev, "adi,lo-x2-en");
- st->lo_ppf_en = device_property_read_bool(&spi->dev, "adi,lo-ppf-en");
- st->lo_en = device_property_read_bool(&spi->dev, "adi,lo-en");
- st->uc_bias_en = device_property_read_bool(&spi->dev, "adi,uc-bias-en");
- st->lo_sideband = device_property_read_bool(&spi->dev, "adi,lo-sideband");
- st->vdet_out_en = device_property_read_bool(&spi->dev, "adi,vdet-out-en");
+ struct device *dev = &st->spi->dev;
+
+ st->vga_buff_en = device_property_read_bool(dev, "adi,vga-buff-en");
+ st->lo_buff_en = device_property_read_bool(dev, "adi,lo-buff-en");
+ st->if_mode_en = device_property_read_bool(dev, "adi,if-mode-en");
+ st->iq_mode_en = device_property_read_bool(dev, "adi,iq-mode-en");
+ st->lo_x2_en = device_property_read_bool(dev, "adi,lo-x2-en");
+ st->lo_ppf_en = device_property_read_bool(dev, "adi,lo-ppf-en");
+ st->lo_en = device_property_read_bool(dev, "adi,lo-en");
+ st->uc_bias_en = device_property_read_bool(dev, "adi,uc-bias-en");
+ st->lo_sideband = device_property_read_bool(dev, "adi,lo-sideband");
+ st->vdet_out_en = device_property_read_bool(dev, "adi,vdet-out-en");
}
static void adrf6780_powerdown(void *data)
@@ -450,9 +447,10 @@ static int adrf6780_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct adrf6780_state *st;
+ struct device *dev = &spi->dev;
int ret;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@@ -467,9 +465,9 @@ static int adrf6780_probe(struct spi_device *spi)
adrf6780_properties_parse(st);
- st->clkin = devm_clk_get_enabled(&spi->dev, "lo_in");
+ st->clkin = devm_clk_get_enabled(dev, "lo_in");
if (IS_ERR(st->clkin))
- return dev_err_probe(&spi->dev, PTR_ERR(st->clkin),
+ return dev_err_probe(dev, PTR_ERR(st->clkin),
"failed to get the LO input clock\n");
mutex_init(&st->lock);
@@ -478,11 +476,11 @@ static int adrf6780_probe(struct spi_device *spi)
if (ret)
return ret;
- ret = devm_add_action_or_reset(&spi->dev, adrf6780_powerdown, st);
+ ret = devm_add_action_or_reset(dev, adrf6780_powerdown, st);
if (ret)
return ret;
- return devm_iio_device_register(&spi->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id adrf6780_id[] = {
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index c43990c518f7..c340cc899a7c 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -42,7 +42,7 @@ static const u32 gyro_3d_addresses[GYRO_3D_CHANNEL_MAX] = {
HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS
};
-static const u32 gryo_3d_sensitivity_addresses[] = {
+static const u32 gyro_3d_sensitivity_addresses[] = {
HID_USAGE_SENSOR_DATA_ANGL_VELOCITY,
};
@@ -297,8 +297,8 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
ret = hid_sensor_parse_common_attributes(hsdev,
HID_USAGE_SENSOR_GYRO_3D,
&gyro_state->common_attributes,
- gryo_3d_sensitivity_addresses,
- ARRAY_SIZE(gryo_3d_sensitivity_addresses));
+ gyro_3d_sensitivity_addresses,
+ ARRAY_SIZE(gyro_3d_sensitivity_addresses));
if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n");
return ret;
diff --git a/drivers/iio/humidity/hdc2010.c b/drivers/iio/humidity/hdc2010.c
index 894a8b4ab193..1a0f18251381 100644
--- a/drivers/iio/humidity/hdc2010.c
+++ b/drivers/iio/humidity/hdc2010.c
@@ -44,7 +44,6 @@ struct hdc2010_data {
struct i2c_client *client;
struct mutex lock;
u8 measurement_config;
- u8 interrupt_config;
u8 drdy_config;
};
diff --git a/drivers/iio/imu/bmi323/bmi323_core.c b/drivers/iio/imu/bmi323/bmi323_core.c
index 6bcb9a436581..f3d499423399 100644
--- a/drivers/iio/imu/bmi323/bmi323_core.c
+++ b/drivers/iio/imu/bmi323/bmi323_core.c
@@ -156,7 +156,6 @@ struct bmi323_data {
struct iio_mount_matrix orientation;
enum bmi323_irq_pin irq_pin;
struct iio_trigger *trig;
- bool drdy_trigger_enabled;
enum bmi323_state state;
s64 fifo_tstamp, old_fifo_tstamp;
u32 odrns[BMI323_SENSORS_CNT];
diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
index 0ab6eddf0543..532d5fdffaf8 100644
--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
@@ -1211,7 +1211,7 @@ int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev)
ssize_t i, size;
unsigned int no;
const void *accel, *gyro, *timestamp;
- const int8_t *temp;
+ const s8 *temp;
unsigned int odr;
int64_t ts_val;
/* buffer is copied to userspace, zeroing it to avoid any data leak */
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
index 6aee6c989485..47394594d17a 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_magn.c
@@ -125,7 +125,7 @@ static int inv_magn_init(struct inv_mpu6050_state *st)
}
/*
- * Sensitivity adjustement and scale to Gauss
+ * Sensitivity adjustment and scale to Gauss
*
* Hadj = H * (((ASA - 128) * 0.5 / 128) + 1)
* Factor simplification:
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
index 7c933218036b..b2a7c2eaf50d 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
@@ -144,6 +144,7 @@ MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
static const struct acpi_device_id st_lsm6dsx_i2c_acpi_match[] = {
{ "SMO8B30", ST_LSM6DS3TRC_ID, },
+ { "SMOCF00", ST_LSM6DSO_ID, },
{ }
};
MODULE_DEVICE_TABLE(acpi, st_lsm6dsx_i2c_acpi_match);
diff --git a/drivers/iio/industrialio-backend.c b/drivers/iio/industrialio-backend.c
index 447b694d6d5f..10e689f49441 100644
--- a/drivers/iio/industrialio-backend.c
+++ b/drivers/iio/industrialio-backend.c
@@ -56,6 +56,7 @@ struct iio_backend {
void *priv;
const char *name;
unsigned int cached_reg_addr;
+ u32 caps;
/*
* This index is relative to the frontend. Meaning that for
* frontends with multiple backends, this will be the index of this
@@ -774,6 +775,20 @@ int iio_backend_extend_chan_spec(struct iio_backend *back,
}
EXPORT_SYMBOL_NS_GPL(iio_backend_extend_chan_spec, "IIO_BACKEND");
+/**
+ * iio_backend_has_caps - Check if backend has specific capabilities
+ * @back: Backend device
+ * @caps: Capabilities to check
+ *
+ * RETURNS:
+ * True if backend has all the requested capabilities, false otherwise.
+ */
+bool iio_backend_has_caps(struct iio_backend *back, u32 caps)
+{
+ return (back->caps & caps) == caps;
+}
+EXPORT_SYMBOL_NS_GPL(iio_backend_has_caps, "IIO_BACKEND");
+
static void iio_backend_release(void *arg)
{
struct iio_backend *back = arg;
@@ -952,7 +967,6 @@ EXPORT_SYMBOL_NS_GPL(iio_backend_data_transfer_addr, "IIO_BACKEND");
static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, const char *name,
struct fwnode_handle *fwnode)
{
- struct fwnode_handle *fwnode_back;
struct iio_backend *back;
unsigned int index;
int ret;
@@ -967,7 +981,8 @@ static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, con
index = 0;
}
- fwnode_back = fwnode_find_reference(fwnode, "io-backends", index);
+ struct fwnode_handle *fwnode_back __free(fwnode_handle) =
+ fwnode_find_reference(fwnode, "io-backends", index);
if (IS_ERR(fwnode_back))
return dev_err_cast_probe(dev, fwnode_back,
"Cannot get Firmware reference\n");
@@ -977,7 +992,6 @@ static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, con
if (!device_match_fwnode(back->dev, fwnode_back))
continue;
- fwnode_handle_put(fwnode_back);
ret = __devm_iio_backend_get(dev, back);
if (ret)
return ERR_PTR(ret);
@@ -988,7 +1002,6 @@ static struct iio_backend *__devm_iio_backend_fwnode_get(struct device *dev, con
return back;
}
- fwnode_handle_put(fwnode_back);
return ERR_PTR(-EPROBE_DEFER);
}
@@ -1114,6 +1127,7 @@ int devm_iio_backend_register(struct device *dev,
back->ops = info->ops;
back->name = info->name;
+ back->caps = info->caps;
back->owner = dev->driver->owner;
back->dev = dev;
back->priv = priv;
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index 4149efcd5539..a0d6fcf2a9c9 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -256,6 +256,7 @@ static const char * const iio_ev_info_text[] = {
[IIO_EV_INFO_TAP2_MIN_DELAY] = "tap2_min_delay",
[IIO_EV_INFO_RUNNING_PERIOD] = "runningperiod",
[IIO_EV_INFO_RUNNING_COUNT] = "runningcount",
+ [IIO_EV_INFO_SCALE] = "scale",
};
static enum iio_event_direction iio_ev_attr_dir(struct iio_dev_attr *attr)
diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
index 7f34fe7bad07..17781c12bc85 100644
--- a/drivers/iio/industrialio-trigger.c
+++ b/drivers/iio/industrialio-trigger.c
@@ -561,10 +561,6 @@ struct iio_trigger *viio_trigger_alloc(struct device *parent,
if (!trig)
return NULL;
- trig->dev.parent = parent;
- trig->dev.type = &iio_trig_type;
- trig->dev.bus = &iio_bus_type;
- device_initialize(&trig->dev);
INIT_WORK(&trig->reenable_work, iio_reenable_work_fn);
mutex_init(&trig->pool_lock);
@@ -592,6 +588,11 @@ struct iio_trigger *viio_trigger_alloc(struct device *parent,
IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
}
+ trig->dev.parent = parent;
+ trig->dev.type = &iio_trig_type;
+ trig->dev.bus = &iio_bus_type;
+ device_initialize(&trig->dev);
+
return trig;
free_descs:
@@ -634,9 +635,9 @@ void iio_trigger_free(struct iio_trigger *trig)
}
EXPORT_SYMBOL(iio_trigger_free);
-static void devm_iio_trigger_release(struct device *dev, void *res)
+static void devm_iio_trigger_release(void *trig)
{
- iio_trigger_free(*(struct iio_trigger **)res);
+ iio_trigger_free(trig);
}
/**
@@ -658,24 +659,20 @@ struct iio_trigger *__devm_iio_trigger_alloc(struct device *parent,
struct module *this_mod,
const char *fmt, ...)
{
- struct iio_trigger **ptr, *trig;
+ struct iio_trigger *trig;
va_list vargs;
-
- ptr = devres_alloc(devm_iio_trigger_release, sizeof(*ptr),
- GFP_KERNEL);
- if (!ptr)
- return NULL;
+ int ret;
/* use raw alloc_dr for kmalloc caller tracing */
va_start(vargs, fmt);
trig = viio_trigger_alloc(parent, this_mod, fmt, vargs);
va_end(vargs);
- if (trig) {
- *ptr = trig;
- devres_add(parent, ptr);
- } else {
- devres_free(ptr);
- }
+ if (!trig)
+ return NULL;
+
+ ret = devm_add_action_or_reset(parent, devm_iio_trigger_release, trig);
+ if (ret)
+ return NULL;
return trig;
}
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index ac1408d374c9..eff33e456c70 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -359,7 +359,7 @@ config ROHM_BU27034
select IIO_KFIFO_BUF
help
Enable support for the ROHM BU27034 ambient light sensor. ROHM BU27034
- is an ambient light sesnor with 3 channels and 3 photo diodes capable
+ is an ambient light sensor with 3 channels and 3 photo diodes capable
of detecting a very wide range of illuminance.
Typical application is adjusting LCD and backlight power of TVs and
mobile phones.
diff --git a/drivers/iio/light/acpi-als.c b/drivers/iio/light/acpi-als.c
index d5d1a8b9c035..ab229318dce9 100644
--- a/drivers/iio/light/acpi-als.c
+++ b/drivers/iio/light/acpi-als.c
@@ -18,6 +18,7 @@
#include <linux/err.h>
#include <linux/irq.h>
#include <linux/mutex.h>
+#include <linux/platform_device.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
@@ -90,9 +91,9 @@ static int acpi_als_read_value(struct acpi_als *als, char *prop, s32 *val)
return 0;
}
-static void acpi_als_notify(struct acpi_device *device, u32 event)
+static void acpi_als_notify(acpi_handle handle, u32 event, void *data)
{
- struct iio_dev *indio_dev = acpi_driver_data(device);
+ struct iio_dev *indio_dev = data;
struct acpi_als *als = iio_priv(indio_dev);
if (iio_buffer_enabled(indio_dev) && iio_trigger_using_own(indio_dev)) {
@@ -102,7 +103,7 @@ static void acpi_als_notify(struct acpi_device *device, u32 event)
break;
default:
/* Unhandled event */
- dev_dbg(&device->dev,
+ dev_dbg(&als->device->dev,
"Unhandled ACPI ALS event (%08x)!\n",
event);
}
@@ -175,9 +176,10 @@ out:
return IRQ_HANDLED;
}
-static int acpi_als_add(struct acpi_device *device)
+static int acpi_als_probe(struct platform_device *pdev)
{
- struct device *dev = &device->dev;
+ struct device *dev = &pdev->dev;
+ struct acpi_device *device = ACPI_COMPANION(dev);
struct iio_dev *indio_dev;
struct acpi_als *als;
int ret;
@@ -188,7 +190,6 @@ static int acpi_als_add(struct acpi_device *device)
als = iio_priv(indio_dev);
- device->driver_data = indio_dev;
als->device = device;
mutex_init(&als->lock);
@@ -218,7 +219,18 @@ static int acpi_als_add(struct acpi_device *device)
if (ret)
return ret;
- return devm_iio_device_register(dev, indio_dev);
+ ret = devm_iio_device_register(dev, indio_dev);
+ if (ret)
+ return ret;
+
+ return acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
+ acpi_als_notify, indio_dev);
+}
+
+static void acpi_als_remove(struct platform_device *pdev)
+{
+ acpi_dev_remove_notify_handler(ACPI_COMPANION(&pdev->dev),
+ ACPI_DEVICE_NOTIFY, acpi_als_notify);
}
static const struct acpi_device_id acpi_als_device_ids[] = {
@@ -228,17 +240,15 @@ static const struct acpi_device_id acpi_als_device_ids[] = {
MODULE_DEVICE_TABLE(acpi, acpi_als_device_ids);
-static struct acpi_driver acpi_als_driver = {
- .name = "acpi_als",
- .class = ACPI_ALS_CLASS,
- .ids = acpi_als_device_ids,
- .ops = {
- .add = acpi_als_add,
- .notify = acpi_als_notify,
+static struct platform_driver acpi_als_driver = {
+ .probe = acpi_als_probe,
+ .remove = acpi_als_remove,
+ .driver = {
+ .name = "acpi_als",
+ .acpi_match_table = acpi_als_device_ids,
},
};
-
-module_acpi_driver(acpi_als_driver);
+module_platform_driver(acpi_als_driver);
MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>");
MODULE_AUTHOR("Martin Liska <marxin.liska@gmail.com>");
diff --git a/drivers/iio/light/apds9160.c b/drivers/iio/light/apds9160.c
index 9b8af11b7b67..3da0bdac04cf 100644
--- a/drivers/iio/light/apds9160.c
+++ b/drivers/iio/light/apds9160.c
@@ -620,7 +620,7 @@ static int apds9160_set_ps_gain(struct apds9160_chip *data, int val)
/*
* The PS intelligent cancellation level register allows
- * for an on-chip substraction of the ADC count caused by
+ * for an on-chip subtraction of the ADC count caused by
* unwanted reflected light from PS ADC output.
*/
static int apds9160_set_ps_cancellation_level(struct apds9160_chip *data,
diff --git a/drivers/iio/light/apds9306.c b/drivers/iio/light/apds9306.c
index 7e68cca0edfa..5ca4c87524fe 100644
--- a/drivers/iio/light/apds9306.c
+++ b/drivers/iio/light/apds9306.c
@@ -168,7 +168,6 @@ struct apds9306_regfields {
* respectively.
* @regmap: Regmap structure pointer
* @rf: Regmap register fields structure
- * @nlux_per_count: Nano lux per ADC count for a particular model
* @read_data_available: Flag set by IRQ handler for ADC data available
*/
struct apds9306_data {
@@ -180,7 +179,6 @@ struct apds9306_data {
struct regmap *regmap;
struct apds9306_regfields rf;
- int nlux_per_count;
int read_data_available;
};
@@ -1176,7 +1174,7 @@ static int apds9306_init_iio_gts(struct apds9306_data *data)
static void apds9306_powerdown(void *ptr)
{
- struct apds9306_data *data = (struct apds9306_data *)ptr;
+ struct apds9306_data *data = ptr;
struct apds9306_regfields *rf = &data->rf;
int ret;
diff --git a/drivers/iio/light/as73211.c b/drivers/iio/light/as73211.c
index 32719f584c47..9fe830dac679 100644
--- a/drivers/iio/light/as73211.c
+++ b/drivers/iio/light/as73211.c
@@ -677,9 +677,6 @@ static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p)
(char *)&scan.chan[0], 3 * sizeof(scan.chan[0]));
if (ret < 0)
goto done;
-
- /* Avoid pushing uninitialized data */
- scan.chan[3] = 0;
}
if (data_result) {
diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c
index c7df4b258e2c..7e388319ee2e 100644
--- a/drivers/iio/light/gp2ap020a00f.c
+++ b/drivers/iio/light/gp2ap020a00f.c
@@ -31,12 +31,14 @@
* the other one.
*/
+#include <linux/cleanup.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irq_work.h>
+#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
@@ -44,6 +46,7 @@
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/unaligned.h>
+
#include <linux/iio/buffer.h>
#include <linux/iio/events.h>
#include <linux/iio/iio.h>
@@ -52,8 +55,6 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
-#define GP2A_I2C_NAME "gp2ap020a00f"
-
/* Registers */
#define GP2AP020A00F_OP_REG 0x00 /* Basic operations */
#define GP2AP020A00F_ALS_REG 0x01 /* ALS related settings */
@@ -174,10 +175,8 @@
#define GP2AP020A00F_CHAN_TIMESTAMP 3
#define GP2AP020A00F_DATA_READY_TIMEOUT msecs_to_jiffies(1000)
-#define GP2AP020A00F_DATA_REG(chan) (GP2AP020A00F_D0_L_REG + \
- (chan) * 2)
-#define GP2AP020A00F_THRESH_REG(th_val_id) (GP2AP020A00F_TL_L_REG + \
- (th_val_id) * 2)
+#define GP2AP020A00F_DATA_REG(chan) (GP2AP020A00F_D0_L_REG + (chan) * 2)
+#define GP2AP020A00F_THRESH_REG(th_val_id) (GP2AP020A00F_TL_L_REG + (th_val_id) * 2)
#define GP2AP020A00F_THRESH_VAL_ID(reg_addr) ((reg_addr - 4) / 2)
#define GP2AP020A00F_SUBTRACT_MODE 0
@@ -194,7 +193,7 @@ enum gp2ap020a00f_opmode {
GP2AP020A00F_OPMODE_ALS_AND_PS,
GP2AP020A00F_OPMODE_PROX_DETECT,
GP2AP020A00F_OPMODE_SHUTDOWN,
- GP2AP020A00F_NUM_OPMODES,
+ GP2AP020A00F_NUM_OPMODES
};
enum gp2ap020a00f_cmd {
@@ -246,7 +245,6 @@ struct gp2ap020a00f_data {
struct iio_trigger *trig;
struct regmap *regmap;
unsigned int thresh_val[4];
- u8 debug_reg_addr;
struct irq_work work;
wait_queue_head_t data_ready_queue;
};
@@ -389,20 +387,17 @@ static int gp2ap020a00f_set_operation_mode(struct gp2ap020a00f_data *data,
}
err = regmap_update_bits(data->regmap, GP2AP020A00F_ALS_REG,
- GP2AP020A00F_PRST_MASK, opmode_regs_settings[op]
- .als_reg);
+ GP2AP020A00F_PRST_MASK, opmode_regs_settings[op].als_reg);
if (err < 0)
return err;
err = regmap_update_bits(data->regmap, GP2AP020A00F_PS_REG,
- GP2AP020A00F_INTTYPE_MASK, opmode_regs_settings[op]
- .ps_reg);
+ GP2AP020A00F_INTTYPE_MASK, opmode_regs_settings[op].ps_reg);
if (err < 0)
return err;
err = regmap_update_bits(data->regmap, GP2AP020A00F_LED_REG,
- GP2AP020A00F_PIN_MASK, opmode_regs_settings[op]
- .led_reg);
+ GP2AP020A00F_PIN_MASK, opmode_regs_settings[op].led_reg);
if (err < 0)
return err;
}
@@ -453,15 +448,13 @@ static int gp2ap020a00f_write_event_threshold(struct gp2ap020a00f_data *data,
*/
thresh_reg_val = data->thresh_val[th_val_id] / 16;
else
- thresh_reg_val = data->thresh_val[th_val_id] > 16000 ?
- 16000 :
- data->thresh_val[th_val_id];
+ thresh_reg_val = min(data->thresh_val[th_val_id], 16000U);
thresh_buf = cpu_to_le16(thresh_reg_val);
return regmap_bulk_write(data->regmap,
GP2AP020A00F_THRESH_REG(th_val_id),
- (u8 *)&thresh_buf, 2);
+ &thresh_buf, sizeof(thresh_buf));
}
static int gp2ap020a00f_alter_opmode(struct gp2ap020a00f_data *data,
@@ -493,27 +486,24 @@ static int gp2ap020a00f_alter_opmode(struct gp2ap020a00f_data *data,
static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
enum gp2ap020a00f_cmd cmd)
{
- int err = 0;
+ int err;
switch (cmd) {
case GP2AP020A00F_CMD_READ_RAW_CLEAR:
if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
return -EBUSY;
- err = gp2ap020a00f_set_operation_mode(data,
+ return gp2ap020a00f_set_operation_mode(data,
GP2AP020A00F_OPMODE_READ_RAW_CLEAR);
- break;
case GP2AP020A00F_CMD_READ_RAW_IR:
if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
return -EBUSY;
- err = gp2ap020a00f_set_operation_mode(data,
+ return gp2ap020a00f_set_operation_mode(data,
GP2AP020A00F_OPMODE_READ_RAW_IR);
- break;
case GP2AP020A00F_CMD_READ_RAW_PROXIMITY:
if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
return -EBUSY;
- err = gp2ap020a00f_set_operation_mode(data,
+ return gp2ap020a00f_set_operation_mode(data,
GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY);
- break;
case GP2AP020A00F_CMD_TRIGGER_CLEAR_EN:
if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
return -EBUSY;
@@ -521,16 +511,17 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
err = gp2ap020a00f_alter_opmode(data,
GP2AP020A00F_OPMODE_ALS,
GP2AP020A00F_ADD_MODE);
+ else
+ err = 0;
set_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
- break;
+ return err;
case GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS:
clear_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
if (gp2ap020a00f_als_enabled(data))
break;
- err = gp2ap020a00f_alter_opmode(data,
+ return gp2ap020a00f_alter_opmode(data,
GP2AP020A00F_OPMODE_ALS,
GP2AP020A00F_SUBTRACT_MODE);
- break;
case GP2AP020A00F_CMD_TRIGGER_IR_EN:
if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
return -EBUSY;
@@ -538,16 +529,17 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
err = gp2ap020a00f_alter_opmode(data,
GP2AP020A00F_OPMODE_ALS,
GP2AP020A00F_ADD_MODE);
+ else
+ err = 0;
set_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
- break;
+ return err;
case GP2AP020A00F_CMD_TRIGGER_IR_DIS:
clear_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
if (gp2ap020a00f_als_enabled(data))
break;
- err = gp2ap020a00f_alter_opmode(data,
+ return gp2ap020a00f_alter_opmode(data,
GP2AP020A00F_OPMODE_ALS,
GP2AP020A00F_SUBTRACT_MODE);
- break;
case GP2AP020A00F_CMD_TRIGGER_PROX_EN:
if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
return -EBUSY;
@@ -555,13 +547,12 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
GP2AP020A00F_OPMODE_PS,
GP2AP020A00F_ADD_MODE);
set_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &data->flags);
- break;
+ return err;
case GP2AP020A00F_CMD_TRIGGER_PROX_DIS:
clear_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &data->flags);
- err = gp2ap020a00f_alter_opmode(data,
+ return gp2ap020a00f_alter_opmode(data,
GP2AP020A00F_OPMODE_PS,
GP2AP020A00F_SUBTRACT_MODE);
- break;
case GP2AP020A00F_CMD_ALS_HIGH_EV_EN:
if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags))
return 0;
@@ -575,9 +566,8 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
return err;
}
set_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags);
- err = gp2ap020a00f_write_event_threshold(data,
+ return gp2ap020a00f_write_event_threshold(data,
GP2AP020A00F_THRESH_TH, true);
- break;
case GP2AP020A00F_CMD_ALS_HIGH_EV_DIS:
if (!test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags))
return 0;
@@ -589,9 +579,8 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
if (err < 0)
return err;
}
- err = gp2ap020a00f_write_event_threshold(data,
+ return gp2ap020a00f_write_event_threshold(data,
GP2AP020A00F_THRESH_TH, false);
- break;
case GP2AP020A00F_CMD_ALS_LOW_EV_EN:
if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags))
return 0;
@@ -605,9 +594,8 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
return err;
}
set_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
- err = gp2ap020a00f_write_event_threshold(data,
+ return gp2ap020a00f_write_event_threshold(data,
GP2AP020A00F_THRESH_TL, true);
- break;
case GP2AP020A00F_CMD_ALS_LOW_EV_DIS:
if (!test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags))
return 0;
@@ -619,9 +607,8 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
if (err < 0)
return err;
}
- err = gp2ap020a00f_write_event_threshold(data,
+ return gp2ap020a00f_write_event_threshold(data,
GP2AP020A00F_THRESH_TL, false);
- break;
case GP2AP020A00F_CMD_PROX_HIGH_EV_EN:
if (test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags))
return 0;
@@ -635,9 +622,8 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
return err;
}
set_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags);
- err = gp2ap020a00f_write_event_threshold(data,
+ return gp2ap020a00f_write_event_threshold(data,
GP2AP020A00F_THRESH_PH, true);
- break;
case GP2AP020A00F_CMD_PROX_HIGH_EV_DIS:
if (!test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags))
return 0;
@@ -646,9 +632,8 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
GP2AP020A00F_OPMODE_SHUTDOWN);
if (err < 0)
return err;
- err = gp2ap020a00f_write_event_threshold(data,
+ return gp2ap020a00f_write_event_threshold(data,
GP2AP020A00F_THRESH_PH, false);
- break;
case GP2AP020A00F_CMD_PROX_LOW_EV_EN:
if (test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags))
return 0;
@@ -662,9 +647,8 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
return err;
}
set_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
- err = gp2ap020a00f_write_event_threshold(data,
+ return gp2ap020a00f_write_event_threshold(data,
GP2AP020A00F_THRESH_PL, true);
- break;
case GP2AP020A00F_CMD_PROX_LOW_EV_DIS:
if (!test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags))
return 0;
@@ -673,12 +657,11 @@ static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
GP2AP020A00F_OPMODE_SHUTDOWN);
if (err < 0)
return err;
- err = gp2ap020a00f_write_event_threshold(data,
+ return gp2ap020a00f_write_event_threshold(data,
GP2AP020A00F_THRESH_PL, false);
- break;
}
- return err;
+ return 0;
}
static int wait_conversion_complete_irq(struct gp2ap020a00f_data *data)
@@ -697,18 +680,18 @@ static int wait_conversion_complete_irq(struct gp2ap020a00f_data *data)
static int gp2ap020a00f_read_output(struct gp2ap020a00f_data *data,
unsigned int output_reg, int *val)
{
- u8 reg_buf[2];
+ __le16 reg_buf;
int err;
err = wait_conversion_complete_irq(data);
if (err < 0)
dev_dbg(&data->client->dev, "data ready timeout\n");
- err = regmap_bulk_read(data->regmap, output_reg, reg_buf, 2);
+ err = regmap_bulk_read(data->regmap, output_reg, &reg_buf, sizeof(reg_buf));
if (err < 0)
return err;
- *val = le16_to_cpup((__le16 *)reg_buf);
+ *val = le16_to_cpu(reg_buf);
return err;
}
@@ -866,13 +849,13 @@ static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data)
{
struct iio_dev *indio_dev = data;
struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
- u8 op_reg_flags, d0_reg_buf[2];
unsigned int output_val, op_reg_val;
+ __le16 d0_reg_buf;
+ u8 op_reg_flags;
int thresh_val_id, ret;
/* Read interrupt flags */
- ret = regmap_read(priv->regmap, GP2AP020A00F_OP_REG,
- &op_reg_val);
+ ret = regmap_read(priv->regmap, GP2AP020A00F_OP_REG, &op_reg_val);
if (ret < 0)
goto done;
@@ -884,8 +867,7 @@ static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data)
/* Clear interrupt flags (if not in INTTYPE_PULSE mode) */
if (priv->cur_opmode != GP2AP020A00F_OPMODE_PROX_DETECT) {
- ret = regmap_write(priv->regmap, GP2AP020A00F_OP_REG,
- op_reg_val);
+ ret = regmap_write(priv->regmap, GP2AP020A00F_OP_REG, op_reg_val);
if (ret < 0)
goto done;
}
@@ -895,11 +877,11 @@ static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data)
* transition is required.
*/
ret = regmap_bulk_read(priv->regmap, GP2AP020A00F_D0_L_REG,
- d0_reg_buf, 2);
+ &d0_reg_buf, sizeof(d0_reg_buf));
if (ret < 0)
goto done;
- output_val = le16_to_cpup((__le16 *)d0_reg_buf);
+ output_val = le16_to_cpu(d0_reg_buf);
if (gp2ap020a00f_adjust_lux_mode(priv, output_val))
goto done;
@@ -966,17 +948,15 @@ static irqreturn_t gp2ap020a00f_trigger_handler(int irq, void *data)
int i, out_val, ret;
iio_for_each_active_channel(indio_dev, i) {
- ret = regmap_bulk_read(priv->regmap,
- GP2AP020A00F_DATA_REG(i),
- &priv->buffer[d_size], 2);
+ ret = regmap_bulk_read(priv->regmap, GP2AP020A00F_DATA_REG(i),
+ &priv->buffer[d_size], 2);
if (ret < 0)
goto done;
if (i == GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR ||
i == GP2AP020A00F_SCAN_MODE_LIGHT_IR) {
- out_val = le16_to_cpup((__le16 *)&priv->buffer[d_size]);
+ out_val = get_unaligned_le16(&priv->buffer[d_size]);
gp2ap020a00f_output_to_lux(priv, &out_val);
-
put_unaligned_le32(out_val, &priv->buffer[d_size]);
d_size += 4;
} else {
@@ -984,16 +964,15 @@ static irqreturn_t gp2ap020a00f_trigger_handler(int irq, void *data)
}
}
- iio_push_to_buffers_with_timestamp(indio_dev, priv->buffer,
- pf->timestamp);
+ iio_push_to_buffers_with_timestamp(indio_dev, priv->buffer, pf->timestamp);
done:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
-static u8 gp2ap020a00f_get_thresh_reg(const struct iio_chan_spec *chan,
- enum iio_event_direction event_dir)
+static int gp2ap020a00f_get_thresh_reg(const struct iio_chan_spec *chan,
+ enum iio_event_direction event_dir)
{
switch (chan->type) {
case IIO_PROXIMITY:
@@ -1007,10 +986,8 @@ static u8 gp2ap020a00f_get_thresh_reg(const struct iio_chan_spec *chan,
else
return GP2AP020A00F_TL_L_REG;
default:
- break;
+ return -EINVAL;
}
-
- return -EINVAL;
}
static int gp2ap020a00f_write_event_val(struct iio_dev *indio_dev,
@@ -1023,53 +1000,41 @@ static int gp2ap020a00f_write_event_val(struct iio_dev *indio_dev,
struct gp2ap020a00f_data *data = iio_priv(indio_dev);
bool event_en = false;
u8 thresh_val_id;
- u8 thresh_reg_l;
- int err = 0;
+ int thresh_reg_l;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir);
- thresh_val_id = GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l);
+ if (thresh_reg_l < 0)
+ return thresh_reg_l;
- if (thresh_val_id > GP2AP020A00F_THRESH_PH) {
- err = -EINVAL;
- goto error_unlock;
- }
+ thresh_val_id = GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l);
+ if (thresh_val_id > GP2AP020A00F_THRESH_PH)
+ return -EINVAL;
switch (thresh_reg_l) {
case GP2AP020A00F_TH_L_REG:
- event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV,
- &data->flags);
+ event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags);
break;
case GP2AP020A00F_TL_L_REG:
- event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV,
- &data->flags);
+ event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
break;
case GP2AP020A00F_PH_L_REG:
- if (val == 0) {
- err = -EINVAL;
- goto error_unlock;
- }
- event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV,
- &data->flags);
+ if (val == 0)
+ return -EINVAL;
+
+ event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags);
break;
case GP2AP020A00F_PL_L_REG:
- if (val == 0) {
- err = -EINVAL;
- goto error_unlock;
- }
- event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV,
- &data->flags);
+ if (val == 0)
+ return -EINVAL;
+
+ event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
break;
}
data->thresh_val[thresh_val_id] = val;
- err = gp2ap020a00f_write_event_threshold(data, thresh_val_id,
- event_en);
-error_unlock:
- mutex_unlock(&data->lock);
-
- return err;
+ return gp2ap020a00f_write_event_threshold(data, thresh_val_id, event_en);
}
static int gp2ap020a00f_read_event_val(struct iio_dev *indio_dev,
@@ -1080,24 +1045,19 @@ static int gp2ap020a00f_read_event_val(struct iio_dev *indio_dev,
int *val, int *val2)
{
struct gp2ap020a00f_data *data = iio_priv(indio_dev);
- u8 thresh_reg_l;
- int err = IIO_VAL_INT;
+ int thresh_reg_l;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir);
-
- if (thresh_reg_l > GP2AP020A00F_PH_L_REG) {
- err = -EINVAL;
- goto error_unlock;
- }
+ if (thresh_reg_l < 0)
+ return thresh_reg_l;
+ if (thresh_reg_l > GP2AP020A00F_PH_L_REG)
+ return -EINVAL;
*val = data->thresh_val[GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l)];
-error_unlock:
- mutex_unlock(&data->lock);
-
- return err;
+ return IIO_VAL_INT;
}
static int gp2ap020a00f_write_prox_event_config(struct iio_dev *indio_dev,
@@ -1163,32 +1123,25 @@ static int gp2ap020a00f_write_event_config(struct iio_dev *indio_dev,
{
struct gp2ap020a00f_data *data = iio_priv(indio_dev);
enum gp2ap020a00f_cmd cmd;
- int err;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
switch (chan->type) {
case IIO_PROXIMITY:
- err = gp2ap020a00f_write_prox_event_config(indio_dev, state);
- break;
+ return gp2ap020a00f_write_prox_event_config(indio_dev, state);
case IIO_LIGHT:
if (dir == IIO_EV_DIR_RISING) {
cmd = state ? GP2AP020A00F_CMD_ALS_HIGH_EV_EN :
GP2AP020A00F_CMD_ALS_HIGH_EV_DIS;
- err = gp2ap020a00f_exec_cmd(data, cmd);
+ return gp2ap020a00f_exec_cmd(data, cmd);
} else {
cmd = state ? GP2AP020A00F_CMD_ALS_LOW_EV_EN :
GP2AP020A00F_CMD_ALS_LOW_EV_DIS;
- err = gp2ap020a00f_exec_cmd(data, cmd);
+ return gp2ap020a00f_exec_cmd(data, cmd);
}
- break;
default:
- err = -EINVAL;
+ return -EINVAL;
}
-
- mutex_unlock(&data->lock);
-
- return err;
}
static int gp2ap020a00f_read_event_config(struct iio_dev *indio_dev,
@@ -1197,40 +1150,29 @@ static int gp2ap020a00f_read_event_config(struct iio_dev *indio_dev,
enum iio_event_direction dir)
{
struct gp2ap020a00f_data *data = iio_priv(indio_dev);
- int event_en = 0;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
switch (chan->type) {
case IIO_PROXIMITY:
if (dir == IIO_EV_DIR_RISING)
- event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV,
- &data->flags);
+ return test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags);
else
- event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV,
- &data->flags);
- break;
+ return test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
case IIO_LIGHT:
if (dir == IIO_EV_DIR_RISING)
- event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV,
- &data->flags);
+ return test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags);
else
- event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV,
- &data->flags);
- break;
+ return test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
default:
- event_en = -EINVAL;
- break;
+ return -EINVAL;
}
-
- mutex_unlock(&data->lock);
-
- return event_en;
}
static int gp2ap020a00f_read_channel(struct gp2ap020a00f_data *data,
struct iio_chan_spec const *chan, int *val)
{
+ struct device *dev = &data->client->dev;
enum gp2ap020a00f_cmd cmd;
int err;
@@ -1250,27 +1192,23 @@ static int gp2ap020a00f_read_channel(struct gp2ap020a00f_data *data,
err = gp2ap020a00f_exec_cmd(data, cmd);
if (err < 0) {
- dev_err(&data->client->dev,
- "gp2ap020a00f_exec_cmd failed\n");
- goto error_ret;
+ dev_err(dev, "gp2ap020a00f_exec_cmd failed\n");
+ return err;
}
err = gp2ap020a00f_read_output(data, chan->address, val);
if (err < 0)
- dev_err(&data->client->dev,
- "gp2ap020a00f_read_output failed\n");
+ dev_err(dev, "gp2ap020a00f_read_output failed\n");
err = gp2ap020a00f_set_operation_mode(data,
GP2AP020A00F_OPMODE_SHUTDOWN);
if (err < 0)
- dev_err(&data->client->dev,
- "Failed to shut down the device.\n");
+ dev_err(dev, "Failed to shut down the device.\n");
if (cmd == GP2AP020A00F_CMD_READ_RAW_CLEAR ||
cmd == GP2AP020A00F_CMD_READ_RAW_IR)
gp2ap020a00f_output_to_lux(data, val);
-error_ret:
return err;
}
@@ -1383,9 +1321,9 @@ static const struct iio_info gp2ap020a00f_info = {
static int gp2ap020a00f_buffer_postenable(struct iio_dev *indio_dev)
{
struct gp2ap020a00f_data *data = iio_priv(indio_dev);
- int i, err = 0;
+ int i, err;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
/*
* Enable triggers according to the scan_mask. Enabling either
@@ -1409,28 +1347,27 @@ static int gp2ap020a00f_buffer_postenable(struct iio_dev *indio_dev)
err = gp2ap020a00f_exec_cmd(data,
GP2AP020A00F_CMD_TRIGGER_PROX_EN);
break;
+ default:
+ err = -EINVAL;
+ break;
}
+ if (err)
+ return err;
}
- if (err < 0)
- goto error_unlock;
-
data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
if (!data->buffer)
- err = -ENOMEM;
-
-error_unlock:
- mutex_unlock(&data->lock);
+ return -ENOMEM;
- return err;
+ return 0;
}
static int gp2ap020a00f_buffer_predisable(struct iio_dev *indio_dev)
{
struct gp2ap020a00f_data *data = iio_priv(indio_dev);
- int i, err = 0;
+ int i, err;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
iio_for_each_active_channel(indio_dev, i) {
switch (i) {
@@ -1446,15 +1383,16 @@ static int gp2ap020a00f_buffer_predisable(struct iio_dev *indio_dev)
err = gp2ap020a00f_exec_cmd(data,
GP2AP020A00F_CMD_TRIGGER_PROX_DIS);
break;
+ default:
+ err = -EINVAL;
+ break;
}
+ if (err)
+ return err;
}
- if (err == 0)
- kfree(data->buffer);
-
- mutex_unlock(&data->lock);
-
- return err;
+ kfree(data->buffer);
+ return 0;
}
static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = {
@@ -1465,18 +1403,19 @@ static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = {
static int gp2ap020a00f_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
+ struct device *dev = &client->dev;
struct gp2ap020a00f_data *data;
struct iio_dev *indio_dev;
struct regmap *regmap;
int err;
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
- data->vled_reg = devm_regulator_get(&client->dev, "vled");
+ data->vled_reg = devm_regulator_get(dev, "vled");
if (IS_ERR(data->vled_reg))
return PTR_ERR(data->vled_reg);
@@ -1486,7 +1425,7 @@ static int gp2ap020a00f_probe(struct i2c_client *client)
regmap = devm_regmap_init_i2c(client, &gp2ap020a00f_regmap_config);
if (IS_ERR(regmap)) {
- dev_err(&client->dev, "Regmap initialization failed.\n");
+ dev_err(dev, "Regmap initialization failed.\n");
err = PTR_ERR(regmap);
goto error_regulator_disable;
}
@@ -1497,7 +1436,7 @@ static int gp2ap020a00f_probe(struct i2c_client *client)
ARRAY_SIZE(gp2ap020a00f_reg_init_tab));
if (err < 0) {
- dev_err(&client->dev, "Device initialization failed.\n");
+ dev_err(dev, "Device initialization failed.\n");
goto error_regulator_disable;
}
@@ -1522,11 +1461,10 @@ static int gp2ap020a00f_probe(struct i2c_client *client)
goto error_regulator_disable;
/* Allocate trigger */
- data->trig = devm_iio_trigger_alloc(&client->dev, "%s-trigger",
- indio_dev->name);
+ data->trig = devm_iio_trigger_alloc(dev, "%s-trigger", indio_dev->name);
if (data->trig == NULL) {
err = -ENOMEM;
- dev_err(&indio_dev->dev, "Failed to allocate iio trigger.\n");
+ dev_err(dev, "Failed to allocate iio trigger.\n");
goto error_uninit_buffer;
}
@@ -1538,7 +1476,7 @@ static int gp2ap020a00f_probe(struct i2c_client *client)
"gp2ap020a00f_als_event",
indio_dev);
if (err < 0) {
- dev_err(&client->dev, "Irq request failed.\n");
+ dev_err(dev, "Irq request failed.\n");
goto error_uninit_buffer;
}
@@ -1546,7 +1484,7 @@ static int gp2ap020a00f_probe(struct i2c_client *client)
err = iio_trigger_register(data->trig);
if (err < 0) {
- dev_err(&client->dev, "Failed to register iio trigger.\n");
+ dev_err(dev, "Failed to register iio trigger.\n");
goto error_free_irq;
}
@@ -1572,12 +1510,12 @@ static void gp2ap020a00f_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+ struct device *dev = &client->dev;
int err;
- err = gp2ap020a00f_set_operation_mode(data,
- GP2AP020A00F_OPMODE_SHUTDOWN);
+ err = gp2ap020a00f_set_operation_mode(data, GP2AP020A00F_OPMODE_SHUTDOWN);
if (err < 0)
- dev_err(&indio_dev->dev, "Failed to power off the device.\n");
+ dev_err(dev, "Failed to power off the device.\n");
iio_device_unregister(indio_dev);
iio_trigger_unregister(data->trig);
@@ -1587,10 +1525,9 @@ static void gp2ap020a00f_remove(struct i2c_client *client)
}
static const struct i2c_device_id gp2ap020a00f_id[] = {
- { GP2A_I2C_NAME },
+ { "gp2ap020a00f" },
{ }
};
-
MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id);
static const struct of_device_id gp2ap020a00f_of_match[] = {
@@ -1601,14 +1538,13 @@ MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match);
static struct i2c_driver gp2ap020a00f_driver = {
.driver = {
- .name = GP2A_I2C_NAME,
+ .name = "gp2ap020a00f",
.of_match_table = gp2ap020a00f_of_match,
},
.probe = gp2ap020a00f_probe,
.remove = gp2ap020a00f_remove,
.id_table = gp2ap020a00f_id,
};
-
module_i2c_driver(gp2ap020a00f_driver);
MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
diff --git a/drivers/iio/light/ltr390.c b/drivers/iio/light/ltr390.c
index fc387426fa87..f1702aca582d 100644
--- a/drivers/iio/light/ltr390.c
+++ b/drivers/iio/light/ltr390.c
@@ -101,7 +101,7 @@ enum ltr390_meas_rate {
struct ltr390_data {
struct regmap *regmap;
struct i2c_client *client;
- /* Protects device from simulataneous reads */
+ /* Protects device from simultaneous reads */
struct mutex lock;
enum ltr390_mode mode;
int gain;
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c
index 022e0693983b..4d99ae336f61 100644
--- a/drivers/iio/light/ltr501.c
+++ b/drivers/iio/light/ltr501.c
@@ -754,7 +754,7 @@ static int ltr501_get_gain_index(const struct ltr501_gain *gain, int size,
if (val == gain[i].scale && val2 == gain[i].uscale)
return i;
- return -1;
+ return -EINVAL;
}
static int __ltr501_write_raw(struct iio_dev *indio_dev,
@@ -773,7 +773,7 @@ static int __ltr501_write_raw(struct iio_dev *indio_dev,
info->als_gain_tbl_size,
val, val2);
if (i < 0)
- return -EINVAL;
+ return i;
data->als_contr &= ~info->als_gain_mask;
data->als_contr |= i << info->als_gain_shift;
@@ -785,7 +785,7 @@ static int __ltr501_write_raw(struct iio_dev *indio_dev,
info->ps_gain_tbl_size,
val, val2);
if (i < 0)
- return -EINVAL;
+ return i;
data->ps_contr &= ~LTR501_CONTR_PS_GAIN_MASK;
data->ps_contr |= i << LTR501_CONTR_PS_GAIN_SHIFT;
diff --git a/drivers/iio/light/opt3001.c b/drivers/iio/light/opt3001.c
index 393a3d2fbe1d..53bc455b7bad 100644
--- a/drivers/iio/light/opt3001.c
+++ b/drivers/iio/light/opt3001.c
@@ -91,7 +91,7 @@ struct opt3001_chip_info {
*/
int factor_integer;
/*
- * Factor used to align decimal part of proccessed value to six decimal
+ * Factor used to align decimal part of processed value to six decimal
* places.
*/
int factor_decimal;
diff --git a/drivers/iio/light/tsl2772.c b/drivers/iio/light/tsl2772.c
index 0b171106441a..c8f15ba95267 100644
--- a/drivers/iio/light/tsl2772.c
+++ b/drivers/iio/light/tsl2772.c
@@ -190,7 +190,7 @@ struct tsl2772_chip {
};
/*
- * Different devices require different coefficents, and these numbers were
+ * Different devices require different coefficients, and these numbers were
* derived from the 'Lux Equation' section of the various device datasheets.
* All of these coefficients assume a Glass Attenuation (GA) factor of 1.
* The coefficients are multiplied by 1000 to avoid floating point operations.
diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c
index a36c23813679..9650dbc41f2b 100644
--- a/drivers/iio/light/vcnl4000.c
+++ b/drivers/iio/light/vcnl4000.c
@@ -18,12 +18,13 @@
*/
#include <linux/bitfield.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
#include <linux/delay.h>
-#include <linux/pm_runtime.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
#include <linux/units.h>
#include <linux/iio/buffer.h>
@@ -185,6 +186,7 @@ static const int vcnl4040_ps_oversampling_ratio[] = {1, 2, 4, 8};
#define VCNL4000_SLEEP_DELAY_MS 2000 /* before we enter pm_runtime_suspend */
enum vcnl4000_device_ids {
+ CM36672P,
VCNL4000,
VCNL4010,
VCNL4040,
@@ -235,6 +237,8 @@ struct vcnl4000_chip_spec {
};
static const struct i2c_device_id vcnl4000_id[] = {
+ { "cm36672p", CM36672P },
+ { "cm36686", VCNL4040 },
{ "vcnl4000", VCNL4000 },
{ "vcnl4010", VCNL4010 },
{ "vcnl4020", VCNL4010 },
@@ -277,7 +281,7 @@ static int vcnl4000_init(struct vcnl4000_data *data)
data->rev = ret & 0xf;
data->al_scale = 250000;
- return data->chip_spec->set_power_state(data, true);
+ return 0;
};
static ssize_t vcnl4000_write_als_enable(struct vcnl4000_data *data, bool en)
@@ -353,17 +357,19 @@ static int vcnl4200_set_power_state(struct vcnl4000_data *data, bool on)
static int vcnl4200_init(struct vcnl4000_data *data)
{
+ struct i2c_client *client = data->client;
+ struct device *dev = &client->dev;
int ret, id;
u16 regval;
- ret = i2c_smbus_read_word_data(data->client, VCNL4200_DEV_ID);
+ ret = i2c_smbus_read_word_data(client, VCNL4200_DEV_ID);
if (ret < 0)
return ret;
id = ret & 0xff;
if (id != VCNL4200_PROD_ID) {
- ret = i2c_smbus_read_word_data(data->client, VCNL4040_DEV_ID);
+ ret = i2c_smbus_read_word_data(client, VCNL4040_DEV_ID);
if (ret < 0)
return ret;
@@ -373,7 +379,7 @@ static int vcnl4200_init(struct vcnl4000_data *data)
return -ENODEV;
}
- dev_dbg(&data->client->dev, "device id 0x%x", id);
+ dev_dbg(dev, "device id 0x%x", id);
data->rev = (ret >> 8) & 0xf;
data->ps_int = 0;
@@ -397,32 +403,32 @@ static int vcnl4200_init(struct vcnl4000_data *data)
}
data->al_scale = data->chip_spec->ulux_step;
data->ps_scale = 16;
- mutex_init(&data->vcnl4200_al.lock);
- mutex_init(&data->vcnl4200_ps.lock);
+
+ ret = devm_mutex_init(dev, &data->vcnl4200_al.lock);
+ if (ret)
+ return ret;
+
+ ret = devm_mutex_init(dev, &data->vcnl4200_ps.lock);
+ if (ret)
+ return ret;
/* Use 16 bits proximity sensor readings */
- ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF1);
+ ret = i2c_smbus_read_word_data(client, VCNL4200_PS_CONF1);
if (ret < 0)
return ret;
regval = ret | VCNL4040_PS_CONF2_PS_HD;
- ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF1,
- regval);
+ ret = i2c_smbus_write_word_data(client, VCNL4200_PS_CONF1, regval);
if (ret < 0)
return ret;
/* Align proximity sensor sample rate to 16 bits data width */
- ret = i2c_smbus_read_word_data(data->client, VCNL4200_PS_CONF3);
+ ret = i2c_smbus_read_word_data(client, VCNL4200_PS_CONF3);
if (ret < 0)
return ret;
regval = ret | VCNL4040_CONF3_PS_SAMPLE_16BITS;
- ret = i2c_smbus_write_word_data(data->client, VCNL4200_PS_CONF3,
- regval);
- if (ret < 0)
- return ret;
-
- ret = data->chip_spec->set_power_state(data, true);
+ ret = i2c_smbus_write_word_data(client, VCNL4200_PS_CONF3, regval);
if (ret < 0)
return ret;
@@ -1842,6 +1848,22 @@ static const struct iio_chan_spec vcnl4040_channels[] = {
}
};
+static const struct iio_chan_spec cm36672p_channels[] = {
+ {
+ .type = IIO_PROXIMITY,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_INT_TIME) |
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
+ BIT(IIO_CHAN_INFO_CALIBBIAS),
+ .info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
+ BIT(IIO_CHAN_INFO_CALIBBIAS),
+ .ext_info = vcnl4000_ext_info,
+ .event_spec = vcnl4040_event_spec,
+ .num_event_specs = ARRAY_SIZE(vcnl4040_event_spec),
+ },
+};
+
static const struct iio_info vcnl4000_info = {
.read_raw = vcnl4000_read_raw,
};
@@ -1867,6 +1889,19 @@ static const struct iio_info vcnl4040_info = {
};
static const struct vcnl4000_chip_spec vcnl4000_chip_spec_cfg[] = {
+ [CM36672P] = {
+ .prod = "CM36672P",
+ .init = vcnl4200_init,
+ .measure_proximity = vcnl4200_measure_proximity,
+ .set_power_state = vcnl4200_set_power_state,
+ .channels = cm36672p_channels,
+ .num_channels = ARRAY_SIZE(cm36672p_channels),
+ .info = &vcnl4040_info,
+ .irq_thread = vcnl4040_irq_thread,
+ .int_reg = VCNL4040_INT_FLAGS,
+ .ps_it_times = &vcnl4040_ps_it_times,
+ .num_ps_it_times = ARRAY_SIZE(vcnl4040_ps_it_times),
+ },
[VCNL4000] = {
.prod = "VCNL4000",
.init = vcnl4000_init,
@@ -1951,11 +1986,13 @@ static int vcnl4010_probe_trigger(struct iio_dev *indio_dev)
static int vcnl4000_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
+ const char * const regulator_names[] = { "vdd", "vio", "vled" };
+ struct device *dev = &client->dev;
struct vcnl4000_data *data;
struct iio_dev *indio_dev;
int ret;
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
@@ -1965,18 +2002,27 @@ static int vcnl4000_probe(struct i2c_client *client)
data->id = id->driver_data;
data->chip_spec = &vcnl4000_chip_spec_cfg[data->id];
- mutex_init(&data->vcnl4000_lock);
+ ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names),
+ regulator_names);
+ if (ret)
+ return ret;
+
+ ret = devm_mutex_init(dev, &data->vcnl4000_lock);
+ if (ret)
+ return ret;
ret = data->chip_spec->init(data);
if (ret < 0)
return ret;
- dev_dbg(&client->dev, "%s Ambient light/proximity sensor, Rev: %02x\n",
+ ret = data->chip_spec->set_power_state(data, true);
+ if (ret)
+ return ret;
+
+ dev_dbg(dev, "%s Ambient light/proximity sensor, Rev: %02x\n",
data->chip_spec->prod, data->rev);
- if (device_property_read_u32(&client->dev, "proximity-near-level",
- &data->near_level))
- data->near_level = 0;
+ device_property_read_u32(dev, "proximity-near-level", &data->near_level);
indio_dev->info = data->chip_spec->info;
indio_dev->channels = data->chip_spec->channels;
@@ -1986,35 +2032,29 @@ static int vcnl4000_probe(struct i2c_client *client)
if (data->chip_spec->trig_buffer_func &&
data->chip_spec->buffer_setup_ops) {
- ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
- NULL,
+ ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
data->chip_spec->trig_buffer_func,
data->chip_spec->buffer_setup_ops);
- if (ret < 0) {
- dev_err(&client->dev,
- "unable to setup iio triggered buffer\n");
+ if (ret < 0)
return ret;
- }
}
if (client->irq && data->chip_spec->irq_thread) {
- ret = devm_request_threaded_irq(&client->dev, client->irq,
- NULL, data->chip_spec->irq_thread,
+ ret = devm_request_threaded_irq(dev, client->irq, NULL,
+ data->chip_spec->irq_thread,
IRQF_TRIGGER_FALLING |
IRQF_ONESHOT,
"vcnl4000_irq",
indio_dev);
- if (ret < 0) {
- dev_err(&client->dev, "irq request failed\n");
+ if (ret < 0)
return ret;
- }
ret = vcnl4010_probe_trigger(indio_dev);
if (ret < 0)
return ret;
}
- ret = pm_runtime_set_active(&client->dev);
+ ret = pm_runtime_set_active(dev);
if (ret < 0)
goto fail_poweroff;
@@ -2022,9 +2062,9 @@ static int vcnl4000_probe(struct i2c_client *client)
if (ret < 0)
goto fail_poweroff;
- pm_runtime_enable(&client->dev);
- pm_runtime_set_autosuspend_delay(&client->dev, VCNL4000_SLEEP_DELAY_MS);
- pm_runtime_use_autosuspend(&client->dev);
+ pm_runtime_enable(dev);
+ pm_runtime_set_autosuspend_delay(dev, VCNL4000_SLEEP_DELAY_MS);
+ pm_runtime_use_autosuspend(dev);
return 0;
fail_poweroff:
@@ -2034,6 +2074,15 @@ fail_poweroff:
static const struct of_device_id vcnl_4000_of_match[] = {
{
+ .compatible = "capella,cm36672p",
+ .data = (void *)CM36672P,
+ },
+ /* Capella CM36686 is fully compatible with Vishay VCNL4040 */
+ {
+ .compatible = "capella,cm36686",
+ .data = (void *)VCNL4040,
+ },
+ {
.compatible = "vishay,vcnl4000",
.data = (void *)VCNL4000,
},
diff --git a/drivers/iio/light/zopt2201.c b/drivers/iio/light/zopt2201.c
index 1dba1b949cc3..0990e4d266eb 100644
--- a/drivers/iio/light/zopt2201.c
+++ b/drivers/iio/light/zopt2201.c
@@ -10,17 +10,17 @@
* TODO: interrupt support, ALS/UVB raw mode
*/
-#include <linux/module.h>
+#include <linux/cleanup.h>
+#include <linux/delay.h>
+#include <linux/err.h>
#include <linux/i2c.h>
+#include <linux/module.h>
#include <linux/mutex.h>
-#include <linux/err.h>
-#include <linux/delay.h>
+#include <linux/unaligned.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
-#include <linux/unaligned.h>
-
#define ZOPT2201_DRV_NAME "zopt2201"
/* Registers */
@@ -186,10 +186,10 @@ static int zopt2201_read(struct zopt2201_data *data, u8 reg)
u8 buf[3];
int ret;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
ret = zopt2201_enable_mode(data, reg == ZOPT2201_UVB_DATA);
if (ret < 0)
- goto fail;
+ return ret;
while (tries--) {
unsigned long t = zopt2201_resolution[data->res].us;
@@ -200,30 +200,25 @@ static int zopt2201_read(struct zopt2201_data *data, u8 reg)
msleep(t / 1000);
ret = i2c_smbus_read_byte_data(client, ZOPT2201_MAIN_STATUS);
if (ret < 0)
- goto fail;
+ return ret;
if (ret & ZOPT2201_MAIN_STATUS_DRDY)
break;
}
if (tries < 0) {
ret = -ETIMEDOUT;
- goto fail;
+ return ret;
}
ret = i2c_smbus_read_i2c_block_data(client, reg, sizeof(buf), buf);
if (ret < 0)
- goto fail;
+ return ret;
ret = i2c_smbus_write_byte_data(client, ZOPT2201_MAIN_CTRL, 0x00);
if (ret < 0)
- goto fail;
- mutex_unlock(&data->lock);
+ return ret;
return get_unaligned_le24(&buf[0]);
-
-fail:
- mutex_unlock(&data->lock);
- return ret;
}
static const struct iio_chan_spec zopt2201_channels[] = {
@@ -317,17 +312,15 @@ static int zopt2201_set_resolution(struct zopt2201_data *data, u8 res)
static int zopt2201_write_resolution(struct zopt2201_data *data,
int val, int val2)
{
- int i, ret;
+ int i;
if (val != 0)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(zopt2201_resolution); i++)
if (val2 == zopt2201_resolution[i].us) {
- mutex_lock(&data->lock);
- ret = zopt2201_set_resolution(data, i);
- mutex_unlock(&data->lock);
- return ret;
+ guard(mutex)(&data->lock);
+ return zopt2201_set_resolution(data, i);
}
return -EINVAL;
@@ -351,16 +344,12 @@ static int zopt2201_write_scale_by_idx(struct zopt2201_data *data, int idx,
{
int ret;
- mutex_lock(&data->lock);
+ guard(mutex)(&data->lock);
ret = zopt2201_set_resolution(data, zopt2201_scale_array[idx].res);
if (ret < 0)
- goto unlock;
-
- ret = zopt2201_set_gain(data, zopt2201_scale_array[idx].gain);
+ return ret;
-unlock:
- mutex_unlock(&data->lock);
- return ret;
+ return zopt2201_set_gain(data, zopt2201_scale_array[idx].gain);
}
static int zopt2201_write_scale_als(struct zopt2201_data *data,
diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c
index 68ece700c7ce..817b18257608 100644
--- a/drivers/iio/magnetometer/ak8974.c
+++ b/drivers/iio/magnetometer/ak8974.c
@@ -577,7 +577,7 @@ static int ak8974_measure_channel(struct ak8974 *ak8974, unsigned long address,
/*
* This explicit cast to (s16) is necessary as the measurement
* is done in 2's complement with positive and negative values.
- * The follwing assignment to *val will then convert the signed
+ * The following assignment to *val will then convert the signed
* s16 value to a signed int value.
*/
*val = (s16)le16_to_cpu(hw_values[address]);
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index d30315ad85de..b648b0afa573 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -545,7 +545,7 @@ static int ak8975_set_mode(struct ak8975_data *data, enum ak_ctrl_mode mode)
return ret;
}
data->cntl_cache = regval;
- /* After mode change wait atleast 100us */
+ /* After mode change wait at least 100us */
usleep_range(100, 500);
return 0;
@@ -697,7 +697,7 @@ static int wait_conversion_complete_polled(struct ak8975_data *data)
return read_status;
}
-/* Returns 0 if the end of conversion interrupt occured or -ETIME otherwise */
+/* Returns 0 if the end of conversion interrupt occurred or -ETIME otherwise */
static int wait_conversion_complete_interrupt(struct ak8975_data *data)
{
int ret;
@@ -759,7 +759,7 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
if (ret < 0)
goto exit;
- /* Read out ST2 for release lock on measurment data. */
+ /* Read out ST2 for release lock on measurement data. */
ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST2]);
if (ret < 0) {
dev_err(&client->dev, "Error in reading ST2\n");
diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c
index a022e1805dff..bf2551988008 100644
--- a/drivers/iio/magnetometer/bmc150_magn.c
+++ b/drivers/iio/magnetometer/bmc150_magn.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
+#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pm.h>
@@ -148,14 +149,16 @@ struct bmc150_magn_data {
static const struct {
int freq;
u8 reg_val;
-} bmc150_magn_samp_freq_table[] = { {2, 0x01},
- {6, 0x02},
- {8, 0x03},
- {10, 0x00},
- {15, 0x04},
- {20, 0x05},
- {25, 0x06},
- {30, 0x07} };
+} bmc150_magn_samp_freq_table[] = {
+ { 2, 0x01 },
+ { 6, 0x02 },
+ { 8, 0x03 },
+ { 10, 0x00 },
+ { 15, 0x04 },
+ { 20, 0x05 },
+ { 25, 0x06 },
+ { 30, 0x07 },
+};
enum bmc150_magn_presets {
LOW_POWER_PRESET,
@@ -169,10 +172,10 @@ static const struct bmc150_magn_preset {
u8 rep_z;
u8 odr;
} bmc150_magn_presets_table[] = {
- [LOW_POWER_PRESET] = {3, 3, 10},
- [REGULAR_PRESET] = {9, 15, 10},
- [ENHANCED_REGULAR_PRESET] = {15, 27, 10},
- [HIGH_ACCURACY_PRESET] = {47, 83, 20},
+ [LOW_POWER_PRESET] = { 3, 3, 10 },
+ [REGULAR_PRESET] = { 9, 15, 10 },
+ [ENHANCED_REGULAR_PRESET] = { 15, 27, 10 },
+ [HIGH_ACCURACY_PRESET] = { 47, 83, 20 },
};
#define BMC150_MAGN_DEFAULT_PRESET REGULAR_PRESET
@@ -255,6 +258,13 @@ static int bmc150_magn_set_power_mode(struct bmc150_magn_data *data,
return -EINVAL;
}
+static int bmc150_magn_set_power_mode_locked(struct bmc150_magn_data *data,
+ enum bmc150_magn_power_modes mode)
+{
+ guard(mutex)(&data->mutex);
+ return bmc150_magn_set_power_mode(data, mode, true);
+}
+
static int bmc150_magn_set_power_state(struct bmc150_magn_data *data, bool on)
{
int ret = 0;
@@ -453,33 +463,29 @@ static int bmc150_magn_read_raw(struct iio_dev *indio_dev,
s32 values[AXIS_XYZ_MAX];
switch (mask) {
- case IIO_CHAN_INFO_RAW:
+ case IIO_CHAN_INFO_RAW: {
if (iio_buffer_enabled(indio_dev))
return -EBUSY;
- mutex_lock(&data->mutex);
+
+ guard(mutex)(&data->mutex);
ret = bmc150_magn_set_power_state(data, true);
- if (ret < 0) {
- mutex_unlock(&data->mutex);
+ if (ret < 0)
return ret;
- }
ret = bmc150_magn_read_xyz(data, values);
if (ret < 0) {
bmc150_magn_set_power_state(data, false);
- mutex_unlock(&data->mutex);
return ret;
}
*val = values[chan->scan_index];
ret = bmc150_magn_set_power_state(data, false);
- if (ret < 0) {
- mutex_unlock(&data->mutex);
+ if (ret < 0)
return ret;
- }
- mutex_unlock(&data->mutex);
return IIO_VAL_INT;
+ }
case IIO_CHAN_INFO_SCALE:
/*
* The API/driver performs an off-chip temperature
@@ -527,48 +533,39 @@ static int bmc150_magn_write_raw(struct iio_dev *indio_dev,
int ret;
switch (mask) {
- case IIO_CHAN_INFO_SAMP_FREQ:
+ case IIO_CHAN_INFO_SAMP_FREQ: {
if (val > data->max_odr)
return -EINVAL;
- mutex_lock(&data->mutex);
- ret = bmc150_magn_set_odr(data, val);
- mutex_unlock(&data->mutex);
- return ret;
+ guard(mutex)(&data->mutex);
+ return bmc150_magn_set_odr(data, val);
+ }
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
switch (chan->channel2) {
case IIO_MOD_X:
- case IIO_MOD_Y:
+ case IIO_MOD_Y: {
if (val < 1 || val > 511)
return -EINVAL;
- mutex_lock(&data->mutex);
+ guard(mutex)(&data->mutex);
ret = bmc150_magn_set_max_odr(data, val, 0, 0);
- if (ret < 0) {
- mutex_unlock(&data->mutex);
+ if (ret < 0)
return ret;
- }
- ret = regmap_update_bits(data->regmap,
+ return regmap_update_bits(data->regmap,
BMC150_MAGN_REG_REP_XY,
BMC150_MAGN_REG_REP_DATAMASK,
- BMC150_MAGN_REPXY_TO_REGVAL
- (val));
- mutex_unlock(&data->mutex);
- return ret;
- case IIO_MOD_Z:
+ BMC150_MAGN_REPXY_TO_REGVAL(val));
+ }
+ case IIO_MOD_Z: {
if (val < 1 || val > 256)
return -EINVAL;
- mutex_lock(&data->mutex);
+ guard(mutex)(&data->mutex);
ret = bmc150_magn_set_max_odr(data, 0, val, 0);
- if (ret < 0) {
- mutex_unlock(&data->mutex);
+ if (ret < 0)
return ret;
- }
- ret = regmap_update_bits(data->regmap,
+ return regmap_update_bits(data->regmap,
BMC150_MAGN_REG_REP_Z,
BMC150_MAGN_REG_REP_DATAMASK,
- BMC150_MAGN_REPZ_TO_REGVAL
- (val));
- mutex_unlock(&data->mutex);
- return ret;
+ BMC150_MAGN_REPZ_TO_REGVAL(val));
+ }
default:
return -EINVAL;
}
@@ -655,8 +652,9 @@ static const struct iio_info bmc150_magn_info = {
};
static const unsigned long bmc150_magn_scan_masks[] = {
- BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
- 0};
+ BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
+ 0
+};
static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p)
{
@@ -695,7 +693,7 @@ static int bmc150_magn_init(struct bmc150_magn_data *data)
* 3ms power-on time according to datasheet, let's better
* be safe than sorry and set this delay to 5ms.
*/
- msleep(5);
+ fsleep(5 * USEC_PER_MSEC);
ret = bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SUSPEND,
false);
@@ -782,9 +780,8 @@ static void bmc150_magn_trig_reen(struct iio_trigger *trig)
if (!data->dready_trigger_on)
return;
- mutex_lock(&data->mutex);
+ guard(mutex)(&data->mutex);
ret = bmc150_magn_reset_intr(data);
- mutex_unlock(&data->mutex);
if (ret)
dev_err(data->dev, "Failed to reset interrupt\n");
}
@@ -794,32 +791,28 @@ static int bmc150_magn_data_rdy_trigger_set_state(struct iio_trigger *trig,
{
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
struct bmc150_magn_data *data = iio_priv(indio_dev);
- int ret = 0;
+ int ret;
+
+ guard(mutex)(&data->mutex);
- mutex_lock(&data->mutex);
if (state == data->dready_trigger_on)
- goto err_unlock;
+ return 0;
ret = regmap_update_bits(data->regmap, BMC150_MAGN_REG_INT_DRDY,
BMC150_MAGN_MASK_DRDY_EN,
state << BMC150_MAGN_SHIFT_DRDY_EN);
if (ret < 0)
- goto err_unlock;
+ return ret;
data->dready_trigger_on = state;
if (state) {
ret = bmc150_magn_reset_intr(data);
if (ret < 0)
- goto err_unlock;
+ return ret;
}
- mutex_unlock(&data->mutex);
return 0;
-
-err_unlock:
- mutex_unlock(&data->mutex);
- return ret;
}
static const struct iio_trigger_ops bmc150_magn_trigger_ops = {
@@ -977,9 +970,7 @@ void bmc150_magn_remove(struct device *dev)
if (data->dready_trig)
iio_trigger_unregister(data->dready_trig);
- mutex_lock(&data->mutex);
- bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SUSPEND, true);
- mutex_unlock(&data->mutex);
+ bmc150_magn_set_power_mode_locked(data, BMC150_MAGN_POWER_MODE_SUSPEND);
regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators);
}
@@ -992,10 +983,8 @@ static int bmc150_magn_runtime_suspend(struct device *dev)
struct bmc150_magn_data *data = iio_priv(indio_dev);
int ret;
- mutex_lock(&data->mutex);
- ret = bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SLEEP,
- true);
- mutex_unlock(&data->mutex);
+ ret = bmc150_magn_set_power_mode_locked(data,
+ BMC150_MAGN_POWER_MODE_SLEEP);
if (ret < 0) {
dev_err(dev, "powering off device failed\n");
return ret;
@@ -1021,28 +1010,18 @@ static int bmc150_magn_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmc150_magn_data *data = iio_priv(indio_dev);
- int ret;
- mutex_lock(&data->mutex);
- ret = bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_SLEEP,
- true);
- mutex_unlock(&data->mutex);
-
- return ret;
+ return bmc150_magn_set_power_mode_locked(data,
+ BMC150_MAGN_POWER_MODE_SLEEP);
}
static int bmc150_magn_resume(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmc150_magn_data *data = iio_priv(indio_dev);
- int ret;
- mutex_lock(&data->mutex);
- ret = bmc150_magn_set_power_mode(data, BMC150_MAGN_POWER_MODE_NORMAL,
- true);
- mutex_unlock(&data->mutex);
-
- return ret;
+ return bmc150_magn_set_power_mode_locked(data,
+ BMC150_MAGN_POWER_MODE_NORMAL);
}
#endif
diff --git a/drivers/iio/magnetometer/si7210.c b/drivers/iio/magnetometer/si7210.c
index 27e3feba7a0f..2a36abd1c99d 100644
--- a/drivers/iio/magnetometer/si7210.c
+++ b/drivers/iio/magnetometer/si7210.c
@@ -128,8 +128,8 @@ static const struct regmap_config si7210_regmap_conf = {
struct si7210_data {
struct regmap *regmap;
struct i2c_client *client;
- struct regulator *vdd;
struct mutex fetch_lock; /* lock for a single measurement fetch */
+ unsigned int vdd_uV;
s8 temp_offset;
s8 temp_gain;
s8 scale_20_a[A_REGS_COUNT];
@@ -221,12 +221,8 @@ static int si7210_read_raw(struct iio_dev *indio_dev,
temp *= (1 + (data->temp_gain / 2048));
temp += (int)(MICRO / 16) * data->temp_offset;
- ret = regulator_get_voltage(data->vdd);
- if (ret < 0)
- return ret;
-
/* temp -= 0.222 * VDD */
- temp -= 222 * div_s64(ret, MILLI);
+ temp -= 222 * (data->vdd_uV / MILLI);
*val = div_s64(temp, MILLI);
@@ -396,14 +392,11 @@ static int si7210_probe(struct i2c_client *client)
return dev_err_probe(&client->dev, PTR_ERR(data->regmap),
"failed to register regmap\n");
- data->vdd = devm_regulator_get(&client->dev, "vdd");
- if (IS_ERR(data->vdd))
- return dev_err_probe(&client->dev, PTR_ERR(data->vdd),
- "failed to get VDD regulator\n");
-
- ret = regulator_enable(data->vdd);
- if (ret)
- return ret;
+ ret = devm_regulator_get_enable_read_voltage(&client->dev, "vdd");
+ if (ret < 0)
+ return dev_err_probe(&client->dev, ret,
+ "Failed to get vdd regulator\n");
+ data->vdd_uV = ret;
indio_dev->name = dev_name(&client->dev);
indio_dev->modes = INDIO_DIRECT_MODE;
diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c
index d49e37edcbed..140c422773f6 100644
--- a/drivers/iio/magnetometer/yamaha-yas530.c
+++ b/drivers/iio/magnetometer/yamaha-yas530.c
@@ -1223,7 +1223,7 @@ static int yas530_measure_offsets(struct yas5xx *yas5xx)
* as the values for [x, y1, y2]. The value is +/-31
* but the effect on the raw values is much larger.
* The effect of the offset is to bring the measure
- * rougly to the center.
+ * roughly to the center.
*/
ox = 0;
oy1 = 0;
diff --git a/drivers/iio/pressure/bmp280-spi.c b/drivers/iio/pressure/bmp280-spi.c
index 3b90384f17d7..04bf2f5be5b1 100644
--- a/drivers/iio/pressure/bmp280-spi.c
+++ b/drivers/iio/pressure/bmp280-spi.c
@@ -47,7 +47,7 @@ static int bmp380_regmap_spi_read(void *context, const void *reg,
return -EINVAL;
/*
- * According to the BMP3xx datasheets, for a basic SPI read opertion,
+ * According to the BMP3xx datasheets, for a basic SPI read operation,
* the first byte needs to be dropped and the rest are the requested
* data.
*/
diff --git a/drivers/iio/pressure/hsc030pa.c b/drivers/iio/pressure/hsc030pa.c
index 2d00c0656259..d6b18a84f0ab 100644
--- a/drivers/iio/pressure/hsc030pa.c
+++ b/drivers/iio/pressure/hsc030pa.c
@@ -273,7 +273,7 @@ static const struct hsc_range_config hsc_range_config[HSC_VARIANTS_MAX] = {
* @data: structure containing instantiated sensor data
* Return: true only if both status bits are zero
*
- * the two MSB from the first transfered byte contain a status code
+ * The two MSB from the first transferred byte contain a status code
* 00 - normal operation, valid data
* 01 - device in factory programming mode
* 10 - stale data
diff --git a/drivers/iio/pressure/hsc030pa_i2c.c b/drivers/iio/pressure/hsc030pa_i2c.c
index a34ef4653f34..3500bda03d75 100644
--- a/drivers/iio/pressure/hsc030pa_i2c.c
+++ b/drivers/iio/pressure/hsc030pa_i2c.c
@@ -34,8 +34,13 @@ static int hsc_i2c_recv(struct hsc_data *data)
msg.buf = data->buffer;
ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret < 0)
+ return ret;
- return (ret == 2) ? 0 : ret;
+ if (ret != 1)
+ return -EIO;
+
+ return 0;
}
static int hsc_i2c_probe(struct i2c_client *client)
diff --git a/drivers/iio/pressure/rohm-bm1390.c b/drivers/iio/pressure/rohm-bm1390.c
index dac27fd359ad..08146ca0f91d 100644
--- a/drivers/iio/pressure/rohm-bm1390.c
+++ b/drivers/iio/pressure/rohm-bm1390.c
@@ -440,7 +440,7 @@ static int bm1390_fifo_flush(struct iio_dev *idev, unsigned int samples)
* the timestamps. If we are ran from IRQ, then the
* IRQF_ONESHOT has us covered - but if we are ran by the
* user-space read we need to disable the IRQ to be on a safe
- * side. We do this usng synchronous disable so that if the
+ * side. We do this using synchronous disable so that if the
* IRQ thread is being ran on other CPU we wait for it to be
* finished.
*/
diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c
index 4923a558a26a..2c68fdf2744e 100644
--- a/drivers/iio/pressure/zpa2326.c
+++ b/drivers/iio/pressure/zpa2326.c
@@ -840,7 +840,7 @@ static irqreturn_t zpa2326_handle_threaded_irq(int irq, void *data)
complete:
/*
- * Wake up direct or externaly triggered buffer mode waiters: see
+ * Wake up direct or externally triggered buffer mode waiters: see
* zpa2326_sample_oneshot() and zpa2326_trigger_handler().
*/
complete(&priv->data_ready);
diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig
index 6070974c2c85..bb77fad2a1b3 100644
--- a/drivers/iio/proximity/Kconfig
+++ b/drivers/iio/proximity/Kconfig
@@ -244,6 +244,21 @@ config VL53L0X_I2C
To compile this driver as a module, choose M here: the
module will be called vl53l0x-i2c.
+config VL53L1X_I2C
+ tristate "STMicroelectronics VL53L1X ToF ranger sensor (I2C)"
+ depends on I2C
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ select REGMAP_I2C
+ select RESET_CONTROLLER
+ help
+ Say Y here to build a driver for STMicroelectronics VL53L1X
+ ToF ranger sensors with i2c interface.
+ This driver can be used to measure the distance of objects.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vl53l1x-i2c.
+
config AW96103
tristate "AW96103/AW96105 Awinic proximity sensor"
select REGMAP_I2C
diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile
index 152034d38c49..4352833dd8a4 100644
--- a/drivers/iio/proximity/Makefile
+++ b/drivers/iio/proximity/Makefile
@@ -23,5 +23,6 @@ obj-$(CONFIG_SX_COMMON) += sx_common.o
obj-$(CONFIG_SX9500) += sx9500.o
obj-$(CONFIG_VCNL3020) += vcnl3020.o
obj-$(CONFIG_VL53L0X_I2C) += vl53l0x-i2c.o
+obj-$(CONFIG_VL53L1X_I2C) += vl53l1x-i2c.o
obj-$(CONFIG_AW96103) += aw96103.o
diff --git a/drivers/iio/proximity/hx9023s.c b/drivers/iio/proximity/hx9023s.c
index 17e00ee2b6f8..9efaa5b6b5bd 100644
--- a/drivers/iio/proximity/hx9023s.c
+++ b/drivers/iio/proximity/hx9023s.c
@@ -1088,6 +1088,7 @@ static int hx9023s_probe(struct i2c_client *client)
struct device *dev = &client->dev;
struct iio_dev *indio_dev;
struct hx9023s_data *data;
+ const char *fw_name;
int ret;
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
@@ -1125,7 +1126,9 @@ static int hx9023s_probe(struct i2c_client *client)
if (ret)
return dev_err_probe(dev, ret, "channel config failed\n");
- ret = request_firmware_nowait(THIS_MODULE, true, "hx9023s.bin", dev,
+ fw_name = "hx9023s.bin";
+ device_property_read_string(dev, "firmware-name", &fw_name);
+ ret = request_firmware_nowait(THIS_MODULE, true, fw_name, dev,
GFP_KERNEL, data, hx9023s_cfg_update);
if (ret)
return dev_err_probe(dev, ret, "reg config failed\n");
diff --git a/drivers/iio/proximity/sx9324.c b/drivers/iio/proximity/sx9324.c
index c7b2d03c23bc..f61eff39751d 100644
--- a/drivers/iio/proximity/sx9324.c
+++ b/drivers/iio/proximity/sx9324.c
@@ -821,7 +821,7 @@ static const struct sx_common_reg_default sx9324_default_regs[] = {
{ SX9324_REG_ADV_CTRL10, 0x00, "adv_ctrl10" },
{ SX9324_REG_ADV_CTRL11, 0x00, "adv_ctrl11" },
{ SX9324_REG_ADV_CTRL12, 0x00, "adv_ctrl12" },
- /* TODO(gwendal): SAR currenly disabled */
+ /* TODO(gwendal): SAR currently disabled */
{ SX9324_REG_ADV_CTRL13, 0x00, "adv_ctrl13" },
{ SX9324_REG_ADV_CTRL14, 0x00, "adv_ctrl14" },
{ SX9324_REG_ADV_CTRL15, 0x00, "adv_ctrl15" },
diff --git a/drivers/iio/proximity/vl53l1x-i2c.c b/drivers/iio/proximity/vl53l1x-i2c.c
new file mode 100644
index 000000000000..4d9cb3983dba
--- /dev/null
+++ b/drivers/iio/proximity/vl53l1x-i2c.c
@@ -0,0 +1,756 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Support for ST VL53L1X FlightSense ToF Ranging Sensor on a i2c bus.
+ *
+ * Copyright (C) 2026 Siratul Islam <email@sirat.me>
+ *
+ * Datasheet available at
+ * <https://www.st.com/resource/en/datasheet/vl53l1x.pdf>
+ *
+ * Default 7-bit i2c slave address 0x29.
+ *
+ * The VL53L1X requires a firmware configuration blob to be loaded at boot.
+ * Register values for the default configuration are taken from
+ * ST's VL53L1X Ultra Lite Driver (STSW-IMG009).
+ */
+
+#include <linux/array_size.h>
+#include <linux/bits.h>
+#include <linux/bitfield.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/math.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/time.h>
+#include <linux/types.h>
+
+#include <asm/byteorder.h>
+
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define VL53L1X_REG_SOFT_RESET 0x0000
+#define VL53L1X_REG_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND 0x0008
+#define VL53L1X_REG_VHV_CONFIG__INIT 0x000B
+#define VL53L1X_REG_GPIO_HV_MUX__CTRL 0x0030
+#define VL53L1X_REG_GPIO__TIO_HV_STATUS 0x0031
+#define VL53L1X_REG_SYSTEM__INTERRUPT_CONFIG_GPIO 0x0046
+#define VL53L1X_REG_PHASECAL_CONFIG__TIMEOUT_MACROP 0x004B
+#define VL53L1X_REG_RANGE_CONFIG__TIMEOUT_MACROP_A 0x005E
+#define VL53L1X_REG_RANGE_CONFIG__VCSEL_PERIOD_A 0x0060
+#define VL53L1X_REG_RANGE_CONFIG__TIMEOUT_MACROP_B 0x0061
+#define VL53L1X_REG_RANGE_CONFIG__VCSEL_PERIOD_B 0x0063
+#define VL53L1X_REG_RANGE_CONFIG__VALID_PHASE_HIGH 0x0069
+#define VL53L1X_REG_SYSTEM__INTERMEASUREMENT_PERIOD 0x006C
+#define VL53L1X_REG_SD_CONFIG__WOI_SD0 0x0078
+#define VL53L1X_REG_SD_CONFIG__WOI_SD1 0x0079
+#define VL53L1X_REG_SD_CONFIG__INITIAL_PHASE_SD0 0x007A
+#define VL53L1X_REG_SD_CONFIG__INITIAL_PHASE_SD1 0x007B
+#define VL53L1X_REG_SYSTEM__INTERRUPT_CLEAR 0x0086
+#define VL53L1X_REG_SYSTEM__MODE_START 0x0087
+#define VL53L1X_REG_RESULT__RANGE_STATUS 0x0089
+#define VL53L1X_REG_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 0x0096
+#define VL53L1X_REG_RESULT__OSC_CALIBRATE_VAL 0x00DE
+#define VL53L1X_REG_FIRMWARE__SYSTEM_STATUS 0x00E5
+#define VL53L1X_REG_IDENTIFICATION__MODEL_ID 0x010F
+#define VL53L1X_REG_DEFAULT_CONFIG 0x002D
+
+#define VL53L1X_MODEL_ID_VAL 0xEACC
+
+#define VL53L1X_MODE_START_TIMED 0x40
+#define VL53L1X_MODE_START_STOP 0x00
+
+#define VL53L1X_INT_NEW_SAMPLE_READY 0x02
+
+#define VL53L1X_GPIO_HV_MUX_POLARITY BIT(4)
+
+#define VL53L1X_VHV_LOOP_BOUND_TWO 0x09
+
+#define VL53L1X_RANGE_STATUS_MASK GENMASK(4, 0)
+#define VL53L1X_RANGE_STATUS_VALID 9
+
+#define VL53L1X_OSC_CALIBRATE_MASK GENMASK(9, 0)
+
+/* Inter-measurement period uses PLL divider with 1.075 oscillator correction */
+static const struct u32_fract vl53l1x_osc_correction = {
+ .numerator = 1075,
+ .denominator = 1000,
+};
+
+enum vl53l1x_distance_mode {
+ VL53L1X_SHORT,
+ VL53L1X_LONG,
+};
+
+struct vl53l1x_data {
+ struct regmap *regmap;
+ struct completion completion;
+ struct reset_control *xshut_reset;
+ enum vl53l1x_distance_mode distance_mode;
+ u8 gpio_polarity;
+ int irq;
+};
+
+static const struct regmap_range vl53l1x_volatile_ranges[] = {
+ regmap_reg_range(VL53L1X_REG_GPIO__TIO_HV_STATUS,
+ VL53L1X_REG_GPIO__TIO_HV_STATUS),
+ regmap_reg_range(VL53L1X_REG_RESULT__RANGE_STATUS,
+ VL53L1X_REG_RESULT__RANGE_STATUS),
+ regmap_reg_range(VL53L1X_REG_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0,
+ VL53L1X_REG_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 + 1),
+ regmap_reg_range(VL53L1X_REG_RESULT__OSC_CALIBRATE_VAL,
+ VL53L1X_REG_RESULT__OSC_CALIBRATE_VAL + 1),
+ regmap_reg_range(VL53L1X_REG_FIRMWARE__SYSTEM_STATUS,
+ VL53L1X_REG_FIRMWARE__SYSTEM_STATUS),
+};
+
+static const struct regmap_access_table vl53l1x_volatile_table = {
+ .yes_ranges = vl53l1x_volatile_ranges,
+ .n_yes_ranges = ARRAY_SIZE(vl53l1x_volatile_ranges),
+};
+
+static const struct regmap_range vl53l1x_write_only_ranges[] = {
+ regmap_reg_range(VL53L1X_REG_SOFT_RESET, VL53L1X_REG_SOFT_RESET),
+ regmap_reg_range(VL53L1X_REG_SYSTEM__INTERRUPT_CLEAR,
+ VL53L1X_REG_SYSTEM__MODE_START),
+};
+
+static const struct regmap_access_table vl53l1x_readable_table = {
+ .no_ranges = vl53l1x_write_only_ranges,
+ .n_no_ranges = ARRAY_SIZE(vl53l1x_write_only_ranges),
+};
+
+static const struct regmap_config vl53l1x_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ /* MODEL_ID is 16-bit. +1 covers the second byte at 0x0110 */
+ .max_register = VL53L1X_REG_IDENTIFICATION__MODEL_ID + 1,
+ .cache_type = REGCACHE_MAPLE,
+ .volatile_table = &vl53l1x_volatile_table,
+ .rd_table = &vl53l1x_readable_table,
+};
+
+static int vl53l1x_read_u16(struct vl53l1x_data *data, u16 reg, u16 *val)
+{
+ __be16 buf;
+ int ret;
+
+ ret = regmap_bulk_read(data->regmap, reg, &buf, sizeof(buf));
+ if (ret)
+ return ret;
+
+ *val = be16_to_cpu(buf);
+ return 0;
+}
+
+static int vl53l1x_write_u16(struct vl53l1x_data *data, u16 reg, u16 val)
+{
+ __be16 buf = cpu_to_be16(val);
+
+ return regmap_bulk_write(data->regmap, reg, &buf, sizeof(buf));
+}
+
+static int vl53l1x_write_u32(struct vl53l1x_data *data, u16 reg, u32 val)
+{
+ __be32 buf = cpu_to_be32(val);
+
+ return regmap_bulk_write(data->regmap, reg, &buf, sizeof(buf));
+}
+
+static int vl53l1x_clear_irq(struct vl53l1x_data *data)
+{
+ return regmap_write(data->regmap, VL53L1X_REG_SYSTEM__INTERRUPT_CLEAR, 0x01);
+}
+
+static int vl53l1x_start_ranging(struct vl53l1x_data *data)
+{
+ int ret;
+
+ ret = vl53l1x_clear_irq(data);
+ if (ret)
+ return ret;
+
+ return regmap_write(data->regmap, VL53L1X_REG_SYSTEM__MODE_START,
+ VL53L1X_MODE_START_TIMED);
+}
+
+static int vl53l1x_stop_ranging(struct vl53l1x_data *data)
+{
+ return regmap_write(data->regmap, VL53L1X_REG_SYSTEM__MODE_START,
+ VL53L1X_MODE_START_STOP);
+}
+
+/*
+ * Default configuration blob from ST's VL53L1X Ultra Lite Driver
+ * (STSW-IMG009).
+ */
+static const u8 vl53l1x_default_config[] = {
+ 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x08, /* reg 0x2d..0x34 */
+ 0x00, 0x08, 0x10, 0x01, 0x01, 0x00, 0x00, 0x00, /* reg 0x35..0x3c */
+ 0x00, 0xFF, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, /* reg 0x3d..0x44 */
+ 0x00, 0x20, 0x0B, 0x00, 0x00, 0x02, 0x0A, 0x21, /* reg 0x45..0x4c */
+ 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0xC8, /* reg 0x4d..0x54 */
+ 0x00, 0x00, 0x38, 0xFF, 0x01, 0x00, 0x08, 0x00, /* reg 0x55..0x5c */
+ 0x00, 0x01, 0xCC, 0x0F, 0x01, 0xF1, 0x0D, 0x01, /* reg 0x5d..0x64 */
+ 0x68, 0x00, 0x80, 0x08, 0xB8, 0x00, 0x00, 0x00, /* reg 0x65..0x6c */
+ 0x00, 0x0F, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, /* reg 0x6d..0x74 */
+ 0x00, 0x00, 0x01, 0x0F, 0x0D, 0x0E, 0x0E, 0x00, /* reg 0x75..0x7c */
+ 0x00, 0x02, 0xC7, 0xFF, 0x9B, 0x00, 0x00, 0x00, /* reg 0x7d..0x84 */
+ 0x01, 0x00, 0x00, /* reg 0x85..0x87 */
+};
+
+static int vl53l1x_chip_init(struct vl53l1x_data *data)
+{
+ struct device *dev = regmap_get_device(data->regmap);
+ unsigned int val;
+ u16 model_id;
+ int ret;
+
+ if (!data->xshut_reset) {
+ ret = regmap_write(data->regmap, VL53L1X_REG_SOFT_RESET, 0x00);
+ if (ret)
+ return ret;
+ fsleep(100); /* conservative reset pulse, no spec */
+
+ ret = regmap_write(data->regmap, VL53L1X_REG_SOFT_RESET, 0x01);
+ if (ret)
+ return ret;
+ fsleep(1000); /* conservative boot wait, no spec */
+ }
+
+ ret = regmap_read_poll_timeout(data->regmap,
+ VL53L1X_REG_FIRMWARE__SYSTEM_STATUS, val,
+ val & BIT(0),
+ 1 * USEC_PER_MSEC,
+ 100 * USEC_PER_MSEC);
+ if (ret)
+ return dev_err_probe(dev, ret, "firmware boot timeout\n");
+
+ ret = vl53l1x_read_u16(data, VL53L1X_REG_IDENTIFICATION__MODEL_ID,
+ &model_id);
+ if (ret)
+ return ret;
+
+ if (model_id != VL53L1X_MODEL_ID_VAL)
+ dev_info(dev, "unknown model id: 0x%04x, continuing\n", model_id);
+
+ ret = regmap_bulk_write(data->regmap, VL53L1X_REG_DEFAULT_CONFIG,
+ vl53l1x_default_config,
+ sizeof(vl53l1x_default_config));
+ if (ret)
+ return ret;
+
+ ret = regmap_read(data->regmap, VL53L1X_REG_GPIO_HV_MUX__CTRL, &val);
+ if (ret)
+ return ret;
+ data->gpio_polarity = !!(val & VL53L1X_GPIO_HV_MUX_POLARITY);
+
+ /* Initial ranging cycle for VHV calibration */
+ ret = vl53l1x_start_ranging(data);
+ if (ret)
+ return ret;
+
+ /* 1ms poll, 1s timeout covers max timing budgets (per ST Ultra Lite Driver) */
+ ret = regmap_read_poll_timeout(data->regmap,
+ VL53L1X_REG_GPIO__TIO_HV_STATUS, val,
+ (val & 1) != data->gpio_polarity,
+ 1 * USEC_PER_MSEC,
+ 1000 * USEC_PER_MSEC);
+ if (ret)
+ return ret;
+
+ ret = vl53l1x_clear_irq(data);
+ if (ret)
+ return ret;
+
+ ret = vl53l1x_stop_ranging(data);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(data->regmap,
+ VL53L1X_REG_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND,
+ VL53L1X_VHV_LOOP_BOUND_TWO);
+ if (ret)
+ return ret;
+
+ return regmap_write(data->regmap, VL53L1X_REG_VHV_CONFIG__INIT, 0x00);
+}
+
+static const struct reg_sequence vl53l1x_mode_short[] = {
+ { VL53L1X_REG_PHASECAL_CONFIG__TIMEOUT_MACROP, 0x14 },
+ { VL53L1X_REG_RANGE_CONFIG__VCSEL_PERIOD_A, 0x07 },
+ { VL53L1X_REG_RANGE_CONFIG__VCSEL_PERIOD_B, 0x05 },
+ { VL53L1X_REG_RANGE_CONFIG__VALID_PHASE_HIGH, 0x38 },
+ { VL53L1X_REG_SD_CONFIG__WOI_SD0, 0x07 },
+ { VL53L1X_REG_SD_CONFIG__WOI_SD1, 0x05 },
+ { VL53L1X_REG_SD_CONFIG__INITIAL_PHASE_SD0, 0x06 },
+ { VL53L1X_REG_SD_CONFIG__INITIAL_PHASE_SD1, 0x06 },
+};
+
+static const struct reg_sequence vl53l1x_mode_long[] = {
+ { VL53L1X_REG_PHASECAL_CONFIG__TIMEOUT_MACROP, 0x0A },
+ { VL53L1X_REG_RANGE_CONFIG__VCSEL_PERIOD_A, 0x0F },
+ { VL53L1X_REG_RANGE_CONFIG__VCSEL_PERIOD_B, 0x0D },
+ { VL53L1X_REG_RANGE_CONFIG__VALID_PHASE_HIGH, 0xB8 },
+ { VL53L1X_REG_SD_CONFIG__WOI_SD0, 0x0F },
+ { VL53L1X_REG_SD_CONFIG__WOI_SD1, 0x0D },
+ { VL53L1X_REG_SD_CONFIG__INITIAL_PHASE_SD0, 0x0E },
+ { VL53L1X_REG_SD_CONFIG__INITIAL_PHASE_SD1, 0x0E },
+};
+
+static const struct {
+ const struct reg_sequence *regs;
+ size_t num_regs;
+} vl53l1x_mode_configs[] = {
+ [VL53L1X_SHORT] = { vl53l1x_mode_short, ARRAY_SIZE(vl53l1x_mode_short) },
+ [VL53L1X_LONG] = { vl53l1x_mode_long, ARRAY_SIZE(vl53l1x_mode_long) },
+};
+
+static int vl53l1x_set_distance_mode(struct vl53l1x_data *data,
+ enum vl53l1x_distance_mode mode)
+{
+ int ret;
+
+ if (mode >= ARRAY_SIZE(vl53l1x_mode_configs))
+ return -EINVAL;
+
+ ret = regmap_multi_reg_write(data->regmap,
+ vl53l1x_mode_configs[mode].regs,
+ vl53l1x_mode_configs[mode].num_regs);
+ if (ret)
+ return ret;
+
+ data->distance_mode = mode;
+ return 0;
+}
+
+/*
+ * The timing budget controls how long the sensor spends collecting
+ * a single range measurement. Pre-computed TIMEOUT_MACROP register
+ * values from ST's VL53L1X Ultra Lite Driver.
+ */
+static int vl53l1x_set_timing_budget(struct vl53l1x_data *data, u16 budget_ms)
+{
+ u16 timeout_a, timeout_b;
+ int ret;
+
+ switch (data->distance_mode) {
+ case VL53L1X_SHORT:
+ switch (budget_ms) {
+ case 15:
+ timeout_a = 0x001D;
+ timeout_b = 0x0027;
+ break;
+ case 20:
+ timeout_a = 0x0051;
+ timeout_b = 0x006E;
+ break;
+ case 33:
+ timeout_a = 0x00D6;
+ timeout_b = 0x006E;
+ break;
+ case 50:
+ timeout_a = 0x01AE;
+ timeout_b = 0x01E8;
+ break;
+ case 100:
+ timeout_a = 0x02E1;
+ timeout_b = 0x0388;
+ break;
+ case 200:
+ timeout_a = 0x03E1;
+ timeout_b = 0x0496;
+ break;
+ case 500:
+ timeout_a = 0x0591;
+ timeout_b = 0x05C1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case VL53L1X_LONG:
+ switch (budget_ms) {
+ case 20:
+ timeout_a = 0x001E;
+ timeout_b = 0x0022;
+ break;
+ case 33:
+ timeout_a = 0x0060;
+ timeout_b = 0x006E;
+ break;
+ case 50:
+ timeout_a = 0x00AD;
+ timeout_b = 0x00C6;
+ break;
+ case 100:
+ timeout_a = 0x01CC;
+ timeout_b = 0x01EA;
+ break;
+ case 200:
+ timeout_a = 0x02D9;
+ timeout_b = 0x02F8;
+ break;
+ case 500:
+ timeout_a = 0x048F;
+ timeout_b = 0x04A4;
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = vl53l1x_write_u16(data, VL53L1X_REG_RANGE_CONFIG__TIMEOUT_MACROP_A,
+ timeout_a);
+ if (ret)
+ return ret;
+
+ return vl53l1x_write_u16(data, VL53L1X_REG_RANGE_CONFIG__TIMEOUT_MACROP_B,
+ timeout_b);
+}
+
+static int vl53l1x_set_inter_measurement_ms(struct vl53l1x_data *data,
+ u16 period_ms)
+{
+ u16 osc_calibrate_val;
+ u16 clock_pll;
+ u32 inter_meas;
+ int ret;
+
+ ret = vl53l1x_read_u16(data, VL53L1X_REG_RESULT__OSC_CALIBRATE_VAL,
+ &osc_calibrate_val);
+ if (ret)
+ return ret;
+
+ clock_pll = osc_calibrate_val & VL53L1X_OSC_CALIBRATE_MASK;
+ inter_meas = (clock_pll * period_ms * vl53l1x_osc_correction.numerator) /
+ vl53l1x_osc_correction.denominator;
+
+ return vl53l1x_write_u32(data,
+ VL53L1X_REG_SYSTEM__INTERMEASUREMENT_PERIOD,
+ inter_meas);
+}
+
+static int vl53l1x_read_proximity(struct vl53l1x_data *data, int *val)
+{
+ unsigned int range_status;
+ u16 distance;
+ int ret;
+
+ if (data->irq) {
+ reinit_completion(&data->completion);
+
+ ret = vl53l1x_clear_irq(data);
+ if (ret)
+ return ret;
+
+ if (!wait_for_completion_timeout(&data->completion, HZ))
+ return -ETIMEDOUT;
+ } else {
+ unsigned int rdy;
+
+ /* 1ms poll, 1s timeout covers max timing budgets (per ST Ultra Lite Driver) */
+ ret = regmap_read_poll_timeout(data->regmap,
+ VL53L1X_REG_GPIO__TIO_HV_STATUS, rdy,
+ (rdy & 1) != data->gpio_polarity,
+ 1 * USEC_PER_MSEC,
+ 1000 * USEC_PER_MSEC);
+ if (ret)
+ return ret;
+ }
+
+ ret = regmap_read(data->regmap, VL53L1X_REG_RESULT__RANGE_STATUS,
+ &range_status);
+ if (ret)
+ goto clear_irq;
+
+ if (FIELD_GET(VL53L1X_RANGE_STATUS_MASK, range_status) !=
+ VL53L1X_RANGE_STATUS_VALID) {
+ ret = -EIO;
+ goto clear_irq;
+ }
+
+ ret = vl53l1x_read_u16(data,
+ VL53L1X_REG_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0,
+ &distance);
+ if (ret)
+ goto clear_irq;
+
+ *val = distance;
+
+clear_irq:
+ vl53l1x_clear_irq(data);
+ return ret;
+}
+
+static const struct iio_chan_spec vl53l1x_channels[] = {
+ {
+ .type = IIO_DISTANCE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 16,
+ .storagebits = 16,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
+static int vl53l1x_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long mask)
+{
+ struct vl53l1x_data *data = iio_priv(indio_dev);
+ int ret;
+
+ if (chan->type != IIO_DISTANCE)
+ return -EINVAL;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
+ ret = vl53l1x_read_proximity(data, val);
+ iio_device_release_direct(indio_dev);
+ if (ret)
+ return ret;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = 1000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info vl53l1x_info = {
+ .read_raw = vl53l1x_read_raw,
+ .validate_trigger = iio_validate_own_trigger,
+};
+
+static irqreturn_t vl53l1x_trigger_handler(int irq, void *priv)
+{
+ struct iio_poll_func *pf = priv;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct vl53l1x_data *data = iio_priv(indio_dev);
+ struct {
+ u16 distance;
+ aligned_s64 timestamp;
+ } scan = { };
+ unsigned int range_status;
+ int ret;
+
+ ret = regmap_read(data->regmap, VL53L1X_REG_RESULT__RANGE_STATUS,
+ &range_status);
+ if (ret)
+ goto notify_and_clear_irq;
+ if (FIELD_GET(VL53L1X_RANGE_STATUS_MASK, range_status) !=
+ VL53L1X_RANGE_STATUS_VALID)
+ goto notify_and_clear_irq;
+
+ ret = vl53l1x_read_u16(data,
+ VL53L1X_REG_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0,
+ &scan.distance);
+ if (ret)
+ goto notify_and_clear_irq;
+
+ iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
+ iio_get_time_ns(indio_dev));
+
+notify_and_clear_irq:
+ iio_trigger_notify_done(indio_dev->trig);
+ vl53l1x_clear_irq(data);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t vl53l1x_irq_handler(int irq, void *priv)
+{
+ struct iio_dev *indio_dev = priv;
+ struct vl53l1x_data *data = iio_priv(indio_dev);
+
+ if (iio_buffer_enabled(indio_dev))
+ iio_trigger_poll(indio_dev->trig);
+ else
+ complete(&data->completion);
+
+ return IRQ_HANDLED;
+}
+
+static const struct iio_trigger_ops vl53l1x_trigger_ops = {
+ .validate_device = iio_trigger_validate_own_device,
+};
+
+static void vl53l1x_stop_ranging_action(void *priv)
+{
+ vl53l1x_stop_ranging(priv);
+}
+
+static int vl53l1x_configure_irq(struct device *dev, int irq,
+ struct iio_dev *indio_dev)
+{
+ struct vl53l1x_data *data = iio_priv(indio_dev);
+ int ret;
+
+ ret = devm_request_irq(dev, irq, vl53l1x_irq_handler, IRQF_NO_THREAD,
+ indio_dev->name, indio_dev);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(data->regmap, VL53L1X_REG_SYSTEM__INTERRUPT_CONFIG_GPIO,
+ VL53L1X_INT_NEW_SAMPLE_READY);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to configure IRQ\n");
+
+ return 0;
+}
+
+static int vl53l1x_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct vl53l1x_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ data->irq = client->irq;
+
+ data->regmap = devm_regmap_init_i2c(client, &vl53l1x_regmap_config);
+ if (IS_ERR(data->regmap))
+ return dev_err_probe(dev, PTR_ERR(data->regmap),
+ "regmap initialization failed\n");
+
+ ret = devm_regulator_get_enable(dev, "vdd");
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable VDD regulator\n");
+
+ /*
+ * XSHUT held low puts the chip in hardware standby. All register
+ * state is lost on de-assert so this is functionally a reset.
+ */
+ data->xshut_reset = devm_reset_control_get_optional_exclusive_deasserted(dev, NULL);
+ if (IS_ERR(data->xshut_reset))
+ return dev_err_probe(dev, PTR_ERR(data->xshut_reset),
+ "Cannot get reset control\n");
+
+ /*
+ * 1.2 ms max boot duration.
+ * Datasheet Section 3.6 "Power up and boot sequence".
+ */
+ fsleep(1200);
+
+ ret = vl53l1x_chip_init(data);
+ if (ret)
+ return ret;
+
+ ret = vl53l1x_set_distance_mode(data, VL53L1X_LONG);
+ if (ret)
+ return ret;
+
+ /* 50 ms timing budget (per ST Ultra Lite Driver) */
+ ret = vl53l1x_set_timing_budget(data, 50);
+ if (ret)
+ return ret;
+
+ /* 50 ms inter-measurement period (per ST Ultra Lite Driver) */
+ ret = vl53l1x_set_inter_measurement_ms(data, 50);
+ if (ret)
+ return ret;
+
+ /*
+ * The hardware only supports "autonomous" continuous ranging mode.
+ * Start ranging here and leave it running for the lifetime of
+ * the device. Both direct reads and the buffer path rely on this.
+ */
+ ret = vl53l1x_start_ranging(data);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(dev, vl53l1x_stop_ranging_action, data);
+ if (ret)
+ return ret;
+
+ indio_dev->name = "vl53l1x";
+ indio_dev->info = &vl53l1x_info;
+ indio_dev->channels = vl53l1x_channels;
+ indio_dev->num_channels = ARRAY_SIZE(vl53l1x_channels);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ if (client->irq) {
+ struct iio_trigger *trig;
+
+ init_completion(&data->completion);
+
+ trig = devm_iio_trigger_alloc(dev, "%s-dev%d", indio_dev->name,
+ iio_device_id(indio_dev));
+ if (!trig)
+ return -ENOMEM;
+
+ trig->ops = &vl53l1x_trigger_ops;
+ iio_trigger_set_drvdata(trig, indio_dev);
+ ret = devm_iio_trigger_register(dev, trig);
+ if (ret)
+ return ret;
+
+ indio_dev->trig = iio_trigger_get(trig);
+
+ ret = vl53l1x_configure_irq(dev, client->irq, indio_dev);
+ if (ret)
+ return ret;
+
+ ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
+ &vl53l1x_trigger_handler,
+ NULL);
+ if (ret)
+ return ret;
+ }
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct i2c_device_id vl53l1x_id[] = {
+ { "vl53l1x" },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, vl53l1x_id);
+
+static const struct of_device_id st_vl53l1x_dt_match[] = {
+ { .compatible = "st,vl53l1x" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, st_vl53l1x_dt_match);
+
+static struct i2c_driver vl53l1x_driver = {
+ .driver = {
+ .name = "vl53l1x-i2c",
+ .of_match_table = st_vl53l1x_dt_match,
+ },
+ .probe = vl53l1x_probe,
+ .id_table = vl53l1x_id,
+};
+module_i2c_driver(vl53l1x_driver);
+
+MODULE_AUTHOR("Siratul Islam <email@sirat.me>");
+MODULE_DESCRIPTION("ST VL53L1X ToF ranging sensor driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/iio/resolver/ad2s1210.c b/drivers/iio/resolver/ad2s1210.c
index 06d9c784f93e..774728c804c0 100644
--- a/drivers/iio/resolver/ad2s1210.c
+++ b/drivers/iio/resolver/ad2s1210.c
@@ -896,14 +896,14 @@ static const struct iio_event_spec ad2s1210_monitor_signal_event_spec[] = {
.mask_separate = BIT(IIO_EV_INFO_VALUE),
},
{
- /* Sine/cosine DOS overrange fault.*/
+ /* Sine/cosine DOS overrange fault. */
.type = IIO_EV_TYPE_THRESH,
.dir = IIO_EV_DIR_RISING,
- /* Degredation of signal overrange threshold. */
+ /* Degradation of signal overrange threshold. */
.mask_separate = BIT(IIO_EV_INFO_VALUE),
},
{
- /* Sine/cosine DOS mismatch fault.*/
+ /* Sine/cosine DOS mismatch fault. */
.type = IIO_EV_TYPE_MAG,
.dir = IIO_EV_DIR_RISING,
.mask_separate = BIT(IIO_EV_INFO_VALUE),
diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
index 7dd40d69cce6..38e6f8dfd3b8 100644
--- a/drivers/iio/temperature/ltc2983.c
+++ b/drivers/iio/temperature/ltc2983.c
@@ -709,7 +709,7 @@ ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data
ret = fwnode_property_read_u32(ref, "reg", &thermo->cold_junction_chan);
if (ret)
/*
- * This would be catched later but we can just return
+ * This would be caught later but we can just return
* the error right away.
*/
return dev_err_ptr_probe(&st->spi->dev, ret,
@@ -798,7 +798,7 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
* For 4wire RTD with rotation, the channel selection cannot be
* >=19 since the chann + 1 is used in this configuration.
* For 4wire RTDs with kelvin rsense, the rsense channel cannot be
- * <=1 since chanel - 1 and channel - 2 are used.
+ * <=1 since channel - 1 and channel - 2 are used.
*/
if (rtd->sensor_config & LTC2983_RTD_4_WIRE_MASK) {
/* 4-wire */
diff --git a/drivers/iio/test/iio-test-gts.c b/drivers/iio/test/iio-test-gts.c
index 11250bc905c9..6ffff85ba853 100644
--- a/drivers/iio/test/iio-test-gts.c
+++ b/drivers/iio/test/iio-test-gts.c
@@ -20,7 +20,7 @@
*
* If yes, then adding a test is probably a good idea but please stop for a
* moment and consider the effort of changing all the tests when code gets
- * refactored. Eventually it neeeds to be.
+ * refactored. Eventually it needs to be.
*/
#define TEST_TSEL_50 1
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 172acf135f3b..0e32a2295990 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -124,8 +124,8 @@ static ssize_t ad7816_show_mode(struct device *dev,
struct ad7816_chip_info *chip = iio_priv(indio_dev);
if (chip->mode)
- return sprintf(buf, "power-save\n");
- return sprintf(buf, "full\n");
+ return sysfs_emit(buf, "power-save\n");
+ return sysfs_emit(buf, "full\n");
}
static ssize_t ad7816_store_mode(struct device *dev,
@@ -156,7 +156,7 @@ static ssize_t ad7816_show_available_modes(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return sprintf(buf, "full\npower-save\n");
+ return sysfs_emit(buf, "full\npower-save\n");
}
static IIO_DEVICE_ATTR(available_modes, 0444, ad7816_show_available_modes,
@@ -169,7 +169,7 @@ static ssize_t ad7816_show_channel(struct device *dev,
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad7816_chip_info *chip = iio_priv(indio_dev);
- return sprintf(buf, "%d\n", chip->channel_id);
+ return sysfs_emit(buf, "%d\n", chip->channel_id);
}
static ssize_t ad7816_store_channel(struct device *dev,
@@ -231,9 +231,9 @@ static ssize_t ad7816_show_value(struct device *dev,
data &= AD7816_TEMP_FLOAT_MASK;
if (value < 0)
data = BIT(AD7816_TEMP_FLOAT_OFFSET) - data;
- return sprintf(buf, "%d.%.2d\n", value, data * 25);
+ return sysfs_emit(buf, "%d.%.2d\n", value, data * 25);
}
- return sprintf(buf, "%u\n", data);
+ return sysfs_emit(buf, "%u\n", data);
}
static IIO_DEVICE_ATTR(value, 0444, ad7816_show_value, NULL, 0);
@@ -281,9 +281,9 @@ static ssize_t ad7816_show_oti(struct device *dev,
value = AD7816_BOUND_VALUE_MIN +
(chip->oti_data[chip->channel_id] -
AD7816_BOUND_VALUE_BASE);
- return sprintf(buf, "%d\n", value);
+ return sysfs_emit(buf, "%d\n", value);
}
- return sprintf(buf, "%u\n", chip->oti_data[chip->channel_id]);
+ return sysfs_emit(buf, "%u\n", chip->oti_data[chip->channel_id]);
}
static inline ssize_t ad7816_set_oti(struct device *dev,
diff --git a/drivers/staging/iio/frequency/ad9834.c b/drivers/staging/iio/frequency/ad9834.c
index d339d5e8e043..bdb2580e29bf 100644
--- a/drivers/staging/iio/frequency/ad9834.c
+++ b/drivers/staging/iio/frequency/ad9834.c
@@ -281,16 +281,12 @@ ssize_t ad9834_show_out0_wavetype_available(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad9834_state *st = iio_priv(indio_dev);
- char *str;
if (st->devid == ID_AD9833 || st->devid == ID_AD9837)
- str = "sine triangle square";
- else if (st->control & AD9834_OPBITEN)
- str = "sine";
- else
- str = "sine triangle";
-
- return sprintf(buf, "%s\n", str);
+ return sysfs_emit(buf, "sine triangle square\n");
+ if (st->control & AD9834_OPBITEN)
+ return sysfs_emit(buf, "sine\n");
+ return sysfs_emit(buf, "sine triangle\n");
}
static IIO_DEVICE_ATTR(out_altvoltage0_out0_wavetype_available, 0444,
@@ -303,14 +299,10 @@ ssize_t ad9834_show_out1_wavetype_available(struct device *dev,
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct ad9834_state *st = iio_priv(indio_dev);
- char *str;
if (st->control & AD9834_MODE)
- str = "";
- else
- str = "square";
-
- return sprintf(buf, "%s\n", str);
+ return sysfs_emit(buf, "\n");
+ return sysfs_emit(buf, "square\n");
}
static IIO_DEVICE_ATTR(out_altvoltage0_out1_wavetype_available, 0444,
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 85a4223295cd..dde2ec9d1f6a 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -5,6 +5,7 @@
* Copyright 2011 Analog Devices Inc.
*/
+#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -194,8 +195,7 @@ static int ad5933_set_freq(struct ad5933_state *st,
u8 d8[4];
} dat;
- freqreg = (u64)freq * (u64)(1 << 27);
- do_div(freqreg, st->mclk_hz / 4);
+ freqreg = div64_ul(BIT_ULL(27) * freq, st->mclk_hz / 4);
switch (reg) {
case AD5933_REG_FREQ_START:
@@ -285,7 +285,7 @@ static ssize_t ad5933_show_frequency(struct device *dev,
freqreg = (u64)freqreg * (u64)(st->mclk_hz / 4);
do_div(freqreg, BIT(27));
- return sprintf(buf, "%d\n", (int)freqreg);
+ return sysfs_emit(buf, "%llu\n", freqreg);
}
static ssize_t ad5933_store_frequency(struct device *dev,
@@ -338,27 +338,27 @@ static ssize_t ad5933_show(struct device *dev,
mutex_lock(&st->lock);
switch ((u32)this_attr->address) {
case AD5933_OUT_RANGE:
- len = sprintf(buf, "%u\n",
- st->range_avail[(st->ctrl_hb >> 1) & 0x3]);
+ len = sysfs_emit(buf, "%u\n",
+ st->range_avail[(st->ctrl_hb >> 1) & 0x3]);
break;
case AD5933_OUT_RANGE_AVAIL:
- len = sprintf(buf, "%u %u %u %u\n", st->range_avail[0],
- st->range_avail[3], st->range_avail[2],
- st->range_avail[1]);
+ len = sysfs_emit(buf, "%u %u %u %u\n", st->range_avail[0],
+ st->range_avail[3], st->range_avail[2],
+ st->range_avail[1]);
break;
case AD5933_OUT_SETTLING_CYCLES:
- len = sprintf(buf, "%d\n", st->settling_cycles);
+ len = sysfs_emit(buf, "%d\n", st->settling_cycles);
break;
case AD5933_IN_PGA_GAIN:
- len = sprintf(buf, "%s\n",
- (st->ctrl_hb & AD5933_CTRL_PGA_GAIN_1) ?
- "1" : "0.2");
+ len = sysfs_emit(buf, "%s\n",
+ (st->ctrl_hb & AD5933_CTRL_PGA_GAIN_1) ?
+ "1" : "0.2");
break;
case AD5933_IN_PGA_GAIN_AVAIL:
- len = sprintf(buf, "1 0.2\n");
+ len = sysfs_emit(buf, "1 0.2\n");
break;
case AD5933_FREQ_POINTS:
- len = sprintf(buf, "%d\n", st->freq_points);
+ len = sysfs_emit(buf, "%d\n", st->freq_points);
break;
default:
ret = -EINVAL;