Commit 91b7334b authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Jonathan Cameron

staging:iio:ad7606: Factor out common code between periodic and one-shot capture

Both the periodic buffer based and one-shot sysfs based capture methods
share a large portion of their code. Factor this out into a common helper
function.

Also provide a comment that better explains in more detail what is going on
in the capture function.
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent f915f7aa
......@@ -84,6 +84,7 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
const struct ad7606_bus_ops *bops);
int ad7606_remove(struct iio_dev *indio_dev, int irq);
int ad7606_reset(struct ad7606_state *st);
int ad7606_read_samples(struct ad7606_state *st);
enum ad7606_supported_device_ids {
ID_AD7606_8,
......
......@@ -36,6 +36,39 @@ int ad7606_reset(struct ad7606_state *st)
return -ENODEV;
}
int ad7606_read_samples(struct ad7606_state *st)
{
unsigned int num = st->chip_info->num_channels;
u16 *data = st->data;
int ret;
/*
* The frstdata signal is set to high while and after reading the sample
* of the first channel and low for all other channels. This can be used
* to check that the incoming data is correctly aligned. During normal
* operation the data should never become unaligned, but some glitch or
* electrostatic discharge might cause an extra read or clock cycle.
* Monitoring the frstdata signal allows to recover from such failure
* situations.
*/
if (gpio_is_valid(st->pdata->gpio_frstdata)) {
ret = st->bops->read_block(st->dev, 1, data);
if (ret)
return ret;
if (!gpio_get_value(st->pdata->gpio_frstdata)) {
ad7606_reset(st);
return -EIO;
}
data++;
num--;
}
return st->bops->read_block(st->dev, num, data);
}
static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch)
{
struct ad7606_state *st = iio_priv(indio_dev);
......@@ -48,28 +81,9 @@ static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch)
if (ret)
goto error_ret;
if (gpio_is_valid(st->pdata->gpio_frstdata)) {
ret = st->bops->read_block(st->dev, 1, st->data);
if (ret)
goto error_ret;
if (!gpio_get_value(st->pdata->gpio_frstdata)) {
/* This should never happen */
ad7606_reset(st);
ret = -EIO;
goto error_ret;
}
ret = st->bops->read_block(st->dev,
st->chip_info->num_channels - 1, &st->data[1]);
if (ret)
goto error_ret;
} else {
ret = st->bops->read_block(st->dev,
st->chip_info->num_channels, st->data);
if (ret)
goto error_ret;
}
ret = st->data[ch];
ret = ad7606_read_samples(st);
if (ret == 0)
ret = st->data[ch];
error_ret:
gpio_set_value(st->pdata->gpio_convst, 0);
......
......@@ -48,33 +48,11 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
struct iio_dev *indio_dev = iio_priv_to_dev(st);
int ret;
if (gpio_is_valid(st->pdata->gpio_frstdata)) {
ret = st->bops->read_block(st->dev, 1, st->data);
if (ret)
goto done;
if (!gpio_get_value(st->pdata->gpio_frstdata)) {
/* This should never happen. However
* some signal glitch caused by bad PCB desgin or
* electrostatic discharge, could cause an extra read
* or clock. This allows recovery.
*/
ad7606_reset(st);
goto done;
}
ret = st->bops->read_block(st->dev,
st->chip_info->num_channels - 1, st->data + 1);
if (ret)
goto done;
} else {
ret = st->bops->read_block(st->dev,
st->chip_info->num_channels, st->data);
if (ret)
goto done;
}
ret = ad7606_read_samples(st);
if (ret == 0)
iio_push_to_buffers_with_timestamp(indio_dev, st->data,
iio_get_time_ns(indio_dev));
iio_push_to_buffers_with_timestamp(indio_dev, st->data,
iio_get_time_ns(indio_dev));
done:
gpio_set_value(st->pdata->gpio_convst, 0);
iio_trigger_notify_done(indio_dev->trig);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment