staging:iio: Add support for multiple buffers

Route all buffer writes through the demux.
Addition or removal of a buffer results in tear down and
setup of all the buffers for a given device.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Tested-by: srinivas pandruvada <srinivas.pandruvada@intel.com>
This commit is contained in:
Jonathan Cameron 2012-06-30 20:06:00 +01:00
Родитель 4eb3ccf157
Коммит 84b36ce5f7
30 изменённых файлов: 313 добавлений и 210 удалений

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

@ -197,21 +197,8 @@ static const struct iio_info accel_3d_info = {
/* Function to push data to buffer */
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");
if (!buffer) {
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);
iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */

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

@ -91,7 +91,6 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct iio_buffer *buffer = indio_dev->buffer;
struct ad7266_state *st = iio_priv(indio_dev);
int ret;
@ -99,7 +98,7 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
if (ret == 0) {
if (indio_dev->scan_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);

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

@ -76,7 +76,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
((s64 *)st->data)[1] = time_ns;
iio_push_to_buffer(indio_dev->buffer, st->data);
iio_push_to_buffers(indio_dev, st->data);
done:
iio_trigger_notify_done(indio_dev->trig);

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

@ -134,7 +134,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
iio_push_to_buffer(indio_dev->buffer, st->data);
iio_push_to_buffers(indio_dev, st->data);
done:
iio_trigger_notify_done(indio_dev->trig);

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

@ -391,7 +391,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
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);
sigma_delta->irq_dis = false;

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

@ -65,7 +65,6 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *idev = pf->indio_dev;
struct at91_adc_state *st = iio_priv(idev);
struct iio_buffer *buffer = idev->buffer;
int i, j = 0;
for (i = 0; i < idev->masklength; i++) {
@ -81,7 +80,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
*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);

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

@ -197,21 +197,8 @@ static const struct iio_info gyro_3d_info = {
/* Function to push data to buffer */
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");
if (!buffer) {
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);
iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */

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

@ -31,6 +31,18 @@ static const char * const iio_endian_prefix[] = {
[IIO_LE] = "le",
};
static bool iio_buffer_is_active(struct iio_dev *indio_dev,
struct iio_buffer *buf)
{
struct list_head *p;
list_for_each(p, &indio_dev->buffer_list)
if (p == &buf->buffer_list)
return true;
return false;
}
/**
* iio_buffer_read_first_n_outer() - chrdev read for buffer access
*
@ -134,7 +146,7 @@ static ssize_t iio_scan_el_store(struct device *dev,
if (ret < 0)
return ret;
mutex_lock(&indio_dev->mlock);
if (iio_buffer_enabled(indio_dev)) {
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
ret = -EBUSY;
goto error_ret;
}
@ -180,12 +192,11 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
return ret;
mutex_lock(&indio_dev->mlock);
if (iio_buffer_enabled(indio_dev)) {
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
ret = -EBUSY;
goto error_ret;
}
indio_dev->buffer->scan_timestamp = state;
indio_dev->scan_timestamp = state;
error_ret:
mutex_unlock(&indio_dev->mlock);
@ -385,7 +396,7 @@ ssize_t iio_buffer_write_length(struct device *dev,
return len;
mutex_lock(&indio_dev->mlock);
if (iio_buffer_enabled(indio_dev)) {
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
ret = -EBUSY;
} else {
if (buffer->access->set_length)
@ -398,102 +409,14 @@ ssize_t iio_buffer_write_length(struct device *dev,
}
EXPORT_SYMBOL(iio_buffer_write_length);
ssize_t iio_buffer_store_enable(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len)
{
int ret;
bool requested_state, current_state;
int previous_mode;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_buffer *buffer = indio_dev->buffer;
mutex_lock(&indio_dev->mlock);
previous_mode = indio_dev->currentmode;
requested_state = !(buf[0] == '0');
current_state = iio_buffer_enabled(indio_dev);
if (current_state == requested_state) {
printk(KERN_INFO "iio-buffer, current state requested again\n");
goto done;
}
if (requested_state) {
if (indio_dev->setup_ops->preenable) {
ret = indio_dev->setup_ops->preenable(indio_dev);
if (ret) {
printk(KERN_ERR
"Buffer not started: "
"buffer preenable failed\n");
goto error_ret;
}
}
if (buffer->access->request_update) {
ret = buffer->access->request_update(buffer);
if (ret) {
printk(KERN_INFO
"Buffer not started: "
"buffer parameter update failed\n");
goto error_ret;
}
}
/* Definitely possible for devices to support both of these. */
if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
if (!indio_dev->trig) {
printk(KERN_INFO
"Buffer not started: no trigger\n");
ret = -EINVAL;
goto error_ret;
}
indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
} else if (indio_dev->modes & INDIO_BUFFER_HARDWARE)
indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
else { /* should never be reached */
ret = -EINVAL;
goto error_ret;
}
if (indio_dev->setup_ops->postenable) {
ret = indio_dev->setup_ops->postenable(indio_dev);
if (ret) {
printk(KERN_INFO
"Buffer not started: "
"postenable failed\n");
indio_dev->currentmode = previous_mode;
if (indio_dev->setup_ops->postdisable)
indio_dev->setup_ops->
postdisable(indio_dev);
goto error_ret;
}
}
} else {
if (indio_dev->setup_ops->predisable) {
ret = indio_dev->setup_ops->predisable(indio_dev);
if (ret)
goto error_ret;
}
indio_dev->currentmode = INDIO_DIRECT_MODE;
if (indio_dev->setup_ops->postdisable) {
ret = indio_dev->setup_ops->postdisable(indio_dev);
if (ret)
goto error_ret;
}
}
done:
mutex_unlock(&indio_dev->mlock);
return len;
error_ret:
mutex_unlock(&indio_dev->mlock);
return ret;
}
EXPORT_SYMBOL(iio_buffer_store_enable);
ssize_t iio_buffer_show_enable(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
return sprintf(buf, "%d\n", iio_buffer_enabled(indio_dev));
return sprintf(buf, "%d\n",
iio_buffer_is_active(indio_dev,
indio_dev->buffer));
}
EXPORT_SYMBOL(iio_buffer_show_enable);
@ -537,35 +460,220 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask,
return bytes;
}
int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
int iio_update_buffers(struct iio_dev *indio_dev,
struct iio_buffer *insert_buffer,
struct iio_buffer *remove_buffer)
{
struct iio_buffer *buffer = indio_dev->buffer;
dev_dbg(&indio_dev->dev, "%s\n", __func__);
int ret;
int success = 0;
struct iio_buffer *buffer;
unsigned long *compound_mask;
const unsigned long *old_mask;
/* How much space will the demuxed element take? */
indio_dev->scan_bytes =
iio_compute_scan_bytes(indio_dev, buffer->scan_mask,
buffer->scan_timestamp);
buffer->access->set_bytes_per_datum(buffer, indio_dev->scan_bytes);
/* Wind down existing buffers - iff there are any */
if (!list_empty(&indio_dev->buffer_list)) {
if (indio_dev->setup_ops->predisable) {
ret = indio_dev->setup_ops->predisable(indio_dev);
if (ret)
goto error_ret;
}
indio_dev->currentmode = INDIO_DIRECT_MODE;
if (indio_dev->setup_ops->postdisable) {
ret = indio_dev->setup_ops->postdisable(indio_dev);
if (ret)
goto error_ret;
}
}
/* Keep a copy of current setup to allow roll back */
old_mask = indio_dev->active_scan_mask;
if (!indio_dev->available_scan_masks)
indio_dev->active_scan_mask = NULL;
if (remove_buffer)
list_del(&remove_buffer->buffer_list);
if (insert_buffer)
list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list);
/* If no buffers in list, we are done */
if (list_empty(&indio_dev->buffer_list)) {
indio_dev->currentmode = INDIO_DIRECT_MODE;
if (indio_dev->available_scan_masks == NULL)
kfree(old_mask);
return 0;
}
/* What scan mask do we actually have ?*/
if (indio_dev->available_scan_masks)
compound_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
sizeof(long), GFP_KERNEL);
if (compound_mask == NULL) {
if (indio_dev->available_scan_masks == NULL)
kfree(old_mask);
return -ENOMEM;
}
indio_dev->scan_timestamp = 0;
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
bitmap_or(compound_mask, compound_mask, buffer->scan_mask,
indio_dev->masklength);
indio_dev->scan_timestamp |= buffer->scan_timestamp;
}
if (indio_dev->available_scan_masks) {
indio_dev->active_scan_mask =
iio_scan_mask_match(indio_dev->available_scan_masks,
indio_dev->masklength,
buffer->scan_mask);
else
indio_dev->active_scan_mask = buffer->scan_mask;
if (indio_dev->active_scan_mask == NULL)
return -EINVAL;
compound_mask);
if (indio_dev->active_scan_mask == NULL) {
/*
* Roll back.
* Note can only occur when adding a buffer.
*/
list_del(&insert_buffer->buffer_list);
indio_dev->active_scan_mask = old_mask;
success = -EINVAL;
}
} else {
indio_dev->active_scan_mask = compound_mask;
}
iio_update_demux(indio_dev);
if (indio_dev->info->update_scan_mode)
return indio_dev->info
/* Wind up again */
if (indio_dev->setup_ops->preenable) {
ret = indio_dev->setup_ops->preenable(indio_dev);
if (ret) {
printk(KERN_ERR
"Buffer not started:"
"buffer preenable failed\n");
goto error_remove_inserted;
}
}
indio_dev->scan_bytes =
iio_compute_scan_bytes(indio_dev,
indio_dev->active_scan_mask,
indio_dev->scan_timestamp);
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
if (buffer->access->request_update) {
ret = buffer->access->request_update(buffer);
if (ret) {
printk(KERN_INFO
"Buffer not started:"
"buffer parameter update failed\n");
goto error_run_postdisable;
}
}
if (indio_dev->info->update_scan_mode) {
ret = indio_dev->info
->update_scan_mode(indio_dev,
indio_dev->active_scan_mask);
if (ret < 0) {
printk(KERN_INFO "update scan mode failed\n");
goto error_run_postdisable;
}
}
/* Definitely possible for devices to support both of these.*/
if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
if (!indio_dev->trig) {
printk(KERN_INFO "Buffer not started: no trigger\n");
ret = -EINVAL;
/* Can only occur on first buffer */
goto error_run_postdisable;
}
indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
} else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) {
indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
} else { /* should never be reached */
ret = -EINVAL;
goto error_run_postdisable;
}
if (indio_dev->setup_ops->postenable) {
ret = indio_dev->setup_ops->postenable(indio_dev);
if (ret) {
printk(KERN_INFO
"Buffer not started: postenable failed\n");
indio_dev->currentmode = INDIO_DIRECT_MODE;
if (indio_dev->setup_ops->postdisable)
indio_dev->setup_ops->postdisable(indio_dev);
goto error_disable_all_buffers;
}
}
if (indio_dev->available_scan_masks)
kfree(compound_mask);
else
kfree(old_mask);
return success;
error_disable_all_buffers:
indio_dev->currentmode = INDIO_DIRECT_MODE;
error_run_postdisable:
if (indio_dev->setup_ops->postdisable)
indio_dev->setup_ops->postdisable(indio_dev);
error_remove_inserted:
if (insert_buffer)
list_del(&insert_buffer->buffer_list);
indio_dev->active_scan_mask = old_mask;
kfree(compound_mask);
error_ret:
return ret;
}
EXPORT_SYMBOL_GPL(iio_update_buffers);
ssize_t iio_buffer_store_enable(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len)
{
int ret;
bool requested_state;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct iio_buffer *pbuf = indio_dev->buffer;
bool inlist;
ret = strtobool(buf, &requested_state);
if (ret < 0)
return ret;
mutex_lock(&indio_dev->mlock);
/* Find out if it is in the list */
inlist = iio_buffer_is_active(indio_dev, pbuf);
/* Already in desired state */
if (inlist == requested_state)
goto done;
if (requested_state)
ret = iio_update_buffers(indio_dev,
indio_dev->buffer, NULL);
else
ret = iio_update_buffers(indio_dev,
NULL, indio_dev->buffer);
if (ret < 0)
goto done;
done:
mutex_unlock(&indio_dev->mlock);
return (ret < 0) ? ret : len;
}
EXPORT_SYMBOL(iio_buffer_store_enable);
int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
{
struct iio_buffer *buffer;
unsigned bytes;
dev_dbg(&indio_dev->dev, "%s\n", __func__);
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
if (buffer->access->set_bytes_per_datum) {
bytes = iio_compute_scan_bytes(indio_dev,
buffer->scan_mask,
buffer->scan_timestamp);
buffer->access->set_bytes_per_datum(buffer, bytes);
}
return 0;
}
EXPORT_SYMBOL(iio_sw_buffer_preenable);
@ -599,7 +707,11 @@ static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
* iio_scan_mask_set() - set particular bit in the scan mask
* @buffer: the buffer whose scan mask we are interested in
* @bit: the bit to be set.
**/
*
* Note that at this point we have no way of knowing what other
* buffers might request, hence this code only verifies that the
* individual buffers request is plausible.
*/
int iio_scan_mask_set(struct iio_dev *indio_dev,
struct iio_buffer *buffer, int bit)
{
@ -682,13 +794,12 @@ static unsigned char *iio_demux(struct iio_buffer *buffer,
return buffer->demux_bounce;
}
int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
static int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
{
unsigned char *dataout = iio_demux(buffer, data);
return buffer->access->store_to(buffer, dataout);
}
EXPORT_SYMBOL_GPL(iio_push_to_buffer);
static void iio_buffer_demux_free(struct iio_buffer *buffer)
{
@ -699,10 +810,26 @@ static void iio_buffer_demux_free(struct iio_buffer *buffer)
}
}
int iio_update_demux(struct iio_dev *indio_dev)
int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data)
{
int ret;
struct iio_buffer *buf;
list_for_each_entry(buf, &indio_dev->buffer_list, buffer_list) {
ret = iio_push_to_buffer(buf, data);
if (ret < 0)
return ret;
}
return 0;
}
EXPORT_SYMBOL_GPL(iio_push_to_buffers);
static int iio_buffer_update_demux(struct iio_dev *indio_dev,
struct iio_buffer *buffer)
{
const struct iio_chan_spec *ch;
struct iio_buffer *buffer = indio_dev->buffer;
int ret, in_ind = -1, out_ind, length;
unsigned in_loc = 0, out_loc = 0;
struct iio_demux_table *p;
@ -787,4 +914,23 @@ error_clear_mux_table:
return ret;
}
int iio_update_demux(struct iio_dev *indio_dev)
{
struct iio_buffer *buffer;
int ret;
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
ret = iio_buffer_update_demux(indio_dev, buffer);
if (ret < 0)
goto error_clear_mux_table;
}
return 0;
error_clear_mux_table:
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
iio_buffer_demux_free(buffer);
return ret;
}
EXPORT_SYMBOL_GPL(iio_update_demux);

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

