mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
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). -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmbCHw0RHGppYzIzQGtl cm5lbC5vcmcACgkQVIU0mcT0FohWcxAAnqGDiukCxWo4YWERhh5CqXpzleiR0QPG xf5vN8w+auMDR+jm+Pr9AE8M+jd8Kn1nJAYEr5ii00ebww7pKIRYLr38D4RYLUx4 ta7+gC6QJh6ZG7T7jDyg4C4Kz3FDWUJFOriQ1EuV2GqClCMc8hhkhus5CPNOAhB6 E9akczbuXbsDIcx04sb3vIkuqAq15NxGY69m157WqzvIDItIoy4LuK9c4B0WjNK3 8SzCRxMTCRICB7RvLIs9nFy3SSqnpjQfJAwhaXTUxEtHd5FM2AhlRxFjLFI5Sb+j WuDmg1HjUEQ8y0xSGcEdKhOsRgkdbBu7GetLn0evxtg9p7qF6KbTHxj3pagSJhB8 WWGpT5c0HG0Wye02gxPL0rOHqOIHjeyzemdiJIPl09uBobqKXv+io6x+uR8WCZW/ kuNubOcAhCtJ/uqIZ7YsXId2444sK7YfBJsFrVQOrqomplZQSrSO46Us92+/lSLL adU8Hm7r5e5c6NqQbyffJXORpCYCpoNmKtknXF0F4b69kBKbewvs5pR7wa7E37V3 IpwU8GMd9LyTFHq72npPZxpc8SHawPMJyBH+G+4GgXpMQpqV4lKV2m8uCBO0o9Ir UgUO29bDf15qgskG+EB18nARza1uNQtpdf4ClrGhxIK2G/bWIdAmgiY8dLVU+9QF PQSPWnuKoq8= =txr2 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
8cbec53959
@ -147,15 +147,18 @@ struct ad7124_chip_info {
|
||||
struct ad7124_channel_config {
|
||||
bool live;
|
||||
unsigned int cfg_slot;
|
||||
enum ad7124_ref_sel refsel;
|
||||
bool bipolar;
|
||||
bool buf_positive;
|
||||
bool buf_negative;
|
||||
unsigned int vref_mv;
|
||||
unsigned int pga_bits;
|
||||
unsigned int odr;
|
||||
unsigned int odr_sel_bits;
|
||||
unsigned int filter_type;
|
||||
/* Following fields are used to compare equality. */
|
||||
struct_group(config_props,
|
||||
enum ad7124_ref_sel refsel;
|
||||
bool bipolar;
|
||||
bool buf_positive;
|
||||
bool buf_negative;
|
||||
unsigned int vref_mv;
|
||||
unsigned int pga_bits;
|
||||
unsigned int odr;
|
||||
unsigned int odr_sel_bits;
|
||||
unsigned int filter_type;
|
||||
);
|
||||
};
|
||||
|
||||
struct ad7124_channel {
|
||||
@ -334,11 +337,12 @@ static struct ad7124_channel_config *ad7124_find_similar_live_cfg(struct ad7124_
|
||||
ptrdiff_t cmp_size;
|
||||
int i;
|
||||
|
||||
cmp_size = (u8 *)&cfg->live - (u8 *)cfg;
|
||||
cmp_size = sizeof_field(struct ad7124_channel_config, config_props);
|
||||
for (i = 0; i < st->num_channels; i++) {
|
||||
cfg_aux = &st->channels[i].cfg;
|
||||
|
||||
if (cfg_aux->live && !memcmp(cfg, cfg_aux, cmp_size))
|
||||
if (cfg_aux->live &&
|
||||
!memcmp(&cfg->config_props, &cfg_aux->config_props, cmp_size))
|
||||
return cfg_aux;
|
||||
}
|
||||
|
||||
@ -764,6 +768,7 @@ static int ad7124_soft_reset(struct ad7124_state *st)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
fsleep(200);
|
||||
timeout = 100;
|
||||
do {
|
||||
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,
|
||||
st->channels = channels;
|
||||
|
||||
device_for_each_child_node_scoped(dev, child) {
|
||||
cfg = &st->channels[channel].cfg;
|
||||
|
||||
ret = fwnode_property_read_u32(child, "reg", &channel);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -858,6 +861,7 @@ static int ad7124_parse_channel_config(struct iio_dev *indio_dev,
|
||||
st->channels[channel].ain = AD7124_CHANNEL_AINP(ain[0]) |
|
||||
AD7124_CHANNEL_AINM(ain[1]);
|
||||
|
||||
cfg = &st->channels[channel].cfg;
|
||||
cfg->bipolar = fwnode_property_read_bool(child, "bipolar");
|
||||
|
||||
ret = fwnode_property_read_u32(child, "adi,reference-select", &tmp);
|
||||
|
@ -302,7 +302,6 @@ static const struct ad7173_device_info ad4114_device_info = {
|
||||
.num_configs = 8,
|
||||
.num_voltage_in = 16,
|
||||
.num_gpios = 4,
|
||||
.higher_gpio_bits = true,
|
||||
.has_vincom_input = true,
|
||||
.has_temp = true,
|
||||
.has_input_buf = true,
|
||||
@ -320,7 +319,6 @@ static const struct ad7173_device_info ad4115_device_info = {
|
||||
.num_configs = 8,
|
||||
.num_voltage_in = 16,
|
||||
.num_gpios = 4,
|
||||
.higher_gpio_bits = true,
|
||||
.has_vincom_input = true,
|
||||
.has_temp = true,
|
||||
.has_input_buf = true,
|
||||
@ -338,7 +336,6 @@ static const struct ad7173_device_info ad4116_device_info = {
|
||||
.num_configs = 8,
|
||||
.num_voltage_in = 16,
|
||||
.num_gpios = 4,
|
||||
.higher_gpio_bits = true,
|
||||
.has_vincom_input = true,
|
||||
.has_temp = true,
|
||||
.has_input_buf = true,
|
||||
@ -1435,11 +1432,11 @@ static int ad7173_probe(struct spi_device *spi)
|
||||
}
|
||||
|
||||
static const struct of_device_id ad7173_of_match[] = {
|
||||
{ .compatible = "ad4111", .data = &ad4111_device_info },
|
||||
{ .compatible = "ad4112", .data = &ad4112_device_info },
|
||||
{ .compatible = "ad4114", .data = &ad4114_device_info },
|
||||
{ .compatible = "ad4115", .data = &ad4115_device_info },
|
||||
{ .compatible = "ad4116", .data = &ad4116_device_info },
|
||||
{ .compatible = "adi,ad4111", .data = &ad4111_device_info },
|
||||
{ .compatible = "adi,ad4112", .data = &ad4112_device_info },
|
||||
{ .compatible = "adi,ad4114", .data = &ad4114_device_info },
|
||||
{ .compatible = "adi,ad4115", .data = &ad4115_device_info },
|
||||
{ .compatible = "adi,ad4116", .data = &ad4116_device_info },
|
||||
{ .compatible = "adi,ad7172-2", .data = &ad7172_2_device_info },
|
||||
{ .compatible = "adi,ad7172-4", .data = &ad7172_4_device_info },
|
||||
{ .compatible = "adi,ad7173-8", .data = &ad7173_8_device_info },
|
||||
|
@ -49,7 +49,7 @@ static const unsigned int ad7616_oversampling_avail[8] = {
|
||||
1, 2, 4, 8, 16, 32, 64, 128,
|
||||
};
|
||||
|
||||
static int ad7606_reset(struct ad7606_state *st)
|
||||
int ad7606_reset(struct ad7606_state *st)
|
||||
{
|
||||
if (st->gpio_reset) {
|
||||
gpiod_set_value(st->gpio_reset, 1);
|
||||
@ -60,6 +60,7 @@ static int ad7606_reset(struct ad7606_state *st)
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ad7606_reset, IIO_AD7606);
|
||||
|
||||
static int ad7606_reg_access(struct iio_dev *indio_dev,
|
||||
unsigned int reg,
|
||||
@ -88,31 +89,6 @@ static int ad7606_read_samples(struct ad7606_state *st)
|
||||
{
|
||||
unsigned int num = st->chip_info->num_channels - 1;
|
||||
u16 *data = st->data;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* The frstdata signal is set to high while and after reading the sample
|
||||
* of the first channel and low for all other channels. This can be used
|
||||
* to check that the incoming data is correctly aligned. During normal
|
||||
* operation the data should never become unaligned, but some glitch or
|
||||
* electrostatic discharge might cause an extra read or clock cycle.
|
||||
* Monitoring the frstdata signal allows to recover from such failure
|
||||
* situations.
|
||||
*/
|
||||
|
||||
if (st->gpio_frstdata) {
|
||||
ret = st->bops->read_block(st->dev, 1, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!gpiod_get_value(st->gpio_frstdata)) {
|
||||
ad7606_reset(st);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
data++;
|
||||
num--;
|
||||
}
|
||||
|
||||
return st->bops->read_block(st->dev, num, data);
|
||||
}
|
||||
|
@ -151,6 +151,8 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
|
||||
const char *name, unsigned int id,
|
||||
const struct ad7606_bus_ops *bops);
|
||||
|
||||
int ad7606_reset(struct ad7606_state *st);
|
||||
|
||||
enum ad7606_supported_device_ids {
|
||||
ID_AD7605_4,
|
||||
ID_AD7606_8,
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/err.h>
|
||||
@ -21,8 +22,29 @@ static int ad7606_par16_read_block(struct device *dev,
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct ad7606_state *st = iio_priv(indio_dev);
|
||||
|
||||
insw((unsigned long)st->base_address, buf, count);
|
||||
|
||||
/*
|
||||
* On the parallel interface, the frstdata signal is set to high while
|
||||
* and after reading the sample of the first channel and low for all
|
||||
* other channels. This can be used to check that the incoming data is
|
||||
* correctly aligned. During normal operation the data should never
|
||||
* become unaligned, but some glitch or electrostatic discharge might
|
||||
* cause an extra read or clock cycle. Monitoring the frstdata signal
|
||||
* allows to recover from such failure situations.
|
||||
*/
|
||||
int num = count;
|
||||
u16 *_buf = buf;
|
||||
|
||||
if (st->gpio_frstdata) {
|
||||
insw((unsigned long)st->base_address, _buf, 1);
|
||||
if (!gpiod_get_value(st->gpio_frstdata)) {
|
||||
ad7606_reset(st);
|
||||
return -EIO;
|
||||
}
|
||||
_buf++;
|
||||
num--;
|
||||
}
|
||||
insw((unsigned long)st->base_address, _buf, num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -35,8 +57,28 @@ static int ad7606_par8_read_block(struct device *dev,
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct ad7606_state *st = iio_priv(indio_dev);
|
||||
/*
|
||||
* On the parallel interface, the frstdata signal is set to high while
|
||||
* and after reading the sample of the first channel and low for all
|
||||
* other channels. This can be used to check that the incoming data is
|
||||
* correctly aligned. During normal operation the data should never
|
||||
* become unaligned, but some glitch or electrostatic discharge might
|
||||
* cause an extra read or clock cycle. Monitoring the frstdata signal
|
||||
* allows to recover from such failure situations.
|
||||
*/
|
||||
int num = count;
|
||||
u16 *_buf = buf;
|
||||
|
||||
insb((unsigned long)st->base_address, buf, count * 2);
|
||||
if (st->gpio_frstdata) {
|
||||
insb((unsigned long)st->base_address, _buf, 2);
|
||||
if (!gpiod_get_value(st->gpio_frstdata)) {
|
||||
ad7606_reset(st);
|
||||
return -EIO;
|
||||
}
|
||||
_buf++;
|
||||
num--;
|
||||
}
|
||||
insb((unsigned long)st->base_address, _buf, num * 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -569,7 +569,7 @@ EXPORT_SYMBOL_NS_GPL(ad_sd_validate_trigger, IIO_AD_SIGMA_DELTA);
|
||||
static int devm_ad_sd_probe_trigger(struct device *dev, struct iio_dev *indio_dev)
|
||||
{
|
||||
struct ad_sigma_delta *sigma_delta = iio_device_get_drvdata(indio_dev);
|
||||
unsigned long irq_flags = irq_get_trigger_type(sigma_delta->spi->irq);
|
||||
unsigned long irq_flags = irq_get_trigger_type(sigma_delta->irq_line);
|
||||
int ret;
|
||||
|
||||
if (dev != &sigma_delta->spi->dev) {
|
||||
|
@ -735,7 +735,7 @@ static int ads1119_probe(struct i2c_client *client)
|
||||
if (client->irq > 0) {
|
||||
ret = devm_request_threaded_irq(dev, client->irq,
|
||||
ads1119_irq_handler,
|
||||
NULL, IRQF_TRIGGER_FALLING,
|
||||
NULL, IRQF_ONESHOT,
|
||||
"ads1119", indio_dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
|
@ -237,7 +237,7 @@ static struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev,
|
||||
|
||||
ret = dma_get_slave_caps(chan, &caps);
|
||||
if (ret < 0)
|
||||
goto err_free;
|
||||
goto err_release;
|
||||
|
||||
/* Needs to be aligned to the maximum of the minimums */
|
||||
if (caps.src_addr_widths)
|
||||
@ -263,6 +263,8 @@ static struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev,
|
||||
|
||||
return &dmaengine_buffer->queue.buffer;
|
||||
|
||||
err_release:
|
||||
dma_release_channel(chan);
|
||||
err_free:
|
||||
kfree(dmaengine_buffer);
|
||||
return ERR_PTR(ret);
|
||||
|
@ -248,12 +248,20 @@ static irqreturn_t inv_mpu6050_interrupt_handle(int irq, void *p)
|
||||
int result;
|
||||
|
||||
switch (st->chip_type) {
|
||||
case INV_MPU6000:
|
||||
case INV_MPU6050:
|
||||
case INV_MPU9150:
|
||||
/*
|
||||
* WoM is not supported and interrupt status read seems to be broken for
|
||||
* some chips. Since data ready is the only interrupt, bypass interrupt
|
||||
* status read and always assert data ready bit.
|
||||
*/
|
||||
wom_bits = 0;
|
||||
int_status = INV_MPU6050_BIT_RAW_DATA_RDY_INT;
|
||||
goto data_ready_interrupt;
|
||||
case INV_MPU6500:
|
||||
case INV_MPU6515:
|
||||
case INV_MPU6880:
|
||||
case INV_MPU6000:
|
||||
case INV_MPU9150:
|
||||
case INV_MPU9250:
|
||||
case INV_MPU9255:
|
||||
wom_bits = INV_MPU6500_BIT_WOM_INT;
|
||||
@ -279,6 +287,7 @@ static irqreturn_t inv_mpu6050_interrupt_handle(int irq, void *p)
|
||||
}
|
||||
}
|
||||
|
||||
data_ready_interrupt:
|
||||
/* handle raw data interrupt */
|
||||
if (int_status & INV_MPU6050_BIT_RAW_DATA_RDY_INT) {
|
||||
indio_dev->pollfunc->timestamp = st->it_timestamp;
|
||||
|
@ -647,17 +647,17 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
|
||||
break;
|
||||
case IIO_VAL_INT_PLUS_MICRO:
|
||||
if (scale_val2 < 0)
|
||||
*processed = -raw64 * scale_val;
|
||||
*processed = -raw64 * scale_val * scale;
|
||||
else
|
||||
*processed = raw64 * scale_val;
|
||||
*processed = raw64 * scale_val * scale;
|
||||
*processed += div_s64(raw64 * (s64)scale_val2 * scale,
|
||||
1000000LL);
|
||||
break;
|
||||
case IIO_VAL_INT_PLUS_NANO:
|
||||
if (scale_val2 < 0)
|
||||
*processed = -raw64 * scale_val;
|
||||
*processed = -raw64 * scale_val * scale;
|
||||
else
|
||||
*processed = raw64 * scale_val;
|
||||
*processed = raw64 * scale_val * scale;
|
||||
*processed += div_s64(raw64 * (s64)scale_val2 * scale,
|
||||
1000000000LL);
|
||||
break;
|
||||
|
@ -114,7 +114,7 @@ static int ad9834_write_frequency(struct ad9834_state *st,
|
||||
|
||||
clk_freq = clk_get_rate(st->mclk);
|
||||
|
||||
if (fout > (clk_freq / 2))
|
||||
if (!clk_freq || fout > (clk_freq / 2))
|
||||
return -EINVAL;
|
||||
|
||||
regval = ad9834_calc_freqreg(clk_freq, fout);
|
||||
|
Loading…
Reference in New Issue
Block a user