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: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
Linus Walleij 2020-04-20 22:40:21 +02:00 коммит произвёл Jonathan Cameron
Родитель b67959eba4
Коммит 55ecaf1717
1 изменённых файлов: 40 добавлений и 26 удалений

Просмотреть файл

@ -554,47 +554,61 @@ static int ak8974_detect(struct ak8974 *ak8974)
return 0;
}
static int ak8974_measure_channel(struct ak8974 *ak8974, unsigned long address,
int *val)
{
__le16 hw_values[3];
int ret;
pm_runtime_get_sync(&ak8974->i2c->dev);
mutex_lock(&ak8974->lock);
/*
* 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;
/*
* 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[address]);
out_unlock:
mutex_unlock(&ak8974->lock);
pm_runtime_mark_last_busy(&ak8974->i2c->dev);
pm_runtime_put_autosuspend(&ak8974->i2c->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);
__le16 hw_values[3];
int ret = -EINVAL;
pm_runtime_get_sync(&ak8974->i2c->dev);
mutex_lock(&ak8974->lock);
int ret;
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;
return -EIO;
}
ret = ak8974_trigmeas(ak8974);
ret = ak8974_measure_channel(ak8974, chan->address, val);
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.
*/
*val = (s16)le16_to_cpu(hw_values[chan->address]);
ret = IIO_VAL_INT;
return ret;
return IIO_VAL_INT;
}
out_unlock:
mutex_unlock(&ak8974->lock);
pm_runtime_mark_last_busy(&ak8974->i2c->dev);
pm_runtime_put_autosuspend(&ak8974->i2c->dev);
return ret;
return -EINVAL;
}
static void ak8974_fill_buffer(struct iio_dev *indio_dev)