Skip to content

Commit 8cbec53

Browse files
committed
Merge tag 'iio-fixes-for-6.11a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-linus
Jonathan writes: IIO: 1st set of fixes for 6.11 The usual mixed bag of new issues and ancient ones. The fact so many are ADI is probably due to an uptick in upstreaming effort from Analog + Baylibre meaning existing code is getting more eyes on it. Hence it's a good sign not a reflection of inherent high bug incidence! Core and helper related ----------------------- in kernel interfaces - Fix missing application of scale to the integer part of IIO_INT_PLUS_XXX value pairs when using the iio_convert_raw_to_processed*() helper. buffer-dmaengine - Make sure to release DMA channel in error path. Driver related -------------- adi,ad-sigma-delta library - Check irq-flags for the correct irq if multiple are provided. adi,ad7124 - Wait after reset before reading the chip ID register. - Compare only the relevant field when looking for an existing config to reuse for a new channel. - Fix an off by one in which channel config is being filled from firmware. adi,ad7173 - Fix missing vendor prefix in compatible strings. - Fix wrong info for GPIO related bit positions for ad4114,ad4115 and ad4116. adi,ad7606 - Drop incorrect check on frstdata when in serial mode, it only applies to parallel mode. adi,ad9834 - Check userspace input for frequency parameter to avoid div by zero. invensense,mpu6050 - Avoid reading interrupt status on some older chips as it seems there is a hardware problem that surfaces as a result of adding wake on motion support to the driver (which these chips don't support). ti,ads1119 - Fix incorrect IRQ flag (new driver so no firmware compatibility regression issues with fixing this now). * tag 'iio-fixes-for-6.11a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: iio: imu: inv_mpu6050: fix interrupt status read for old buggy chips iio: adc: ad7173: fix GPIO device info iio: adc: ad7124: fix DT configuration parsing iio: adc: ad_sigma_delta: fix irq_flags on irq request iio: adc: ads1119: Fix IRQ flags iio: fix scale application in iio_convert_raw_to_processed_unlocked iio: adc: ad7124: fix config comparison iio: adc: ad7124: fix chip ID mismatch iio: adc: ad7173: Fix incorrect compatible string iio: buffer-dmaengine: fix releasing dma channel on error iio: adc: ad7606: remove frstdata check for serial mode staging: iio: frequency: ad9834: Validate frequency parameter value
2 parents 47ac09b + 0a3b517 commit 8cbec53

File tree

11 files changed

+92
-60
lines changed

11 files changed

+92
-60
lines changed

