Commit fe85261d authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'iio-fixes-for-6.17a' of...

Merge tag 'iio-fixes-for-6.17a' 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.17

Usual mixed bunch of ancient issues and relatively new ones.

adi,ad7124
- Fix channel lookup to use chan->address for indexing array.
adi,ad7173
- Stop accidentally enabling more configs than supported at one time.
adi,ad7380
- Fill in missing max_conversion_rate_hz for adaq4381-4
ams,as73211
- Fix uninitialized holes in scan data exposed to userspace.
bosch,bmp280
- Check for error when requesting optional GPIO rather than simply assuming
  success or a NULL return when no GPIO provided.
invensense,icm42600
- Change error code returned to -EBUSY on a temperature read with neither
  accelerometer nor gyroscope in use.  Reduces chance of misinterpretation
  by userspace.
kionix,sca3300
- Fix uninitialized holes in scan data exposed to userspace.
maxim,thermocouple
- Use a DMA-safe buffer for spi_read().
renesas,isl29501
- Fix ordering issue for big endian systems
renesas,rsg2l
- Fix an underflow issue around suspend/resume.
- Make sure driver data is in place before enabling runtime PM that uses
  it.
rohm,bd79124
- Add missing GPIOLIB dependency.  May rework in future to allow this to be
  optional in future but for now this is the least invasive build fix.

* tag 'iio-fixes-for-6.17a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio:
  iio: pressure: bmp280: Use IS_ERR() in bmp280_common_probe()
  iio: light: as73211: Ensure buffer holes are zeroed
  iio: adc: rzg2l_adc: Set driver data before enabling runtime PM
  iio: adc: rzg2l: Cleanup suspend/resume path
  iio: adc: ad7380: fix missing max_conversion_rate_hz on adaq4381-4
  iio: adc: bd79124: Add GPIOLIB dependency
  iio: imu: inv_icm42600: change invalid data error to -EBUSY
  iio: adc: ad7124: fix channel lookup in syscalib functions
  iio: temperature: maxim_thermocouple: use DMA-safe buffer for spi_read()
  iio: adc: ad7173: prevent scan if too many setups requested
  iio: proximity: isl29501: fix buffered read on big-endian systems
  iio: accel: sca3300: fix uninitialized iio scan data
parents b47b493d 43c0f645
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -477,7 +477,7 @@ static irqreturn_t sca3300_trigger_handler(int irq, void *p)
	struct iio_dev *indio_dev = pf->indio_dev;
	struct sca3300_data *data = iio_priv(indio_dev);
	int bit, ret, val, i = 0;
	IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX);
	IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX) = { };

	iio_for_each_active_channel(indio_dev, bit) {
		ret = sca3300_read_reg(data, indio_dev->channels[bit].address, &val);
+1 −1
Original line number Diff line number Diff line
@@ -1300,7 +1300,7 @@ config RN5T618_ADC

config ROHM_BD79124
	tristate "Rohm BD79124 ADC driver"
	depends on I2C
	depends on I2C && GPIOLIB
	select REGMAP_I2C
	select IIO_ADC_HELPER
	help
+7 −7
Original line number Diff line number Diff line
@@ -849,7 +849,7 @@ enum {
static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan_spec *chan)
{
	struct device *dev = &st->sd.spi->dev;
	struct ad7124_channel *ch = &st->channels[chan->channel];
	struct ad7124_channel *ch = &st->channels[chan->address];
	int ret;

	if (ch->syscalib_mode == AD7124_SYSCALIB_ZERO_SCALE) {
@@ -865,8 +865,8 @@ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan
		if (ret < 0)
			return ret;

		dev_dbg(dev, "offset for channel %d after zero-scale calibration: 0x%x\n",
			chan->channel, ch->cfg.calibration_offset);
		dev_dbg(dev, "offset for channel %lu after zero-scale calibration: 0x%x\n",
			chan->address, ch->cfg.calibration_offset);
	} else {
		ch->cfg.calibration_gain = st->gain_default;

@@ -880,8 +880,8 @@ static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan
		if (ret < 0)
			return ret;

		dev_dbg(dev, "gain for channel %d after full-scale calibration: 0x%x\n",
			chan->channel, ch->cfg.calibration_gain);
		dev_dbg(dev, "gain for channel %lu after full-scale calibration: 0x%x\n",
			chan->address, ch->cfg.calibration_gain);
	}

	return 0;
@@ -924,7 +924,7 @@ static int ad7124_set_syscalib_mode(struct iio_dev *indio_dev,
{
	struct ad7124_state *st = iio_priv(indio_dev);

	st->channels[chan->channel].syscalib_mode = mode;
	st->channels[chan->address].syscalib_mode = mode;

	return 0;
}
@@ -934,7 +934,7 @@ static int ad7124_get_syscalib_mode(struct iio_dev *indio_dev,
{
	struct ad7124_state *st = iio_priv(indio_dev);

	return st->channels[chan->channel].syscalib_mode;
	return st->channels[chan->address].syscalib_mode;
}

static const struct iio_enum ad7124_syscalib_mode_enum = {
+75 −12
Original line number Diff line number Diff line
@@ -200,7 +200,7 @@ struct ad7173_channel_config {
	/*
	 * Following fields are used to compare equality. If you
	 * make adaptations in it, you most likely also have to adapt
	 * ad7173_find_live_config(), too.
	 * ad7173_is_setup_equal(), too.
	 */
	struct_group(config_props,
		bool bipolar;
@@ -561,12 +561,19 @@ static void ad7173_reset_usage_cnts(struct ad7173_state *st)
	st->config_usage_counter = 0;
}

static struct ad7173_channel_config *
ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg)
/**
 * ad7173_is_setup_equal - Compare two channel setups
 * @cfg1: First channel configuration
 * @cfg2: Second channel configuration
 *
 * Compares all configuration options that affect the registers connected to
 * SETUP_SEL, namely CONFIGx, FILTERx, GAINx and OFFSETx.
 *
 * Returns: true if the setups are identical, false otherwise
 */
static bool ad7173_is_setup_equal(const struct ad7173_channel_config *cfg1,
				  const struct ad7173_channel_config *cfg2)
{
	struct ad7173_channel_config *cfg_aux;
	int i;

	/*
	 * This is just to make sure that the comparison is adapted after
	 * struct ad7173_channel_config was changed.
@@ -579,14 +586,22 @@ ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *c
				     u8 ref_sel;
			     }));

	return cfg1->bipolar == cfg2->bipolar &&
	       cfg1->input_buf == cfg2->input_buf &&
	       cfg1->odr == cfg2->odr &&
	       cfg1->ref_sel == cfg2->ref_sel;
}

static struct ad7173_channel_config *
ad7173_find_live_config(struct ad7173_state *st, struct ad7173_channel_config *cfg)
{
	struct ad7173_channel_config *cfg_aux;
	int i;

	for (i = 0; i < st->num_channels; i++) {
		cfg_aux = &st->channels[i].cfg;

		if (cfg_aux->live &&
		    cfg->bipolar == cfg_aux->bipolar &&
		    cfg->input_buf == cfg_aux->input_buf &&
		    cfg->odr == cfg_aux->odr &&
		    cfg->ref_sel == cfg_aux->ref_sel)
		if (cfg_aux->live && ad7173_is_setup_equal(cfg, cfg_aux))
			return cfg_aux;
	}
	return NULL;
@@ -1228,7 +1243,7 @@ static int ad7173_update_scan_mode(struct iio_dev *indio_dev,
				   const unsigned long *scan_mask)
{
	struct ad7173_state *st = iio_priv(indio_dev);
	int i, ret;
	int i, j, k, ret;

	for (i = 0; i < indio_dev->num_channels; i++) {
		if (test_bit(i, scan_mask))
@@ -1239,6 +1254,54 @@ static int ad7173_update_scan_mode(struct iio_dev *indio_dev,
			return ret;
	}

	/*
	 * On some chips, there are more channels that setups, so if there were
	 * more unique setups requested than the number of available slots,
	 * ad7173_set_channel() will have written over some of the slots. We
	 * can detect this by making sure each assigned cfg_slot matches the
	 * requested configuration. If it doesn't, we know that the slot was
	 * overwritten by a different channel.
	 */
	for_each_set_bit(i, scan_mask, indio_dev->num_channels) {
		const struct ad7173_channel_config *cfg1, *cfg2;

		cfg1 = &st->channels[i].cfg;

		for_each_set_bit(j, scan_mask, indio_dev->num_channels) {
			cfg2 = &st->channels[j].cfg;

			/*
			 * Only compare configs that are assigned to the same
			 * SETUP_SEL slot and don't compare channel to itself.
			 */
			if (i == j || cfg1->cfg_slot != cfg2->cfg_slot)
				continue;

			/*
			 * If we find two different configs trying to use the
			 * same SETUP_SEL slot, then we know that the that we
			 * have too many unique configurations requested for
			 * the available slots and at least one was overwritten.
			 */
			if (!ad7173_is_setup_equal(cfg1, cfg2)) {
				/*
				 * At this point, there isn't a way to tell
				 * which setups are actually programmed in the
				 * ADC anymore, so we could read them back to
				 * see, but it is simpler to just turn off all
				 * of the live flags so that everything gets
				 * reprogramed on the next attempt read a sample.
				 */
				for (k = 0; k < st->num_channels; k++)
					st->channels[k].cfg.live = false;

				dev_err(&st->sd.spi->dev,
					"Too many unique channel configurations requested for scan\n");
				return -EINVAL;
			}
		}
	}

	return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -873,6 +873,7 @@ static const struct ad7380_chip_info adaq4381_4_chip_info = {
	.has_hardware_gain = true,
	.available_scan_masks = ad7380_4_channel_scan_masks,
	.timing_specs = &ad7380_4_timing,
	.max_conversion_rate_hz = 4 * MEGA,
};

static const struct spi_offload_config ad7380_offload_config = {
Loading