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, ...@@ -84,6 +84,7 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
const struct ad7606_bus_ops *bops); const struct ad7606_bus_ops *bops);
int ad7606_remove(struct iio_dev *indio_dev, int irq); int ad7606_remove(struct iio_dev *indio_dev, int irq);
int ad7606_reset(struct ad7606_state *st); int ad7606_reset(struct ad7606_state *st);
int ad7606_read_samples(struct ad7606_state *st);
enum ad7606_supported_device_ids { enum ad7606_supported_device_ids {
ID_AD7606_8, ID_AD7606_8,
......
...@@ -36,39 +36,53 @@ int ad7606_reset(struct ad7606_state *st) ...@@ -36,39 +36,53 @@ int ad7606_reset(struct ad7606_state *st)
return -ENODEV; return -ENODEV;
} }
static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch) int ad7606_read_samples(struct ad7606_state *st)
{ {
struct ad7606_state *st = iio_priv(indio_dev); unsigned int num = st->chip_info->num_channels;
u16 *data = st->data;
int ret; int ret;
st->done = false; /*
gpio_set_value(st->pdata->gpio_convst, 1); * 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
ret = wait_event_interruptible(st->wq_data_avail, st->done); * to check that the incoming data is correctly aligned. During normal
if (ret) * operation the data should never become unaligned, but some glitch or
goto error_ret; * 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)) { if (gpio_is_valid(st->pdata->gpio_frstdata)) {
ret = st->bops->read_block(st->dev, 1, st->data); ret = st->bops->read_block(st->dev, 1, data);
if (ret) if (ret)
goto error_ret; return ret;
if (!gpio_get_value(st->pdata->gpio_frstdata)) { if (!gpio_get_value(st->pdata->gpio_frstdata)) {
/* This should never happen */
ad7606_reset(st); ad7606_reset(st);
ret = -EIO; return -EIO;
goto error_ret;
} }
ret = st->bops->read_block(st->dev,
st->chip_info->num_channels - 1, &st->data[1]); data++;
if (ret) num--;
goto error_ret; }
} else {
ret = st->bops->read_block(st->dev, return st->bops->read_block(st->dev, num, data);
st->chip_info->num_channels, st->data); }
static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch)
{
struct ad7606_state *st = iio_priv(indio_dev);
int ret;
st->done = false;
gpio_set_value(st->pdata->gpio_convst, 1);
ret = wait_event_interruptible(st->wq_data_avail, st->done);
if (ret) if (ret)
goto error_ret; goto error_ret;
}
ret = ad7606_read_samples(st);
if (ret == 0)
ret = st->data[ch]; ret = st->data[ch];
error_ret: error_ret:
......
...@@ -48,33 +48,11 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) ...@@ -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); struct iio_dev *indio_dev = iio_priv_to_dev(st);
int ret; int ret;
if (gpio_is_valid(st->pdata->gpio_frstdata)) { ret = ad7606_read_samples(st);
ret = st->bops->read_block(st->dev, 1, st->data); if (ret == 0)
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;
}
iio_push_to_buffers_with_timestamp(indio_dev, st->data, iio_push_to_buffers_with_timestamp(indio_dev, st->data,
iio_get_time_ns(indio_dev)); iio_get_time_ns(indio_dev));
done:
gpio_set_value(st->pdata->gpio_convst, 0); gpio_set_value(st->pdata->gpio_convst, 0);
iio_trigger_notify_done(indio_dev->trig); 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