Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4aee9873 authored by Alison Schofield's avatar Alison Schofield Committed by Jonathan Cameron
Browse files

iio: light: ltr501: claim direct mode during raw writes



Driver was checking for direct mode but not locking it.  Use
claim/release helper functions to guarantee the device stays
in direct mode during all raw write operations.

Signed-off-by: default avatarAlison Schofield <amsfield22@gmail.com>
Acked-by: default avatarPeter Meerwald-Stadler <pmeerw@pmeerw.net>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 218e95e9
Loading
Loading
Loading
Loading
+51 −30
Original line number Diff line number Diff line
@@ -739,8 +739,9 @@ static int ltr501_write_raw(struct iio_dev *indio_dev,
	int i, ret, freq_val, freq_val2;
	struct ltr501_chip_info *info = data->chip_info;

	if (iio_buffer_enabled(indio_dev))
		return -EBUSY;
	ret = iio_device_claim_direct_mode(indio_dev);
	if (ret)
		return ret;

	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
@@ -749,85 +750,105 @@ static int ltr501_write_raw(struct iio_dev *indio_dev,
			i = ltr501_get_gain_index(info->als_gain,
						  info->als_gain_tbl_size,
						  val, val2);
			if (i < 0)
				return -EINVAL;
			if (i < 0) {
				ret = -EINVAL;
				break;
			}

			data->als_contr &= ~info->als_gain_mask;
			data->als_contr |= i << info->als_gain_shift;

			return regmap_write(data->regmap, LTR501_ALS_CONTR,
			ret = regmap_write(data->regmap, LTR501_ALS_CONTR,
					   data->als_contr);
			break;
		case IIO_PROXIMITY:
			i = ltr501_get_gain_index(info->ps_gain,
						  info->ps_gain_tbl_size,
						  val, val2);
			if (i < 0)
				return -EINVAL;
			if (i < 0) {
				ret = -EINVAL;
				break;
			}
			data->ps_contr &= ~LTR501_CONTR_PS_GAIN_MASK;
			data->ps_contr |= i << LTR501_CONTR_PS_GAIN_SHIFT;

			return regmap_write(data->regmap, LTR501_PS_CONTR,
			ret = regmap_write(data->regmap, LTR501_PS_CONTR,
					   data->ps_contr);
			break;
		default:
			return -EINVAL;
			ret = -EINVAL;
			break;
		}
		break;

	case IIO_CHAN_INFO_INT_TIME:
		switch (chan->type) {
		case IIO_INTENSITY:
			if (val != 0)
				return -EINVAL;
			if (val != 0) {
				ret = -EINVAL;
				break;
			}
			mutex_lock(&data->lock_als);
			i = ltr501_set_it_time(data, val2);
			ret = ltr501_set_it_time(data, val2);
			mutex_unlock(&data->lock_als);
			return i;
			break;
		default:
			return -EINVAL;
			ret = -EINVAL;
			break;
		}
		break;

	case IIO_CHAN_INFO_SAMP_FREQ:
		switch (chan->type) {
		case IIO_INTENSITY:
			ret = ltr501_als_read_samp_freq(data, &freq_val,
							&freq_val2);
			if (ret < 0)
				return ret;
				break;

			ret = ltr501_als_write_samp_freq(data, val, val2);
			if (ret < 0)
				return ret;
				break;

			/* update persistence count when changing frequency */
			ret = ltr501_write_intr_prst(data, chan->type,
						     0, data->als_period);

			if (ret < 0)
				return ltr501_als_write_samp_freq(data,
								  freq_val,
				ret = ltr501_als_write_samp_freq(data, freq_val,
								 freq_val2);
			return ret;
			break;
		case IIO_PROXIMITY:
			ret = ltr501_ps_read_samp_freq(data, &freq_val,
						       &freq_val2);
			if (ret < 0)
				return ret;
				break;

			ret = ltr501_ps_write_samp_freq(data, val, val2);
			if (ret < 0)
				return ret;
				break;

			/* update persistence count when changing frequency */
			ret = ltr501_write_intr_prst(data, chan->type,
						     0, data->ps_period);

			if (ret < 0)
				return ltr501_ps_write_samp_freq(data,
								 freq_val,
				ret = ltr501_ps_write_samp_freq(data, freq_val,
								freq_val2);
			return ret;
			break;
		default:
			return -EINVAL;
			ret = -EINVAL;
			break;
		}
		break;

	default:
		ret = -EINVAL;
		break;
	}
	return -EINVAL;

	iio_device_release_direct_mode(indio_dev);
	return ret;
}

static int ltr501_read_thresh(struct iio_dev *indio_dev,