IIO: 1st set of fixes for the 7.2 cycle

Usual mixed bag of recently introduced issues and much older ones.
 
 core
 - Ensure kfifo is reset before fd is allocated avoiding concurrent use of
   fifo with reset.
 multiple drivers
 - Fix up missing Kconfig dependencies.
 hid-sensors
 - Add support for multibyte read as necessary precursor to...
 - Fix stale or zero output when reading raw values for quaternions.
 adi,adis
 - Add IRQF_NO_THREAD to ensure interrupt is not pushed to the software
   interrupt chip used for trigger demux in the IIO core from a thread.
 bosch,bmc150
 - Hardening against device returning a reserved out of range value for
   how many entries are in the FIFO.
 bosch,bmi160
 - Add IRQF_NO_THREAD to ensure interrupt is not pushed to the software
   interrupt chip used for trigger demux in the IIO core from a thread.
 dynaimage,al3010
 - Fix wrong scale for highest gain_range due to too many digits in the
   micro part (val2).
 freescale,mpl3115
 - Fix unbalanced runtime pm on error in read_raw().
 invensens,icm42600
 - Avoid wrong divisor for fifo timestamps when using the watermark
   interrupt.
 - Fix timestamp accuracy loss due to excessive divisor for calculations.
 kionix,kxsd9
 - Fix unbalanced runtime pm on an error in write_raw().
 microchip,mcp37feb02
 - Fix an uninitialized reference voltage value for particular DT config.
 melix,mlx90635
 - Build on basis of right Kconfig symbol.
 nxp,lpc32xx
 - Ensure completion initialized before requesting irq. Hardening against
   spurious IRQ.
 nxp,saradc
 - Fix a delay calculation.
 sharp,gp2ap0002
 - Fix unbalanced runtime pm on error in read_raw().
 st,lsm6dsx
 - Fix an issue seen in wild where an unplanned CPU reset can leave the
   device on the wrong register page, thus leaving the driver wedged.
 st,st_sensors library
 - Make sure to handle a device that provides data as big endian correctly.
 st,spear
 - Ensure completion initialized before requesting irq. Hardening against
   spurious IRQ.
 taos,tsl2591
 - Don't eat return from devm_request_threaded_irq() as that breaks
   deferred probing.
 ti,ads1119
 - Fix a pm reference count leak in an error path.
 ti,ads124s08
 - Handle gpio look up errors correctly.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmpPApkRHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0Foi03BAArG+wqqRwlf/P3gDROAYYuIS3llKXlFRP
 PHtYdW6m27v542eJk+Gz/AmF/MCEZX9jYxD4QPbMdijn7vxKbEp77ZyTbJn74A7A
 gF+AHZDg0yzVxNhv7K78np/nyocLkYfEH8tIUBu1tceWxpOFeT8M4eu01i+Ow0fZ
 diSD3iyvv7Dx94u6h9ozllJf2X7+QxmPWq+c9aICK8xM+c5nOp6eZ8WE20Qot3B4
 oN20NtoeoLL2j3YYV2dz0YM+s5MsBIiFybyjwUbtwaxTRU+MqFErMJSikfbr/gIW
 JrTQBq4RApXSZp8tP96Y6m9O7lSKeP380elYdAMFZiA9k3o3uSGcb4PxJbDxNDAA
 Lemcj73kFpvFpLjApt5wbEn8xJi/jApTAae0JLKSXDvulB9WfuOyBsQpe7qRi50X
 ASpxOfzdnoLWzTYYQzqcZVSxBzw/5lei8UiquhqNGuAEoUucnQfrdPjmLZdK1cVy
 rADf+d9ENTcanNAA8uqj7B2NGBLk6X0TnPYEYY9Oxp6hDFszMHySS4Q7c2Bfm5sH
 KswF1Wtmc362c0fhGz2CnS676KFJlika7HTKJKXJ1RUkRa9+GgkMp37i0MEreWqx
 XvwBZHl3NV25j0r0VOlT6DXLht5cQJxgWVIpAyXXP0OR/UlivYsBAkJbFTlDTr5i
 cqCgmCKrXwM=
 =Eph0
 -----END PGP SIGNATURE-----

Merge tag 'iio-fixes-for-7.2a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-linus

Jonathan writes:

IIO: 1st set of fixes for the 7.2 cycle

Usual mixed bag of recently introduced issues and much older ones.

core
- Ensure kfifo is reset before fd is allocated avoiding concurrent use of
  fifo with reset.
multiple drivers
- Fix up missing Kconfig dependencies.
hid-sensors
- Add support for multibyte read as necessary precursor to...
- Fix stale or zero output when reading raw values for quaternions.
adi,adis
- Add IRQF_NO_THREAD to ensure interrupt is not pushed to the software
  interrupt chip used for trigger demux in the IIO core from a thread.
bosch,bmc150
- Hardening against device returning a reserved out of range value for
  how many entries are in the FIFO.
bosch,bmi160
- Add IRQF_NO_THREAD to ensure interrupt is not pushed to the software
  interrupt chip used for trigger demux in the IIO core from a thread.
dynaimage,al3010
- Fix wrong scale for highest gain_range due to too many digits in the
  micro part (val2).
freescale,mpl3115
- Fix unbalanced runtime pm on error in read_raw().
invensens,icm42600
- Avoid wrong divisor for fifo timestamps when using the watermark
  interrupt.
- Fix timestamp accuracy loss due to excessive divisor for calculations.
kionix,kxsd9
- Fix unbalanced runtime pm on an error in write_raw().
microchip,mcp37feb02
- Fix an uninitialized reference voltage value for particular DT config.
melix,mlx90635
- Build on basis of right Kconfig symbol.
nxp,lpc32xx
- Ensure completion initialized before requesting irq. Hardening against
  spurious IRQ.
nxp,saradc
- Fix a delay calculation.
sharp,gp2ap0002
- Fix unbalanced runtime pm on error in read_raw().
st,lsm6dsx
- Fix an issue seen in wild where an unplanned CPU reset can leave the
  device on the wrong register page, thus leaving the driver wedged.
st,st_sensors library
- Make sure to handle a device that provides data as big endian correctly.
st,spear
- Ensure completion initialized before requesting irq. Hardening against
  spurious IRQ.
taos,tsl2591
- Don't eat return from devm_request_threaded_irq() as that breaks
  deferred probing.
ti,ads1119
- Fix a pm reference count leak in an error path.
ti,ads124s08
- Handle gpio look up errors correctly.

* tag 'iio-fixes-for-7.2a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (28 commits)
  iio: event: Fix event FIFO reset race
  iio: imu: inv_icm42600: fix timestamp clock period by using lower value
  iio: light: al3010: fix incorrect scale for the highest gain range
  iio: adc: nxp-sar-adc: Fix the delay calculation in nxp_sar_adc_wait_for()
  iio: light: tsl2591: return actual error from probe IRQ failure
  iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading
  iio: imu: st_lsm6dsx: deselect shub page before reading whoami
  iio: adc: ad7779: add missing 'select IIO_TRIGGERED_BUFFER' to Kconfig
  iio: adc: ad4130: add missing `select IIO_TRIGGERED_BUFFER` to Kconfig
  iio: adc: ti-ads124s08: Return reset GPIO lookup errors
  iio: temperature: Build mlx90635 with CONFIG_MLX90635
  iio: light: al3320a: add missing REGMAP_I2C to Kconfig
  iio: light: al3010: add missing REGMAP_I2C to Kconfig
  iio: light: al3000a: add missing REGMAP_I2C to Kconfig
  iio: common: st_sensors: honour channel endianness in read_axis_data
  iio: imu: bmi160: add IRQF_NO_THREAD to data-ready trigger IRQ
  iio: imu: adis: add IRQF_NO_THREAD to non-FIFO trigger IRQ
  iio: hid-sensor-rotation: Fix stale or zero output when reading raw values
  HID: sensor-hub: Add sensor_hub_input_attr_read_values() for multi-byte reads
  iio: adc: spear: Initialize completion before requesting IRQ
  ...
This commit is contained in:
Greg Kroah-Hartman 2026-07-09 07:44:06 +02:00
commit 3585cfd456
27 changed files with 238 additions and 62 deletions

View File

