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:
parent
4eb3ccf157
commit
84b36ce5f7
|
@ -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 */
|
||||||
|
|
|
@ -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)
|
||||||
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)
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
|
||||||
memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
|
memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
|
||||||
&time_ns, sizeof(time_ns));
|
&time_ns, sizeof(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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
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)
|
||||||
*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);
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -31,6 +31,18 @@ static const char * const iio_endian_prefix[] = {
|
||||||
[IIO_LE] = "le",
|
[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
|
* 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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
mutex_lock(&indio_dev->mlock);
|
mutex_lock(&indio_dev->mlock);
|
||||||
if (iio_buffer_enabled(indio_dev)) {
|
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
|
@ -180,12 +192,11 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
mutex_lock(&indio_dev->mlock);
|
mutex_lock(&indio_dev->mlock);
|
||||||
if (iio_buffer_enabled(indio_dev)) {
|
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
indio_dev->buffer->scan_timestamp = state;
|
indio_dev->buffer->scan_timestamp = state;
|
||||||
indio_dev->scan_timestamp = state;
|
|
||||||
error_ret:
|
error_ret:
|
||||||
mutex_unlock(&indio_dev->mlock);
|
mutex_unlock(&indio_dev->mlock);
|
||||||
|
|
||||||
|
@ -385,7 +396,7 @@ ssize_t iio_buffer_write_length(struct device *dev,
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
mutex_lock(&indio_dev->mlock);
|
mutex_lock(&indio_dev->mlock);
|
||||||
if (iio_buffer_enabled(indio_dev)) {
|
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
} else {
|
} else {
|
||||||
if (buffer->access->set_length)
|
if (buffer->access->set_length)
|
||||||
|
@ -398,102 +409,14 @@ ssize_t iio_buffer_write_length(struct device *dev,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iio_buffer_write_length);
|
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,
|
ssize_t iio_buffer_show_enable(struct device *dev,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
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);
|
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;
|
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;
|
int ret;
|
||||||
dev_dbg(&indio_dev->dev, "%s\n", __func__);
|
int success = 0;
|
||||||
|
struct iio_buffer *buffer;
|
||||||
|
unsigned long *compound_mask;
|
||||||
|
const unsigned long *old_mask;
|
||||||
|
|
||||||
/* How much space will the demuxed element take? */
|
/* Wind down existing buffers - iff there are any */
|
||||||
indio_dev->scan_bytes =
|
if (!list_empty(&indio_dev->buffer_list)) {
|
||||||
iio_compute_scan_bytes(indio_dev, buffer->scan_mask,
|
if (indio_dev->setup_ops->predisable) {
|
||||||
buffer->scan_timestamp);
|
ret = indio_dev->setup_ops->predisable(indio_dev);
|
||||||
buffer->access->set_bytes_per_datum(buffer, indio_dev->scan_bytes);
|
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 ?*/
|
/* 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 =
|
indio_dev->active_scan_mask =
|
||||||
iio_scan_mask_match(indio_dev->available_scan_masks,
|
iio_scan_mask_match(indio_dev->available_scan_masks,
|
||||||
indio_dev->masklength,
|
indio_dev->masklength,
|
||||||
buffer->scan_mask);
|
compound_mask);
|
||||||
else
|
if (indio_dev->active_scan_mask == NULL) {
|
||||||
indio_dev->active_scan_mask = buffer->scan_mask;
|
/*
|
||||||
|
* Roll back.
|
||||||
if (indio_dev->active_scan_mask == NULL)
|
* Note can only occur when adding a buffer.
|
||||||
return -EINVAL;
|
*/
|
||||||
|
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);
|
iio_update_demux(indio_dev);
|
||||||
|
|
||||||
if (indio_dev->info->update_scan_mode)
|
/* Wind up again */
|
||||||
return indio_dev->info
|
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,
|
->update_scan_mode(indio_dev,
|
||||||
indio_dev->active_scan_mask);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iio_sw_buffer_preenable);
|
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
|
* iio_scan_mask_set() - set particular bit in the scan mask
|
||||||
* @buffer: the buffer whose scan mask we are interested in
|
* @buffer: the buffer whose scan mask we are interested in
|
||||||
* @bit: the bit to be set.
|
* @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,
|
int iio_scan_mask_set(struct iio_dev *indio_dev,
|
||||||
struct iio_buffer *buffer, int bit)
|
struct iio_buffer *buffer, int bit)
|
||||||
{
|
{
|
||||||
|
@ -682,13 +794,12 @@ static unsigned char *iio_demux(struct iio_buffer *buffer,
|
||||||
return buffer->demux_bounce;
|
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);
|
unsigned char *dataout = iio_demux(buffer, data);
|
||||||
|
|
||||||
return buffer->access->store_to(buffer, dataout);
|
return buffer->access->store_to(buffer, dataout);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(iio_push_to_buffer);
|
|
||||||
|
|
||||||
static void iio_buffer_demux_free(struct iio_buffer *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;
|
const struct iio_chan_spec *ch;
|
||||||
struct iio_buffer *buffer = indio_dev->buffer;
|
|
||||||
int ret, in_ind = -1, out_ind, length;
|
int ret, in_ind = -1, out_ind, length;
|
||||||
unsigned in_loc = 0, out_loc = 0;
|
unsigned in_loc = 0, out_loc = 0;
|
||||||
struct iio_demux_table *p;
|
struct iio_demux_table *p;
|
||||||
|
@ -787,4 +914,23 @@ error_clear_mux_table:
|
||||||
|
|
||||||
return ret;
|
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);
|
EXPORT_SYMBOL_GPL(iio_update_demux);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
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 = {
|
||||||
/* 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 = {
|
||||||
/* 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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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:
|
||||||
|
|
|
@ -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)
|
||||||
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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -80,7 +80,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
|
||||||
|
|
||||||
if (indio_dev->scan_timestamp)
|
if (indio_dev->scan_timestamp)
|
||||||
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
|
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:
|
done_free:
|
||||||
kfree(rxbuf);
|
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_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)
|
||||||
*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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
} 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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* 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)
|
||||||
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 {
|
||||||
* @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 {
|
||||||
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,
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue