staging: iio move scan_elements into ring buffer
tested with sca3000, adis16400 Signed-off-by: Manuel Stahl <manuel.stahl@iis.fraunhofer.de> Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
07e6229e42
commit
bf32963cbe
@ -115,11 +115,11 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
struct adis16209_state *st
|
struct adis16209_state *st
|
||||||
= container_of(work_s, struct adis16209_state,
|
= container_of(work_s, struct adis16209_state,
|
||||||
work_trigger_to_ring);
|
work_trigger_to_ring);
|
||||||
|
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
s16 *data;
|
s16 *data;
|
||||||
size_t datasize = st->indio_dev
|
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
|
||||||
|
|
||||||
data = kmalloc(datasize , GFP_KERNEL);
|
data = kmalloc(datasize , GFP_KERNEL);
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
@ -127,19 +127,19 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->indio_dev->scan_count)
|
if (ring->scan_count)
|
||||||
if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
|
if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
|
||||||
for (; i < st->indio_dev->scan_count; i++)
|
for (; i < ring->scan_count; i++)
|
||||||
data[i] = be16_to_cpup(
|
data[i] = be16_to_cpup(
|
||||||
(__be16 *)&(st->rx[i*2]));
|
(__be16 *)&(st->rx[i*2]));
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
/* Guaranteed to be aligned with 8 byte boundary */
|
||||||
if (st->indio_dev->scan_timestamp)
|
if (ring->scan_timestamp)
|
||||||
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
||||||
|
|
||||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
ring->access.store_to(ring,
|
||||||
(u8 *)data,
|
(u8 *)data,
|
||||||
st->last_timestamp);
|
st->last_timestamp);
|
||||||
|
|
||||||
iio_trigger_notify_done(st->indio_dev->trig);
|
iio_trigger_notify_done(st->indio_dev->trig);
|
||||||
kfree(data);
|
kfree(data);
|
||||||
@ -159,19 +159,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
|
|||||||
struct adis16209_state *st = indio_dev->dev_data;
|
struct adis16209_state *st = indio_dev->dev_data;
|
||||||
struct iio_ring_buffer *ring;
|
struct iio_ring_buffer *ring;
|
||||||
INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring);
|
INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring);
|
||||||
/* Set default scan mode */
|
|
||||||
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_rot.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
|
|
||||||
indio_dev->scan_timestamp = true;
|
|
||||||
|
|
||||||
indio_dev->scan_el_attrs = &adis16209_scan_el_group;
|
|
||||||
|
|
||||||
ring = iio_sw_rb_allocate(indio_dev);
|
ring = iio_sw_rb_allocate(indio_dev);
|
||||||
if (!ring) {
|
if (!ring) {
|
||||||
@ -182,11 +169,23 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
|
|||||||
/* Effectively select the ring buffer implementation */
|
/* Effectively select the ring buffer implementation */
|
||||||
iio_ring_sw_register_funcs(&ring->access);
|
iio_ring_sw_register_funcs(&ring->access);
|
||||||
ring->bpe = 2;
|
ring->bpe = 2;
|
||||||
|
ring->scan_el_attrs = &adis16209_scan_el_group;
|
||||||
|
ring->scan_timestamp = true;
|
||||||
ring->preenable = &iio_sw_ring_preenable;
|
ring->preenable = &iio_sw_ring_preenable;
|
||||||
ring->postenable = &iio_triggered_ring_postenable;
|
ring->postenable = &iio_triggered_ring_postenable;
|
||||||
ring->predisable = &iio_triggered_ring_predisable;
|
ring->predisable = &iio_triggered_ring_predisable;
|
||||||
ring->owner = THIS_MODULE;
|
ring->owner = THIS_MODULE;
|
||||||
|
|
||||||
|
/* Set default scan mode */
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_supply.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_rot.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_temp.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_aux_adc.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
|
||||||
|
|
||||||
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th);
|
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_iio_sw_rb_free;
|
goto error_iio_sw_rb_free;
|
||||||
|
@ -107,11 +107,11 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
struct adis16240_state *st
|
struct adis16240_state *st
|
||||||
= container_of(work_s, struct adis16240_state,
|
= container_of(work_s, struct adis16240_state,
|
||||||
work_trigger_to_ring);
|
work_trigger_to_ring);
|
||||||
|
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
s16 *data;
|
s16 *data;
|
||||||
size_t datasize = st->indio_dev
|
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
|
||||||
|
|
||||||
data = kmalloc(datasize , GFP_KERNEL);
|
data = kmalloc(datasize , GFP_KERNEL);
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
@ -119,17 +119,17 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->indio_dev->scan_count)
|
if (ring->scan_count)
|
||||||
if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
|
if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
|
||||||
for (; i < st->indio_dev->scan_count; i++)
|
for (; i < ring->scan_count; i++)
|
||||||
data[i] = be16_to_cpup(
|
data[i] = be16_to_cpup(
|
||||||
(__be16 *)&(st->rx[i*2]));
|
(__be16 *)&(st->rx[i*2]));
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
/* Guaranteed to be aligned with 8 byte boundary */
|
||||||
if (st->indio_dev->scan_timestamp)
|
if (ring->scan_timestamp)
|
||||||
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
||||||
|
|
||||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
ring->access.store_to(ring,
|
||||||
(u8 *)data,
|
(u8 *)data,
|
||||||
st->last_timestamp);
|
st->last_timestamp);
|
||||||
|
|
||||||
@ -151,17 +151,6 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
|
|||||||
struct adis16240_state *st = indio_dev->dev_data;
|
struct adis16240_state *st = indio_dev->dev_data;
|
||||||
struct iio_ring_buffer *ring;
|
struct iio_ring_buffer *ring;
|
||||||
INIT_WORK(&st->work_trigger_to_ring, adis16240_trigger_bh_to_ring);
|
INIT_WORK(&st->work_trigger_to_ring, adis16240_trigger_bh_to_ring);
|
||||||
/* Set default scan mode */
|
|
||||||
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
|
|
||||||
indio_dev->scan_timestamp = true;
|
|
||||||
|
|
||||||
indio_dev->scan_el_attrs = &adis16240_scan_el_group;
|
|
||||||
|
|
||||||
ring = iio_sw_rb_allocate(indio_dev);
|
ring = iio_sw_rb_allocate(indio_dev);
|
||||||
if (!ring) {
|
if (!ring) {
|
||||||
@ -172,11 +161,21 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
|
|||||||
/* Effectively select the ring buffer implementation */
|
/* Effectively select the ring buffer implementation */
|
||||||
iio_ring_sw_register_funcs(&ring->access);
|
iio_ring_sw_register_funcs(&ring->access);
|
||||||
ring->bpe = 2;
|
ring->bpe = 2;
|
||||||
|
ring->scan_el_attrs = &adis16240_scan_el_group;
|
||||||
|
ring->scan_timestamp = true;
|
||||||
ring->preenable = &iio_sw_ring_preenable;
|
ring->preenable = &iio_sw_ring_preenable;
|
||||||
ring->postenable = &iio_triggered_ring_postenable;
|
ring->postenable = &iio_triggered_ring_postenable;
|
||||||
ring->predisable = &iio_triggered_ring_predisable;
|
ring->predisable = &iio_triggered_ring_predisable;
|
||||||
ring->owner = THIS_MODULE;
|
ring->owner = THIS_MODULE;
|
||||||
|
|
||||||
|
/* Set default scan mode */
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_supply.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_temp.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_aux_adc.number);
|
||||||
|
|
||||||
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
|
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_iio_sw_rb_free;
|
goto error_iio_sw_rb_free;
|
||||||
|
@ -150,38 +150,40 @@ ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
|
|||||||
int ret, len = 0, i = 0;
|
int ret, len = 0, i = 0;
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
struct iio_dev *dev_info = dev_get_drvdata(dev);
|
struct iio_dev *dev_info = dev_get_drvdata(dev);
|
||||||
|
struct iio_ring_buffer *ring = dev_info->ring;
|
||||||
|
struct attribute_group *scan_el_attrs = ring->scan_el_attrs;
|
||||||
s16 *data;
|
s16 *data;
|
||||||
|
|
||||||
while (dev_info->scan_el_attrs->attrs[i]) {
|
while (scan_el_attrs->attrs[i]) {
|
||||||
el = to_iio_scan_el((struct device_attribute *)
|
el = to_iio_scan_el((struct device_attribute *)
|
||||||
(dev_info->scan_el_attrs->attrs[i]));
|
(scan_el_attrs->attrs[i]));
|
||||||
/* label is in fact the address */
|
/* label is in fact the address */
|
||||||
if (el->label == this_attr->address)
|
if (el->label == this_attr->address)
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (!dev_info->scan_el_attrs->attrs[i]) {
|
if (!scan_el_attrs->attrs[i]) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
/* If this element is in the scan mask */
|
/* If this element is in the scan mask */
|
||||||
ret = iio_scan_mask_query(dev_info, el->number);
|
ret = iio_scan_mask_query(ring, el->number);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
if (ret) {
|
if (ret) {
|
||||||
data = kmalloc(dev_info->ring->access.get_bytes_per_datum(dev_info->ring),
|
data = kmalloc(ring->access.get_bytes_per_datum(ring),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
ret = dev_info->ring->access.read_last(dev_info->ring,
|
ret = ring->access.read_last(ring,
|
||||||
(u8 *)data);
|
(u8 *)data);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_data;
|
goto error_free_data;
|
||||||
} else {
|
} else {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
len = iio_scan_mask_count_to_right(dev_info, el->number);
|
len = iio_scan_mask_count_to_right(ring, el->number);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
ret = len;
|
ret = len;
|
||||||
goto error_free_data;
|
goto error_free_data;
|
||||||
@ -211,11 +213,12 @@ static const u8 read_all_tx_array[] = {
|
|||||||
**/
|
**/
|
||||||
static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
|
static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
|
||||||
{
|
{
|
||||||
|
struct iio_ring_buffer *ring = st->help.indio_dev->ring;
|
||||||
struct spi_transfer *xfers;
|
struct spi_transfer *xfers;
|
||||||
struct spi_message msg;
|
struct spi_message msg;
|
||||||
int ret, i, j = 0;
|
int ret, i, j = 0;
|
||||||
|
|
||||||
xfers = kzalloc((st->help.indio_dev->scan_count) * 2
|
xfers = kzalloc((ring->scan_count) * 2
|
||||||
* sizeof(*xfers), GFP_KERNEL);
|
* sizeof(*xfers), GFP_KERNEL);
|
||||||
if (!xfers)
|
if (!xfers)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -223,7 +226,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
|
|||||||
mutex_lock(&st->buf_lock);
|
mutex_lock(&st->buf_lock);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) {
|
for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) {
|
||||||
if (st->help.indio_dev->scan_mask & (1 << i)) {
|
if (ring->scan_mask & (1 << i)) {
|
||||||
/* lower byte */
|
/* lower byte */
|
||||||
xfers[j].tx_buf = st->tx + 2*j;
|
xfers[j].tx_buf = st->tx + 2*j;
|
||||||
st->tx[2*j] = read_all_tx_array[i*4];
|
st->tx[2*j] = read_all_tx_array[i*4];
|
||||||
@ -251,7 +254,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
|
|||||||
* values in alternate bytes
|
* values in alternate bytes
|
||||||
*/
|
*/
|
||||||
spi_message_init(&msg);
|
spi_message_init(&msg);
|
||||||
for (j = 0; j < st->help.indio_dev->scan_count * 2; j++)
|
for (j = 0; j < ring->scan_count * 2; j++)
|
||||||
spi_message_add_tail(&xfers[j], &msg);
|
spi_message_add_tail(&xfers[j], &msg);
|
||||||
|
|
||||||
ret = spi_sync(st->us, &msg);
|
ret = spi_sync(st->us, &msg);
|
||||||
@ -279,13 +282,13 @@ static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
|
|||||||
u8 *rx_array ;
|
u8 *rx_array ;
|
||||||
s16 *data = (s16 *)buf;
|
s16 *data = (s16 *)buf;
|
||||||
|
|
||||||
rx_array = kzalloc(4 * (h->indio_dev->scan_count), GFP_KERNEL);
|
rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
|
||||||
if (rx_array == NULL)
|
if (rx_array == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
|
ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
for (i = 0; i < h->indio_dev->scan_count; i++)
|
for (i = 0; i < h->indio_dev->ring->scan_count; i++)
|
||||||
data[i] = combine_8_to_16(rx_array[i*4+1],
|
data[i] = combine_8_to_16(rx_array[i*4+1],
|
||||||
rx_array[i*4+3]);
|
rx_array[i*4+3]);
|
||||||
kfree(rx_array);
|
kfree(rx_array);
|
||||||
@ -481,14 +484,7 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
|
|||||||
struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
|
struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
|
||||||
struct iio_ring_buffer *ring;
|
struct iio_ring_buffer *ring;
|
||||||
INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
|
INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
|
||||||
/* Set default scan mode */
|
|
||||||
h->get_ring_element = &lis3l02dq_get_ring_element;
|
h->get_ring_element = &lis3l02dq_get_ring_element;
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
|
|
||||||
indio_dev->scan_timestamp = true;
|
|
||||||
|
|
||||||
indio_dev->scan_el_attrs = &lis3l02dq_scan_el_group;
|
|
||||||
|
|
||||||
ring = iio_sw_rb_allocate(indio_dev);
|
ring = iio_sw_rb_allocate(indio_dev);
|
||||||
if (!ring)
|
if (!ring)
|
||||||
@ -498,11 +494,18 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
|
|||||||
/* Effectively select the ring buffer implementation */
|
/* Effectively select the ring buffer implementation */
|
||||||
iio_ring_sw_register_funcs(&ring->access);
|
iio_ring_sw_register_funcs(&ring->access);
|
||||||
ring->bpe = 2;
|
ring->bpe = 2;
|
||||||
|
ring->scan_el_attrs = &lis3l02dq_scan_el_group;
|
||||||
|
ring->scan_timestamp = true;
|
||||||
ring->preenable = &iio_sw_ring_preenable;
|
ring->preenable = &iio_sw_ring_preenable;
|
||||||
ring->postenable = &iio_triggered_ring_postenable;
|
ring->postenable = &iio_triggered_ring_postenable;
|
||||||
ring->predisable = &iio_triggered_ring_predisable;
|
ring->predisable = &iio_triggered_ring_predisable;
|
||||||
ring->owner = THIS_MODULE;
|
ring->owner = THIS_MODULE;
|
||||||
|
|
||||||
|
/* Set default scan mode */
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
|
||||||
|
|
||||||
ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
|
ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_iio_sw_rb_free;;
|
goto error_iio_sw_rb_free;;
|
||||||
|
@ -264,12 +264,12 @@ static inline void sca3000_rb_free(struct iio_ring_buffer *r)
|
|||||||
|
|
||||||
int sca3000_configure_ring(struct iio_dev *indio_dev)
|
int sca3000_configure_ring(struct iio_dev *indio_dev)
|
||||||
{
|
{
|
||||||
indio_dev->scan_el_attrs = &sca3000_scan_el_group;
|
|
||||||
indio_dev->ring = sca3000_rb_allocate(indio_dev);
|
indio_dev->ring = sca3000_rb_allocate(indio_dev);
|
||||||
if (indio_dev->ring == NULL)
|
if (indio_dev->ring == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
|
indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
|
||||||
|
|
||||||
|
indio_dev->ring->scan_el_attrs = &sca3000_scan_el_group;
|
||||||
indio_dev->ring->access.rip_lots = &sca3000_rip_hw_rb;
|
indio_dev->ring->access.rip_lots = &sca3000_rip_hw_rb;
|
||||||
indio_dev->ring->access.get_length = &sca3000_ring_get_length;
|
indio_dev->ring->access.get_length = &sca3000_ring_get_length;
|
||||||
indio_dev->ring->access.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum;
|
indio_dev->ring->access.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum;
|
||||||
|
@ -1631,7 +1631,6 @@ static int __devinit max1363_probe(struct i2c_client *client,
|
|||||||
st->indio_dev->attrs = st->chip_info->dev_attrs;
|
st->indio_dev->attrs = st->chip_info->dev_attrs;
|
||||||
|
|
||||||
/* Todo: this shouldn't be here. */
|
/* Todo: this shouldn't be here. */
|
||||||
st->indio_dev->scan_el_attrs = st->chip_info->scan_attrs;
|
|
||||||
st->indio_dev->dev_data = (void *)(st);
|
st->indio_dev->dev_data = (void *)(st);
|
||||||
st->indio_dev->driver_module = THIS_MODULE;
|
st->indio_dev->driver_module = THIS_MODULE;
|
||||||
st->indio_dev->modes = INDIO_DIRECT_MODE;
|
st->indio_dev->modes = INDIO_DIRECT_MODE;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
/* Todo: test this */
|
/* Todo: test this */
|
||||||
int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
|
int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
|
||||||
{
|
{
|
||||||
|
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||||
unsigned long numvals;
|
unsigned long numvals;
|
||||||
int count = 0, ret;
|
int count = 0, ret;
|
||||||
u8 *ring_data;
|
u8 *ring_data;
|
||||||
@ -44,8 +45,7 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
|
|||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
ret = st->indio_dev->ring->access.read_last(st->indio_dev->ring,
|
ret = ring->access.read_last(ring, ring_data);
|
||||||
ring_data);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_ring_data;
|
goto error_free_ring_data;
|
||||||
/* Need a count of channels prior to this one */
|
/* Need a count of channels prior to this one */
|
||||||
@ -77,6 +77,7 @@ error_ret:
|
|||||||
static int max1363_ring_preenable(struct iio_dev *indio_dev)
|
static int max1363_ring_preenable(struct iio_dev *indio_dev)
|
||||||
{
|
{
|
||||||
struct max1363_state *st = indio_dev->dev_data;
|
struct max1363_state *st = indio_dev->dev_data;
|
||||||
|
struct iio_ring_buffer *ring = indio_dev->ring;
|
||||||
size_t d_size;
|
size_t d_size;
|
||||||
unsigned long numvals;
|
unsigned long numvals;
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
|
|||||||
* Need to figure out the current mode based upon the requested
|
* Need to figure out the current mode based upon the requested
|
||||||
* scan mask in iio_dev
|
* scan mask in iio_dev
|
||||||
*/
|
*/
|
||||||
st->current_mode = max1363_match_mode(st->indio_dev->scan_mask,
|
st->current_mode = max1363_match_mode(ring->scan_mask,
|
||||||
st->chip_info);
|
st->chip_info);
|
||||||
if (!st->current_mode)
|
if (!st->current_mode)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -92,14 +93,14 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
|
|||||||
max1363_set_scan_mode(st);
|
max1363_set_scan_mode(st);
|
||||||
|
|
||||||
numvals = hweight_long(st->current_mode->modemask);
|
numvals = hweight_long(st->current_mode->modemask);
|
||||||
if (indio_dev->ring->access.set_bytes_per_datum) {
|
if (ring->access.set_bytes_per_datum) {
|
||||||
if (st->chip_info->bits != 8)
|
if (st->chip_info->bits != 8)
|
||||||
d_size = numvals*2 + sizeof(s64);
|
d_size = numvals*2 + sizeof(s64);
|
||||||
else
|
else
|
||||||
d_size = numvals + sizeof(s64);
|
d_size = numvals + sizeof(s64);
|
||||||
if (d_size % 8)
|
if (d_size % 8)
|
||||||
d_size += 8 - (d_size % 8);
|
d_size += 8 - (d_size % 8);
|
||||||
indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, d_size);
|
ring->access.set_bytes_per_datum(ring, d_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -135,7 +136,7 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
|
|||||||
struct max1363_state *st = container_of(work_s, struct max1363_state,
|
struct max1363_state *st = container_of(work_s, struct max1363_state,
|
||||||
poll_work);
|
poll_work);
|
||||||
struct iio_dev *indio_dev = st->indio_dev;
|
struct iio_dev *indio_dev = st->indio_dev;
|
||||||
struct iio_sw_ring_buffer *ring = iio_to_sw_ring(indio_dev->ring);
|
struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
|
||||||
s64 time_ns;
|
s64 time_ns;
|
||||||
__u8 *rxbuf;
|
__u8 *rxbuf;
|
||||||
int b_sent;
|
int b_sent;
|
||||||
@ -175,7 +176,7 @@ static void max1363_poll_bh_to_ring(struct work_struct *work_s)
|
|||||||
|
|
||||||
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
|
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
|
||||||
|
|
||||||
indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns);
|
indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
|
||||||
done:
|
done:
|
||||||
kfree(rxbuf);
|
kfree(rxbuf);
|
||||||
atomic_dec(&st->protect_ring);
|
atomic_dec(&st->protect_ring);
|
||||||
@ -193,12 +194,13 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
|
|||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
/* Effectively select the ring buffer implementation */
|
/* Effectively select the ring buffer implementation */
|
||||||
iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
|
iio_ring_sw_register_funcs(&indio_dev->ring->access);
|
||||||
ret = iio_alloc_pollfunc(indio_dev, NULL, &max1363_poll_func_th);
|
ret = iio_alloc_pollfunc(indio_dev, NULL, &max1363_poll_func_th);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_deallocate_sw_rb;
|
goto error_deallocate_sw_rb;
|
||||||
|
|
||||||
/* Ring buffer functions - here trigger setup related */
|
/* Ring buffer functions - here trigger setup related */
|
||||||
|
indio_dev->ring->scan_el_attrs = st->chip_info->scan_attrs;
|
||||||
indio_dev->ring->postenable = &iio_triggered_ring_postenable;
|
indio_dev->ring->postenable = &iio_triggered_ring_postenable;
|
||||||
indio_dev->ring->preenable = &max1363_ring_preenable;
|
indio_dev->ring->preenable = &max1363_ring_preenable;
|
||||||
indio_dev->ring->predisable = &iio_triggered_ring_predisable;
|
indio_dev->ring->predisable = &iio_triggered_ring_predisable;
|
||||||
|
@ -110,11 +110,11 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
struct adis16260_state *st
|
struct adis16260_state *st
|
||||||
= container_of(work_s, struct adis16260_state,
|
= container_of(work_s, struct adis16260_state,
|
||||||
work_trigger_to_ring);
|
work_trigger_to_ring);
|
||||||
|
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
s16 *data;
|
s16 *data;
|
||||||
size_t datasize = st->indio_dev
|
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
|
||||||
|
|
||||||
data = kmalloc(datasize , GFP_KERNEL);
|
data = kmalloc(datasize , GFP_KERNEL);
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
@ -122,17 +122,17 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->indio_dev->scan_count)
|
if (ring->scan_count)
|
||||||
if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
|
if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
|
||||||
for (; i < st->indio_dev->scan_count; i++)
|
for (; i < ring->scan_count; i++)
|
||||||
data[i] = be16_to_cpup(
|
data[i] = be16_to_cpup(
|
||||||
(__be16 *)&(st->rx[i*2]));
|
(__be16 *)&(st->rx[i*2]));
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
/* Guaranteed to be aligned with 8 byte boundary */
|
||||||
if (st->indio_dev->scan_timestamp)
|
if (ring->scan_timestamp)
|
||||||
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
||||||
|
|
||||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
ring->access.store_to(ring,
|
||||||
(u8 *)data,
|
(u8 *)data,
|
||||||
st->last_timestamp);
|
st->last_timestamp);
|
||||||
|
|
||||||
@ -154,16 +154,6 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
|
|||||||
struct adis16260_state *st = indio_dev->dev_data;
|
struct adis16260_state *st = indio_dev->dev_data;
|
||||||
struct iio_ring_buffer *ring;
|
struct iio_ring_buffer *ring;
|
||||||
INIT_WORK(&st->work_trigger_to_ring, adis16260_trigger_bh_to_ring);
|
INIT_WORK(&st->work_trigger_to_ring, adis16260_trigger_bh_to_ring);
|
||||||
/* Set default scan mode */
|
|
||||||
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_gyro.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_angl.number);
|
|
||||||
indio_dev->scan_timestamp = true;
|
|
||||||
|
|
||||||
indio_dev->scan_el_attrs = &adis16260_scan_el_group;
|
|
||||||
|
|
||||||
ring = iio_sw_rb_allocate(indio_dev);
|
ring = iio_sw_rb_allocate(indio_dev);
|
||||||
if (!ring) {
|
if (!ring) {
|
||||||
@ -174,11 +164,20 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
|
|||||||
/* Effectively select the ring buffer implementation */
|
/* Effectively select the ring buffer implementation */
|
||||||
iio_ring_sw_register_funcs(&ring->access);
|
iio_ring_sw_register_funcs(&ring->access);
|
||||||
ring->bpe = 2;
|
ring->bpe = 2;
|
||||||
|
ring->scan_el_attrs = &adis16260_scan_el_group;
|
||||||
|
ring->scan_timestamp = true;
|
||||||
ring->preenable = &iio_sw_ring_preenable;
|
ring->preenable = &iio_sw_ring_preenable;
|
||||||
ring->postenable = &iio_triggered_ring_postenable;
|
ring->postenable = &iio_triggered_ring_postenable;
|
||||||
ring->predisable = &iio_triggered_ring_predisable;
|
ring->predisable = &iio_triggered_ring_predisable;
|
||||||
ring->owner = THIS_MODULE;
|
ring->owner = THIS_MODULE;
|
||||||
|
|
||||||
|
/* Set default scan mode */
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_supply.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_gyro.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_aux_adc.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_temp.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_angl.number);
|
||||||
|
|
||||||
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16260_poll_func_th);
|
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16260_poll_func_th);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_iio_sw_rb_free;
|
goto error_iio_sw_rb_free;
|
||||||
|
@ -90,12 +90,7 @@ void iio_remove_event_from_list(struct iio_event_handler_list *el,
|
|||||||
* @ring: [DRIVER] any ring buffer present
|
* @ring: [DRIVER] any ring buffer present
|
||||||
* @mlock: [INTERN] lock used to prevent simultaneous device state
|
* @mlock: [INTERN] lock used to prevent simultaneous device state
|
||||||
* changes
|
* changes
|
||||||
* @scan_el_attrs: [DRIVER] control of scan elements if that scan mode
|
|
||||||
* control method is used
|
|
||||||
* @scan_count: [INTERN] the number of elements in the current scan mode
|
|
||||||
* @scan_mask: [INTERN] bitmask used in masking scan mode elements
|
|
||||||
* @available_scan_masks: [DRIVER] optional array of allowed bitmasks
|
* @available_scan_masks: [DRIVER] optional array of allowed bitmasks
|
||||||
* @scan_timestamp: [INTERN] does the scan mode include a timestamp
|
|
||||||
* @trig: [INTERN] current device trigger (ring buffer modes)
|
* @trig: [INTERN] current device trigger (ring buffer modes)
|
||||||
* @pollfunc: [DRIVER] function run on trigger being recieved
|
* @pollfunc: [DRIVER] function run on trigger being recieved
|
||||||
**/
|
**/
|
||||||
@ -118,104 +113,11 @@ struct iio_dev {
|
|||||||
struct iio_ring_buffer *ring;
|
struct iio_ring_buffer *ring;
|
||||||
struct mutex mlock;
|
struct mutex mlock;
|
||||||
|
|
||||||
struct attribute_group *scan_el_attrs;
|
|
||||||
int scan_count;
|
|
||||||
|
|
||||||
u32 scan_mask;
|
|
||||||
u32 *available_scan_masks;
|
u32 *available_scan_masks;
|
||||||
bool scan_timestamp;
|
|
||||||
struct iio_trigger *trig;
|
struct iio_trigger *trig;
|
||||||
struct iio_poll_func *pollfunc;
|
struct iio_poll_func *pollfunc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* These are mainly provided to allow for a change of implementation if a device
|
|
||||||
* has a large number of scan elements
|
|
||||||
*/
|
|
||||||
#define IIO_MAX_SCAN_LENGTH 31
|
|
||||||
|
|
||||||
/* note 0 used as error indicator as it doesn't make sense. */
|
|
||||||
static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
|
|
||||||
{
|
|
||||||
while (*av_masks) {
|
|
||||||
if (!(~*av_masks & mask))
|
|
||||||
return *av_masks;
|
|
||||||
av_masks++;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int iio_scan_mask_query(struct iio_dev *dev_info, int bit)
|
|
||||||
{
|
|
||||||
u32 mask;
|
|
||||||
|
|
||||||
if (bit > IIO_MAX_SCAN_LENGTH)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!dev_info->scan_mask)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (dev_info->available_scan_masks)
|
|
||||||
mask = iio_scan_mask_match(dev_info->available_scan_masks,
|
|
||||||
dev_info->scan_mask);
|
|
||||||
else
|
|
||||||
mask = dev_info->scan_mask;
|
|
||||||
|
|
||||||
if (!mask)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return !!(mask & (1 << bit));
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline int iio_scan_mask_set(struct iio_dev *dev_info, int bit)
|
|
||||||
{
|
|
||||||
u32 mask;
|
|
||||||
u32 trialmask = dev_info->scan_mask | (1 << bit);
|
|
||||||
|
|
||||||
if (bit > IIO_MAX_SCAN_LENGTH)
|
|
||||||
return -EINVAL;
|
|
||||||
if (dev_info->available_scan_masks) {
|
|
||||||
mask = iio_scan_mask_match(dev_info->available_scan_masks,
|
|
||||||
trialmask);
|
|
||||||
if (!mask)
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
dev_info->scan_mask = trialmask;
|
|
||||||
dev_info->scan_count++;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline int iio_scan_mask_clear(struct iio_dev *dev_info, int bit)
|
|
||||||
{
|
|
||||||
if (bit > IIO_MAX_SCAN_LENGTH)
|
|
||||||
return -EINVAL;
|
|
||||||
dev_info->scan_mask &= ~(1 << bit);
|
|
||||||
dev_info->scan_count--;
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* iio_scan_mask_count_to_right() - how many scan elements occur before here
|
|
||||||
* @dev_info: the iio_device whose scan mode we are querying
|
|
||||||
* @bit: which number scan element is this
|
|
||||||
**/
|
|
||||||
static inline int iio_scan_mask_count_to_right(struct iio_dev *dev_info,
|
|
||||||
int bit)
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
int mask = (1 << bit);
|
|
||||||
if (bit > IIO_MAX_SCAN_LENGTH)
|
|
||||||
return -EINVAL;
|
|
||||||
while (mask) {
|
|
||||||
mask >>= 1;
|
|
||||||
if (mask & dev_info->scan_mask)
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iio_device_register() - register a device with the IIO subsystem
|
* iio_device_register() - register a device with the IIO subsystem
|
||||||
* @dev_info: Device structure filled by the device driver
|
* @dev_info: Device structure filled by the device driver
|
||||||
|
@ -134,11 +134,11 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
struct adis16300_state *st
|
struct adis16300_state *st
|
||||||
= container_of(work_s, struct adis16300_state,
|
= container_of(work_s, struct adis16300_state,
|
||||||
work_trigger_to_ring);
|
work_trigger_to_ring);
|
||||||
|
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
s16 *data;
|
s16 *data;
|
||||||
size_t datasize = st->indio_dev
|
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
|
||||||
|
|
||||||
data = kmalloc(datasize , GFP_KERNEL);
|
data = kmalloc(datasize , GFP_KERNEL);
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
@ -146,19 +146,19 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->indio_dev->scan_count)
|
if (ring->scan_count)
|
||||||
if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
|
if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
|
||||||
for (; i < st->indio_dev->scan_count; i++)
|
for (; i < ring->scan_count; i++)
|
||||||
data[i] = be16_to_cpup(
|
data[i] = be16_to_cpup(
|
||||||
(__be16 *)&(st->rx[i*2]));
|
(__be16 *)&(st->rx[i*2]));
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
/* Guaranteed to be aligned with 8 byte boundary */
|
||||||
if (st->indio_dev->scan_timestamp)
|
if (ring->scan_timestamp)
|
||||||
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
||||||
|
|
||||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
ring->access.store_to(ring,
|
||||||
(u8 *)data,
|
(u8 *)data,
|
||||||
st->last_timestamp);
|
st->last_timestamp);
|
||||||
|
|
||||||
iio_trigger_notify_done(st->indio_dev->trig);
|
iio_trigger_notify_done(st->indio_dev->trig);
|
||||||
kfree(data);
|
kfree(data);
|
||||||
@ -178,20 +178,6 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
|
|||||||
struct adis16300_state *st = indio_dev->dev_data;
|
struct adis16300_state *st = indio_dev->dev_data;
|
||||||
struct iio_ring_buffer *ring;
|
struct iio_ring_buffer *ring;
|
||||||
INIT_WORK(&st->work_trigger_to_ring, adis16300_trigger_bh_to_ring);
|
INIT_WORK(&st->work_trigger_to_ring, adis16300_trigger_bh_to_ring);
|
||||||
/* Set default scan mode */
|
|
||||||
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
|
|
||||||
indio_dev->scan_timestamp = true;
|
|
||||||
|
|
||||||
indio_dev->scan_el_attrs = &adis16300_scan_el_group;
|
|
||||||
|
|
||||||
ring = iio_sw_rb_allocate(indio_dev);
|
ring = iio_sw_rb_allocate(indio_dev);
|
||||||
if (!ring) {
|
if (!ring) {
|
||||||
@ -202,11 +188,24 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
|
|||||||
/* Effectively select the ring buffer implementation */
|
/* Effectively select the ring buffer implementation */
|
||||||
iio_ring_sw_register_funcs(&ring->access);
|
iio_ring_sw_register_funcs(&ring->access);
|
||||||
ring->bpe = 2;
|
ring->bpe = 2;
|
||||||
|
ring->scan_el_attrs = &adis16300_scan_el_group;
|
||||||
|
ring->scan_timestamp = true;
|
||||||
ring->preenable = &iio_sw_ring_preenable;
|
ring->preenable = &iio_sw_ring_preenable;
|
||||||
ring->postenable = &iio_triggered_ring_postenable;
|
ring->postenable = &iio_triggered_ring_postenable;
|
||||||
ring->predisable = &iio_triggered_ring_predisable;
|
ring->predisable = &iio_triggered_ring_predisable;
|
||||||
ring->owner = THIS_MODULE;
|
ring->owner = THIS_MODULE;
|
||||||
|
|
||||||
|
/* Set default scan mode */
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_supply.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_temp.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_adc_0.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
|
||||||
|
|
||||||
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16300_poll_func_th);
|
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16300_poll_func_th);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_iio_sw_rb_free;
|
goto error_iio_sw_rb_free;
|
||||||
|
@ -134,11 +134,11 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
struct adis16350_state *st
|
struct adis16350_state *st
|
||||||
= container_of(work_s, struct adis16350_state,
|
= container_of(work_s, struct adis16350_state,
|
||||||
work_trigger_to_ring);
|
work_trigger_to_ring);
|
||||||
|
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
s16 *data;
|
s16 *data;
|
||||||
size_t datasize = st->indio_dev
|
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
|
||||||
|
|
||||||
data = kmalloc(datasize , GFP_KERNEL);
|
data = kmalloc(datasize , GFP_KERNEL);
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
@ -146,19 +146,19 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->indio_dev->scan_count)
|
if (ring->scan_count)
|
||||||
if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
|
if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
|
||||||
for (; i < st->indio_dev->scan_count; i++)
|
for (; i < ring->scan_count; i++)
|
||||||
data[i] = be16_to_cpup(
|
data[i] = be16_to_cpup(
|
||||||
(__be16 *)&(st->rx[i*2]));
|
(__be16 *)&(st->rx[i*2]));
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
/* Guaranteed to be aligned with 8 byte boundary */
|
||||||
if (st->indio_dev->scan_timestamp)
|
if (ring->scan_timestamp)
|
||||||
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
||||||
|
|
||||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
ring->access.store_to(ring,
|
||||||
(u8 *)data,
|
(u8 *)data,
|
||||||
st->last_timestamp);
|
st->last_timestamp);
|
||||||
|
|
||||||
iio_trigger_notify_done(st->indio_dev->trig);
|
iio_trigger_notify_done(st->indio_dev->trig);
|
||||||
kfree(data);
|
kfree(data);
|
||||||
@ -178,22 +178,6 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
|
|||||||
struct adis16350_state *st = indio_dev->dev_data;
|
struct adis16350_state *st = indio_dev->dev_data;
|
||||||
struct iio_ring_buffer *ring;
|
struct iio_ring_buffer *ring;
|
||||||
INIT_WORK(&st->work_trigger_to_ring, adis16350_trigger_bh_to_ring);
|
INIT_WORK(&st->work_trigger_to_ring, adis16350_trigger_bh_to_ring);
|
||||||
/* Set default scan mode */
|
|
||||||
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_temp_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_temp_y.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_temp_z.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
|
|
||||||
indio_dev->scan_timestamp = true;
|
|
||||||
|
|
||||||
indio_dev->scan_el_attrs = &adis16350_scan_el_group;
|
|
||||||
|
|
||||||
ring = iio_sw_rb_allocate(indio_dev);
|
ring = iio_sw_rb_allocate(indio_dev);
|
||||||
if (!ring) {
|
if (!ring) {
|
||||||
@ -204,11 +188,26 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
|
|||||||
/* Effectively select the ring buffer implementation */
|
/* Effectively select the ring buffer implementation */
|
||||||
iio_ring_sw_register_funcs(&ring->access);
|
iio_ring_sw_register_funcs(&ring->access);
|
||||||
ring->bpe = 2;
|
ring->bpe = 2;
|
||||||
|
ring->scan_el_attrs = &adis16350_scan_el_group;
|
||||||
|
ring->scan_timestamp = true;
|
||||||
ring->preenable = &iio_sw_ring_preenable;
|
ring->preenable = &iio_sw_ring_preenable;
|
||||||
ring->postenable = &iio_triggered_ring_postenable;
|
ring->postenable = &iio_triggered_ring_postenable;
|
||||||
ring->predisable = &iio_triggered_ring_predisable;
|
ring->predisable = &iio_triggered_ring_predisable;
|
||||||
ring->owner = THIS_MODULE;
|
ring->owner = THIS_MODULE;
|
||||||
|
|
||||||
|
/* Set default scan mode */
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_supply.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_gyro_y.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_gyro_z.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_temp_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_temp_y.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_temp_z.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_adc_0.number);
|
||||||
|
|
||||||
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
|
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_iio_sw_rb_free;
|
goto error_iio_sw_rb_free;
|
||||||
|
@ -143,11 +143,11 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
struct adis16400_state *st
|
struct adis16400_state *st
|
||||||
= container_of(work_s, struct adis16400_state,
|
= container_of(work_s, struct adis16400_state,
|
||||||
work_trigger_to_ring);
|
work_trigger_to_ring);
|
||||||
|
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
s16 *data;
|
s16 *data;
|
||||||
size_t datasize = st->indio_dev
|
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
|
||||||
|
|
||||||
data = kmalloc(datasize , GFP_KERNEL);
|
data = kmalloc(datasize , GFP_KERNEL);
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
@ -155,19 +155,19 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->indio_dev->scan_count)
|
if (ring->scan_count)
|
||||||
if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
|
if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
|
||||||
for (; i < st->indio_dev->scan_count; i++)
|
for (; i < ring->scan_count; i++)
|
||||||
data[i] = be16_to_cpup(
|
data[i] = be16_to_cpup(
|
||||||
(__be16 *)&(st->rx[i*2]));
|
(__be16 *)&(st->rx[i*2]));
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
/* Guaranteed to be aligned with 8 byte boundary */
|
||||||
if (st->indio_dev->scan_timestamp)
|
if (ring->scan_timestamp)
|
||||||
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
|
||||||
|
|
||||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
ring->access.store_to(ring,
|
||||||
(u8 *)data,
|
(u8 *) data,
|
||||||
st->last_timestamp);
|
st->last_timestamp);
|
||||||
|
|
||||||
iio_trigger_notify_done(st->indio_dev->trig);
|
iio_trigger_notify_done(st->indio_dev->trig);
|
||||||
kfree(data);
|
kfree(data);
|
||||||
@ -187,23 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
|
|||||||
struct adis16400_state *st = indio_dev->dev_data;
|
struct adis16400_state *st = indio_dev->dev_data;
|
||||||
struct iio_ring_buffer *ring;
|
struct iio_ring_buffer *ring;
|
||||||
INIT_WORK(&st->work_trigger_to_ring, adis16400_trigger_bh_to_ring);
|
INIT_WORK(&st->work_trigger_to_ring, adis16400_trigger_bh_to_ring);
|
||||||
/* Set default scan mode */
|
|
||||||
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_magn_x.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_magn_y.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_magn_z.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
|
|
||||||
iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
|
|
||||||
indio_dev->scan_timestamp = true;
|
|
||||||
|
|
||||||
indio_dev->scan_el_attrs = &adis16400_scan_el_group;
|
|
||||||
|
|
||||||
ring = iio_sw_rb_allocate(indio_dev);
|
ring = iio_sw_rb_allocate(indio_dev);
|
||||||
if (!ring) {
|
if (!ring) {
|
||||||
@ -214,11 +197,27 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
|
|||||||
/* Effectively select the ring buffer implementation */
|
/* Effectively select the ring buffer implementation */
|
||||||
iio_ring_sw_register_funcs(&ring->access);
|
iio_ring_sw_register_funcs(&ring->access);
|
||||||
ring->bpe = 2;
|
ring->bpe = 2;
|
||||||
|
ring->scan_el_attrs = &adis16400_scan_el_group;
|
||||||
|
ring->scan_timestamp = true;
|
||||||
ring->preenable = &iio_sw_ring_preenable;
|
ring->preenable = &iio_sw_ring_preenable;
|
||||||
ring->postenable = &iio_triggered_ring_postenable;
|
ring->postenable = &iio_triggered_ring_postenable;
|
||||||
ring->predisable = &iio_triggered_ring_predisable;
|
ring->predisable = &iio_triggered_ring_predisable;
|
||||||
ring->owner = THIS_MODULE;
|
ring->owner = THIS_MODULE;
|
||||||
|
|
||||||
|
/* Set default scan mode */
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_supply.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_gyro_y.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_gyro_z.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_magn_x.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_magn_y.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_magn_z.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_temp.number);
|
||||||
|
iio_scan_mask_set(ring, iio_scan_el_adc_0.number);
|
||||||
|
|
||||||
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
|
ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_iio_sw_rb_free;
|
goto error_iio_sw_rb_free;
|
||||||
|
@ -507,24 +507,12 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
|
|||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_info->scan_el_attrs) {
|
|
||||||
ret = sysfs_create_group(&dev_info->dev.kobj,
|
|
||||||
dev_info->scan_el_attrs);
|
|
||||||
if (ret)
|
|
||||||
dev_err(&dev_info->dev,
|
|
||||||
"Failed to add sysfs scan els\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
error_ret:
|
error_ret:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
|
static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
|
||||||
{
|
{
|
||||||
if (dev_info->scan_el_attrs)
|
|
||||||
sysfs_remove_group(&dev_info->dev.kobj,
|
|
||||||
dev_info->scan_el_attrs);
|
|
||||||
|
|
||||||
sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
|
sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,6 +279,16 @@ int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_ring_buffer_event_chrdev;
|
goto error_free_ring_buffer_event_chrdev;
|
||||||
|
|
||||||
|
if (ring->scan_el_attrs) {
|
||||||
|
ret = sysfs_create_group(&ring->dev.kobj,
|
||||||
|
ring->scan_el_attrs);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&ring->dev,
|
||||||
|
"Failed to add sysfs scan elements\n");
|
||||||
|
goto error_free_ring_buffer_event_chrdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
error_free_ring_buffer_event_chrdev:
|
error_free_ring_buffer_event_chrdev:
|
||||||
__iio_free_ring_buffer_event_chrdev(ring);
|
__iio_free_ring_buffer_event_chrdev(ring);
|
||||||
@ -291,6 +301,10 @@ EXPORT_SYMBOL(iio_ring_buffer_register);
|
|||||||
|
|
||||||
void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
|
void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
|
||||||
{
|
{
|
||||||
|
if (ring->scan_el_attrs)
|
||||||
|
sysfs_remove_group(&ring->dev.kobj,
|
||||||
|
ring->scan_el_attrs);
|
||||||
|
|
||||||
__iio_free_ring_buffer_access_chrdev(ring);
|
__iio_free_ring_buffer_access_chrdev(ring);
|
||||||
__iio_free_ring_buffer_event_chrdev(ring);
|
__iio_free_ring_buffer_event_chrdev(ring);
|
||||||
device_del(&ring->dev);
|
device_del(&ring->dev);
|
||||||
@ -465,10 +479,10 @@ ssize_t iio_scan_el_show(struct device *dev,
|
|||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
struct iio_ring_buffer *ring = dev_get_drvdata(dev);
|
||||||
struct iio_scan_el *this_el = to_iio_scan_el(attr);
|
struct iio_scan_el *this_el = to_iio_scan_el(attr);
|
||||||
|
|
||||||
ret = iio_scan_mask_query(indio_dev, this_el->number);
|
ret = iio_scan_mask_query(ring, this_el->number);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
return sprintf(buf, "%d\n", ret);
|
return sprintf(buf, "%d\n", ret);
|
||||||
@ -482,7 +496,8 @@ ssize_t iio_scan_el_store(struct device *dev,
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool state;
|
bool state;
|
||||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
struct iio_ring_buffer *ring = dev_get_drvdata(dev);
|
||||||
|
struct iio_dev *indio_dev = ring->indio_dev;
|
||||||
struct iio_scan_el *this_el = to_iio_scan_el(attr);
|
struct iio_scan_el *this_el = to_iio_scan_el(attr);
|
||||||
|
|
||||||
state = !(buf[0] == '0');
|
state = !(buf[0] == '0');
|
||||||
@ -491,19 +506,17 @@ ssize_t iio_scan_el_store(struct device *dev,
|
|||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
ret = iio_scan_mask_query(indio_dev, this_el->number);
|
ret = iio_scan_mask_query(ring, this_el->number);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
if (!state && ret) {
|
if (!state && ret) {
|
||||||
ret = iio_scan_mask_clear(indio_dev, this_el->number);
|
ret = iio_scan_mask_clear(ring, this_el->number);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
indio_dev->scan_count--;
|
|
||||||
} else if (state && !ret) {
|
} else if (state && !ret) {
|
||||||
ret = iio_scan_mask_set(indio_dev, this_el->number);
|
ret = iio_scan_mask_set(ring, this_el->number);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
indio_dev->scan_count++;
|
|
||||||
}
|
}
|
||||||
if (this_el->set_state)
|
if (this_el->set_state)
|
||||||
ret = this_el->set_state(this_el, indio_dev, state);
|
ret = this_el->set_state(this_el, indio_dev, state);
|
||||||
@ -519,8 +532,8 @@ ssize_t iio_scan_el_ts_show(struct device *dev,
|
|||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
struct iio_ring_buffer *ring = dev_get_drvdata(dev);
|
||||||
return sprintf(buf, "%d\n", indio_dev->scan_timestamp);
|
return sprintf(buf, "%d\n", ring->scan_timestamp);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iio_scan_el_ts_show);
|
EXPORT_SYMBOL(iio_scan_el_ts_show);
|
||||||
|
|
||||||
@ -530,7 +543,8 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
|
|||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
struct iio_ring_buffer *ring = dev_get_drvdata(dev);
|
||||||
|
struct iio_dev *indio_dev = ring->indio_dev;
|
||||||
bool state;
|
bool state;
|
||||||
state = !(buf[0] == '0');
|
state = !(buf[0] == '0');
|
||||||
mutex_lock(&indio_dev->mlock);
|
mutex_lock(&indio_dev->mlock);
|
||||||
@ -538,7 +552,7 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
|
|||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
indio_dev->scan_timestamp = state;
|
ring->scan_timestamp = state;
|
||||||
error_ret:
|
error_ret:
|
||||||
mutex_unlock(&indio_dev->mlock);
|
mutex_unlock(&indio_dev->mlock);
|
||||||
|
|
||||||
|
@ -102,6 +102,11 @@ struct iio_ring_access_funcs {
|
|||||||
* @bytes_per_datum [DEVICE] size of individual datum including timestamp
|
* @bytes_per_datum [DEVICE] size of individual datum including timestamp
|
||||||
* @bpe: [DEVICE] size of individual channel value
|
* @bpe: [DEVICE] size of individual channel value
|
||||||
* @loopcount: [INTERN] number of times the ring has looped
|
* @loopcount: [INTERN] number of times the ring has looped
|
||||||
|
* @scan_el_attrs: [DRIVER] control of scan elements if that scan mode
|
||||||
|
* control method is used
|
||||||
|
* @scan_count: [INTERN] the number of elements in the current scan mode
|
||||||
|
* @scan_mask: [INTERN] bitmask used in masking scan mode elements
|
||||||
|
* @scan_timestamp: [INTERN] does the scan mode include a timestamp
|
||||||
* @access_handler: [INTERN] chrdev access handling
|
* @access_handler: [INTERN] chrdev access handling
|
||||||
* @ev_int: [INTERN] chrdev interface for the event chrdev
|
* @ev_int: [INTERN] chrdev interface for the event chrdev
|
||||||
* @shared_ev_pointer: [INTERN] the shared event pointer to allow escalation of
|
* @shared_ev_pointer: [INTERN] the shared event pointer to allow escalation of
|
||||||
@ -124,6 +129,10 @@ struct iio_ring_buffer {
|
|||||||
int bytes_per_datum;
|
int bytes_per_datum;
|
||||||
int bpe;
|
int bpe;
|
||||||
int loopcount;
|
int loopcount;
|
||||||
|
struct attribute_group *scan_el_attrs;
|
||||||
|
int scan_count;
|
||||||
|
u32 scan_mask;
|
||||||
|
bool scan_timestamp;
|
||||||
struct iio_handler access_handler;
|
struct iio_handler access_handler;
|
||||||
struct iio_event_interface ev_int;
|
struct iio_event_interface ev_int;
|
||||||
struct iio_shared_ev_pointer shared_ev_pointer;
|
struct iio_shared_ev_pointer shared_ev_pointer;
|
||||||
@ -258,6 +267,97 @@ ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
|
|||||||
iio_scan_el_ts_store), \
|
iio_scan_el_ts_store), \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are mainly provided to allow for a change of implementation if a device
|
||||||
|
* has a large number of scan elements
|
||||||
|
*/
|
||||||
|
#define IIO_MAX_SCAN_LENGTH 31
|
||||||
|
|
||||||
|
/* note 0 used as error indicator as it doesn't make sense. */
|
||||||
|
static inline u32 iio_scan_mask_match(u32 *av_masks, u32 mask)
|
||||||
|
{
|
||||||
|
while (*av_masks) {
|
||||||
|
if (!(~*av_masks & mask))
|
||||||
|
return *av_masks;
|
||||||
|
av_masks++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int iio_scan_mask_query(struct iio_ring_buffer *ring, int bit)
|
||||||
|
{
|
||||||
|
struct iio_dev *dev_info = ring->indio_dev;
|
||||||
|
u32 mask;
|
||||||
|
|
||||||
|
if (bit > IIO_MAX_SCAN_LENGTH)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!ring->scan_mask)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (dev_info->available_scan_masks)
|
||||||
|
mask = iio_scan_mask_match(dev_info->available_scan_masks,
|
||||||
|
ring->scan_mask);
|
||||||
|
else
|
||||||
|
mask = ring->scan_mask;
|
||||||
|
|
||||||
|
if (!mask)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return !!(mask & (1 << bit));
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int iio_scan_mask_set(struct iio_ring_buffer *ring, int bit)
|
||||||
|
{
|
||||||
|
struct iio_dev *dev_info = ring->indio_dev;
|
||||||
|
u32 mask;
|
||||||
|
u32 trialmask = ring->scan_mask | (1 << bit);
|
||||||
|
|
||||||
|
if (bit > IIO_MAX_SCAN_LENGTH)
|
||||||
|
return -EINVAL;
|
||||||
|
if (dev_info->available_scan_masks) {
|
||||||
|
mask = iio_scan_mask_match(dev_info->available_scan_masks,
|
||||||
|
trialmask);
|
||||||
|
if (!mask)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
ring->scan_mask = trialmask;
|
||||||
|
ring->scan_count++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
|
||||||
|
{
|
||||||
|
if (bit > IIO_MAX_SCAN_LENGTH)
|
||||||
|
return -EINVAL;
|
||||||
|
ring->scan_mask &= ~(1 << bit);
|
||||||
|
ring->scan_count--;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iio_scan_mask_count_to_right() - how many scan elements occur before here
|
||||||
|
* @dev_info: the iio_device whose scan mode we are querying
|
||||||
|
* @bit: which number scan element is this
|
||||||
|
**/
|
||||||
|
static inline int iio_scan_mask_count_to_right(struct iio_ring_buffer *ring,
|
||||||
|
int bit)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
int mask = (1 << bit);
|
||||||
|
if (bit > IIO_MAX_SCAN_LENGTH)
|
||||||
|
return -EINVAL;
|
||||||
|
while (mask) {
|
||||||
|
mask >>= 1;
|
||||||
|
if (mask & ring->scan_mask)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
|
static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
|
||||||
{
|
{
|
||||||
put_device(&ring->dev);
|
put_device(&ring->dev);
|
||||||
|
@ -435,23 +435,24 @@ EXPORT_SYMBOL(iio_sw_rb_free);
|
|||||||
|
|
||||||
int iio_sw_ring_preenable(struct iio_dev *indio_dev)
|
int iio_sw_ring_preenable(struct iio_dev *indio_dev)
|
||||||
{
|
{
|
||||||
|
struct iio_ring_buffer *ring = indio_dev->ring;
|
||||||
size_t size;
|
size_t size;
|
||||||
dev_dbg(&indio_dev->dev, "%s\n", __func__);
|
dev_dbg(&indio_dev->dev, "%s\n", __func__);
|
||||||
/* Check if there are any scan elements enabled, if not fail*/
|
/* Check if there are any scan elements enabled, if not fail*/
|
||||||
if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
|
if (!(ring->scan_count || ring->scan_timestamp))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (indio_dev->scan_timestamp)
|
if (ring->scan_timestamp)
|
||||||
if (indio_dev->scan_count)
|
if (ring->scan_count)
|
||||||
/* Timestamp (aligned to s64) and data */
|
/* Timestamp (aligned to s64) and data */
|
||||||
size = (((indio_dev->scan_count * indio_dev->ring->bpe)
|
size = (((ring->scan_count * ring->bpe)
|
||||||
+ sizeof(s64) - 1)
|
+ sizeof(s64) - 1)
|
||||||
& ~(sizeof(s64) - 1))
|
& ~(sizeof(s64) - 1))
|
||||||
+ sizeof(s64);
|
+ sizeof(s64);
|
||||||
else /* Timestamp only */
|
else /* Timestamp only */
|
||||||
size = sizeof(s64);
|
size = sizeof(s64);
|
||||||
else /* Data only */
|
else /* Data only */
|
||||||
size = indio_dev->scan_count * indio_dev->ring->bpe;
|
size = ring->scan_count * ring->bpe;
|
||||||
indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, size);
|
ring->access.set_bytes_per_datum(ring, size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -462,9 +463,9 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
struct iio_sw_ring_helper_state *st
|
struct iio_sw_ring_helper_state *st
|
||||||
= container_of(work_s, struct iio_sw_ring_helper_state,
|
= container_of(work_s, struct iio_sw_ring_helper_state,
|
||||||
work_trigger_to_ring);
|
work_trigger_to_ring);
|
||||||
|
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
size_t datasize = st->indio_dev
|
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
|
||||||
char *data = kmalloc(datasize, GFP_KERNEL);
|
char *data = kmalloc(datasize, GFP_KERNEL);
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
@ -473,16 +474,16 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->indio_dev->scan_count)
|
if (ring->scan_count)
|
||||||
len = st->get_ring_element(st, data);
|
len = st->get_ring_element(st, data);
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
/* Guaranteed to be aligned with 8 byte boundary */
|
||||||
if (st->indio_dev->scan_timestamp)
|
if (ring->scan_timestamp)
|
||||||
*(s64 *)(((phys_addr_t)data + len
|
*(s64 *)(((phys_addr_t)data + len
|
||||||
+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
|
+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
|
||||||
= st->last_timestamp;
|
= st->last_timestamp;
|
||||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
ring->access.store_to(ring,
|
||||||
(u8 *)data,
|
(u8 *)data,
|
||||||
st->last_timestamp);
|
st->last_timestamp);
|
||||||
|
|
||||||
iio_trigger_notify_done(st->indio_dev->trig);
|
iio_trigger_notify_done(st->indio_dev->trig);
|
||||||
|
Loading…
Reference in New Issue
Block a user