@ -286,6 +286,54 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
}
EXPORT_SYMBOL_GPL(sensor_hub_get_feature);
int sensor_hub_input_attr_read_values(struct hid_sensor_hub_device *hsdev,
u32 usage_id, u32 attr_usage_id,
u32 report_id,
enum sensor_hub_read_flags flag,
u32 buffer_size, u8 *buffer)
{
struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
struct hid_report *report;
unsigned long flags;
long cycles;
int ret;
report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT);
if (!report)
return -EINVAL;
mutex_lock(hsdev->mutex_ptr);
if (flag == SENSOR_HUB_SYNC) {
memset(&hsdev->pending, 0, sizeof(hsdev->pending));
init_completion(&hsdev->pending.ready);
hsdev->pending.usage_id = usage_id;
hsdev->pending.attr_usage_id = attr_usage_id;
hsdev->pending.max_raw_size = buffer_size;
hsdev->pending.raw_data = buffer;
spin_lock_irqsave(&data->lock, flags);
hsdev->pending.status = true;
spin_unlock_irqrestore(&data->lock, flags);
}
mutex_lock(&data->mutex);
hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT);
mutex_unlock(&data->mutex);
ret = 0;
if (flag == SENSOR_HUB_SYNC) {
cycles = wait_for_completion_interruptible_timeout(&hsdev->pending.ready,
HZ * 5);
if (cycles == 0)
ret = -ETIMEDOUT;
else if (cycles < 0)
ret = cycles;
hsdev->pending.status = false;
}
mutex_unlock(hsdev->mutex_ptr);
return ret;
}
EXPORT_SYMBOL_GPL(sensor_hub_input_attr_read_values);
int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
u32 usage_id,
@ -478,6 +526,8 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
struct hid_collection *collection = NULL;
void *priv = NULL;
struct hid_sensor_hub_device *hsdev = NULL;
u32 copy_size;
u32 avail;
hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n",
report->id, size, report->type);
@ -518,12 +568,27 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
hsdev->pending.attr_usage_id ==
report->field[i]->logical)) {
hid_dbg(hdev, "data was pending ...\n");
hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC);
if (hsdev->pending.raw_data)
hsdev->pending.raw_size = sz;
else
hsdev->pending.raw_size = 0;
complete(&hsdev->pending.ready);
if (hsdev->pending.max_raw_size) {
if (hsdev->pending.index < hsdev->pending.max_raw_size) {
avail = hsdev->pending.max_raw_size - hsdev->pending.index;
copy_size = clamp(sz, 0U, avail);
memcpy(hsdev->pending.raw_data + hsdev->pending.index,
ptr, copy_size);
hsdev->pending.index += copy_size;
if (hsdev->pending.index >= hsdev->pending.max_raw_size) {
hsdev->pending.raw_size = hsdev->pending.index;
complete(&hsdev->pending.ready);
}
}
} else {
hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC);
if (hsdev->pending.raw_data)
hsdev->pending.raw_size = sz;
else
hsdev->pending.raw_size = 0;
complete(&hsdev->pending.ready);
}
}
if (callback->capture_sample) {
if (report->field[i]->logical)

View File

@ -991,6 +991,8 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
if (samples && count > samples)
count = samples;
count = min_t(u8, count, BMC150_ACCEL_FIFO_LENGTH);
ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
if (ret)
return ret;

View File

@ -147,8 +147,9 @@ static int kxsd9_write_raw(struct iio_dev *indio_dev,
if (mask == IIO_CHAN_INFO_SCALE) {
/* Check no integer component */
if (val)
return -EINVAL;
ret = kxsd9_write_scale(indio_dev, val2);
ret = -EINVAL;
else
ret = kxsd9_write_scale(indio_dev, val2);
}
pm_runtime_put_autosuspend(st->dev);

View File

@ -108,6 +108,7 @@ config AD4130
depends on SPI
depends on GPIOLIB
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select IIO_KFIFO_BUF
select REGMAP_SPI
depends on COMMON_CLK
@ -328,6 +329,7 @@ config AD7298
config AD7380
tristate "Analog Devices AD7380 ADC driver"
depends on SPI_MASTER
select REGMAP
select SPI_OFFLOAD
select IIO_BUFFER
select IIO_BUFFER_DMAENGINE
@ -452,6 +454,7 @@ config AD7779
depends on SPI
select CRC8
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select IIO_BACKEND
help
Say yes here to build support for Analog Devices AD777X family

View File

@ -179,6 +179,8 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
init_completion(&st->completion);
retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
LPC32XXAD_NAME, st);
if (retval < 0) {
@ -197,8 +199,6 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, iodev);
init_completion(&st->completion);
iodev->name = LPC32XXAD_NAME;
iodev->info = &lpc32xx_adc_iio_info;
iodev->modes = INDIO_DIRECT_MODE;

View File

@ -198,13 +198,13 @@ 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)
static void nxp_sar_adc_wait_for(struct nxp_sar_adc *info, u64 cycles)
{
u64 rate;
rate = clk_get_rate(info->clk);
if (rate)
ndelay(div64_u64(NSEC_PER_SEC, rate * cycles));
ndelay(div64_u64(NSEC_PER_SEC * cycles, rate));
}
static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable)