@ -856,6 +856,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv)
return NULL;
}
dev_set_name(&dev->dev, "iio:device%d", dev->id);
INIT_LIST_HEAD(&dev->buffer_list);
}
return dev;

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

@ -164,7 +164,6 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->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();
int len = 0;
int i, j = 0;
@ -187,7 +186,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64)))
= time_ns;
iio_push_to_buffer(buffer, (u8 *)data->buffer);
iio_push_to_buffers(indio_dev, (u8 *)data->buffer);
done:
iio_trigger_notify_done(indio_dev->trig);

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

@ -176,21 +176,8 @@ static const struct iio_info als_info = {
/* Function to push data to buffer */
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");
if (!buffer) {
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);
iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* Callback handler to send event after all samples are received and captured */

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

@ -198,21 +198,8 @@ static const struct iio_info magn_3d_info = {
/* Function to push data to buffer */
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");
if (!buffer) {
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);
iio_push_to_buffers(indio_dev, (u8 *)data);
}
/* 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)
if (indio_dev->scan_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);
done:

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

@ -81,7 +81,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p)
if (indio_dev->scan_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);
done:

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

@ -78,7 +78,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p)
if (indio_dev->scan_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);
done:

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

@ -78,7 +78,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p)
if (indio_dev->scan_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);
done:

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

@ -76,7 +76,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p)
if (indio_dev->scan_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);
done:

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

@ -154,7 +154,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
= pf->timestamp;
iio_push_to_buffer(indio_dev->buffer, (u8 *)data);
iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data);
done:

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

@ -93,7 +93,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
indio_dev->masklength); 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:
iio_trigger_notify_done(indio_dev->trig);

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

@ -83,7 +83,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
if (indio_dev->scan_timestamp)
*((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:
gpio_set_value(st->pdata->gpio_convst, 0);
iio_trigger_notify_done(indio_dev->trig);

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

@ -77,7 +77,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64),
&time_ns, sizeof(time_ns));
iio_push_to_buffer(indio_dev->buffer, rxbuf);
iio_push_to_buffers(indio_dev, rxbuf);
done:
kfree(rxbuf);
out:

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

@ -80,7 +80,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
if (indio_dev->scan_timestamp)
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
iio_push_to_buffer(indio_dev->buffer, rxbuf);
iio_push_to_buffers(indio_dev, rxbuf);
done_free:
kfree(rxbuf);

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

@ -237,7 +237,6 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *iio = pf->indio_dev;
struct mxs_lradc *lradc = iio_priv(iio);
struct iio_buffer *buffer = iio->buffer;
const uint32_t chan_value = LRADC_CH_ACCUMULATE |
((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
int i, j = 0;
@ -256,7 +255,7 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
*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);

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

@ -81,7 +81,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p)
if (indio_dev->scan_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);
done:

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

@ -46,7 +46,6 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct iio_buffer *buffer = indio_dev->buffer;
int len = 0;
u16 *data;
@ -76,7 +75,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
i < bitmap_weight(indio_dev->active_scan_mask,
indio_dev->masklength);
i++, j++) {
j = find_next_bit(buffer->scan_mask,
j = find_next_bit(indio_dev->active_scan_mask,
indio_dev->masklength, j);
/* random access read from the 'device' */
data[i] = fakedata[j];
@ -87,7 +86,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
if (indio_dev->scan_timestamp)
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
= iio_get_time_ns();
iio_push_to_buffer(buffer, (u8 *)data);
iio_push_to_buffers(indio_dev, (u8 *)data);
kfree(data);

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

@ -647,7 +647,6 @@ static void ad5933_work(struct work_struct *work)
struct ad5933_state *st = container_of(work,
struct ad5933_state, work.work);
struct iio_dev *indio_dev = i2c_get_clientdata(st->client);
struct iio_buffer *ring = indio_dev->buffer;
signed short buf[2];
unsigned char status;
@ -677,8 +676,7 @@ static void ad5933_work(struct work_struct *work)
} else {
buf[0] = be16_to_cpu(buf[0]);
}
/* save datum to the ring */
iio_push_to_buffer(ring, (u8 *)buf);
iio_push_to_buffers(indio_dev, (u8 *)buf);
} else {
/* no data available - try again later */
schedule_delayed_work(&st->work, st->poll_time_jiffies);

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

@ -114,7 +114,6 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct adis16400_state *st = iio_priv(indio_dev);
struct iio_buffer *ring = indio_dev->buffer;
int i = 0, j, ret = 0;
s16 *data;
@ -148,9 +147,9 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p)
}
}
/* 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;
iio_push_to_buffer(ring, (u8 *) data);
iio_push_to_buffers(indio_dev, (u8 *) data);
done:
kfree(data);

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

@ -73,7 +73,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
if (indio_dev->scan_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);

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

@ -66,7 +66,8 @@ struct iio_buffer_access_funcs {
* @stufftoread: [INTERN] flag to indicate new data.
* @demux_list: [INTERN] list of operations required to demux the 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 {
int length;
int bytes_per_datum;
@ -81,8 +82,21 @@ struct iio_buffer {
const struct attribute_group *attrs;
struct list_head demux_list;
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
* @buffer: buffer to be initialized
@ -115,11 +129,11 @@ int iio_scan_mask_set(struct iio_dev *indio_dev,
struct iio_buffer *buffer, int bit);
/**
* iio_push_to_buffer() - push to a registered buffer.
* @buffer: IIO buffer structure for device
* @data: the data to push to the buffer
* iio_push_to_buffers() - push to a registered buffer.
* @indio_dev: iio_dev structure for device.
* @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);

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

@ -410,6 +410,7 @@ struct iio_buffer_setup_ops {
* and owner
* @event_interface: [INTERN] event chrdevs associated with interrupt lines
* @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
* @mlock: [INTERN] lock used to prevent simultaneous device state
* changes
@ -448,6 +449,7 @@ struct iio_dev {
struct iio_event_interface *event_interface;
struct iio_buffer *buffer;
struct list_head buffer_list;
int scan_bytes;
struct mutex mlock;