Skip to content

Commit 3f3d316

Browse files
committed
Merge tag 'iio-fixes-for-5.4a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus
Jonathan writes: First set of IIO fixes for the 5.4 cycle. * adis16400 - Make sure to free memory on a few failure paths. * adxl372 - Fix wrong fifo depth - Fix wrong indexing of data from the fifo. - Perform a reset at startup to avoid a problem with inconsistent state. * axp288 - This is a fix for a fix. The original fix made sure we kept the configuration from some firmwares to preserve a bias current. Unfortunately it appears the previous behaviour was working around a buggy firmware by overwriting the wrong value it had. Hence a regression was seen. * bmc150 - Fix the centre temperature. This was due to an error in one of the datasheets. * hx711 - Fix an issue where a badly timed interrupt could lead to a control line being high long enough to put the device into a low power state. * meson_sar_adc - Fix a case where the irq was enabled before everything it uses was allocated. * st_lsm6dsx - Ensure we don't set the sensor sensitivity to 0 as it will force all readings to 0. - Fix a wait time for the slave i2c controller when the accelerometer is not enabled. * stm32-adc - Precursor for fix. Move a set of register definitions to a header. - Fix a race when several ADCs are in use with some using interrupts to control the dataflow and some using DMA. * vcnl4000 - Fix a garbage of_match_table in which a string was passed instead of the intended enum. * tag 'iio-fixes-for-5.4a' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: iio: Fix an undefied reference error in noa1305_probe iio: light: opt3001: fix mutex unlock race iio: adc: ad799x: fix probe error handling iio: light: add missing vcnl4040 of_compatible iio: light: fix vcnl4000 devicetree hooks iio: imu: st_lsm6dsx: fix waitime for st_lsm6dsx i2c controller iio: adc: axp288: Override TS pin bias current for some models iio: imu: adis16400: fix memory leak iio: imu: adis16400: release allocated memory on failure iio: adc: stm32-adc: fix a race when using several adcs with dma and irq iio: adc: stm32-adc: move registers definitions iio: accel: adxl372: Perform a reset at start up iio: accel: adxl372: Fix push to buffers lost samples iio: accel: adxl372: Fix/remove limitation for FIFO samples iio: adc: hx711: fix bug in sampling of data iio: fix center temperature of bmc150-accel-core iio: imu: st_lsm6dsx: forbid 0 sensor sensitivity iio: adc: meson_saradc: Fix memory allocation order
2 parents 80b15db + a26e0fb commit 3f3d316

16 files changed

+290
-182
lines changed

drivers/iio/accel/adxl372.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -474,12 +474,17 @@ static int adxl372_configure_fifo(struct adxl372_state *st)
474474
if (ret < 0)
475475
return ret;
476476

477-
fifo_samples = st->watermark & 0xFF;
477+
/*
478+
* watermark stores the number of sets; we need to write the FIFO
479+
* registers with the number of samples
480+
*/
481+
fifo_samples = (st->watermark * st->fifo_set_size);
478482
fifo_ctl = ADXL372_FIFO_CTL_FORMAT_MODE(st->fifo_format) |
479483
ADXL372_FIFO_CTL_MODE_MODE(st->fifo_mode) |
480-
ADXL372_FIFO_CTL_SAMPLES_MODE(st->watermark);
484+
ADXL372_FIFO_CTL_SAMPLES_MODE(fifo_samples);
481485

482-
ret = regmap_write(st->regmap, ADXL372_FIFO_SAMPLES, fifo_samples);
486+
ret = regmap_write(st->regmap,
487+
ADXL372_FIFO_SAMPLES, fifo_samples & 0xFF);
483488
if (ret < 0)
484489
return ret;
485490

@@ -548,8 +553,7 @@ static irqreturn_t adxl372_trigger_handler(int irq, void *p)
548553
goto err;
549554

550555
/* Each sample is 2 bytes */
551-
for (i = 0; i < fifo_entries * sizeof(u16);
552-
i += st->fifo_set_size * sizeof(u16))
556+
for (i = 0; i < fifo_entries; i += st->fifo_set_size)
553557
iio_push_to_buffers(indio_dev, &st->fifo_buf[i]);
554558
}
555559
err:
@@ -571,6 +575,14 @@ static int adxl372_setup(struct adxl372_state *st)
571575
return -ENODEV;
572576
}
573577