View File

@ -283,6 +283,7 @@ static int spear_adc_probe(struct platform_device *pdev)
st = iio_priv(indio_dev);
st->dev = dev;
init_completion(&st->completion);
mutex_init(&st->lock);
/*
@ -329,8 +330,6 @@ static int spear_adc_probe(struct platform_device *pdev)
spear_adc_configure(st);
init_completion(&st->completion);
indio_dev->name = SPEAR_ADC_MOD_NAME;
indio_dev->info = &spear_adc_info;
indio_dev->modes = INDIO_DIRECT_MODE;

View File

@ -459,7 +459,11 @@ static int ads1119_triggered_buffer_preenable(struct iio_dev *indio_dev)
if (ret)
return ret;
return i2c_smbus_write_byte(st->client, ADS1119_CMD_START_SYNC);
ret = i2c_smbus_write_byte(st->client, ADS1119_CMD_START_SYNC);
if (ret)
pm_runtime_put_autosuspend(dev);
return ret;
}
static int ads1119_triggered_buffer_postdisable(struct iio_dev *indio_dev)

View File

@ -321,7 +321,8 @@ static int ads124s_probe(struct spi_device *spi)
ads124s_priv->reset_gpio = devm_gpiod_get_optional(&spi->dev,
"reset", GPIOD_OUT_LOW);
if (IS_ERR(ads124s_priv->reset_gpio))
dev_info(&spi->dev, "Reset GPIO not defined\n");
return dev_err_probe(&spi->dev, PTR_ERR(ads124s_priv->reset_gpio),
"Failed to get reset GPIO\n");
ads124s_priv->chip_info = &ads124s_chip_info_tbl[spi_id->driver_data];

View File

@ -498,6 +498,7 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
u8 *outdata;
struct st_sensor_data *sdata = iio_priv(indio_dev);
unsigned int byte_for_channel;
u32 tmp;
byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits +
ch->scan_type.shift, 8);
@ -508,12 +509,22 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
if (err < 0)
return err;
if (byte_for_channel == 1)
*data = (s8)*outdata;
else if (byte_for_channel == 2)
*data = (s16)get_unaligned_le16(outdata);
else if (byte_for_channel == 3)
*data = (s32)sign_extend32(get_unaligned_le24(outdata), 23);
if (byte_for_channel == 1) {
tmp = *outdata;
} else if (byte_for_channel == 2) {
if (ch->scan_type.endianness == IIO_BE)
tmp = get_unaligned_be16(outdata);
else
tmp = get_unaligned_le16(outdata);
} else if (byte_for_channel == 3) {
if (ch->scan_type.endianness == IIO_BE)
tmp = get_unaligned_be24(outdata);
else
tmp = get_unaligned_le24(outdata);
} else {
return -EINVAL;
}
*data = sign_extend32(tmp, BYTES_TO_BITS(byte_for_channel) - 1);
return 0;
}

View File

@ -1136,26 +1136,33 @@ static int mcp47feb02_probe(struct i2c_client *client)
vdd_uV = ret;
ret = devm_regulator_get_enable_read_voltage(dev, "vref");
if (ret > 0) {
vref_uV = ret;
if (device_property_present(dev, "vref-supply")) {
vref_uV = devm_regulator_get_enable_read_voltage(dev, "vref");
if (vref_uV < 0)
return vref_uV;
if (vref_uV == 0)
return dev_err_probe(dev, -EINVAL, "Vref is 0 uV.\n");
data->use_vref = true;
} else {
vref_uV = 0;
dev_dbg(dev, "using internal band gap as voltage reference.\n");
dev_dbg(dev, "Vref is unavailable.\n");
dev_dbg(dev, "Using internal band gap as voltage reference.\n");
}
if (chip_features->have_ext_vref1) {
ret = devm_regulator_get_enable_read_voltage(dev, "vref1");
if (ret > 0) {
vref1_uV = ret;
data->use_vref1 = true;
} else {
vref1_uV = 0;
dev_dbg(dev, "using internal band gap as voltage reference 1.\n");
dev_dbg(dev, "Vref1 is unavailable.\n");
}
if (chip_features->have_ext_vref1 &&
device_property_present(dev, "vref1-supply")) {
vref1_uV = devm_regulator_get_enable_read_voltage(dev, "vref1");
if (vref1_uV < 0)
return vref1_uV;
if (vref1_uV == 0)
return dev_err_probe(dev, -EINVAL, "Vref1 is 0 uV.\n");
data->use_vref1 = true;
} else {
vref1_uV = 0;
dev_dbg(dev, "Using internal band gap as voltage reference 1.\n");
}
ret = mcp47feb02_init_ctrl_regs(data);

View File

@ -94,7 +94,7 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
else
ret = devm_request_irq(&adis->spi->dev, adis->spi->irq,
&iio_trigger_generic_data_rdy_poll,
adis->irq_flag,
adis->irq_flag | IRQF_NO_THREAD,
indio_dev->name,
adis->trig);
if (ret)

View File

@ -788,7 +788,8 @@ int bmi160_probe_trigger(struct iio_dev *indio_dev, int irq, u32 irq_type)
ret = devm_request_irq(&indio_dev->dev, irq,
&iio_trigger_generic_data_rdy_poll,
irq_type, "bmi160", data->trig);
irq_type | IRQF_NO_THREAD,
"bmi160", data->trig);
if (ret)
return ret;

View File

@ -1170,10 +1170,10 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st)
accel_st->filter = INV_ICM42600_FILTER_AVG_16X;
/*
* clock period is 32kHz (31250ns)
* clock period is 8kHz (125000ns)
* jitter is +/- 2% (20 per mille)
*/
ts_chip.clock_period = 31250;
ts_chip.clock_period = 125000;
ts_chip.jitter = 20;
ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
inv_sensors_timestamp_init(&accel_st->ts, &ts_chip);