drivers/iio/adc/ad7124.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,18 @@ struct ad7124_chip_info {
147147
struct ad7124_channel_config {
148148
bool live;
149149
unsigned int cfg_slot;
150-
enum ad7124_ref_sel refsel;
151-
bool bipolar;
152-
bool buf_positive;
153-
bool buf_negative;
154-
unsigned int vref_mv;
155-
unsigned int pga_bits;
156-
unsigned int odr;
157-
unsigned int odr_sel_bits;
158-
unsigned int filter_type;
150+
/* Following fields are used to compare equality. */
151+
struct_group(config_props,
152+
enum ad7124_ref_sel refsel;
153+
bool bipolar;
154+
bool buf_positive;
155+
bool buf_negative;
156+
unsigned int vref_mv;
157+
unsigned int pga_bits;
158+
unsigned int odr;
159+
unsigned int odr_sel_bits;
160+
unsigned int filter_type;
161+
);
159162
};
160163

161164
struct ad7124_channel {
@@ -334,11 +337,12 @@ static struct ad7124_channel_config *ad7124_find_similar_live_cfg(struct ad7124_
334337
ptrdiff_t cmp_size;
335338
int i;
336339

337-
cmp_size = (u8 *)&cfg->live - (u8 *)cfg;
340+
cmp_size = sizeof_field(struct ad7124_channel_config, config_props);
338341
for (i = 0; i < st->num_channels; i++) {
339342
cfg_aux = &st->channels[i].cfg;
340343

341-
if (cfg_aux->live && !memcmp(cfg, cfg_aux, cmp_size))
344+
if (cfg_aux->live &&
345+
!memcmp(&cfg->config_props, &cfg_aux->config_props, cmp_size))
342346
return cfg_aux;
343347
}
344348

@@ -764,6 +768,7 @@ static int ad7124_soft_reset(struct ad7124_state *st)
764768
if (ret < 0)
765769
return ret;
766770

771+
fsleep(200);
767772
timeout = 100;
768773
do {
769774
ret = ad_sd_read_reg(&st->sd, AD7124_STATUS, 1, &readval);
@@ -839,8 +844,6 @@ static int ad7124_parse_channel_config(struct iio_dev *indio_dev,
839844
st->channels = channels;
840845

841846
device_for_each_child_node_scoped(dev, child) {
842-
cfg = &st->channels[channel].cfg;
843-
844847
ret = fwnode_property_read_u32(child, "reg", &channel);
845848
if (ret)
846849
return ret;
@@ -858,6 +861,7 @@ static int ad7124_parse_channel_config(struct iio_dev *indio_dev,
858861
st->channels[channel].ain = AD7124_CHANNEL_AINP(ain[0]) |
859862
AD7124_CHANNEL_AINM(ain[1]);
860863

864+
cfg = &st->channels[channel].cfg;
861865
cfg->bipolar = fwnode_property_read_bool(child, "bipolar");
862866

863867
ret = fwnode_property_read_u32(child, "adi,reference-select", &tmp);

drivers/iio/adc/ad7173.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,6 @@ static const struct ad7173_device_info ad4114_device_info = {
302302
.num_configs = 8,
303303
.num_voltage_in = 16,
304304
.num_gpios = 4,
305-
.higher_gpio_bits = true,
306305
.has_vincom_input = true,
307306
.has_temp = true,
308307
.has_input_buf = true,
@@ -320,7 +319,6 @@ static const struct ad7173_device_info ad4115_device_info = {
320319
.num_configs = 8,
321320
.num_voltage_in = 16,
322321
.num_gpios = 4,
323-
.higher_gpio_bits = true,
324322
.has_vincom_input = true,
325323
.has_temp = true,
326324
.has_input_buf = true,
@@ -338,7 +336,6 @@ static const struct ad7173_device_info ad4116_device_info = {
338336
.num_configs = 8,
339337
.num_voltage_in = 16,
340338
.num_gpios = 4,
341-
.higher_gpio_bits = true,
342339
.has_vincom_input = true,
343340
.has_temp = true,
344341
.has_input_buf = true,
@@ -1435,11 +1432,11 @@ static int ad7173_probe(struct spi_device *spi)
14351432
}
14361433

14371434
static const struct of_device_id ad7173_of_match[] = {
1438-
{ .compatible = "ad4111", .data = &ad4111_device_info },
1439-
{ .compatible = "ad4112", .data = &ad4112_device_info },
1440-
{ .compatible = "ad4114", .data = &ad4114_device_info },
1441-
{ .compatible = "ad4115", .data = &ad4115_device_info },
1442-
{ .compatible = "ad4116", .data = &ad4116_device_info },
1435+
{ .compatible = "adi,ad4111", .data = &ad4111_device_info },
1436+
{ .compatible = "adi,ad4112", .data = &ad4112_device_info },
1437+
{ .compatible = "adi,ad4114", .data = &ad4114_device_info },
1438+
{ .compatible = "adi,ad4115", .data = &ad4115_device_info },
1439+
{ .compatible = "adi,ad4116", .data = &ad4116_device_info },
14431440
{ .compatible = "adi,ad7172-2", .data = &ad7172_2_device_info },
14441441
{ .compatible = "adi,ad7172-4", .data = &ad7172_4_device_info },
14451442
{ .compatible = "adi,ad7173-8", .data = &ad7173_8_device_info },

drivers/iio/adc/ad7606.c

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static const unsigned int ad7616_oversampling_avail[8] = {
4949
1, 2, 4, 8, 16, 32, 64, 128,
5050
};
5151

52-
static int ad7606_reset(struct ad7606_state *st)
52+
int ad7606_reset(struct ad7606_state *st)
5353
{
5454
if (st->gpio_reset) {
5555
gpiod_set_value(st->gpio_reset, 1);
@@ -60,6 +60,7 @@ static int ad7606_reset(struct ad7606_state *st)
6060

6161
return -ENODEV;
6262
}
63+
EXPORT_SYMBOL_NS_GPL(ad7606_reset, IIO_AD7606);
6364

6465
static int ad7606_reg_access(struct iio_dev *indio_dev,
6566
unsigned int reg,
@@ -88,31 +89,6 @@ static int ad7606_read_samples(struct ad7606_state *st)
8889
{
8990
unsigned int num = st->chip_info->num_channels - 1;
9091
u16 *data = st->data;
91-
int ret;
92-
93-
/*
94-
* The frstdata signal is set to high while and after reading the sample
95-
* of the first channel and low for all other channels. This can be used
96-
* to check that the incoming data is correctly aligned. During normal
97-
* operation the data should never become unaligned, but some glitch or
98-
* electrostatic discharge might cause an extra read or clock cycle.
99-
* Monitoring the frstdata signal allows to recover from such failure
100-
* situations.
101-
*/
102-
103-
if (st->gpio_frstdata) {
104-
ret = st->bops->read_block(st->dev, 1, data);
105-
if (ret)
106-
return ret;
107-
108-
if (!gpiod_get_value(st->gpio_frstdata)) {
109-
ad7606_reset(st);
110-
return -EIO;
111-
}
112-
113-
data++;
114-
num--;
115-
}
11692

11793
return st->bops->read_block(st->dev, num, data);
11894
}

drivers/iio/adc/ad7606.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
151151
const char *name, unsigned int id,
152152
const struct ad7606_bus_ops *bops);
153153

154+
int ad7606_reset(struct ad7606_state *st);
155+
154156
enum ad7606_supported_device_ids {
155157
ID_AD7605_4,
156158
ID_AD7606_8,

drivers/iio/adc/ad7606_par.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <linux/mod_devicetable.h>
99
#include <linux/module.h>
10+
#include <linux/gpio/consumer.h>
1011
#include <linux/platform_device.h>
1112
#include <linux/types.h>
1213
#include <linux/err.h>
@@ -21,8 +22,29 @@ static int ad7606_par16_read_block(struct device *dev,
2122
struct iio_dev *indio_dev = dev_get_drvdata(dev);
2223
struct ad7606_state *st = iio_priv(indio_dev);
2324

24-
insw((unsigned long)st->base_address, buf, count);
2525

26+
/*
27+
* On the parallel interface, the frstdata signal is set to high while
28+
* and after reading the sample of the first channel and low for all
29+
* other channels. This can be used to check that the incoming data is
30+
* correctly aligned. During normal operation the data should never
31+
* become unaligned, but some glitch or electrostatic discharge might
32+
* cause an extra read or clock cycle. Monitoring the frstdata signal
33+
* allows to recover from such failure situations.
34+
*/
35+
int num = count;
36+
u16 *_buf = buf;
37+
38+
if (st->gpio_frstdata) {
39+
insw((unsigned long)st->base_address, _buf, 1);
40+
if (!gpiod_get_value(st->gpio_frstdata)) {
41+
ad7606_reset(st);
42+
return -EIO;
43+
}
44+
_buf++;
45+
num--;
46+
}
47+
insw((unsigned long)st->base_address, _buf, num);
2648
return 0;
2749
}
2850

@@ -35,8 +57,28 @@ static int ad7606_par8_read_block(struct device *dev,
3557
{
3658
struct iio_dev *indio_dev = dev_get_drvdata(dev);
3759
struct ad7606_state *st = iio_priv(indio_dev);
38-
39-
insb((unsigned long)st->base_address, buf, count * 2);
60+
/*
61+
* On the parallel interface, the frstdata signal is set to high while
62+
* and after reading the sample of the first channel and low for all
63+
* other channels. This can be used to check that the incoming data is
64+
* correctly aligned. During normal operation the data should never
65+
* become unaligned, but some glitch or electrostatic discharge might
66+
* cause an extra read or clock cycle. Monitoring the frstdata signal
67+
* allows to recover from such failure situations.
68+
*/
69+
int num = count;
70+
u16 *_buf = buf;
71+
72+
if (st->gpio_frstdata) {
73+
insb((unsigned long)st->base_address, _buf, 2);
74+
if (!gpiod_get_value(st->gpio_frstdata)) {
75+
ad7606_reset(st);
76+
return -EIO;
77+
}
78+
_buf++;
79+
num--;
80+
}
81+
insb((unsigned long)st->base_address, _buf, num * 2);
4082

4183
return 0;
4284
}

drivers/iio/adc/ad_sigma_delta.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ EXPORT_SYMBOL_NS_GPL(ad_sd_validate_trigger, IIO_AD_SIGMA_DELTA);
569569
static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_dev)
570570
{
571571
struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
572-
unsigned long irq_flags = irq_get_trigger_type(sigma_delta->spi->irq);
572+
unsigned long irq_flags = irq_get_trigger_type(sigma_delta->irq_line);
573573
int ret;
574574

575575
if (dev != &sigma_delta->spi->dev) {

drivers/iio/adc/ti-ads1119.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ static int ads1119_probe(struct i2c_client *client)
735735
if (client->irq > 0) {
736736
ret = devm_request_threaded_irq(dev, client->irq,
737737
ads1119_irq_handler,
738-
NULL, IRQF_TRIGGER_FALLING,
738+
NULL, IRQF_ONESHOT,
739739
"ads1119", indio_dev);
740740
if (ret)
741741
return dev_err_probe(dev, ret,

drivers/iio/buffer/industrialio-buffer-dmaengine.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ static struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev,
237237

238238
ret = dma_get_slave_caps(chan, &caps);
239239
if (ret < 0)
240-
goto err_free;
240+
goto err_release;
241241

242242
/* Needs to be aligned to the maximum of the minimums */
243243
if (caps.src_addr_widths)
@@ -263,6 +263,8 @@ static struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev,
263263

264264
return &dmaengine_buffer->queue.buffer;
265265

266+
err_release:
267+
dma_release_channel(chan);
266268
err_free:
267269
kfree(dmaengine_buffer);
268270
return ERR_PTR(ret);

drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,20 @@ static irqreturn_t inv_mpu6050_interrupt_handle(int irq, void *p)
248248
int result;
249249

250250
switch (st->chip_type) {
251+
case INV_MPU6000:
251252
case INV_MPU6050:
253+
case INV_MPU9150:
254+
/*
255+
* WoM is not supported and interrupt status read seems to be broken for
256+
* some chips. Since data ready is the only interrupt, bypass interrupt
257+
* status read and always assert data ready bit.
258+
*/
259+
wom_bits = 0;
260+
int_status = INV_MPU6050_BIT_RAW_DATA_RDY_INT;
261+
goto data_ready_interrupt;
252262
case INV_MPU6500:
253263
case INV_MPU6515:
254264
case INV_MPU6880:
255-
case INV_MPU6000:
256-
case INV_MPU9150:
257265
case INV_MPU9250:
258266
case INV_MPU9255:
259267
wom_bits = INV_MPU6500_BIT_WOM_INT;
@@ -279,6 +287,7 @@ static irqreturn_t inv_mpu6050_interrupt_handle(int irq, void *p)
279287
}
280288
}
281289

290+
data_ready_interrupt:
282291
/* handle raw data interrupt */
283292
if (int_status & INV_MPU6050_BIT_RAW_DATA_RDY_INT) {
284293
indio_dev->pollfunc->timestamp = st->it_timestamp;

drivers/iio/inkern.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -647,17 +647,17 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
647647
break;
648648
case IIO_VAL_INT_PLUS_MICRO:
649649
if (scale_val2 < 0)
650-
*processed = -raw64 * scale_val;
650+
*processed = -raw64 * scale_val * scale;
651651
else
652-
*processed = raw64 * scale_val;
652+
*processed = raw64 * scale_val * scale;
653653
*processed += div_s64(raw64 * (s64)scale_val2 * scale,
654654
1000000LL);
655655
break;
656656
case IIO_VAL_INT_PLUS_NANO:
657657
if (scale_val2 < 0)
658-
*processed = -raw64 * scale_val;
658+
*processed = -raw64 * scale_val * scale;
659659
else
660-
*processed = raw64 * scale_val;
660+
*processed = raw64 * scale_val * scale;
661661
*processed += div_s64(raw64 * (s64)scale_val2 * scale,
662662
1000000000LL);
663663
break;

0 commit comments

Comments
 (0)