mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
iio: adc: ltc2378: Enable triggered buffer data capture
Enable users to run triggered data captures with LTC2378 and similar ADCs. Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com> Reviewed-by: David Lechner <dlechner@baylibre.com> Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com> Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
This commit is contained in:
parent
b587716e8c
commit
54355e3b18
|
|
@ -952,6 +952,7 @@ config LTC2378
|
|||
select IIO_BUFFER
|
||||
select IIO_BUFFER_DMA
|
||||
select IIO_BUFFER_DMAENGINE
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
select SPI_OFFLOAD
|
||||
select SPI_OFFLOAD_TRIGGER_PWM
|
||||
help
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* Author: Marcelo Schmitt <marcelo.schmitt@analog.com>
|
||||
*/
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
|
|
@ -32,6 +33,8 @@
|
|||
#include <linux/iio/buffer.h>
|
||||
#include <linux/iio/buffer-dmaengine.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/triggered_buffer.h>
|
||||
#include <linux/iio/trigger_consumer.h>
|
||||
#include <linux/iio/types.h>
|
||||
|
||||
#define LTC2378_TDSDOBUSYL_NS 5
|
||||
|
|
@ -104,7 +107,7 @@
|
|||
|
||||
struct ltc2378_chip_info {
|
||||
const char *name;
|
||||
struct iio_chan_spec chan;
|
||||
struct iio_chan_spec chan[2]; /* 1 physical chan + 1 timestamp chan */
|
||||
struct iio_chan_spec offload_chan;
|
||||
unsigned int max_sample_rate_Hz;
|
||||
unsigned int tconv_ns;
|
||||
|
|
@ -144,7 +147,7 @@ struct ltc2378_state {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2364_16_chip_info = {
|
||||
.name = "ltc2364-16",
|
||||
.chan = LTC2378_PSEUDO_DIFF_CHANNEL(16),
|
||||
.chan = { LTC2378_PSEUDO_DIFF_CHANNEL(16), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_PSEUDO_DIFF_CHANNEL(16),
|
||||
.max_sample_rate_Hz = 250 * HZ_PER_KHZ,
|
||||
.tconv_ns = 3000,
|
||||
|
|
@ -152,7 +155,7 @@ static const struct ltc2378_chip_info ltc2364_16_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2364_18_chip_info = {
|
||||
.name = "ltc2364-18",
|
||||
.chan = LTC2378_PSEUDO_DIFF_CHANNEL(18),
|
||||
.chan = { LTC2378_PSEUDO_DIFF_CHANNEL(18), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_PSEUDO_DIFF_CHANNEL(18),
|
||||
.max_sample_rate_Hz = 250 * HZ_PER_KHZ,
|
||||
.tconv_ns = 3000,
|
||||
|
|
@ -160,7 +163,7 @@ static const struct ltc2378_chip_info ltc2364_18_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2367_16_chip_info = {
|
||||
.name = "ltc2367-16",
|
||||
.chan = LTC2378_PSEUDO_DIFF_CHANNEL(16),
|
||||
.chan = { LTC2378_PSEUDO_DIFF_CHANNEL(16), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_PSEUDO_DIFF_CHANNEL(16),
|
||||
.max_sample_rate_Hz = 500 * HZ_PER_KHZ,
|
||||
.tconv_ns = 1500,
|
||||
|
|
@ -168,7 +171,7 @@ static const struct ltc2378_chip_info ltc2367_16_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2367_18_chip_info = {
|
||||
.name = "ltc2367-18",
|
||||
.chan = LTC2378_PSEUDO_DIFF_CHANNEL(18),
|
||||
.chan = { LTC2378_PSEUDO_DIFF_CHANNEL(18), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_PSEUDO_DIFF_CHANNEL(18),
|
||||
.max_sample_rate_Hz = 500 * HZ_PER_KHZ,
|
||||
.tconv_ns = 1500,
|
||||
|
|
@ -176,7 +179,7 @@ static const struct ltc2378_chip_info ltc2367_18_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2368_16_chip_info = {
|
||||
.name = "ltc2368-16",
|
||||
.chan = LTC2378_PSEUDO_DIFF_CHANNEL(16),
|
||||
.chan = { LTC2378_PSEUDO_DIFF_CHANNEL(16), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_PSEUDO_DIFF_CHANNEL(16),
|
||||
.max_sample_rate_Hz = 1 * HZ_PER_MHZ,
|
||||
.tconv_ns = 527,
|
||||
|
|
@ -184,7 +187,7 @@ static const struct ltc2378_chip_info ltc2368_16_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2368_18_chip_info = {
|
||||
.name = "ltc2368-18",
|
||||
.chan = LTC2378_PSEUDO_DIFF_CHANNEL(18),
|
||||
.chan = { LTC2378_PSEUDO_DIFF_CHANNEL(18), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_PSEUDO_DIFF_CHANNEL(18),
|
||||
.max_sample_rate_Hz = 1 * HZ_PER_MHZ,
|
||||
.tconv_ns = 527,
|
||||
|
|
@ -192,7 +195,7 @@ static const struct ltc2378_chip_info ltc2368_18_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2369_18_chip_info = {
|
||||
.name = "ltc2369-18",
|
||||
.chan = LTC2378_PSEUDO_DIFF_CHANNEL(18),
|
||||
.chan = { LTC2378_PSEUDO_DIFF_CHANNEL(18), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_PSEUDO_DIFF_CHANNEL(18),
|
||||
.max_sample_rate_Hz = 1600 * HZ_PER_KHZ,
|
||||
.tconv_ns = 412,
|
||||
|
|
@ -200,7 +203,7 @@ static const struct ltc2378_chip_info ltc2369_18_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2370_16_chip_info = {
|
||||
.name = "ltc2370-16",
|
||||
.chan = LTC2378_PSEUDO_DIFF_CHANNEL(16),
|
||||
.chan = { LTC2378_PSEUDO_DIFF_CHANNEL(16), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_PSEUDO_DIFF_CHANNEL(16),
|
||||
.max_sample_rate_Hz = 2 * HZ_PER_MHZ,
|
||||
.tconv_ns = 322,
|
||||
|
|
@ -208,7 +211,7 @@ static const struct ltc2378_chip_info ltc2370_16_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2376_16_chip_info = {
|
||||
.name = "ltc2376-16",
|
||||
.chan = LTC2378_DIFF_CHANNEL(16),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(16), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(16),
|
||||
.max_sample_rate_Hz = 250 * HZ_PER_KHZ,
|
||||
.tconv_ns = 3000,
|
||||
|
|
@ -216,7 +219,7 @@ static const struct ltc2378_chip_info ltc2376_16_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2376_18_chip_info = {
|
||||
.name = "ltc2376-18",
|
||||
.chan = LTC2378_DIFF_CHANNEL(18),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(18), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(18),
|
||||
.max_sample_rate_Hz = 250 * HZ_PER_KHZ,
|
||||
.tconv_ns = 3000,
|
||||
|
|
@ -224,7 +227,7 @@ static const struct ltc2378_chip_info ltc2376_18_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2376_20_chip_info = {
|
||||
.name = "ltc2376-20",
|
||||
.chan = LTC2378_DIFF_CHANNEL(20),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(20), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(20),
|
||||
.max_sample_rate_Hz = 250 * HZ_PER_KHZ,
|
||||
.tconv_ns = 3000,
|
||||
|
|
@ -232,7 +235,7 @@ static const struct ltc2378_chip_info ltc2376_20_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2377_16_chip_info = {
|
||||
.name = "ltc2377-16",
|
||||
.chan = LTC2378_DIFF_CHANNEL(16),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(16), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(16),
|
||||
.max_sample_rate_Hz = 500 * HZ_PER_KHZ,
|
||||
.tconv_ns = 1500,
|
||||
|
|
@ -240,7 +243,7 @@ static const struct ltc2378_chip_info ltc2377_16_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2377_18_chip_info = {
|
||||
.name = "ltc2377-18",
|
||||
.chan = LTC2378_DIFF_CHANNEL(18),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(18), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(18),
|
||||
.max_sample_rate_Hz = 500 * HZ_PER_KHZ,
|
||||
.tconv_ns = 1500,
|
||||
|
|
@ -248,7 +251,7 @@ static const struct ltc2378_chip_info ltc2377_18_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2377_20_chip_info = {
|
||||
.name = "ltc2377-20",
|
||||
.chan = LTC2378_DIFF_CHANNEL(20),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(20), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(20),
|
||||
.max_sample_rate_Hz = 500 * HZ_PER_KHZ,
|
||||
.tconv_ns = 1500,
|
||||
|
|
@ -256,7 +259,7 @@ static const struct ltc2378_chip_info ltc2377_20_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2378_16_chip_info = {
|
||||
.name = "ltc2378-16",
|
||||
.chan = LTC2378_DIFF_CHANNEL(16),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(16), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(16),
|
||||
.max_sample_rate_Hz = 1 * HZ_PER_MHZ,
|
||||
.tconv_ns = 527,
|
||||
|
|
@ -264,7 +267,7 @@ static const struct ltc2378_chip_info ltc2378_16_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2378_18_chip_info = {
|
||||
.name = "ltc2378-18",
|
||||
.chan = LTC2378_DIFF_CHANNEL(18),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(18), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(18),
|
||||
.max_sample_rate_Hz = 1 * HZ_PER_MHZ,
|
||||
.tconv_ns = 527,
|
||||
|
|
@ -272,7 +275,7 @@ static const struct ltc2378_chip_info ltc2378_18_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2378_20_chip_info = {
|
||||
.name = "ltc2378-20",
|
||||
.chan = LTC2378_DIFF_CHANNEL(20),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(20), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(20),
|
||||
.max_sample_rate_Hz = 1 * HZ_PER_MHZ,
|
||||
.tconv_ns = 675,
|
||||
|
|
@ -280,7 +283,7 @@ static const struct ltc2378_chip_info ltc2378_20_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2379_18_chip_info = {
|
||||
.name = "ltc2379-18",
|
||||
.chan = LTC2378_DIFF_CHANNEL(18),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(18), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(18),
|
||||
.max_sample_rate_Hz = 1600 * HZ_PER_KHZ,
|
||||
.tconv_ns = 412,
|
||||
|
|
@ -288,7 +291,7 @@ static const struct ltc2378_chip_info ltc2379_18_chip_info = {
|
|||
|
||||
static const struct ltc2378_chip_info ltc2380_16_chip_info = {
|
||||
.name = "ltc2380-16",
|
||||
.chan = LTC2378_DIFF_CHANNEL(16),
|
||||
.chan = { LTC2378_DIFF_CHANNEL(16), IIO_CHAN_SOFT_TIMESTAMP(1) },
|
||||
.offload_chan = LTC2378_OFFLOAD_DIFF_CHANNEL(16),
|
||||
.max_sample_rate_Hz = 2 * HZ_PER_MHZ,
|
||||
.tconv_ns = 322,
|
||||
|
|
@ -307,6 +310,25 @@ static int ltc2378_convert_and_acquire(struct ltc2378_state *st)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static irqreturn_t ltc2378_trigger_handler(int irq, void *p)
|
||||
{
|
||||
struct iio_poll_func *pf = p;
|
||||
struct iio_dev *indio_dev = pf->indio_dev;
|
||||
struct ltc2378_state *st = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
ret = ltc2378_convert_and_acquire(st);
|
||||
if (ret < 0)
|
||||
goto err_out;
|
||||
|
||||
iio_push_to_buffers_with_ts(indio_dev, &st->scan, sizeof(st->scan),
|
||||
pf->timestamp);
|
||||
|
||||
err_out:
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int ltc2378_channel_single_read(const struct iio_chan_spec *chan,
|
||||
struct ltc2378_state *st, int *val)
|
||||
{
|
||||
|
|
@ -671,8 +693,15 @@ static int ltc2378_probe(struct spi_device *spi)
|
|||
/* Fall back to low speed usage when no SPI offload is available. */
|
||||
if (ret == -ENODEV) {
|
||||
indio_dev->info = <c2378_iio_info;
|
||||
indio_dev->channels = &st->info->chan;
|
||||
indio_dev->num_channels = 1;
|
||||
indio_dev->channels = st->info->chan;
|
||||
indio_dev->num_channels = ARRAY_SIZE(st->info->chan);
|
||||
|
||||
ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
|
||||
iio_pollfunc_store_time,
|
||||
ltc2378_trigger_handler,
|
||||
NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (ret) {
|
||||
return dev_err_probe(dev, ret, "failed to get offload\n");
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user