mirror of
https://github.com/torvalds/linux.git
synced 2026-06-03 12:03:54 +02:00
iio-fixes-for-7.a IIO: 1st set of fixes for the 7.1 cycle
Usual mixed bag of ancient issues and more recent. Lots of new contributors this cycle and some of that work has uncovered bugs in the code they were looking at. core,buffer - Add missing dma_fence_put() - hw-consumer - Fix a use after free in cleaning up a list. core,inkern - Fix return value handling in iio_read_channel_processed_scale() that meant a correct result was treated as an error. adi,ad3530r - Fix powerdown mode strings for AD3531 and AD3531R. adi,ad4695 - Fix ordering so by the time device transitions to offload mode all setup transfers are done. This avoids issues with offload controllers that cannot handle normal transfers after offload has begun. adi,ad5686 - Fix wrong initialization of reference bit for single channel parts. - Fix off by one in check on input raw value adi,adis16260 - Fix division by zero triggerable from sysfs. adi,adis16550 - Fix a stack leak to userspace. amlogic,meson-adc - Fix a buffer allocation leak in an error path. bosch,bmp280 - Fix a stack leak to userspace. capella,cm3323 - Fix wrong return value rather than register value being written data->reg_conf on write. maxim,max5821 - Check correct length i2c_master_send() in max5821_sync_powerdown_mode(). mediatek,mt6359 - Fix potential uninitialized value. nuvoton,npcm_adc - Fix unbalance clk_disable_unprepare() nxp,sar-adc - Avoid a division by zero if the common clock framework is disabled. - Fix a division by zero triggerable from sysfs. - Ensure all of struct dma_slave_config is initialized. qcom,spmi-adc-gen3 - Fix an off by one that leads to an out of bounds array read. samsung,ssp_sensors - Ensure work is cancelled during remove to avoid use after free. sensiron,scd30 - Fix a division by zero triggerable from sysfs. st,lsm6dsx - Fix a stack leak to userspace. st,magn - Fix default value for data ready pin selection for devices that have no data ready pin selection. vishay,veml6070 - Close a resource leak in an error path. winsen,mhz19b - Reject over-sized serial messages from device. xilinx,xadc - Fix sequencer handling for dual MUX cases -----BEGIN PGP SIGNATURE----- iQJFBAABCgAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmoG/rkRHGppYzIzQGtl cm5lbC5vcmcACgkQVIU0mcT0FohZ9w//c9Hycnr8BDjluSDZ0hlGzv1CTO3FeHwM OgW/IXCLFK0y66xDkD08w8pwkn8Ol/wCrXoFitGinUhNc3MdK7lNtvvALiFnvU2f OP4wAvlCWjJlMb1Q8BCAtl/0W2rlb9gpm13pyBH4401IoGnf9sMdVkNortCEse3P 0uH/0UdpFoN8Ke5WvwnC22gZiCF4SaJtyShcR9INyHz70uA8WUOXVCHloWuUZEeC WrXRwBollXwa7mLiYkDRr6lle71+xQPFVi+1tTUBAFaXZtJlEA3vWMkKHX1I0ywy 6oANSvW/VQJkkZwgRUmANbqBffCL/CyOoLDC7plzELqMQXTh52Jw8Zxt+Xf/nq8u dSYVxJ4tt7RGxCYGekQdGc1bKz2HwvIXGBUigGbxzZKj6z7rrqbfHq9sXs1FTi3n PwF3rC43v3LAgtJ7yoS9U3KvZ08B/ydDkfvPlWEHXOveLWLpyVeMQf76JI9O2M7j 4baK99ngEQmrjwSHM9ZVS/cx/alLQjwegkmpsa/OOkuIHBTyECBerIAirwF52eOC kGo7fcAHazGp3te20/51FNBgilD2RIlMtwEGXsxDOcN/nnA3e0tQVpDJeCXepP8t 8AzeRsMMII5GiLkqqwg/bGpJ0qNWCqqoNse5x/LXbKXGSCCffe3xahZFIzxP5FxK y4lj71MPAS8= =Ja6W -----END PGP SIGNATURE----- Merge tag 'iio-fixes-for-7.1a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-linus Jonathan writes: iio-fixes-for-7.a IIO: 1st set of fixes for the 7.1 cycle Usual mixed bag of ancient issues and more recent. Lots of new contributors this cycle and some of that work has uncovered bugs in the code they were looking at. core,buffer - Add missing dma_fence_put() - hw-consumer - Fix a use after free in cleaning up a list. core,inkern - Fix return value handling in iio_read_channel_processed_scale() that meant a correct result was treated as an error. adi,ad3530r - Fix powerdown mode strings for AD3531 and AD3531R. adi,ad4695 - Fix ordering so by the time device transitions to offload mode all setup transfers are done. This avoids issues with offload controllers that cannot handle normal transfers after offload has begun. adi,ad5686 - Fix wrong initialization of reference bit for single channel parts. - Fix off by one in check on input raw value adi,adis16260 - Fix division by zero triggerable from sysfs. adi,adis16550 - Fix a stack leak to userspace. amlogic,meson-adc - Fix a buffer allocation leak in an error path. bosch,bmp280 - Fix a stack leak to userspace. capella,cm3323 - Fix wrong return value rather than register value being written data->reg_conf on write. maxim,max5821 - Check correct length i2c_master_send() in max5821_sync_powerdown_mode(). mediatek,mt6359 - Fix potential uninitialized value. nuvoton,npcm_adc - Fix unbalance clk_disable_unprepare() nxp,sar-adc - Avoid a division by zero if the common clock framework is disabled. - Fix a division by zero triggerable from sysfs. - Ensure all of struct dma_slave_config is initialized. qcom,spmi-adc-gen3 - Fix an off by one that leads to an out of bounds array read. samsung,ssp_sensors - Ensure work is cancelled during remove to avoid use after free. sensiron,scd30 - Fix a division by zero triggerable from sysfs. st,lsm6dsx - Fix a stack leak to userspace. st,magn - Fix default value for data ready pin selection for devices that have no data ready pin selection. vishay,veml6070 - Close a resource leak in an error path. winsen,mhz19b - Reject over-sized serial messages from device. xilinx,xadc - Fix sequencer handling for dual MUX cases * tag 'iio-fixes-for-7.1a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (31 commits) iio: adc: viperboard: Fix error handling in vprbrd_iio_read_raw iio: gyro: itg3200: fix i2c read into the wrong stack location iio: dac: ad5686: fix powerdown control on dual-channel devices iio: dac: ad5686: acquire lock when doing powerdown control iio: temperature: tsys01: fix broken PROM checksum validation iio: dac: ad3530r: Fix AD3531/AD3531R powerdown mode strings iio: buffer: hw-consumer: fix use-after-free in error path iio: dac: ad5686: fix input raw value check iio: dac: ad5686: fix ref bit initialization for single-channel parts iio: ssp_sensors: cancel delayed work_refresh on remove iio: adc: meson-saradc: fix calibration buffer leak on error iio: dac: max5821: fix return value check in powerdown sync iio: adc: mt6359: fix unchecked return value in mt6358_read_imp iio: adc: qcom-spmi-adc5-gen3: Fix off by one in adc5_gen3_get_fw_channel_data() iio: imu: adis16550: fix stack leak in trigger handler iio: imu: st_lsm6dsx: fix stack leak in tagged FIFO buffer iio: pressure: bmp280: fix stack leak in bmp580 trigger handler iio: adc: nxp-sar-adc: zero-initialize dma_slave_config iio: light: cm3323: fix reg_conf not being initialized correctly iio: magnetometer: st_magn: fix default DRDY pin selection for LIS2MDL ...
This commit is contained in:
commit
329db447f8
|
|
@ -876,14 +876,14 @@ static int ad4695_offload_buffer_postenable(struct iio_dev *indio_dev)
|
|||
if (ret)
|
||||
goto err_unoptimize_message;
|
||||
|
||||
ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
|
||||
&config);
|
||||
ret = ad4695_enter_advanced_sequencer_mode(st, num_slots);
|
||||
if (ret)
|
||||
goto err_disable_busy_output;
|
||||
|
||||
ret = ad4695_enter_advanced_sequencer_mode(st, num_slots);
|
||||
ret = spi_offload_trigger_enable(st->offload, st->offload_trigger,
|
||||
&config);
|
||||
if (ret)
|
||||
goto err_offload_trigger_disable;
|
||||
goto err_exit_conversion_mode;
|
||||
|
||||
mutex_lock(&st->cnv_pwm_lock);
|
||||
pwm_get_state(st->cnv_pwm, &state);
|
||||
|
|
@ -895,23 +895,16 @@ static int ad4695_offload_buffer_postenable(struct iio_dev *indio_dev)
|
|||
ret = pwm_apply_might_sleep(st->cnv_pwm, &state);
|
||||
mutex_unlock(&st->cnv_pwm_lock);
|
||||
if (ret)
|
||||
goto err_offload_exit_conversion_mode;
|
||||
goto err_offload_trigger_disable;
|
||||
|
||||
return 0;
|
||||
|
||||
err_offload_exit_conversion_mode:
|
||||
/*
|
||||
* We have to unwind in a different order to avoid triggering offload.
|
||||
* ad4695_exit_conversion_mode() triggers a conversion, so it has to be
|
||||
* done after spi_offload_trigger_disable().
|
||||
*/
|
||||
spi_offload_trigger_disable(st->offload, st->offload_trigger);
|
||||
ad4695_exit_conversion_mode(st);
|
||||
goto err_disable_busy_output;
|
||||
|
||||
err_offload_trigger_disable:
|
||||
spi_offload_trigger_disable(st->offload, st->offload_trigger);
|
||||
|
||||
err_exit_conversion_mode:
|
||||
ad4695_exit_conversion_mode(st);
|
||||
|
||||
err_disable_busy_output:
|
||||
regmap_clear_bits(st->regmap, AD4695_REG_GP_MODE,
|
||||
AD4695_REG_GP_MODE_BUSY_GP_EN);
|
||||
|
|
|
|||
|
|
@ -817,9 +817,11 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
|
|||
}
|
||||
|
||||
priv->tsc_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "amlogic,hhi-sysctrl");
|
||||
if (IS_ERR(priv->tsc_regmap))
|
||||
if (IS_ERR(priv->tsc_regmap)) {
|
||||
kfree(buf);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -497,6 +497,7 @@ static int mt6358_read_imp(struct mt6359_auxadc *adc_dev,
|
|||
return ret;
|
||||
|
||||
/* Read the params before stopping */
|
||||
val_v = 0;
|
||||
regmap_read(regmap, reg_adc0 + (cinfo->imp_adc_num << 1), &val_v);
|
||||
|
||||
mt6358_stop_imp_conv(adc_dev);
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ static int npcm_adc_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(info->reset))
|
||||
return PTR_ERR(info->reset);
|
||||
|
||||
info->adc_clk = devm_clk_get(&pdev->dev, NULL);
|
||||
info->adc_clk = devm_clk_get_enabled(&pdev->dev, NULL);
|
||||
if (IS_ERR(info->adc_clk)) {
|
||||
dev_warn(&pdev->dev, "ADC clock failed: can't read clk\n");
|
||||
return PTR_ERR(info->adc_clk);
|
||||
|
|
@ -244,17 +244,13 @@ static int npcm_adc_probe(struct platform_device *pdev)
|
|||
info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
ret = irq;
|
||||
goto err_disable_clk;
|
||||
}
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, npcm_adc_isr, 0,
|
||||
"NPCM_ADC", indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed requesting interrupt\n");
|
||||
goto err_disable_clk;
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
reg_con = ioread32(info->regs + NPCM_ADCCON);
|
||||
info->vref = devm_regulator_get_optional(&pdev->dev, "vref");
|
||||
|
|
@ -262,7 +258,7 @@ static int npcm_adc_probe(struct platform_device *pdev)
|
|||
ret = regulator_enable(info->vref);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Can't enable ADC reference voltage\n");
|
||||
goto err_disable_clk;
|
||||
return ret;
|
||||
}
|
||||
|
||||
iowrite32(reg_con & ~NPCM_ADCCON_REFSEL,
|
||||
|
|
@ -272,10 +268,8 @@ static int npcm_adc_probe(struct platform_device *pdev)
|
|||
* Any error which is not ENODEV indicates the regulator
|
||||
* has been specified and so is a failure case.
|
||||
*/
|
||||
if (PTR_ERR(info->vref) != -ENODEV) {
|
||||
ret = PTR_ERR(info->vref);
|
||||
goto err_disable_clk;
|
||||
}
|
||||
if (PTR_ERR(info->vref) != -ENODEV)
|
||||
return PTR_ERR(info->vref);
|
||||
|
||||
/* Use internal reference */
|
||||
iowrite32(reg_con | NPCM_ADCCON_REFSEL,
|
||||
|
|
@ -314,8 +308,6 @@ static int npcm_adc_probe(struct platform_device *pdev)
|
|||
iowrite32(reg_con & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON);
|
||||
if (!IS_ERR(info->vref))
|
||||
regulator_disable(info->vref);
|
||||
err_disable_clk:
|
||||
clk_disable_unprepare(info->adc_clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -332,7 +324,6 @@ static void npcm_adc_remove(struct platform_device *pdev)
|
|||
iowrite32(regtemp & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON);
|
||||
if (!IS_ERR(info->vref))
|
||||
regulator_disable(info->vref);
|
||||
clk_disable_unprepare(info->adc_clk);
|
||||
}
|
||||
|
||||
static struct platform_driver npcm_adc_driver = {
|
||||
|
|
|
|||
|
|
@ -198,6 +198,15 @@ static void nxp_sar_adc_irq_cfg(struct nxp_sar_adc *info, bool enable)
|
|||
writel(0, NXP_SAR_ADC_IMR(info->regs));
|
||||
}
|
||||
|
||||
static void nxp_sar_adc_wait_for(struct nxp_sar_adc *info, unsigned int cycles)
|
||||
{
|
||||
u64 rate;
|
||||
|
||||
rate = clk_get_rate(info->clk);
|
||||
if (rate)
|
||||
ndelay(div64_u64(NSEC_PER_SEC, rate * cycles));
|
||||
}
|
||||
|
||||
static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable)
|
||||
{
|
||||
u32 mcr;
|
||||
|
|
@ -221,7 +230,7 @@ static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable)
|
|||
* configuration of NCMR and the setting of NSTART.
|
||||
*/
|
||||
if (enable)
|
||||
ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk) * 3));
|
||||
nxp_sar_adc_wait_for(info, 3);
|
||||
|
||||
return pwdn;
|
||||
}
|
||||
|
|
@ -469,7 +478,7 @@ static void nxp_sar_adc_stop_conversion(struct nxp_sar_adc *info)
|
|||
* only when the capture finishes. The delay will be very
|
||||
* short, usec-ish, which is acceptable in the atomic context.
|
||||
*/
|
||||
ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk)) * 80);
|
||||
nxp_sar_adc_wait_for(info, 80);
|
||||
}
|
||||
|
||||
static int nxp_sar_adc_start_conversion(struct nxp_sar_adc *info, bool raw)
|
||||
|
|
@ -560,6 +569,9 @@ static int nxp_sar_adc_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec
|
|||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
if (val <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Configures the sample period duration in terms of the SAR
|
||||
* controller clock. The minimum acceptable value is 8.
|
||||
|
|
@ -568,7 +580,11 @@ static int nxp_sar_adc_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec
|
|||
* sampling timing which gives us the number of cycles expected.
|
||||
* The value is 8-bit wide, consequently the max value is 0xFF.
|
||||
*/
|
||||
inpsamp = clk_get_rate(info->clk) / val - NXP_SAR_ADC_CONV_TIME;
|
||||
inpsamp = clk_get_rate(info->clk) / val;
|
||||
if (inpsamp < NXP_SAR_ADC_CONV_TIME)
|
||||
return -EINVAL;
|
||||
|
||||
inpsamp -= NXP_SAR_ADC_CONV_TIME;
|
||||
nxp_sar_adc_conversion_timing_set(info, inpsamp);
|
||||
return 0;
|
||||
|
||||
|
|
@ -660,7 +676,7 @@ static void nxp_sar_adc_dma_cb(void *data)
|
|||
static int nxp_sar_adc_start_cyclic_dma(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct nxp_sar_adc *info = iio_priv(indio_dev);
|
||||
struct dma_slave_config config;
|
||||
struct dma_slave_config config = { };
|
||||
struct dma_async_tx_descriptor *desc;
|
||||
int ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -482,7 +482,7 @@ static int adc5_gen3_get_fw_channel_data(struct adc5_chip *adc,
|
|||
sid = FIELD_GET(ADC5_GEN3_VIRTUAL_SID_MASK, chan);
|
||||
chan = FIELD_GET(ADC5_GEN3_CHANNEL_MASK, chan);
|
||||
|
||||
if (chan > ADC5_MAX_CHANNEL)
|
||||
if (chan >= ADC5_MAX_CHANNEL)
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"%s invalid channel number %d\n",
|
||||
name, chan);
|
||||
|
|
|
|||
|
|
@ -70,8 +70,10 @@ static int vprbrd_iio_read_raw(struct iio_dev *iio_dev,
|
|||
VPRBRD_USB_TYPE_OUT, 0x0000, 0x0000, admsg,
|
||||
sizeof(struct vprbrd_adc_msg), VPRBRD_USB_TIMEOUT_MS);
|
||||
if (ret != sizeof(struct vprbrd_adc_msg)) {
|
||||
dev_err(&iio_dev->dev, "usb send error on adc read\n");
|
||||
mutex_unlock(&vb->lock);
|
||||
error = -EREMOTEIO;
|
||||
dev_err(&iio_dev->dev, "usb send error on adc read\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = usb_control_msg(vb->usb_dev,
|
||||
|
|
|
|||
|
|
@ -817,6 +817,7 @@ static int xadc_postdisable(struct iio_dev *indio_dev)
|
|||
{
|
||||
struct xadc *xadc = iio_priv(indio_dev);
|
||||
unsigned long scan_mask;
|
||||
int seq_mode;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
|
@ -824,6 +825,12 @@ static int xadc_postdisable(struct iio_dev *indio_dev)
|
|||
for (i = 0; i < indio_dev->num_channels; i++)
|
||||
scan_mask |= BIT(indio_dev->channels[i].scan_index);
|
||||
|
||||
/*
|
||||
* Use the correct sequencer mode for the idle state: simultaneous
|
||||
* mode for dual external mux configurations, continuous otherwise.
|
||||
*/
|
||||
seq_mode = xadc_get_seq_mode(xadc, scan_mask);
|
||||
|
||||
/* Enable all channels and calibration */
|
||||
ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(0), scan_mask & 0xffff);
|
||||
if (ret)
|
||||
|
|
@ -834,11 +841,11 @@ static int xadc_postdisable(struct iio_dev *indio_dev)
|
|||
return ret;
|
||||
|
||||
ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_SEQ_MASK,
|
||||
XADC_CONF1_SEQ_CONTINUOUS);
|
||||
seq_mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return xadc_power_adc_b(xadc, XADC_CONF1_SEQ_CONTINUOUS);
|
||||
return xadc_power_adc_b(xadc, seq_mode);
|
||||
}
|
||||
|
||||
static int xadc_preenable(struct iio_dev *indio_dev)
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ static struct hw_consumer_buffer *iio_hw_consumer_get_buffer(
|
|||
*/
|
||||
struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev)
|
||||
{
|
||||
struct hw_consumer_buffer *buf;
|
||||
struct hw_consumer_buffer *buf, *tmp;
|
||||
struct iio_hw_consumer *hwc;
|
||||
struct iio_channel *chan;
|
||||
int ret;
|
||||
|
|
@ -116,7 +116,7 @@ struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev)
|
|||
return hwc;
|
||||
|
||||
err_put_buffers:
|
||||
list_for_each_entry(buf, &hwc->buffers, head)
|
||||
list_for_each_entry_safe(buf, tmp, &hwc->buffers, head)
|
||||
iio_buffer_put(&buf->buffer);
|
||||
iio_channel_release_all(hwc->channels);
|
||||
err_free_hwc:
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ struct mhz19b_state {
|
|||
struct completion buf_ready;
|
||||
|
||||
u8 buf_idx;
|
||||
bool buf_overflow;
|
||||
|
||||
/*
|
||||
* Serdev receive buffer.
|
||||
* When data is received from the MH-Z19B,
|
||||
|
|
@ -106,6 +108,10 @@ static int mhz19b_serdev_cmd(struct iio_dev *indio_dev, int cmd, u16 arg)
|
|||
cmd_buf[8] = mhz19b_get_checksum(cmd_buf);
|
||||
|
||||
/* Write buf to uart ctrl synchronously */
|
||||
st->buf_idx = 0;
|
||||
st->buf_overflow = false;
|
||||
reinit_completion(&st->buf_ready);
|
||||
|
||||
ret = serdev_device_write(serdev, cmd_buf, MHZ19B_CMD_SIZE, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
@ -121,6 +127,9 @@ static int mhz19b_serdev_cmd(struct iio_dev *indio_dev, int cmd, u16 arg)
|
|||
if (!ret)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
if (st->buf_overflow)
|
||||
return -EMSGSIZE;
|
||||
|
||||
if (st->buf[8] != mhz19b_get_checksum(st->buf)) {
|
||||
dev_err(dev, "checksum err");
|
||||
return -EINVAL;
|
||||
|
|
@ -240,6 +249,14 @@ static size_t mhz19b_receive_buf(struct serdev_device *serdev,
|
|||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(&serdev->dev);
|
||||
struct mhz19b_state *st = iio_priv(indio_dev);
|
||||
size_t remaining = MHZ19B_CMD_SIZE - st->buf_idx;
|
||||
|
||||
if (len > remaining) {
|
||||
st->buf_idx = 0;
|
||||
st->buf_overflow = true;
|
||||
complete(&st->buf_ready);
|
||||
return len;
|
||||
}
|
||||
|
||||
memcpy(st->buf + st->buf_idx, data, len);
|
||||
st->buf_idx += len;
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ static int scd30_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const
|
|||
guard(mutex)(&state->lock);
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
if (val)
|
||||
if (val || !val2)
|
||||
return -EINVAL;
|
||||
|
||||
val = 1000000000 / val2;
|
||||
|
|
|
|||
|
|
@ -590,6 +590,7 @@ static void ssp_remove(struct spi_device *spi)
|
|||
ssp_clean_pending_list(data);
|
||||
|
||||
free_irq(data->spi->irq, data);
|
||||
cancel_delayed_work_sync(&data->work_refresh);
|
||||
|
||||
timer_delete_sync(&data->wdt_timer);
|
||||
cancel_work_sync(&data->work_wdt);
|
||||
|
|
|
|||
|
|
@ -105,6 +105,12 @@ static const char * const ad3530r_powerdown_modes[] = {
|
|||
"32kohm_to_gnd",
|
||||
};
|
||||
|
||||
static const char * const ad3531r_powerdown_modes[] = {
|
||||
"500ohm_to_gnd",
|
||||
"3.85kohm_to_gnd",
|
||||
"16kohm_to_gnd",
|
||||
};
|
||||
|
||||
static int ad3530r_get_powerdown_mode(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan)
|
||||
{
|
||||
|
|
@ -133,6 +139,13 @@ static const struct iio_enum ad3530r_powerdown_mode_enum = {
|
|||
.set = ad3530r_set_powerdown_mode,
|
||||
};
|
||||
|
||||
static const struct iio_enum ad3531r_powerdown_mode_enum = {
|
||||
.items = ad3531r_powerdown_modes,
|
||||
.num_items = ARRAY_SIZE(ad3531r_powerdown_modes),
|
||||
.get = ad3530r_get_powerdown_mode,
|
||||
.set = ad3530r_set_powerdown_mode,
|
||||
};
|
||||
|
||||
static ssize_t ad3530r_get_dac_powerdown(struct iio_dev *indio_dev,
|
||||
uintptr_t private,
|
||||
const struct iio_chan_spec *chan,
|
||||
|
|
@ -276,7 +289,20 @@ static const struct iio_chan_spec_ext_info ad3530r_ext_info[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
#define AD3530R_CHAN(_chan) \
|
||||
static const struct iio_chan_spec_ext_info ad3531r_ext_info[] = {
|
||||
{
|
||||
.name = "powerdown",
|
||||
.shared = IIO_SEPARATE,
|
||||
.read = ad3530r_get_dac_powerdown,
|
||||
.write = ad3530r_set_dac_powerdown,
|
||||
},
|
||||
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad3531r_powerdown_mode_enum),
|
||||
IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE,
|
||||
&ad3531r_powerdown_mode_enum),
|
||||
{ }
|
||||
};
|
||||
|
||||
#define AD3530R_CHAN(_chan, _ext_info) \
|
||||
{ \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.indexed = 1, \
|
||||
|
|
@ -284,25 +310,25 @@ static const struct iio_chan_spec_ext_info ad3530r_ext_info[] = {
|
|||
.output = 1, \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
||||
BIT(IIO_CHAN_INFO_SCALE), \
|
||||
.ext_info = ad3530r_ext_info, \
|
||||
.ext_info = _ext_info, \
|
||||
}
|
||||
|
||||
static const struct iio_chan_spec ad3530r_channels[] = {
|
||||
AD3530R_CHAN(0),
|
||||
AD3530R_CHAN(1),
|
||||
AD3530R_CHAN(2),
|
||||
AD3530R_CHAN(3),
|
||||
AD3530R_CHAN(4),
|
||||
AD3530R_CHAN(5),
|
||||
AD3530R_CHAN(6),
|
||||
AD3530R_CHAN(7),
|
||||
AD3530R_CHAN(0, ad3530r_ext_info),
|
||||
AD3530R_CHAN(1, ad3530r_ext_info),
|
||||
AD3530R_CHAN(2, ad3530r_ext_info),
|
||||
AD3530R_CHAN(3, ad3530r_ext_info),
|
||||
AD3530R_CHAN(4, ad3530r_ext_info),
|
||||
AD3530R_CHAN(5, ad3530r_ext_info),
|
||||
AD3530R_CHAN(6, ad3530r_ext_info),
|
||||
AD3530R_CHAN(7, ad3530r_ext_info),
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec ad3531r_channels[] = {
|
||||
AD3530R_CHAN(0),
|
||||
AD3530R_CHAN(1),
|
||||
AD3530R_CHAN(2),
|
||||
AD3530R_CHAN(3),
|
||||
AD3530R_CHAN(0, ad3531r_ext_info),
|
||||
AD3530R_CHAN(1, ad3531r_ext_info),
|
||||
AD3530R_CHAN(2, ad3531r_ext_info),
|
||||
AD3530R_CHAN(3, ad3531r_ext_info),
|
||||
};
|
||||
|
||||
static const struct ad3530r_chip_info ad3530_chip = {
|
||||
|
|
|
|||
|
|
@ -25,22 +25,37 @@ static const char * const ad5686_powerdown_modes[] = {
|
|||
"three_state"
|
||||
};
|
||||
|
||||
static inline unsigned int ad5686_pd_mask_shift(const struct iio_chan_spec *chan)
|
||||
{
|
||||
if (chan->channel == chan->address)
|
||||
return chan->channel * 2;
|
||||
|
||||
/* one-hot encoding is used in dual/quad channel devices */
|
||||
return __ffs(chan->address) * 2;
|
||||
}
|
||||
|
||||
static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan)
|
||||
{
|
||||
unsigned int shift = ad5686_pd_mask_shift(chan);
|
||||
struct ad5686_state *st = iio_priv(indio_dev);
|
||||
|
||||
return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1;
|
||||
guard(mutex)(&st->lock);
|
||||
|
||||
return ((st->pwr_down_mode >> shift) & 0x3U) - 1;
|
||||
}
|
||||
|
||||
static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan,
|
||||
unsigned int mode)
|
||||
{
|
||||
unsigned int shift = ad5686_pd_mask_shift(chan);
|
||||
struct ad5686_state *st = iio_priv(indio_dev);
|
||||
|
||||
st->pwr_down_mode &= ~(0x3 << (chan->channel * 2));
|
||||
st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2));
|
||||
guard(mutex)(&st->lock);
|
||||
|
||||
st->pwr_down_mode &= ~(0x3U << shift);
|
||||
st->pwr_down_mode |= (mode + 1) << shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -55,10 +70,12 @@ static const struct iio_enum ad5686_powerdown_mode_enum = {
|
|||
static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev,
|
||||
uintptr_t private, const struct iio_chan_spec *chan, char *buf)
|
||||
{
|
||||
unsigned int shift = ad5686_pd_mask_shift(chan);
|
||||
struct ad5686_state *st = iio_priv(indio_dev);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask &
|
||||
(0x3 << (chan->channel * 2))));
|
||||
guard(mutex)(&st->lock);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & (0x3U << shift)));
|
||||
}
|
||||
|
||||
static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
|
|
@ -77,10 +94,12 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
guard(mutex)(&st->lock);
|
||||
|
||||
if (readin)
|
||||
st->pwr_down_mask |= (0x3 << (chan->channel * 2));
|
||||
st->pwr_down_mask |= 0x3U << ad5686_pd_mask_shift(chan);
|
||||
else
|
||||
st->pwr_down_mask &= ~(0x3 << (chan->channel * 2));
|
||||
st->pwr_down_mask &= ~(0x3U << ad5686_pd_mask_shift(chan));
|
||||
|
||||
switch (st->chip_info->regmap_type) {
|
||||
case AD5310_REGMAP:
|
||||
|
|
@ -154,7 +173,7 @@ static int ad5686_write_raw(struct iio_dev *indio_dev,
|
|||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
if (val > (1 << chan->scan_type.realbits) || val < 0)
|
||||
if (val >= (1 << chan->scan_type.realbits) || val < 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&st->lock);
|
||||
|
|
@ -460,7 +479,7 @@ int ad5686_probe(struct device *dev,
|
|||
{
|
||||
struct ad5686_state *st;
|
||||
struct iio_dev *indio_dev;
|
||||
unsigned int val, ref_bit_msk;
|
||||
unsigned int val, ref_bit_msk, shift;
|
||||
bool has_external_vref;
|
||||
u8 cmd;
|
||||
int ret, i;
|
||||
|
|
@ -484,9 +503,18 @@ int ad5686_probe(struct device *dev,
|
|||
has_external_vref = ret != -ENODEV;
|
||||
st->vref_mv = has_external_vref ? ret / 1000 : st->chip_info->int_vref_mv;
|
||||
|
||||
/* Initialize masks to all ones provided the max shift (last channel) */
|
||||
shift = ad5686_pd_mask_shift(&st->chip_info->channels[st->chip_info->num_channels - 1]);
|
||||
st->pwr_down_mask = GENMASK(shift + 1, 0);
|
||||
st->pwr_down_mode = GENMASK(shift + 1, 0);
|
||||
|
||||
/* Set all the power down mode for all channels to 1K pulldown */
|
||||
for (i = 0; i < st->chip_info->num_channels; i++)
|
||||
st->pwr_down_mode |= (0x01 << (i * 2));
|
||||
for (i = 0; i < st->chip_info->num_channels; i++) {
|
||||
shift = ad5686_pd_mask_shift(&st->chip_info->channels[i]);
|
||||
st->pwr_down_mask &= ~(0x3U << shift); /* powered up state */
|
||||
st->pwr_down_mode &= ~(0x3U << shift);
|
||||
st->pwr_down_mode |= 0x01U << shift;
|
||||
}
|
||||
|
||||
indio_dev->name = name;
|
||||
indio_dev->info = &ad5686_info;
|
||||
|
|
@ -509,7 +537,7 @@ int ad5686_probe(struct device *dev,
|
|||
break;
|
||||
case AD5686_REGMAP:
|
||||
cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
|
||||
ref_bit_msk = 0;
|
||||
ref_bit_msk = AD5686_REF_BIT_MSK;
|
||||
break;
|
||||
case AD5693_REGMAP:
|
||||
cmd = AD5686_CMD_CONTROL_REG;
|
||||
|
|
@ -520,9 +548,9 @@ int ad5686_probe(struct device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
val = (has_external_vref | ref_bit_msk);
|
||||
val = has_external_vref ? ref_bit_msk : 0;
|
||||
|
||||
ret = st->write(st, cmd, 0, !!val);
|
||||
ret = st->write(st, cmd, 0, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
#define AD5310_REF_BIT_MSK BIT(8)
|
||||
#define AD5683_REF_BIT_MSK BIT(12)
|
||||
#define AD5686_REF_BIT_MSK BIT(0)
|
||||
#define AD5693_REF_BIT_MSK BIT(12)
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ static int max5821_sync_powerdown_mode(struct max5821_data *data,
|
|||
const struct iio_chan_spec *chan)
|
||||
{
|
||||
u8 outbuf[2];
|
||||
int ret;
|
||||
|
||||
outbuf[0] = MAX5821_EXTENDED_COMMAND_MODE;
|
||||
|
||||
|
|
@ -103,7 +104,13 @@ static int max5821_sync_powerdown_mode(struct max5821_data *data,
|
|||
else
|
||||
outbuf[1] |= MAX5821_EXTENDED_POWER_UP;
|
||||
|
||||
return i2c_master_send(data->client, outbuf, 2);
|
||||
ret = i2c_master_send(data->client, outbuf, sizeof(outbuf));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret != sizeof(outbuf))
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
|
|
|
|||
|
|
@ -287,6 +287,9 @@ static int adis16260_write_raw(struct iio_dev *indio_dev,
|
|||
addr = adis16260_addresses[chan->scan_index][1];
|
||||
return adis_write_reg_16(adis, addr, val);
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
if (val <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (spi_get_device_id(adis->spi)->driver_data)
|
||||
t = 256 / val;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ static int itg3200_read_all_channels(struct i2c_client *i2c, __be16 *buf)
|
|||
.addr = i2c->addr,
|
||||
.flags = i2c->flags | I2C_M_RD,
|
||||
.len = ITG3200_SCAN_ELEMENTS * sizeof(s16),
|
||||
.buf = (char *)&buf,
|
||||
.buf = (char *)buf,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -836,7 +836,7 @@ static irqreturn_t adis16550_trigger_handler(int irq, void *p)
|
|||
u16 dummy;
|
||||
bool valid;
|
||||
struct iio_poll_func *pf = p;
|
||||
__be32 data[ADIS16550_MAX_SCAN_DATA] __aligned(8);
|
||||
__be32 data[ADIS16550_MAX_SCAN_DATA] __aligned(8) = { };
|
||||
struct iio_dev *indio_dev = pf->indio_dev;
|
||||
struct adis16550 *st = iio_priv(indio_dev);
|
||||
struct adis *adis = iio_device_get_drvdata(indio_dev);
|
||||
|
|
|
|||
|
|
@ -609,7 +609,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw)
|
|||
* must be passed a buffer that is aligned to 8 bytes so
|
||||
* as to allow insertion of a naturally aligned timestamp.
|
||||
*/
|
||||
u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8);
|
||||
u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8) = { };
|
||||
u8 tag;
|
||||
bool reset_ts = false;
|
||||
int i, err, read_len;
|
||||
|
|
|
|||
|
|
@ -1909,6 +1909,7 @@ static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib,
|
|||
|
||||
dma_resv_add_fence(dmabuf->resv, &fence->base,
|
||||
dma_to_ram ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ);
|
||||
dma_fence_put(&fence->base);
|
||||
dma_resv_unlock(dmabuf->resv);
|
||||
|
||||
cookie = dma_fence_begin_signalling();
|
||||
|
|
|
|||
|
|
@ -738,7 +738,11 @@ int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return iio_multiply_value(val, scale, ret, pval, pval2);
|
||||
ret = iio_multiply_value(val, scale, ret, pval, pval2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
|
||||
if (ret < 0)
|
||||
|
|
|
|||
|
|
@ -89,15 +89,14 @@ static int cm3323_init(struct iio_dev *indio_dev)
|
|||
|
||||
/* enable sensor and set auto force mode */
|
||||
ret &= ~(CM3323_CONF_SD_BIT | CM3323_CONF_AF_BIT);
|
||||
data->reg_conf = ret;
|
||||
|
||||
ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, ret);
|
||||
ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, data->reg_conf);
|
||||
if (ret < 0) {
|
||||
dev_err(&data->client->dev, "Error writing reg_conf\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
data->reg_conf = ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,13 +245,6 @@ static const struct iio_info veml6070_info = {
|
|||
.write_raw = veml6070_write_raw,
|
||||
};
|
||||
|
||||
static void veml6070_i2c_unreg(void *p)
|
||||
{
|
||||
struct veml6070_data *data = p;
|
||||
|
||||
i2c_unregister_device(data->client2);
|
||||
}
|
||||
|
||||
static int veml6070_probe(struct i2c_client *client)
|
||||
{
|
||||
struct veml6070_data *data;
|
||||
|
|
@ -281,7 +274,8 @@ static int veml6070_probe(struct i2c_client *client)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
data->client2 = i2c_new_dummy_device(client->adapter, VEML6070_ADDR_DATA_LSB);
|
||||
data->client2 = devm_i2c_new_dummy_device(&client->dev, client->adapter,
|
||||
VEML6070_ADDR_DATA_LSB);
|
||||
if (IS_ERR(data->client2))
|
||||
return dev_err_probe(&client->dev, PTR_ERR(data->client2),
|
||||
"i2c device for second chip address failed\n");
|
||||
|
|
@ -292,10 +286,6 @@ static int veml6070_probe(struct i2c_client *client)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(&client->dev, veml6070_i2c_unreg, data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return devm_iio_device_register(&client->dev, indio_dev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -506,6 +506,11 @@ static const struct st_sensors_platform_data default_magn_pdata = {
|
|||
.drdy_int_pin = 2,
|
||||
};
|
||||
|
||||
/* LIS2MDL only supports DRDY on INT1 */
|
||||
static const struct st_sensors_platform_data alt_magn_pdata = {
|
||||
.drdy_int_pin = 1,
|
||||
};
|
||||
|
||||
static int st_magn_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *ch, int *val,
|
||||
int *val2, long mask)
|
||||
|
|
@ -628,8 +633,12 @@ int st_magn_common_probe(struct iio_dev *indio_dev)
|
|||
mdata->current_fullscale = &mdata->sensor_settings->fs.fs_avl[0];
|
||||
mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz;
|
||||
|
||||
if (!pdata)
|
||||
pdata = (struct st_sensors_platform_data *)&default_magn_pdata;
|
||||
if (!pdata) {
|
||||
if (mdata->sensor_settings->drdy_irq.int2.mask)
|
||||
pdata = (struct st_sensors_platform_data *)&default_magn_pdata;
|
||||
else
|
||||
pdata = (struct st_sensors_platform_data *)&alt_magn_pdata;
|
||||
}
|
||||
|
||||
err = st_sensors_init_sensor(indio_dev, pdata);
|
||||
if (err < 0)
|
||||
|
|
|
|||
|
|
@ -2616,7 +2616,7 @@ static irqreturn_t bmp580_trigger_handler(int irq, void *p)
|
|||
__le32 comp_temp;
|
||||
__le32 comp_press;
|
||||
aligned_s64 timestamp;
|
||||
} buffer;
|
||||
} buffer = { };
|
||||
int ret;
|
||||
|
||||
guard(mutex)(&data->lock);
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ static bool tsys01_crc_valid(u16 *n_prom)
|
|||
u8 sum = 0;
|
||||
|
||||
for (cnt = 0; cnt < TSYS01_PROM_WORDS_NB; cnt++)
|
||||
sum += ((n_prom[0] >> 8) + (n_prom[0] & 0xFF));
|
||||
sum += ((n_prom[cnt] >> 8) + (n_prom[cnt] & 0xFF));
|
||||
|
||||
return (sum == 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user