578+
/*
579+
* Perform a software reset to make sure the device is in a consistent
580+
* state after start up.
581+
*/
582+
ret = regmap_write(st->regmap, ADXL372_RESET, ADXL372_RESET_CODE);
583+
if (ret < 0)
584+
return ret;
585+
574586
ret = adxl372_set_op_mode(st, ADXL372_STANDBY);
575587
if (ret < 0)
576588
return ret;

drivers/iio/accel/bmc150-accel-core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
#define BMC150_ACCEL_SLEEP_1_SEC 0x0F
118118

119119
#define BMC150_ACCEL_REG_TEMP 0x08
120-
#define BMC150_ACCEL_TEMP_CENTER_VAL 24
120+
#define BMC150_ACCEL_TEMP_CENTER_VAL 23
121121

122122
#define BMC150_ACCEL_AXIS_TO_REG(axis) (BMC150_ACCEL_REG_XOUT_L + (axis * 2))
123123
#define BMC150_AUTO_SUSPEND_DELAY_MS 2000

drivers/iio/adc/ad799x.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -810,10 +810,10 @@ static int ad799x_probe(struct i2c_client *client,
810810

811811
ret = ad799x_write_config(st, st->chip_config->default_config);
812812
if (ret < 0)
813-
goto error_disable_reg;
813+
goto error_disable_vref;
814814
ret = ad799x_read_config(st);
815815
if (ret < 0)
816-
goto error_disable_reg;
816+
goto error_disable_vref;
817817
st->config = ret;
818818

819819
ret = iio_triggered_buffer_setup(indio_dev, NULL,

drivers/iio/adc/axp288_adc.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
88
*/
99

10+
#include <linux/dmi.h>
1011
#include <linux/module.h>
1112
#include <linux/kernel.h>
1213
#include <linux/device.h>
@@ -25,6 +26,11 @@
2526
#define AXP288_ADC_EN_MASK 0xF0
2627
#define AXP288_ADC_TS_ENABLE 0x01
2728

29+
#define AXP288_ADC_TS_BIAS_MASK GENMASK(5, 4)
30+
#define AXP288_ADC_TS_BIAS_20UA (0 << 4)
31+
#define AXP288_ADC_TS_BIAS_40UA (1 << 4)
32+
#define AXP288_ADC_TS_BIAS_60UA (2 << 4)
33+
#define AXP288_ADC_TS_BIAS_80UA (3 << 4)
2834
#define AXP288_ADC_TS_CURRENT_ON_OFF_MASK GENMASK(1, 0)
2935
#define AXP288_ADC_TS_CURRENT_OFF (0 << 0)
3036
#define AXP288_ADC_TS_CURRENT_ON_WHEN_CHARGING (1 << 0)
@@ -177,10 +183,36 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
177183
return ret;
178184
}
179185

186+
/*
187+
* We rely on the machine's firmware to correctly setup the TS pin bias current
188+
* at boot. This lists systems with broken fw where we need to set it ourselves.
189+
*/
190+
static const struct dmi_system_id axp288_adc_ts_bias_override[] = {
191+
{
192+
/* Lenovo Ideapad 100S (11 inch) */
193+
.matches = {
194+
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
195+
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 100S-11IBY"),
196+
},
197+
.driver_data = (void *)(uintptr_t)AXP288_ADC_TS_BIAS_80UA,
198+
},
199+
{}
200+
};
201+
180202
static int axp288_adc_initialize(struct axp288_adc_info *info)
181203
{
204+
const struct dmi_system_id *bias_override;
182205
int ret, adc_enable_val;
183206

207+
bias_override = dmi_first_match(axp288_adc_ts_bias_override);
208+
if (bias_override) {
209+
ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL,
210+
AXP288_ADC_TS_BIAS_MASK,
211+
(uintptr_t)bias_override->driver_data);
212+
if (ret)
213+
return ret;
214+
}
215+
184216
/*
185217
* Determine if the TS pin is enabled and set the TS current-source
186218
* accordingly.

drivers/iio/adc/hx711.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,14 @@ struct hx711_data {
100100

101101
static int hx711_cycle(struct hx711_data *hx711_data)
102102
{
103-
int val;
103+
unsigned long flags;
104104

105105
/*
106106
* if preempted for more then 60us while PD_SCK is high:
107107
* hx711 is going in reset
108108
* ==> measuring is false
109109
*/
110-
preempt_disable();
110+
local_irq_save(flags);
111111
gpiod_set_value(hx711_data->gpiod_pd_sck, 1);
112112

113113
/*
@@ -117,23 +117,23 @@ static int hx711_cycle(struct hx711_data *hx711_data)
117117
*/
118118
ndelay(hx711_data->data_ready_delay_ns);
119119

120-
val = gpiod_get_value(hx711_data->gpiod_dout);
121120
/*
122121
* here we are not waiting for 0.2 us as suggested by the datasheet,
123122
* because the oscilloscope showed in a test scenario
124123
* at least 1.15 us for PD_SCK high (T3 in datasheet)
125124
* and 0.56 us for PD_SCK low on TI Sitara with 800 MHz
126125
*/
127126
gpiod_set_value(hx711_data->gpiod_pd_sck, 0);
128-
preempt_enable();
127+
local_irq_restore(flags);
129128

130129
/*
131130
* make it a square wave for addressing cases with capacitance on
132131
* PC_SCK
133132
*/
134133
ndelay(hx711_data->data_ready_delay_ns);
135134

136-
return val;
135+
/* sample as late as possible */
136+
return gpiod_get_value(hx711_data->gpiod_dout);
137137
}
138138