View File

@ -248,6 +248,7 @@ int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st)
/* compute watermark value in bytes */
wm_size = watermark * packet_size;
st->fifo.watermark.value = watermark;
/* changing FIFO watermark requires to turn off watermark interrupt */
ret = regmap_update_bits_check(st->map, INV_ICM42600_REG_INT_SOURCE0,
@ -454,11 +455,10 @@ int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st,
st->fifo.nb.accel = 0;
st->fifo.nb.total = 0;
/* compute maximum FIFO read size */
/* compute maximum FIFO read size (watermark for max = 0 interrupt case) */
if (max == 0)
max_count = sizeof(st->fifo.data);
else
max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
max = st->fifo.watermark.value;
max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
/* read FIFO count value */
raw_fifo_count = (__be16 *)st->buffer;
@ -574,6 +574,7 @@ int inv_icm42600_buffer_init(struct inv_icm42600_state *st)
st->fifo.watermark.eff_gyro = 1;
st->fifo.watermark.eff_accel = 1;
st->fifo.watermark.value = 1;
/*
* Default FIFO configuration (bits 7 to 5)

View File

@ -34,6 +34,7 @@ struct inv_icm42600_fifo {
unsigned int accel;
unsigned int eff_gyro;
unsigned int eff_accel;
unsigned int value;
} watermark;
size_t count;
struct {

View File

@ -755,10 +755,10 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st)
}
/*
* clock period is 32kHz (31250ns)
* clock period is 8kHz (125000ns)
* jitter is +/- 2% (20 per mille)
*/
ts_chip.clock_period = 31250;
ts_chip.clock_period = 125000;
ts_chip.jitter = 20;
ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
inv_sensors_timestamp_init(&gyro_st->ts, &ts_chip);

View File

@ -1712,6 +1712,26 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
return -ENODEV;
}
hw->settings = &st_lsm6dsx_sensor_settings[i];
if (hw->settings->shub_settings.page_mux.addr) {
/*
* If the IMU has the shub page selected on init, for example
* after a CPU watchdog reset while the page is selected, the
* regular register space is shadowed. While the regular
* register space is shadowed, the registers needed for
* initializing the IMU are not available.
*
* Unconditionally clear the shub page selection to ensure
* normal register access.
*/
err = st_lsm6dsx_set_page(hw, false);
if (err < 0) {
dev_err(hw->dev, "failed to clear shub page\n");
return err;
}
}
err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
if (err < 0) {
dev_err(hw->dev, "failed to read whoami register\n");
@ -1724,7 +1744,6 @@ static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
}
*name = st_lsm6dsx_sensor_settings[i].id[j].name;
hw->settings = &st_lsm6dsx_sensor_settings[i];
return 0;
}

