Commit 045020e7 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-3.8d' of...

Merge tag 'iio-for-3.8d' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

IIO cleanups and fixes from Jonathan:

"4th set of IIO driver updates and new functionality for the 3.8 cycle.

2 drivers going through final cleanup and moving out of staging.

Addition to the core of support for multiple buffers from a single
datastream.  This functionality is core in allowing multiple users
of interrupt driven data streams from the devices.  First user
will shortly be an input bridge driver.  This has been in review
/ revision for over a year resulting in a far cleaner result.
Much of the work had been in precursor patches. Here we just
add the buffer set tear up and down support + switch to multiple
buffer pushing in the drivers (a one line change in all users).
Thanks to those who have tested / reviewed this set."
parents fa7952bf 168c9d95
...@@ -20,6 +20,12 @@ config IIO_BUFFER ...@@ -20,6 +20,12 @@ config IIO_BUFFER
if IIO_BUFFER if IIO_BUFFER
config IIO_BUFFER_CB
boolean "IIO callback buffer used for push in-kernel interfaces"
help
Should be selected by any drivers that do-inkernel push
usage. That is, those where the data is pushed to the consumer.
config IIO_KFIFO_BUF config IIO_KFIFO_BUF
select IIO_TRIGGER select IIO_TRIGGER
tristate "Industrial I/O buffering based on kfifo" tristate "Industrial I/O buffering based on kfifo"
......
...@@ -6,6 +6,7 @@ obj-$(CONFIG_IIO) += industrialio.o ...@@ -6,6 +6,7 @@ obj-$(CONFIG_IIO) += industrialio.o
industrialio-y := industrialio-core.o industrialio-event.o inkern.o industrialio-y := industrialio-core.o industrialio-event.o inkern.o
industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o
industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o
industrialio-$(CONFIG_IIO_BUFFER_CB) += buffer_cb.o
obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o
obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o
......
...@@ -197,21 +197,8 @@ static const struct iio_info accel_3d_info = { ...@@ -197,21 +197,8 @@ static const struct iio_info accel_3d_info = {
/* Function to push data to buffer */ /* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
{ {
struct iio_buffer *buffer = indio_dev->buffer;
int datum_sz;
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
if (!buffer) { iio_push_to_buffers(indio_dev, (u8 *)data);
dev_err(&indio_dev->dev, "Buffer == NULL\n");
return;
}
datum_sz = buffer->access->get_bytes_per_datum(buffer);
if (len > datum_sz) {
dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
datum_sz);
return;
}
iio_push_to_buffer(buffer, (u8 *)data);
} }
/* Callback handler to send event after all samples are received and captured */ /* Callback handler to send event after all samples are received and captured */
......
...@@ -45,6 +45,19 @@ config AD7476 ...@@ -45,6 +45,19 @@ config AD7476
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called ad7476. module will be called ad7476.
config AD7887
tristate "Analog Devices AD7887 ADC driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Analog Devices
AD7887 SPI analog to digital converter (ADC).
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
module will be called ad7887.
config AT91_ADC config AT91_ADC
tristate "Atmel AT91 ADC" tristate "Atmel AT91 ADC"
depends on ARCH_AT91 depends on ARCH_AT91
...@@ -60,4 +73,22 @@ config LP8788_ADC ...@@ -60,4 +73,22 @@ config LP8788_ADC
help help
Say yes here to build support for TI LP8788 ADC. Say yes here to build support for TI LP8788 ADC.
config MAX1363
tristate "Maxim max1363 ADC driver"
depends on I2C
select IIO_TRIGGER
select MAX1363_RING_BUFFER
select IIO_BUFFER
select IIO_KFIFO_BUF
help
Say yes here to build support for many Maxim i2c analog to digital
converters (ADC). (max1361, max1362, max1363, max1364, max1036,
max1037, max1038, max1039, max1136, max1136, max1137, max1138,
max1139, max1236, max1237, max11238, max1239, max11600, max11601,
max11602, max11603, max11604, max11605, max11606, max11607,
max11608, max11609, max11610, max11611, max11612, max11613,
max11614, max11615, max11616, max11617, max11644, max11645,
max11646, max11647) Provides direct access via sysfs and buffered
data via the iio dev interface.
endmenu endmenu
...@@ -6,5 +6,7 @@ obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o ...@@ -6,5 +6,7 @@ obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o
obj-$(CONFIG_AD7266) += ad7266.o obj-$(CONFIG_AD7266) += ad7266.o
obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7476) += ad7476.o
obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AD7791) += ad7791.o
obj-$(CONFIG_AD7887) += ad7887.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o obj-$(CONFIG_AT91_ADC) += at91_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_MAX1363) += max1363.o
...@@ -91,7 +91,6 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p) ...@@ -91,7 +91,6 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
{ {
struct iio_poll_func *pf = p; struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev; struct iio_dev *indio_dev = pf->indio_dev;
struct iio_buffer *buffer = indio_dev->buffer;
struct ad7266_state *st = iio_priv(indio_dev); struct ad7266_state *st = iio_priv(indio_dev);
int ret; int ret;
...@@ -99,7 +98,7 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p) ...@@ -99,7 +98,7 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
if (ret == 0) { if (ret == 0) {
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
((s64 *)st->data)[1] = pf->timestamp; ((s64 *)st->data)[1] = pf->timestamp;
iio_push_to_buffer(buffer, (u8 *)st->data); iio_push_to_buffers(indio_dev, (u8 *)st->data);
} }
iio_trigger_notify_done(indio_dev->trig); iio_trigger_notify_done(indio_dev->trig);
......
...@@ -76,7 +76,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) ...@@ -76,7 +76,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
((s64 *)st->data)[1] = time_ns; ((s64 *)st->data)[1] = time_ns;
iio_push_to_buffer(indio_dev->buffer, st->data); iio_push_to_buffers(indio_dev, st->data);
done: done:
iio_trigger_notify_done(indio_dev->trig); iio_trigger_notify_done(indio_dev->trig);
......
...@@ -14,13 +14,139 @@ ...@@ -14,13 +14,139 @@
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h> #include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include "ad7887.h" #include <linux/platform_data/ad7887.h>
#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */
#define AD7887_DUAL (1 << 4) /* dual-channel mode */
#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */
#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */
#define AD7887_PM_MODE1 (0) /* CS based shutdown */
#define AD7887_PM_MODE2 (1) /* full on */
#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */
#define AD7887_PM_MODE4 (3) /* standby mode */
enum ad7887_channels {
AD7887_CH0,
AD7887_CH0_CH1,
AD7887_CH1,
};
#define RES_MASK(bits) ((1 << (bits)) - 1)
/**
* struct ad7887_chip_info - chip specifc information
* @int_vref_mv: the internal reference voltage
* @channel: channel specification
*/
struct ad7887_chip_info {
u16 int_vref_mv;
struct iio_chan_spec channel[3];
};
struct ad7887_state {
struct spi_device *spi;
const struct ad7887_chip_info *chip_info;
struct regulator *reg;
struct spi_transfer xfer[4];
struct spi_message msg[3];
struct spi_message *ring_msg;
unsigned char tx_cmd_buf[4];
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
* Buffer needs to be large enough to hold two 16 bit samples and a
* 64 bit aligned 64 bit timestamp.
*/
unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)]
____cacheline_aligned;
};
enum ad7887_supported_device_ids {
ID_AD7887
};
static int ad7887_ring_preenable(struct iio_dev *indio_dev)
{
struct ad7887_state *st = iio_priv(indio_dev);
int ret;
ret = iio_sw_buffer_preenable(indio_dev);
if (ret < 0)
return ret;
/* We know this is a single long so can 'cheat' */
switch (*indio_dev->active_scan_mask) {
case (1 << 0):
st->ring_msg = &st->msg[AD7887_CH0];
break;
case (1 << 1):
st->ring_msg = &st->msg[AD7887_CH1];
/* Dummy read: push CH1 setting down to hardware */
spi_sync(st->spi, st->ring_msg);
break;
case ((1 << 1) | (1 << 0)):
st->ring_msg = &st->msg[AD7887_CH0_CH1];
break;
}
return 0;
}
static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
{
struct ad7887_state *st = iio_priv(indio_dev);
/* dummy read: restore default CH0 settin */
return spi_sync(st->spi, &st->msg[AD7887_CH0]);
}
/**
* ad7887_trigger_handler() bh of trigger launched polling to ring buffer
*
* Currently there is no option in this driver to disable the saving of
* timestamps within the ring.
**/
static irqreturn_t ad7887_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7887_state *st = iio_priv(indio_dev);
s64 time_ns;
int b_sent;
b_sent = spi_sync(st->spi, st->ring_msg);
if (b_sent)
goto done;
time_ns = iio_get_time_ns();
if (indio_dev->scan_timestamp)
memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
iio_push_to_buffers(indio_dev, st->data);
done:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = {
.preenable = &ad7887_ring_preenable,
.postenable = &iio_triggered_buffer_postenable,
.predisable = &iio_triggered_buffer_predisable,
.postdisable = &ad7887_ring_postdisable,
};
static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch) static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch)
{ {
...@@ -39,7 +165,6 @@ static int ad7887_read_raw(struct iio_dev *indio_dev, ...@@ -39,7 +165,6 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
{ {
int ret; int ret;
struct ad7887_state *st = iio_priv(indio_dev); struct ad7887_state *st = iio_priv(indio_dev);
unsigned int scale_uv;
switch (m) { switch (m) {
case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_RAW:
...@@ -52,15 +177,22 @@ static int ad7887_read_raw(struct iio_dev *indio_dev, ...@@ -52,15 +177,22 @@ static int ad7887_read_raw(struct iio_dev *indio_dev,
if (ret < 0) if (ret < 0)
return ret; return ret;
*val = (ret >> st->chip_info->channel[0].scan_type.shift) & *val = ret >> chan->scan_type.shift;
RES_MASK(st->chip_info->channel[0].scan_type.realbits); *val &= RES_MASK(chan->scan_type.realbits);
return IIO_VAL_INT; return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE: case IIO_CHAN_INFO_SCALE:
scale_uv = (st->int_vref_mv * 1000) if (st->reg) {
>> st->chip_info->channel[0].scan_type.realbits; *val = regulator_get_voltage(st->reg);
*val = scale_uv/1000; if (*val < 0)
*val2 = (scale_uv%1000)*1000; return *val;
return IIO_VAL_INT_PLUS_MICRO; *val /= 1000;
} else {
*val = st->chip_info->int_vref_mv;
}
*val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
} }
return -EINVAL; return -EINVAL;
} }
...@@ -105,21 +237,25 @@ static int __devinit ad7887_probe(struct spi_device *spi) ...@@ -105,21 +237,25 @@ static int __devinit ad7887_probe(struct spi_device *spi)
{ {
struct ad7887_platform_data *pdata = spi->dev.platform_data; struct ad7887_platform_data *pdata = spi->dev.platform_data;
struct ad7887_state *st; struct ad7887_state *st;
int ret, voltage_uv = 0;
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
uint8_t mode;
int ret;
if (indio_dev == NULL) if (indio_dev == NULL)
return -ENOMEM; return -ENOMEM;
st = iio_priv(indio_dev); st = iio_priv(indio_dev);
st->reg = regulator_get(&spi->dev, "vcc"); if (!pdata || !pdata->use_onchip_ref) {
if (!IS_ERR(st->reg)) { st->reg = regulator_get(&spi->dev, "vref");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_free;
}
ret = regulator_enable(st->reg); ret = regulator_enable(st->reg);
if (ret) if (ret)
goto error_put_reg; goto error_put_reg;
voltage_uv = regulator_get_voltage(st->reg);
} }
st->chip_info = st->chip_info =
...@@ -136,9 +272,13 @@ static int __devinit ad7887_probe(struct spi_device *spi) ...@@ -136,9 +272,13 @@ static int __devinit ad7887_probe(struct spi_device *spi)
/* Setup default message */ /* Setup default message */
st->tx_cmd_buf[0] = AD7887_CH_AIN0 | AD7887_PM_MODE4 | mode = AD7887_PM_MODE4;
((pdata && pdata->use_onchip_ref) ? if (!pdata || !pdata->use_onchip_ref)
0 : AD7887_REF_DIS); mode |= AD7887_REF_DIS;
if (pdata && pdata->en_dual)
mode |= AD7887_DUAL;
st->tx_cmd_buf[0] = AD7887_CH_AIN0 | mode;
st->xfer[0].rx_buf = &st->data[0]; st->xfer[0].rx_buf = &st->data[0];
st->xfer[0].tx_buf = &st->tx_cmd_buf[0]; st->xfer[0].tx_buf = &st->tx_cmd_buf[0];
...@@ -148,56 +288,36 @@ static int __devinit ad7887_probe(struct spi_device *spi) ...@@ -148,56 +288,36 @@ static int __devinit ad7887_probe(struct spi_device *spi)
spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]); spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]);
if (pdata && pdata->en_dual) { if (pdata && pdata->en_dual) {
st->tx_cmd_buf[0] |= AD7887_DUAL | AD7887_REF_DIS; st->tx_cmd_buf[2] = AD7887_CH_AIN1 | mode;
st->tx_cmd_buf[2] = AD7887_CH_AIN1 | AD7887_DUAL |
AD7887_REF_DIS | AD7887_PM_MODE4;
st->tx_cmd_buf[4] = AD7887_CH_AIN0 | AD7887_DUAL |
AD7887_REF_DIS | AD7887_PM_MODE4;
st->tx_cmd_buf[6] = AD7887_CH_AIN1 | AD7887_DUAL |
AD7887_REF_DIS | AD7887_PM_MODE4;
st->xfer[1].rx_buf = &st->data[0]; st->xfer[1].rx_buf = &st->data[0];
st->xfer[1].tx_buf = &st->tx_cmd_buf[2]; st->xfer[1].tx_buf = &st->tx_cmd_buf[2];
st->xfer[1].len = 2; st->xfer[1].len = 2;
st->xfer[2].rx_buf = &st->data[2]; st->xfer[2].rx_buf = &st->data[2];
st->xfer[2].tx_buf = &st->tx_cmd_buf[4]; st->xfer[2].tx_buf = &st->tx_cmd_buf[0];
st->xfer[2].len = 2; st->xfer[2].len = 2;
spi_message_init(&st->msg[AD7887_CH0_CH1]); spi_message_init(&st->msg[AD7887_CH0_CH1]);
spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]); spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]);
spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]); spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]);
st->xfer[3].rx_buf = &st->data[0]; st->xfer[3].rx_buf = &st->data[2];
st->xfer[3].tx_buf = &st->tx_cmd_buf[6]; st->xfer[3].tx_buf = &st->tx_cmd_buf[2];
st->xfer[3].len = 2; st->xfer[3].len = 2;
spi_message_init(&st->msg[AD7887_CH1]); spi_message_init(&st->msg[AD7887_CH1]);
spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]); spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]);
if (pdata && pdata->vref_mv)
st->int_vref_mv = pdata->vref_mv;
else if (voltage_uv)
st->int_vref_mv = voltage_uv / 1000;
else
dev_warn(&spi->dev, "reference voltage unspecified\n");
indio_dev->channels = st->chip_info->channel; indio_dev->channels = st->chip_info->channel;
indio_dev->num_channels = 3; indio_dev->num_channels = 3;
} else { } else {
if (pdata && pdata->vref_mv)
st->int_vref_mv = pdata->vref_mv;
else if (pdata && pdata->use_onchip_ref)
st->int_vref_mv = st->chip_info->int_vref_mv;
else
dev_warn(&spi->dev, "reference voltage unspecified\n");
indio_dev->channels = &st->chip_info->channel[1]; indio_dev->channels = &st->chip_info->channel[1];
indio_dev->num_channels = 2; indio_dev->num_channels = 2;
} }
ret = ad7887_register_ring_funcs_and_init(indio_dev); ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
&ad7887_trigger_handler, &ad7887_ring_setup_ops);
if (ret) if (ret)
goto error_disable_reg; goto error_disable_reg;
...@@ -207,13 +327,14 @@ static int __devinit ad7887_probe(struct spi_device *spi) ...@@ -207,13 +327,14 @@ static int __devinit ad7887_probe(struct spi_device *spi)
return 0; return 0;
error_unregister_ring: error_unregister_ring:
ad7887_ring_cleanup(indio_dev); iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg: error_disable_reg:
if (!IS_ERR(st->reg)) if (st->reg)
regulator_disable(st->reg); regulator_disable(st->reg);
error_put_reg: error_put_reg:
if (!IS_ERR(st->reg)) if (st->reg)
regulator_put(st->reg); regulator_put(st->reg);
error_free:
iio_device_free(indio_dev); iio_device_free(indio_dev);
return ret; return ret;
...@@ -225,8 +346,8 @@ static int __devexit ad7887_remove(struct spi_device *spi) ...@@ -225,8 +346,8 @@ static int __devexit ad7887_remove(struct spi_device *spi)
struct ad7887_state *st = iio_priv(indio_dev); struct ad7887_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
ad7887_ring_cleanup(indio_dev); iio_triggered_buffer_cleanup(indio_dev);
if (!IS_ERR(st->reg)) { if (st->reg) {
regulator_disable(st->reg); regulator_disable(st->reg);
regulator_put(st->reg); regulator_put(st->reg);
} }
......
...@@ -391,7 +391,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) ...@@ -391,7 +391,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
break; break;
} }
iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data); iio_push_to_buffers(indio_dev, (uint8_t *)data);
iio_trigger_notify_done(indio_dev->trig); iio_trigger_notify_done(indio_dev->trig);
sigma_delta->irq_dis = false; sigma_delta->irq_dis = false;
......
...@@ -65,7 +65,6 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) ...@@ -65,7 +65,6 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p; struct iio_poll_func *pf = p;
struct iio_dev *idev = pf->indio_dev; struct iio_dev *idev = pf->indio_dev;
struct at91_adc_state *st = iio_priv(idev); struct at91_adc_state *st = iio_priv(idev);
struct iio_buffer *buffer = idev->buffer;
int i, j = 0; int i, j = 0;
for (i = 0; i < idev->masklength; i++) { for (i = 0; i < idev->masklength; i++) {
...@@ -81,7 +80,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) ...@@ -81,7 +80,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
*timestamp = pf->timestamp; *timestamp = pf->timestamp;
} }
iio_push_to_buffer(buffer, st->buffer); iio_push_to_buffers(indio_dev, (u8 *)st->buffer);
iio_trigger_notify_done(idev->trig); iio_trigger_notify_done(idev->trig);
......
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/iio/buffer.h>
#include <linux/iio/consumer.h>
struct iio_cb_buffer {
struct iio_buffer buffer;
int (*cb)(u8 *data, void *private);
void *private;
struct iio_channel *channels;
};
static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data)
{
struct iio_cb_buffer *cb_buff = container_of(buffer,
struct iio_cb_buffer,
buffer);
return cb_buff->cb(data, cb_buff->private);
}
static struct iio_buffer_access_funcs iio_cb_access = {
.store_to = &iio_buffer_cb_store_to,
};
struct iio_cb_buffer *iio_channel_get_all_cb(const char *name,
int (*cb)(u8 *data,
void *private),
void *private)
{
int ret;
struct iio_cb_buffer *cb_buff;
struct iio_dev *indio_dev;
struct iio_channel *chan;
cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL);
if (cb_buff == NULL) {
ret = -ENOMEM;
goto error_ret;
}
cb_buff->private = private;
cb_buff->cb = cb;
cb_buff->buffer.access = &iio_cb_access;
INIT_LIST_HEAD(&cb_buff->buffer.demux_list);
cb_buff->channels = iio_channel_get_all(name);
if (IS_ERR(cb_buff->channels)) {
ret = PTR_ERR(cb_buff->channels);
goto error_free_cb_buff;
}
indio_dev = cb_buff->channels[0].indio_dev;
cb_buff->buffer.scan_mask
= kcalloc(BITS_TO_LONGS(indio_dev->masklength), sizeof(long),
GFP_KERNEL);
if (cb_buff->buffer.scan_mask == NULL) {
ret = -ENOMEM;
goto error_release_channels;
}
chan = &cb_buff->channels[0];
while (chan->indio_dev) {
if (chan->indio_dev != indio_dev) {
ret = -EINVAL;
goto error_release_channels;
}
set_bit(chan->channel->scan_index,
cb_buff->buffer.scan_mask);
chan++;
}
return cb_buff;
error_release_channels:
iio_channel_release_all(cb_buff->channels);
error_free_cb_buff:
kfree(cb_buff);
error_ret:
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(iio_channel_get_all_cb);
int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff)
{
return iio_update_buffers(cb_buff->channels[0].indio_dev,
&cb_buff->buffer,
NULL);
}
EXPORT_SYMBOL_GPL(iio_channel_start_all_cb);
void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff)
{
iio_update_buffers(cb_buff->channels[0].indio_dev,
NULL,
&cb_buff->buffer);
}
EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)
{
iio_channel_release_all(cb_buff->channels);
kfree(cb_buff);
}
EXPORT_SYMBOL_GPL(iio_channel_release_all_cb);
struct iio_channel
*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer)
{
return cb_buffer->channels;
}
EXPORT_SYMBOL_GPL(iio_channel_cb_get_channels);
...@@ -197,21 +197,8 @@ static const struct iio_info gyro_3d_info = { ...@@ -197,21 +197,8 @@ static const struct iio_info gyro_3d_info = {
/* Function to push data to buffer */ /* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
{ {
struct iio_buffer *buffer = indio_dev->buffer;
int datum_sz;
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
if (!buffer) { iio_push_to_buffers(indio_dev, (u8 *)data);
dev_err(&indio_dev->dev, "Buffer == NULL\n");
return;
}
datum_sz = buffer->access->get_bytes_per_datum(buffer);
if (len > datum_sz) {
dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
datum_sz);
return;
}
iio_push_to_buffer(buffer, (u8 *)data);
} }
/* Callback handler to send event after all samples are received and captured */ /* Callback handler to send event after all samples are received and captured */
......
This diff is collapsed.
...@@ -856,6 +856,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) ...@@ -856,6 +856,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv)
return NULL; return NULL;
} }
dev_set_name(&dev->dev, "iio:device%d", dev->id); dev_set_name(&dev->dev, "iio:device%d", dev->id);
INIT_LIST_HEAD(&dev->buffer_list);
} }
return dev; return dev;
......
...@@ -203,6 +203,7 @@ struct iio_channel *iio_channel_get_all(const char *name) ...@@ -203,6 +203,7 @@ struct iio_channel *iio_channel_get_all(const char *name)
if (name && strcmp(name, c->map->consumer_dev_name) != 0) if (name && strcmp(name, c->map->consumer_dev_name) != 0)
continue; continue;
chans[mapind].indio_dev = c->indio_dev; chans[mapind].indio_dev = c->indio_dev;
chans[mapind].data = c->map->consumer_data;
chans[mapind].channel = chans[mapind].channel =
iio_chan_spec_from_name(chans[mapind].indio_dev, iio_chan_spec_from_name(chans[mapind].indio_dev,
c->map->adc_channel_label); c->map->adc_channel_label);
......
...@@ -164,7 +164,6 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p) ...@@ -164,7 +164,6 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p; struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev; struct iio_dev *indio_dev = pf->indio_dev;
struct adjd_s311_data *data = iio_priv(indio_dev); struct adjd_s311_data *data = iio_priv(indio_dev);
struct iio_buffer *buffer = indio_dev->buffer;
s64 time_ns = iio_get_time_ns(); s64 time_ns = iio_get_time_ns();
int len = 0; int len = 0;
int i, j = 0; int i, j = 0;
...@@ -187,7 +186,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p) ...@@ -187,7 +186,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64))) *(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64)))
= time_ns; = time_ns;
iio_push_to_buffer(buffer, (u8 *)data->buffer); iio_push_to_buffers(indio_dev, (u8 *)data->buffer);
done: done:
iio_trigger_notify_done(indio_dev->trig); iio_trigger_notify_done(indio_dev->trig);
......
...@@ -176,21 +176,8 @@ static const struct iio_info als_info = { ...@@ -176,21 +176,8 @@ static const struct iio_info als_info = {
/* Function to push data to buffer */ /* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
{ {
struct iio_buffer *buffer = indio_dev->buffer;
int datum_sz;
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
if (!buffer) { iio_push_to_buffers(indio_dev, (u8 *)data);
dev_err(&indio_dev->dev, "Buffer == NULL\n");
return;
}
datum_sz = buffer->access->get_bytes_per_datum(buffer);
if (len > datum_sz) {
dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
datum_sz);
return;
}
iio_push_to_buffer(buffer, (u8 *)data);
} }
/* Callback handler to send event after all samples are received and captured */ /* Callback handler to send event after all samples are received and captured */
......
...@@ -198,21 +198,8 @@ static const struct iio_info magn_3d_info = { ...@@ -198,21 +198,8 @@ static const struct iio_info magn_3d_info = {
/* Function to push data to buffer */ /* Function to push data to buffer */
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
{ {
struct iio_buffer *buffer = indio_dev->buffer;
int datum_sz;
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
if (!buffer) { iio_push_to_buffers(indio_dev, (u8 *)data);
dev_err(&indio_dev->dev, "Buffer == NULL\n");
return;
}
datum_sz = buffer->access->get_bytes_per_datum(buffer);
if (len > datum_sz) {
dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len,
datum_sz);
return;
}
iio_push_to_buffer(buffer, (u8 *)data);
} }
/* Callback handler to send event after all samples are received and captured */ /* Callback handler to send event after all samples are received and captured */
......
...@@ -82,7 +82,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) ...@@ -82,7 +82,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
iio_push_to_buffer(indio_dev->buffer, (u8 *)data); iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data); kfree(data);
done: done:
......
...@@ -81,7 +81,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) ...@@ -81,7 +81,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
iio_push_to_buffer(indio_dev->buffer, (u8 *)data); iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data); kfree(data);
done: done:
......
...@@ -78,7 +78,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) ...@@ -78,7 +78,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
iio_push_to_buffer(indio_dev->buffer, (u8 *)data); iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data); kfree(data);
done: done:
......
...@@ -78,7 +78,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) ...@@ -78,7 +78,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
iio_push_to_buffer(indio_dev->buffer, (u8 *)data); iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data); kfree(data);
done: done:
......
...@@ -76,7 +76,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) ...@@ -76,7 +76,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
iio_push_to_buffer(indio_dev->buffer, (u8 *)data); iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data); kfree(data);
done: done:
......
...@@ -154,7 +154,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) ...@@ -154,7 +154,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64))) *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
= pf->timestamp; = pf->timestamp;
iio_push_to_buffer(indio_dev->buffer, (u8 *)data); iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data); kfree(data);
done: done:
......
...@@ -68,19 +68,6 @@ config AD799X_RING_BUFFER ...@@ -68,19 +68,6 @@ config AD799X_RING_BUFFER
Say yes here to include ring buffer support in the AD799X Say yes here to include ring buffer support in the AD799X
ADC driver. ADC driver.
config AD7887
tristate "Analog Devices AD7887 ADC driver"
depends on SPI
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help
Say yes here to build support for Analog Devices
AD7887 SPI analog to digital converter (ADC).
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
module will be called ad7887.
config AD7780 config AD7780
tristate "Analog Devices AD7780 and similar ADCs driver" tristate "Analog Devices AD7780 and similar ADCs driver"
depends on SPI depends on SPI
...@@ -143,30 +130,6 @@ config AD7280 ...@@ -143,30 +130,6 @@ config AD7280
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called ad7280a module will be called ad7280a
config MAX1363
tristate "Maxim max1363 ADC driver"
depends on I2C
select IIO_TRIGGER if IIO_BUFFER
select MAX1363_RING_BUFFER
help
Say yes here to build support for many Maxim i2c analog to digital
converters (ADC). (max1361, max1362, max1363, max1364, max1036,
max1037, max1038, max1039, max1136, max1136, max1137, max1138,
max1139, max1236, max1237, max11238, max1239, max11600, max11601,
max11602, max11603, max11604, max11605, max11606, max11607,
max11608, max11609, max11610, max11611, max11612, max11613,
max11614, max11615, max11616, max11617, max11644, max11645,
max11646, max11647) Provides direct access via sysfs.
config MAX1363_RING_BUFFER
bool "Maxim max1363: use ring buffer"
depends on MAX1363
select IIO_BUFFER
select IIO_SW_RING
help
Say yes here to include ring buffer support in the MAX1363
ADC driver.
config LPC32XX_ADC config LPC32XX_ADC
tristate "NXP LPC32XX ADC" tristate "NXP LPC32XX ADC"
depends on ARCH_LPC32XX depends on ARCH_LPC32XX
......
...@@ -2,11 +2,6 @@ ...@@ -2,11 +2,6 @@
# Makefile for industrial I/O ADC drivers # Makefile for industrial I/O ADC drivers
# #
max1363-y := max1363_core.o
max1363-y += max1363_ring.o
obj-$(CONFIG_MAX1363) += max1363.o
ad7606-y := ad7606_core.o ad7606-y := ad7606_core.o
ad7606-$(CONFIG_IIO_BUFFER) += ad7606_ring.o ad7606-$(CONFIG_IIO_BUFFER) += ad7606_ring.o
ad7606-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o ad7606-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o
...@@ -17,10 +12,6 @@ ad799x-y := ad799x_core.o ...@@ -17,10 +12,6 @@ ad799x-y := ad799x_core.o
ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o
obj-$(CONFIG_AD799X) += ad799x.o obj-$(CONFIG_AD799X) += ad799x.o
ad7887-y := ad7887_core.o
ad7887-$(CONFIG_IIO_BUFFER) += ad7887_ring.o
obj-$(CONFIG_AD7887) += ad7887.o
ad7298-y := ad7298_core.o ad7298-y := ad7298_core.o
ad7298-$(CONFIG_IIO_BUFFER) += ad7298_ring.o ad7298-$(CONFIG_IIO_BUFFER) += ad7298_ring.o
obj-$(CONFIG_AD7298) += ad7298.o obj-$(CONFIG_AD7298) += ad7298.o
......
...@@ -93,7 +93,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) ...@@ -93,7 +93,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
indio_dev->masklength); i++) indio_dev->masklength); i++)
buf[i] = be16_to_cpu(st->rx_buf[i]); buf[i] = be16_to_cpu(st->rx_buf[i]);
iio_push_to_buffer(indio_dev->buffer, (u8 *)buf); iio_push_to_buffers(indio_dev, (u8 *)buf);
done: done:
iio_trigger_notify_done(indio_dev->trig); iio_trigger_notify_done(indio_dev->trig);
......
...@@ -83,7 +83,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) ...@@ -83,7 +83,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
*((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns; *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns;
iio_push_to_buffer(indio_dev->buffer, buf); iio_push_to_buffers(indio_dev, buf);
done: 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);
......
/*
* AD7887 SPI ADC driver
*
* Copyright 2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
#ifndef IIO_ADC_AD7887_H_
#define IIO_ADC_AD7887_H_
#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */
#define AD7887_DUAL (1 << 4) /* dual-channel mode */
#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */
#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */
#define AD7887_PM_MODE1 (0) /* CS based shutdown */
#define AD7887_PM_MODE2 (1) /* full on */
#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */
#define AD7887_PM_MODE4 (3) /* standby mode */
enum ad7887_channels {
AD7887_CH0,
AD7887_CH0_CH1,
AD7887_CH1,
};
#define RES_MASK(bits) ((1 << (bits)) - 1) /* TODO: move this into a common header */
/*
* TODO: struct ad7887_platform_data needs to go into include/linux/iio
*/
struct ad7887_platform_data {
/* External Vref voltage applied */
u16 vref_mv;
/*
* AD7887:
* In single channel mode en_dual = flase, AIN1/Vref pins assumes its
* Vref function. In dual channel mode en_dual = true, AIN1 becomes the
* second input channel, and Vref is internally connected to Vdd.
*/
bool en_dual;
/*
* AD7887:
* use_onchip_ref = true, the Vref is internally connected to the 2.500V
* Voltage reference. If use_onchip_ref = false, the reference voltage
* is supplied by AIN1/Vref
*/
bool use_onchip_ref;
};
/**
* struct ad7887_chip_info - chip specifc information
* @int_vref_mv: the internal reference voltage
* @channel: channel specification
*/
struct ad7887_chip_info {
u16 int_vref_mv;
struct iio_chan_spec channel[3];
};
struct ad7887_state {
struct spi_device *spi;
const struct ad7887_chip_info *chip_info;
struct regulator *reg;
u16 int_vref_mv;
struct spi_transfer xfer[4];
struct spi_message msg[3];
struct spi_message *ring_msg;
unsigned char tx_cmd_buf[8];
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
*/
unsigned char data[4] ____cacheline_aligned;
};
enum ad7887_supported_device_ids {
ID_AD7887
};
#ifdef CONFIG_IIO_BUFFER
int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void ad7887_ring_cleanup(struct iio_dev *indio_dev);
#else /* CONFIG_IIO_BUFFER */
static inline int
ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
{
return 0;
}
static inline void ad7887_ring_cleanup(struct iio_dev *indio_dev)
{
}
#endif /* CONFIG_IIO_BUFFER */
#endif /* IIO_ADC_AD7887_H_ */
/*
* Copyright 2010-2012 Analog Devices Inc.
* Copyright (C) 2008 Jonathan Cameron
*
* Licensed under the GPL-2.
*
* ad7887_ring.c
*/
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include "ad7887.h"
/**
* ad7887_ring_preenable() setup the parameters of the ring before enabling
*
* The complex nature of the setting of the nuber of bytes per datum is due
* to this driver currently ensuring that the timestamp is stored at an 8
* byte boundary.
**/
static int ad7887_ring_preenable(struct iio_dev *indio_dev)
{
struct ad7887_state *st = iio_priv(indio_dev);
int ret;
ret = iio_sw_buffer_preenable(indio_dev);
if (ret < 0)
return ret;
/* We know this is a single long so can 'cheat' */
switch (*indio_dev->active_scan_mask) {
case (1 << 0):
st->ring_msg = &st->msg[AD7887_CH0];
break;
case (1 << 1):
st->ring_msg = &st->msg[AD7887_CH1];
/* Dummy read: push CH1 setting down to hardware */
spi_sync(st->spi, st->ring_msg);
break;
case ((1 << 1) | (1 << 0)):
st->ring_msg = &st->msg[AD7887_CH0_CH1];
break;
}
return 0;
}
static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
{
struct ad7887_state *st = iio_priv(indio_dev);
/* dummy read: restore default CH0 settin */
return spi_sync(st->spi, &st->msg[AD7887_CH0]);
}
/**
* ad7887_trigger_handler() bh of trigger launched polling to ring buffer
*
* Currently there is no option in this driver to disable the saving of
* timestamps within the ring.
**/
static irqreturn_t ad7887_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7887_state *st = iio_priv(indio_dev);
s64 time_ns;
__u8 *buf;
int b_sent;
unsigned int bytes = bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength) *
st->chip_info->channel[0].scan_type.storagebits / 8;
buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
if (buf == NULL)
goto done;
b_sent = spi_sync(st->spi, st->ring_msg);
if (b_sent)
goto done;
time_ns = iio_get_time_ns();
memcpy(buf, st->data, bytes);
if (indio_dev->scan_timestamp)
memcpy(buf + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
iio_push_to_buffer(indio_dev->buffer, buf);
done:
kfree(buf);
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = {
.preenable = &ad7887_ring_preenable,
.postenable = &iio_triggered_buffer_postenable,
.predisable = &iio_triggered_buffer_predisable,
.postdisable = &ad7887_ring_postdisable,
};
int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
{
return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
&ad7887_trigger_handler, &ad7887_ring_setup_ops);
}
void ad7887_ring_cleanup(struct iio_dev *indio_dev)
{
iio_triggered_buffer_cleanup(indio_dev);
}
...@@ -77,7 +77,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) ...@@ -77,7 +77,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns)); &time_ns, sizeof(time_ns));
iio_push_to_buffer(indio_dev->buffer, rxbuf); iio_push_to_buffers(indio_dev, rxbuf);
done: done:
kfree(rxbuf); kfree(rxbuf);
out: out:
......
#ifndef _MAX1363_H_
#define _MAX1363_H_
#define MAX1363_SETUP_BYTE(a) ((a) | 0x80)
/* There is a fair bit more defined here than currently
* used, but the intention is to support everything these
* chips do in the long run */
/* see data sheets */
/* max1363 and max1236, max1237, max1238, max1239 */
#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00
#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20
#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40
#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60
#define MAX1363_SETUP_POWER_UP_INT_REF 0x10
#define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00
/* think about includeing max11600 etc - more settings */
#define MAX1363_SETUP_EXT_CLOCK 0x08
#define MAX1363_SETUP_INT_CLOCK 0x00
#define MAX1363_SETUP_UNIPOLAR 0x00
#define MAX1363_SETUP_BIPOLAR 0x04
#define MAX1363_SETUP_RESET 0x00
#define MAX1363_SETUP_NORESET 0x02
/* max1363 only - though don't care on others.
* For now monitor modes are not implemented as the relevant
* line is not connected on my test board.
* The definitions are here as I intend to add this soon.
*/
#define MAX1363_SETUP_MONITOR_SETUP 0x01
/* Specific to the max1363 */
#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4))
#define MAX1363_MON_INT_ENABLE 0x01
/* defined for readability reasons */
/* All chips */
#define MAX1363_CONFIG_BYTE(a) ((a))
#define MAX1363_CONFIG_SE 0x01
#define MAX1363_CONFIG_DE 0x00
#define MAX1363_CONFIG_SCAN_TO_CS 0x00
#define MAX1363_CONFIG_SCAN_SINGLE_8 0x20
#define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40
#define MAX1363_CONFIG_SCAN_SINGLE_1 0x60
/* max123{6-9} only */
#define MAX1236_SCAN_MID_TO_CHANNEL 0x40
/* max1363 only - merely part of channel selects or don't care for others*/
#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18
#define MAX1363_CHANNEL_SEL(a) ((a) << 1)
/* max1363 strictly 0x06 - but doesn't matter */
#define MAX1363_CHANNEL_SEL_MASK 0x1E
#define MAX1363_SCAN_MASK 0x60
#define MAX1363_SE_DE_MASK 0x01
#define MAX1363_MAX_CHANNELS 25
/**
* struct max1363_mode - scan mode information
* @conf: The corresponding value of the configuration register
* @modemask: Bit mask corresponding to channels enabled in this mode
*/
struct max1363_mode {
int8_t conf;
DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS);
};
/* This must be maintained along side the max1363_mode_table in max1363_core */
enum max1363_modes {
/* Single read of a single channel */
_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
/* Differential single read */
d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
/* Scan to channel and mid to channel where overlapping */
s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6,
s6to7, s0to7, s6to8, s0to8, s6to9,
s0to9, s6to10, s0to10, s6to11, s0to11,
/* Differential scan to channel and mid to channel where overlapping */
d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9,
d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2,
d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8,
d7m6to11m10, d1m0to11m10,
};
/**
* struct max1363_chip_info - chip specifc information
* @name: indentification string for chip
* @bits: accuracy of the adc in bits
* @int_vref_mv: the internal reference voltage
* @info: iio core function callbacks structure
* @mode_list: array of available scan modes
* @num_modes: the number of scan modes available
* @default_mode: the scan mode in which the chip starts up
* @channel: channel specification
* @num_channels: number of channels
*/
struct max1363_chip_info {
const struct iio_info *info;
const struct iio_chan_spec *channels;
int num_channels;
const enum max1363_modes *mode_list;
enum max1363_modes default_mode;
u16 int_vref_mv;
u8 num_modes;
u8 bits;
};
/**
* struct max1363_state - driver instance specific data
* @client: i2c_client
* @setupbyte: cache of current device setup byte
* @configbyte: cache of current device config byte
* @chip_info: chip model specific constants, available modes etc
* @current_mode: the scan mode of this chip
* @requestedmask: a valid requested set of channels
* @reg: supply regulator
* @monitor_on: whether monitor mode is enabled
* @monitor_speed: parameter corresponding to device monitor speed setting
* @mask_high: bitmask for enabled high thresholds
* @mask_low: bitmask for enabled low thresholds
* @thresh_high: high threshold values
* @thresh_low: low threshold values
*/
struct max1363_state {
struct i2c_client *client;
u8 setupbyte;
u8 configbyte;
const struct max1363_chip_info *chip_info;
const struct max1363_mode *current_mode;
u32 requestedmask;
struct regulator *reg;
/* Using monitor modes and buffer at the same time is
currently not supported */
bool monitor_on;
unsigned int monitor_speed:3;
u8 mask_high;
u8 mask_low;
/* 4x unipolar first then the fours bipolar ones */
s16 thresh_high[8];
s16 thresh_low[8];
};
const struct max1363_mode
*max1363_match_mode(const unsigned long *mask,
const struct max1363_chip_info *ci);
int max1363_set_scan_mode(struct max1363_state *st);
#ifdef CONFIG_MAX1363_RING_BUFFER
int max1363_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *scan_mask);
int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void max1363_ring_cleanup(struct iio_dev *indio_dev);
#else /* CONFIG_MAX1363_RING_BUFFER */
int max1363_update_scan_mode(struct iio_dev *indio_dev,
const long *scan_mask)
{
return 0;
}
static inline int
max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
{
return 0;
}
static inline void max1363_ring_cleanup(struct iio_dev *indio_dev)
{
}
#endif /* CONFIG_MAX1363_RING_BUFFER */
#endif /* _MAX1363_H_ */
/*
* Copyright (C) 2008 Jonathan Cameron
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* max1363_ring.c
*/
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/bitops.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include "../ring_sw.h"
#include <linux/iio/trigger_consumer.h>
#include "max1363.h"
int max1363_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *scan_mask)
{
struct max1363_state *st = iio_priv(indio_dev);
/*
* Need to figure out the current mode based upon the requested
* scan mask in iio_dev
*/
st->current_mode = max1363_match_mode(scan_mask, st->chip_info);
if (!st->current_mode)
return -EINVAL;
max1363_set_scan_mode(st);
return 0;
}
static irqreturn_t max1363_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct max1363_state *st = iio_priv(indio_dev);
s64 time_ns;
__u8 *rxbuf;
int b_sent;
size_t d_size;
unsigned long numvals = bitmap_weight(st->current_mode->modemask,
MAX1363_MAX_CHANNELS);
/* Ensure the timestamp is 8 byte aligned */
if (st->chip_info->bits != 8)
d_size = numvals*2;
else
d_size = numvals;
if (indio_dev->scan_timestamp) {
d_size += sizeof(s64);
if (d_size % sizeof(s64))
d_size += sizeof(s64) - (d_size % sizeof(s64));
}
/* Monitor mode prevents reading. Whilst not currently implemented
* might as well have this test in here in the meantime as it does
* no harm.
*/
if (numvals == 0)
goto done;
rxbuf = kmalloc(d_size, GFP_KERNEL);
if (rxbuf == NULL)
goto done;
if (st->chip_info->bits != 8)
b_sent = i2c_master_recv(st->client, rxbuf, numvals*2);
else
b_sent = i2c_master_recv(st->client, rxbuf, numvals);
if (b_sent < 0)
goto done_free;
time_ns = iio_get_time_ns();
if (indio_dev->scan_timestamp)
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
iio_push_to_buffer(indio_dev->buffer, rxbuf);
done_free:
kfree(rxbuf);
done:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static const struct iio_buffer_setup_ops max1363_ring_setup_ops = {
.postenable = &iio_triggered_buffer_postenable,
.preenable = &iio_sw_buffer_preenable,
.predisable = &iio_triggered_buffer_predisable,
};
int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
{
struct max1363_state *st = iio_priv(indio_dev);
int ret = 0;
indio_dev->buffer = iio_sw_rb_allocate(indio_dev);
if (!indio_dev->buffer) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
&max1363_trigger_handler,
IRQF_ONESHOT,
indio_dev,
"%s_consumer%d",
st->client->name,
indio_dev->id);
if (indio_dev->pollfunc == NULL) {
ret = -ENOMEM;
goto error_deallocate_sw_rb;
}
/* Ring buffer functions - here trigger setup related */
indio_dev->setup_ops = &max1363_ring_setup_ops;
/* Flag that polled ring buffering is possible */
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
return 0;
error_deallocate_sw_rb:
iio_sw_rb_free(indio_dev->buffer);
error_ret:
return ret;
}
void max1363_ring_cleanup(struct iio_dev *indio_dev)
{
/* ensure that the trigger has been detached */
iio_dealloc_pollfunc(indio_dev->pollfunc);
iio_sw_rb_free(indio_dev->buffer);
}
...@@ -237,7 +237,6 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p) ...@@ -237,7 +237,6 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p; struct iio_poll_func *pf = p;
struct iio_dev *iio = pf->indio_dev; struct iio_dev *iio = pf->indio_dev;
struct mxs_lradc *lradc = iio_priv(iio); struct mxs_lradc *lradc = iio_priv(iio);
struct iio_buffer *buffer = iio->buffer;
const uint32_t chan_value = LRADC_CH_ACCUMULATE | const uint32_t chan_value = LRADC_CH_ACCUMULATE |
((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET); ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
int i, j = 0; int i, j = 0;
...@@ -256,7 +255,7 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p) ...@@ -256,7 +255,7 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
*timestamp = pf->timestamp; *timestamp = pf->timestamp;
} }
iio_push_to_buffer(buffer, (u8 *)lradc->buffer); iio_push_to_buffers(iio, (u8 *)lradc->buffer);
iio_trigger_notify_done(iio->trig); iio_trigger_notify_done(iio->trig);
......
...@@ -81,7 +81,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) ...@@ -81,7 +81,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
iio_push_to_buffer(indio_dev->buffer, (u8 *)data); iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data); kfree(data);
done: done:
......
...@@ -46,7 +46,6 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) ...@@ -46,7 +46,6 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
{ {
struct iio_poll_func *pf = p; struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev; struct iio_dev *indio_dev = pf->indio_dev;
struct iio_buffer *buffer = indio_dev->buffer;
int len = 0; int len = 0;
u16 *data; u16 *data;
...@@ -76,7 +75,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) ...@@ -76,7 +75,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
i < bitmap_weight(indio_dev->active_scan_mask, i < bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength); indio_dev->masklength);
i++, j++) { i++, j++) {
j = find_next_bit(buffer->scan_mask, j = find_next_bit(indio_dev->active_scan_mask,
indio_dev->masklength, j); indio_dev->masklength, j);
/* random access read from the 'device' */ /* random access read from the 'device' */
data[i] = fakedata[j]; data[i] = fakedata[j];
...@@ -87,7 +86,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) ...@@ -87,7 +86,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64))) *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
= iio_get_time_ns(); = iio_get_time_ns();
iio_push_to_buffer(buffer, (u8 *)data); iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data); kfree(data);
......
...@@ -647,7 +647,6 @@ static void ad5933_work(struct work_struct *work) ...@@ -647,7 +647,6 @@ static void ad5933_work(struct work_struct *work)
struct ad5933_state *st = container_of(work, struct ad5933_state *st = container_of(work,
struct ad5933_state, work.work); struct ad5933_state, work.work);
struct iio_dev *indio_dev = i2c_get_clientdata(st->client); struct iio_dev *indio_dev = i2c_get_clientdata(st->client);
struct iio_buffer *ring = indio_dev->buffer;
signed short buf[2]; signed short buf[2];
unsigned char status; unsigned char status;
...@@ -677,8 +676,7 @@ static void ad5933_work(struct work_struct *work) ...@@ -677,8 +676,7 @@ static void ad5933_work(struct work_struct *work)
} else { } else {
buf[0] = be16_to_cpu(buf[0]); buf[0] = be16_to_cpu(buf[0]);
} }
/* save datum to the ring */ iio_push_to_buffers(indio_dev, (u8 *)buf);
iio_push_to_buffer(ring, (u8 *)buf);
} else { } else {
/* no data available - try again later */ /* no data available - try again later */
schedule_delayed_work(&st->work, st->poll_time_jiffies); schedule_delayed_work(&st->work, st->poll_time_jiffies);
......
...@@ -114,7 +114,6 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) ...@@ -114,7 +114,6 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p; struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev; struct iio_dev *indio_dev = pf->indio_dev;
struct adis16400_state *st = iio_priv(indio_dev); struct adis16400_state *st = iio_priv(indio_dev);
struct iio_buffer *ring = indio_dev->buffer;
int i = 0, j, ret = 0; int i = 0, j, ret = 0;
s16 *data; s16 *data;
...@@ -148,9 +147,9 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) ...@@ -148,9 +147,9 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
} }
} }
/* Guaranteed to be aligned with 8 byte boundary */ /* Guaranteed to be aligned with 8 byte boundary */
if (ring->scan_timestamp) if (indio_dev->scan_timestamp)
*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
iio_push_to_buffer(ring, (u8 *) data); iio_push_to_buffers(indio_dev, (u8 *) data);
done: done:
kfree(data); kfree(data);
......
...@@ -73,7 +73,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p) ...@@ -73,7 +73,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp) if (indio_dev->scan_timestamp)
dat64[1] = pf->timestamp; dat64[1] = pf->timestamp;
iio_push_to_buffer(indio_dev->buffer, (u8 *)dat64); iio_push_to_buffers(indio_dev, (u8 *)dat64);
iio_trigger_notify_done(indio_dev->trig); iio_trigger_notify_done(indio_dev->trig);
......
...@@ -66,7 +66,8 @@ struct iio_buffer_access_funcs { ...@@ -66,7 +66,8 @@ struct iio_buffer_access_funcs {
* @stufftoread: [INTERN] flag to indicate new data. * @stufftoread: [INTERN] flag to indicate new data.
* @demux_list: [INTERN] list of operations required to demux the scan. * @demux_list: [INTERN] list of operations required to demux the scan.
* @demux_bounce: [INTERN] buffer for doing gather from incoming scan. * @demux_bounce: [INTERN] buffer for doing gather from incoming scan.
**/ * @buffer_list: [INTERN] entry in the devices list of current buffers.
*/
struct iio_buffer { struct iio_buffer {
int length; int length;
int bytes_per_datum; int bytes_per_datum;
...@@ -81,8 +82,21 @@ struct iio_buffer { ...@@ -81,8 +82,21 @@ struct iio_buffer {
const struct attribute_group *attrs; const struct attribute_group *attrs;
struct list_head demux_list; struct list_head demux_list;
unsigned char *demux_bounce; unsigned char *demux_bounce;
struct list_head buffer_list;
}; };
/**
* iio_update_buffers() - add or remove buffer from active list
* @indio_dev: device to add buffer to
* @insert_buffer: buffer to insert
* @remove_buffer: buffer_to_remove
*
* Note this will tear down the all buffering and build it up again
*/
int iio_update_buffers(struct iio_dev *indio_dev,
struct iio_buffer *insert_buffer,
struct iio_buffer *remove_buffer);
/** /**
* iio_buffer_init() - Initialize the buffer structure * iio_buffer_init() - Initialize the buffer structure
* @buffer: buffer to be initialized * @buffer: buffer to be initialized
...@@ -115,11 +129,11 @@ int iio_scan_mask_set(struct iio_dev *indio_dev, ...@@ -115,11 +129,11 @@ int iio_scan_mask_set(struct iio_dev *indio_dev,
struct iio_buffer *buffer, int bit); struct iio_buffer *buffer, int bit);
/** /**
* iio_push_to_buffer() - push to a registered buffer. * iio_push_to_buffers() - push to a registered buffer.
* @buffer: IIO buffer structure for device * @indio_dev: iio_dev structure for device.
* @data: the data to push to the buffer * @data: Full scan.
*/ */
int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data); int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data);
int iio_update_demux(struct iio_dev *indio_dev); int iio_update_demux(struct iio_dev *indio_dev);
......
...@@ -18,10 +18,12 @@ struct iio_chan_spec; ...@@ -18,10 +18,12 @@ struct iio_chan_spec;
* struct iio_channel - everything needed for a consumer to use a channel * struct iio_channel - everything needed for a consumer to use a channel
* @indio_dev: Device on which the channel exists. * @indio_dev: Device on which the channel exists.
* @channel: Full description of the channel. * @channel: Full description of the channel.
* @data: Data about the channel used by consumer.
*/ */
struct iio_channel { struct iio_channel {
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
const struct iio_chan_spec *channel; const struct iio_chan_spec *channel;
void *data;
}; };
/** /**
...@@ -59,6 +61,52 @@ struct iio_channel *iio_channel_get_all(const char *name); ...@@ -59,6 +61,52 @@ struct iio_channel *iio_channel_get_all(const char *name);
*/ */
void iio_channel_release_all(struct iio_channel *chan); void iio_channel_release_all(struct iio_channel *chan);
struct iio_cb_buffer;
/**
* iio_channel_get_all_cb() - register callback for triggered capture
* @name: Name of client device.
* @cb: Callback function.
* @private: Private data passed to callback.
*
* NB right now we have no ability to mux data from multiple devices.
* So if the channels requested come from different devices this will
* fail.
*/
struct iio_cb_buffer *iio_channel_get_all_cb(const char *name,
int (*cb)(u8 *data,
void *private),
void *private);
/**
* iio_channel_release_all_cb() - release and unregister the callback.
* @cb_buffer: The callback buffer that was allocated.
*/
void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buffer);
/**
* iio_channel_start_all_cb() - start the flow of data through callback.
* @cb_buff: The callback buffer we are starting.
*/
int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff);
/**
* iio_channel_stop_all_cb() - stop the flow of data through the callback.
* @cb_buff: The callback buffer we are stopping.
*/
void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff);
/**
* iio_channel_cb_get_channels() - get access to the underlying channels.
* @cb_buff: The callback buffer from whom we want the channel
* information.
*
* This function allows one to obtain information about the channels.
* Whilst this may allow direct reading if all buffers are disabled, the
* primary aim is to allow drivers that are consuming a channel to query
* things like scaling of the channel.
*/
struct iio_channel
*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer);
/** /**
* iio_read_channel_raw() - read from a given channel * iio_read_channel_raw() - read from a given channel
* @chan: The channel being queried. * @chan: The channel being queried.
......
...@@ -410,6 +410,7 @@ struct iio_buffer_setup_ops { ...@@ -410,6 +410,7 @@ struct iio_buffer_setup_ops {
* and owner * and owner
* @event_interface: [INTERN] event chrdevs associated with interrupt lines * @event_interface: [INTERN] event chrdevs associated with interrupt lines
* @buffer: [DRIVER] any buffer present * @buffer: [DRIVER] any buffer present
* @buffer_list: [INTERN] list of all buffers currently attached
* @scan_bytes: [INTERN] num bytes captured to be fed to buffer demux * @scan_bytes: [INTERN] num bytes captured to be fed to buffer demux
* @mlock: [INTERN] lock used to prevent simultaneous device state * @mlock: [INTERN] lock used to prevent simultaneous device state
* changes * changes
...@@ -448,6 +449,7 @@ struct iio_dev { ...@@ -448,6 +449,7 @@ struct iio_dev {
struct iio_event_interface *event_interface; struct iio_event_interface *event_interface;
struct iio_buffer *buffer; struct iio_buffer *buffer;
struct list_head buffer_list;
int scan_bytes; int scan_bytes;
struct mutex mlock; struct mutex mlock;
......
...@@ -19,11 +19,13 @@ ...@@ -19,11 +19,13 @@
* @consumer_dev_name: Name to uniquely identify the consumer device. * @consumer_dev_name: Name to uniquely identify the consumer device.
* @consumer_channel: Unique name used to identify the channel on the * @consumer_channel: Unique name used to identify the channel on the
* consumer side. * consumer side.
* @consumer_data: Data about the channel for use by the consumer driver.
*/ */
struct iio_map { struct iio_map {
const char *adc_channel_label; const char *adc_channel_label;
const char *consumer_dev_name; const char *consumer_dev_name;
const char *consumer_channel; const char *consumer_channel;
void *consumer_data;
}; };
#endif #endif
/*
* AD7887 SPI ADC driver
*
* Copyright 2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
#ifndef IIO_ADC_AD7887_H_
#define IIO_ADC_AD7887_H_
/**
* struct ad7887_platform_data - AD7887 ADC driver platform data
* @en_dual: Whether to use dual channel mode. If set to true AIN1 becomes the
* second input channel, and Vref is internally connected to Vdd. If set to
* false the device is used in single channel mode and AIN1/Vref is used as
* VREF input.
* @use_onchip_ref: Whether to use the onchip reference. If set to true the
* internal 2.5V reference is used. If set to false a external reference is
* used.
*/
struct ad7887_platform_data {
bool en_dual;
bool use_onchip_ref;
};
#endif /* IIO_ADC_AD7887_H_ */
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