139139
static int hx711_read(struct hx711_data *hx711_data)

drivers/iio/adc/meson_saradc.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,11 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
12191219
if (IS_ERR(base))
12201220
return PTR_ERR(base);
12211221

1222+
priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
1223+
priv->param->regmap_config);
1224+
if (IS_ERR(priv->regmap))
1225+
return PTR_ERR(priv->regmap);
1226+
12221227
irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
12231228
if (!irq)
12241229
return -EINVAL;
@@ -1228,11 +1233,6 @@ static int meson_sar_adc_probe(struct platform_device *pdev)
12281233
if (ret)
12291234
return ret;
12301235

1231-
priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
1232-
priv->param->regmap_config);
1233-
if (IS_ERR(priv->regmap))
1234-
return PTR_ERR(priv->regmap);
1235-
12361236
priv->clkin = devm_clk_get(&pdev->dev, "clkin");
12371237
if (IS_ERR(priv->clkin)) {
12381238
dev_err(&pdev->dev, "failed to get clkin\n");

drivers/iio/adc/stm32-adc-core.c

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,33 +24,6 @@
2424

2525
#include "stm32-adc-core.h"
2626

27-
/* STM32F4 - common registers for all ADC instances: 1, 2 & 3 */
28-
#define STM32F4_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00)
29-
#define STM32F4_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x04)
30-
31-
/* STM32F4_ADC_CSR - bit fields */
32-
#define STM32F4_EOC3 BIT(17)
33-
#define STM32F4_EOC2 BIT(9)
34-
#define STM32F4_EOC1 BIT(1)
35-
36-
/* STM32F4_ADC_CCR - bit fields */
37-
#define STM32F4_ADC_ADCPRE_SHIFT 16
38-
#define STM32F4_ADC_ADCPRE_MASK GENMASK(17, 16)
39-
40-
/* STM32H7 - common registers for all ADC instances */
41-
#define STM32H7_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00)
42-
#define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08)
43-
44-
/* STM32H7_ADC_CSR - bit fields */
45-
#define STM32H7_EOC_SLV BIT(18)
46-
#define STM32H7_EOC_MST BIT(2)
47-
48-
/* STM32H7_ADC_CCR - bit fields */
49-
#define STM32H7_PRESC_SHIFT 18
50-
#define STM32H7_PRESC_MASK GENMASK(21, 18)
51-
#define STM32H7_CKMODE_SHIFT 16
52-
#define STM32H7_CKMODE_MASK GENMASK(17, 16)
53-
5427
#define STM32_ADC_CORE_SLEEP_DELAY_MS 2000
5528

5629
/* SYSCFG registers */
@@ -71,13 +44,17 @@
7144
* @eoc1: adc1 end of conversion flag in @csr
7245
* @eoc2: adc2 end of conversion flag in @csr
7346
* @eoc3: adc3 end of conversion flag in @csr
47+
* @ier: interrupt enable register offset for each adc
48+
* @eocie_msk: end of conversion interrupt enable mask in @ier
7449
*/
7550
struct stm32_adc_common_regs {
7651
u32 csr;
7752
u32 ccr;
7853
u32 eoc1_msk;
7954
u32 eoc2_msk;
8055
u32 eoc3_msk;
56+
u32 ier;
57+
u32 eocie_msk;
8158
};
8259

8360
struct stm32_adc_priv;
@@ -303,6 +280,8 @@ static const struct stm32_adc_common_regs stm32f4_adc_common_regs = {
303280
.eoc1_msk = STM32F4_EOC1,
304281
.eoc2_msk = STM32F4_EOC2,
305282
.eoc3_msk = STM32F4_EOC3,
283+
.ier = STM32F4_ADC_CR1,
284+
.eocie_msk = STM32F4_EOCIE,
306285
};
307286

308287
/* STM32H7 common registers definitions */
@@ -311,8 +290,24 @@ static const struct stm32_adc_common_regs stm32h7_adc_common_regs = {
311290
.ccr = STM32H7_ADC_CCR,
312291
.eoc1_msk = STM32H7_EOC_MST,
313292
.eoc2_msk = STM32H7_EOC_SLV,
293+
.ier = STM32H7_ADC_IER,
294+
.eocie_msk = STM32H7_EOCIE,
295+
};
296+
297+
static const unsigned int stm32_adc_offset[STM32_ADC_MAX_ADCS] = {
298+
0, STM32_ADC_OFFSET, STM32_ADC_OFFSET * 2,
314299
};
315300

301+
static unsigned int stm32_adc_eoc_enabled(struct stm32_adc_priv *priv,
302+
unsigned int adc)
303+
{
304+
u32 ier, offset = stm32_adc_offset[adc];
305+
306+
ier = readl_relaxed(priv->common.base + offset + priv->cfg->regs->ier);
307+
308+
return ier & priv->cfg->regs->eocie_msk;
309+
}
310+
316311
/* ADC common interrupt for all instances */
317312
static void stm32_adc_irq_handler(struct irq_desc *desc)
318313
{
@@ -323,13 +318,28 @@ static void stm32_adc_irq_handler(struct irq_desc *desc)
323318
chained_irq_enter(chip, desc);
324319
status = readl_relaxed(priv->common.base + priv->cfg->regs->csr);
325320

326-
if (status & priv->cfg->regs->eoc1_msk)
321+
/*
322+
* End of conversion may be handled by using IRQ or DMA. There may be a
323+
* race here when two conversions complete at the same time on several
324+
* ADCs. EOC may be read 'set' for several ADCs, with:
325+
* - an ADC configured to use DMA (EOC triggers the DMA request, and
326+
* is then automatically cleared by DR read in hardware)
327+
* - an ADC configured to use IRQs (EOCIE bit is set. The handler must
328+
* be called in this case)
329+
* So both EOC status bit in CSR and EOCIE control bit must be checked
330+
* before invoking the interrupt handler (e.g. call ISR only for
331+
* IRQ-enabled ADCs).
332+
*/
333+
if (status & priv->cfg->regs->eoc1_msk &&
334+
stm32_adc_eoc_enabled(priv, 0))
327335
generic_handle_irq(irq_find_mapping(priv->domain, 0));
328336

329-
if (status & priv->cfg->regs->eoc2_msk)
337+
if (status & priv->cfg->regs->eoc2_msk &&
338+
stm32_adc_eoc_enabled(priv, 1))
330339
generic_handle_irq(irq_find_mapping(priv->domain, 1));
331340

332-
if (status & priv->cfg->regs->eoc3_msk)
341+
if (status & priv->cfg->regs->eoc3_msk &&
342+
stm32_adc_eoc_enabled(priv, 2))
333343
generic_handle_irq(irq_find_mapping(priv->domain, 2));
334344

335345
chained_irq_exit(chip, desc);

0 commit comments

Comments
 (0)