View File

@ -207,6 +207,8 @@ static int iio_event_getfd(struct iio_dev *indio_dev)
goto unlock;
}
kfifo_reset_out(&ev_int->det_events);
iio_device_get(indio_dev);
fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,
@ -214,10 +216,7 @@ static int iio_event_getfd(struct iio_dev *indio_dev)
if (fd < 0) {
clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
iio_device_put(indio_dev);
} else {
kfifo_reset_out(&ev_int->det_events);
}
unlock:
mutex_unlock(&iio_dev_opaque->mlock);
return fd;

View File

@ -45,6 +45,7 @@ config ADUX1020
config AL3000A
tristate "AL3000a ambient light sensor"
select REGMAP_I2C
depends on I2C
help
Say Y here if you want to build a driver for the Dyna Image AL3000a
@ -55,6 +56,7 @@ config AL3000A
config AL3010
tristate "AL3010 ambient light sensor"
select REGMAP_I2C
depends on I2C
help
Say Y here if you want to build a driver for the Dyna Image AL3010
@ -65,6 +67,7 @@ config AL3010
config AL3320A
tristate "AL3320A ambient light sensor"
select REGMAP_I2C
depends on I2C
help
Say Y here if you want to build a driver for the Dyna Image AL3320A

View File

@ -42,7 +42,7 @@ enum al3xxxx_range {
};
static const int al3010_scales[][2] = {
{0, 1187200}, {0, 296800}, {0, 74200}, {0, 18600}
{ 1, 187200 }, { 0, 296800 }, { 0, 74200 }, { 0, 18600 },
};
static const struct regmap_config al3010_regmap_config = {

View File

@ -258,7 +258,7 @@ static int gp2ap002_read_raw(struct iio_dev *indio_dev,
case IIO_LIGHT:
ret = gp2ap002_get_lux(gp2ap002);
if (ret < 0)
return ret;
goto out;
*val = ret;
ret = IIO_VAL_INT;
goto out;

View File

@ -1070,10 +1070,8 @@ static int tsl2591_probe(struct i2c_client *client)
NULL, tsl2591_event_handler,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"tsl2591_irq", indio_dev);
if (ret) {
dev_err_probe(&client->dev, ret, "IRQ request error\n");
return -EINVAL;
}
if (ret)
return ret;
indio_dev->info = &tsl2591_info;
} else {
indio_dev->info = &tsl2591_info_no_irq;

View File

@ -86,6 +86,13 @@ static int dev_rot_read_raw(struct iio_dev *indio_dev,
long mask)
{
struct dev_rot_state *rot_state = iio_priv(indio_dev);
struct hid_sensor_hub_device *hsdev = rot_state->common_attributes.hsdev;
struct hid_sensor_hub_attribute_info *info = &rot_state->quaternion;
u32 usage_id = HID_USAGE_SENSOR_ORIENT_QUATERNION;
union {
s16 val16[4];
s32 val32[4];
} raw_buf;
int ret_type;
int i;
@ -95,8 +102,37 @@ static int dev_rot_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (size >= 4) {
for (i = 0; i < 4; ++i)
vals[i] = rot_state->scan.sampled_vals[i];
if (info->size <= 0 || info->size > sizeof(raw_buf))
return -EINVAL;
hid_sensor_power_state(&rot_state->common_attributes, true);
ret_type = sensor_hub_input_attr_read_values(hsdev,
hsdev->usage,
usage_id,
info->report_id,
SENSOR_HUB_SYNC,
info->size,
(u8 *)&raw_buf);
hid_sensor_power_state(&rot_state->common_attributes, false);
if (ret_type < 0)
return ret_type;
switch (info->size) {
case sizeof(raw_buf.val16):
for (i = 0; i < ARRAY_SIZE(raw_buf.val16); i++)
vals[i] = raw_buf.val16[i];
break;
case sizeof(raw_buf.val32):
for (i = 0; i < ARRAY_SIZE(raw_buf.val32); i++)
vals[i] = raw_buf.val32[i];
break;
default:
return -EINVAL;
}
ret_type = IIO_VAL_INT_MULTIPLE;
*val_len = 4;
} else

View File

@ -106,18 +106,18 @@ static int mpl115_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_PROCESSED:
pm_runtime_get_sync(data->dev);
ret = mpl115_comp_pressure(data, val, val2);
pm_runtime_put_autosuspend(data->dev);
if (ret < 0)
return ret;
pm_runtime_put_autosuspend(data->dev);
return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_RAW:
pm_runtime_get_sync(data->dev);
/* temperature -5.35 C / LSB, 472 LSB is 25 C */
ret = mpl115_read_temp(data);
pm_runtime_put_autosuspend(data->dev);
if (ret < 0)
return ret;
pm_runtime_put_autosuspend(data->dev);
*val = ret >> 6;
return IIO_VAL_INT;

View File

@ -13,7 +13,7 @@ obj-$(CONFIG_MAX31865) += max31865.o
obj-$(CONFIG_MCP9600) += mcp9600.o
obj-$(CONFIG_MLX90614) += mlx90614.o
obj-$(CONFIG_MLX90632) += mlx90632.o
obj-$(CONFIG_MLX90632) += mlx90635.o
obj-$(CONFIG_MLX90635) += mlx90635.o
obj-$(CONFIG_TMP006) += tmp006.o
obj-$(CONFIG_TMP007) += tmp007.o
obj-$(CONFIG_TMP117) += tmp117.o

View File

@ -43,6 +43,8 @@ struct hid_sensor_hub_attribute_info {
* @attr_usage_id: Usage Id of a field, e.g. X-axis for a gyro.
* @raw_size: Response size for a read request.
* @raw_data: Place holder for received response.
* @index: Current write index into raw_data for multi-byte reads.
* @max_raw_size: Total buffer size for multi-byte reads; 0 for single-value reads.
*/
struct sensor_hub_pending {
bool status;
@ -51,6 +53,8 @@ struct sensor_hub_pending {
u32 attr_usage_id;
int raw_size;
u8 *raw_data;
u32 index;
u32 max_raw_size;
};
/**
@ -183,6 +187,27 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
bool is_signed
);
/**
* sensor_hub_input_attr_read_values() - Synchronous multi-byte read request
* @hsdev: Hub device instance.
* @usage_id: Attribute usage id of parent physical device as per spec
* @attr_usage_id: Attribute usage id as per spec
* @report_id: Report id to look for
* @flag: Synchronous or asynchronous read
* @buffer_size: Size of the buffer in bytes
* @buffer: Buffer to store the read data
*
* Issues a synchronous or asynchronous read request for an input attribute,
* accumulating data into the provided buffer until it is full.
* Return: 0 on success, -ETIMEDOUT if the device did not respond, or a
* negative error code.
*/
int sensor_hub_input_attr_read_values(struct hid_sensor_hub_device *hsdev,
u32 usage_id, u32 attr_usage_id,
u32 report_id,
enum sensor_hub_read_flags flag,
u32 buffer_size, u8 *buffer);
/**
* sensor_hub_set_feature() - Feature set request
* @hsdev: Hub device instance.