Commit 55ecaf17 authored by Linus Walleij's avatar Linus Walleij Committed by Jonathan Cameron
Browse files

iio: magnetometer: ak8974: Break out measurement



This breaks out the measurement code to its own function
so we can handle this without swirling it up with the
big switch() statement inside ak8974_read_raw().

Keep a local s16 helper variable for the signed value
coming out of the measurement before assigning it to the
integer *val. The local variable makes the code easier
to read and the compiler will optimize it if possible.

Cc: Nick Reitemeyer <nick.reitemeyer@web.de>
Cc: Stephan Gerhold <stephan@gerhold.net>
Reviewed-by: default avatarMichał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent b67959eb
Loading
Loading
Loading
Loading
+40 −26
Original line number Diff line number Diff line
@@ -554,41 +554,32 @@ static int ak8974_detect(struct ak8974 *ak8974)
	return 0;
}

static int ak8974_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2,
			   long mask)
static int ak8974_measure_channel(struct ak8974 *ak8974, unsigned long address,
				  int *val)
{
	struct ak8974 *ak8974 = iio_priv(indio_dev);
	__le16 hw_values[3];
	int ret = -EINVAL;
	int ret;

	pm_runtime_get_sync(&ak8974->i2c->dev);
	mutex_lock(&ak8974->lock);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (chan->address > 2) {
			dev_err(&ak8974->i2c->dev, "faulty channel address\n");
			ret = -EIO;
			goto out_unlock;
		}
	/*
	 * We read all axes and discard all but one, for optimized
	 * reading, use the triggered buffer.
	 */
	ret = ak8974_trigmeas(ak8974);
	if (ret)
		goto out_unlock;
	ret = ak8974_getresult(ak8974, hw_values);
	if (ret)
		goto out_unlock;

	/*
		 * We read all axes and discard all but one, for optimized
		 * reading, use the triggered buffer.
	 * This explicit cast to (s16) is necessary as the measurement
	 * is done in 2's complement with positive and negative values.
	 * The follwing assignment to *val will then convert the signed
	 * s16 value to a signed int value.
	 */
		*val = (s16)le16_to_cpu(hw_values[chan->address]);

		ret = IIO_VAL_INT;
	}

	*val = (s16)le16_to_cpu(hw_values[address]);
out_unlock:
	mutex_unlock(&ak8974->lock);
	pm_runtime_mark_last_busy(&ak8974->i2c->dev);
@@ -597,6 +588,29 @@ static int ak8974_read_raw(struct iio_dev *indio_dev,
	return ret;
}

static int ak8974_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2,
			   long mask)
{
	struct ak8974 *ak8974 = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (chan->address > 2) {
			dev_err(&ak8974->i2c->dev, "faulty channel address\n");
			return -EIO;
		}
		ret = ak8974_measure_channel(ak8974, chan->address, val);
		if (ret)
			return ret;
		return IIO_VAL_INT;
	}

	return -EINVAL;
}

static void ak8974_fill_buffer(struct iio_dev *indio_dev)
{
	struct ak8974 *ak8974 = iio_priv(indio_dev);