mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-29 23:53:32 +00:00
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
15 changed files with 292 additions and 289 deletions
|
@ -115,11 +115,11 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
|
|||
struct adis16209_state *st
|
||||
= container_of(work_s, struct adis16209_state,
|
||||
work_trigger_to_ring);
|
||||
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||
|
||||
int i = 0;
|
||||
s16 *data;
|
||||
size_t datasize = st->indio_dev
|
||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
||||
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||
|
||||
data = kmalloc(datasize , GFP_KERNEL);
|
||||
if (data == NULL) {
|
||||
|
@ -127,19 +127,19 @@ static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
|
|||
return;
|
||||
}
|
||||
|
||||
if (st->indio_dev->scan_count)
|
||||
if (ring->scan_count)
|
||||
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(
|
||||
(__be16 *)&(st->rx[i*2]));
|
||||
|
||||
/* 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;
|
||||
|
||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
||||
(u8 *)data,
|
||||
st->last_timestamp);
|
||||
ring->access.store_to(ring,
|
||||
(u8 *)data,
|
||||
st->last_timestamp);
|
||||
|
||||
iio_trigger_notify_done(st->indio_dev->trig);
|
||||
kfree(data);
|
||||
|
@ -159,19 +159,6 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
|
|||
struct adis16209_state *st = indio_dev->dev_data;
|
||||
struct iio_ring_buffer *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);
|
||||
if (!ring) {
|
||||
|
@ -182,11 +169,23 @@ int adis16209_configure_ring(struct iio_dev *indio_dev)
|
|||
/* Effectively select the ring buffer implementation */
|
||||
iio_ring_sw_register_funcs(&ring->access);
|
||||
ring->bpe = 2;
|
||||
ring->scan_el_attrs = &adis16209_scan_el_group;
|
||||
ring->scan_timestamp = true;
|
||||
ring->preenable = &iio_sw_ring_preenable;
|
||||
ring->postenable = &iio_triggered_ring_postenable;
|
||||
ring->predisable = &iio_triggered_ring_predisable;
|
||||
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);
|
||||
if (ret)
|
||||
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
|
||||
= container_of(work_s, struct adis16240_state,
|
||||
work_trigger_to_ring);
|
||||
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||
|
||||
int i = 0;
|
||||
s16 *data;
|
||||
size_t datasize = st->indio_dev
|
||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
||||
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||
|
||||
data = kmalloc(datasize , GFP_KERNEL);
|
||||
if (data == NULL) {
|
||||
|
@ -119,17 +119,17 @@ static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
|
|||
return;
|
||||
}
|
||||
|
||||
if (st->indio_dev->scan_count)
|
||||
if (ring->scan_count)
|
||||
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(
|
||||
(__be16 *)&(st->rx[i*2]));
|
||||
|
||||
/* 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;
|
||||
|
||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
||||
ring->access.store_to(ring,
|
||||
(u8 *)data,
|
||||
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 iio_ring_buffer *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);
|
||||
if (!ring) {
|
||||
|
@ -172,11 +161,21 @@ int adis16240_configure_ring(struct iio_dev *indio_dev)
|
|||
/* Effectively select the ring buffer implementation */
|
||||
iio_ring_sw_register_funcs(&ring->access);
|
||||
ring->bpe = 2;
|
||||
ring->scan_el_attrs = &adis16240_scan_el_group;
|
||||
ring->scan_timestamp = true;
|
||||
ring->preenable = &iio_sw_ring_preenable;
|
||||
ring->postenable = &iio_triggered_ring_postenable;
|
||||
ring->predisable = &iio_triggered_ring_predisable;
|
||||
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);
|
||||
if (ret)
|
||||
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;
|
||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||
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;
|
||||
|
||||
while (dev_info->scan_el_attrs->attrs[i]) {
|
||||
while (scan_el_attrs->attrs[i]) {
|
||||
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 */
|
||||
if (el->label == this_attr->address)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
if (!dev_info->scan_el_attrs->attrs[i]) {
|
||||
if (!scan_el_attrs->attrs[i]) {
|
||||
ret = -EINVAL;
|
||||
goto error_ret;
|
||||
}
|
||||
/* 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)
|
||||
goto error_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);
|
||||
if (data == NULL)
|
||||
return -ENOMEM;
|
||||
ret = dev_info->ring->access.read_last(dev_info->ring,
|
||||
(u8 *)data);
|
||||
ret = ring->access.read_last(ring,
|
||||
(u8 *)data);
|
||||
if (ret)
|
||||
goto error_free_data;
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
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) {
|
||||
ret = len;
|
||||
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)
|
||||
{
|
||||
struct iio_ring_buffer *ring = st->help.indio_dev->ring;
|
||||
struct spi_transfer *xfers;
|
||||
struct spi_message msg;
|
||||
int ret, i, j = 0;
|
||||
|
||||
xfers = kzalloc((st->help.indio_dev->scan_count) * 2
|
||||
xfers = kzalloc((ring->scan_count) * 2
|
||||
* sizeof(*xfers), GFP_KERNEL);
|
||||
if (!xfers)
|
||||
return -ENOMEM;
|
||||
|
@ -223,7 +226,7 @@ static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
|
|||
mutex_lock(&st->buf_lock);
|
||||
|
||||
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 */
|
||||
xfers[j].tx_buf = st->tx + 2*j;
|
||||
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
|
||||
*/
|
||||
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);
|
||||
|
||||
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 ;
|
||||
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)
|
||||
return -ENOMEM;
|
||||
ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
|
||||
if (ret < 0)
|
||||
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],
|
||||
rx_array[i*4+3]);
|
||||
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_ring_buffer *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;
|
||||
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);
|
||||
if (!ring)
|
||||
|
@ -498,11 +494,18 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
|
|||
/* Effectively select the ring buffer implementation */
|
||||
iio_ring_sw_register_funcs(&ring->access);
|
||||
ring->bpe = 2;
|
||||
ring->scan_el_attrs = &lis3l02dq_scan_el_group;
|
||||
ring->scan_timestamp = true;
|
||||
ring->preenable = &iio_sw_ring_preenable;
|
||||
ring->postenable = &iio_triggered_ring_postenable;
|
||||
ring->predisable = &iio_triggered_ring_predisable;
|
||||
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);
|
||||
if (ret)
|
||||
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)
|
||||
{
|
||||
indio_dev->scan_el_attrs = &sca3000_scan_el_group;
|
||||
indio_dev->ring = sca3000_rb_allocate(indio_dev);
|
||||
if (indio_dev->ring == NULL)
|
||||
return -ENOMEM;
|
||||
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.get_length = &sca3000_ring_get_length;
|
||||
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;
|
||||
|
||||
/* 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->driver_module = THIS_MODULE;
|
||||
st->indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
/* Todo: test this */
|
||||
int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
|
||||
{
|
||||
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||
unsigned long numvals;
|
||||
int count = 0, ret;
|
||||
u8 *ring_data;
|
||||
|
@ -44,8 +45,7 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
|
|||
ret = -ENOMEM;
|
||||
goto error_ret;
|
||||
}
|
||||
ret = st->indio_dev->ring->access.read_last(st->indio_dev->ring,
|
||||
ring_data);
|
||||
ret = ring->access.read_last(ring, ring_data);
|
||||
if (ret)
|
||||
goto error_free_ring_data;
|
||||
/* Need a count of channels prior to this one */
|
||||
|
@ -77,6 +77,7 @@ int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
|
|||
static int max1363_ring_preenable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct max1363_state *st = indio_dev->dev_data;
|
||||
struct iio_ring_buffer *ring = indio_dev->ring;
|
||||
size_t d_size;
|
||||
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
|
||||
* 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);
|
||||
if (!st->current_mode)
|
||||
return -EINVAL;
|
||||
|
@ -92,14 +93,14 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev)
|
|||
max1363_set_scan_mode(st);
|
||||
|
||||
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)
|
||||
d_size = numvals*2 + sizeof(s64);
|
||||
else
|
||||
d_size = numvals + sizeof(s64);
|
||||
if (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;
|
||||
|
@ -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,
|
||||
poll_work);
|
||||
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;
|
||||
__u8 *rxbuf;
|
||||
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));
|
||||
|
||||
indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns);
|
||||
indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
|
||||
done:
|
||||
kfree(rxbuf);
|
||||
atomic_dec(&st->protect_ring);
|
||||
|
@ -193,12 +194,13 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
|
|||
goto error_ret;
|
||||
}
|
||||
/* 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);
|
||||
if (ret)
|
||||
goto error_deallocate_sw_rb;
|
||||
|
||||
/* 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->preenable = &max1363_ring_preenable;
|
||||
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
|
||||
= container_of(work_s, struct adis16260_state,
|
||||
work_trigger_to_ring);
|
||||
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||
|
||||
int i = 0;
|
||||
s16 *data;
|
||||
size_t datasize = st->indio_dev
|
||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
||||
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||
|
||||
data = kmalloc(datasize , GFP_KERNEL);
|
||||
if (data == NULL) {
|
||||
|
@ -122,17 +122,17 @@ static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
|
|||
return;
|
||||
}
|
||||
|
||||
if (st->indio_dev->scan_count)
|
||||
if (ring->scan_count)
|
||||
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(
|
||||
(__be16 *)&(st->rx[i*2]));
|
||||
|
||||
/* 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;
|
||||
|
||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
||||
ring->access.store_to(ring,
|
||||
(u8 *)data,
|
||||
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 iio_ring_buffer *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);
|
||||
if (!ring) {
|
||||
|
@ -174,11 +164,20 @@ int adis16260_configure_ring(struct iio_dev *indio_dev)
|
|||
/* Effectively select the ring buffer implementation */
|
||||
iio_ring_sw_register_funcs(&ring->access);
|
||||
ring->bpe = 2;
|
||||
ring->scan_el_attrs = &adis16260_scan_el_group;
|
||||
ring->scan_timestamp = true;
|
||||
ring->preenable = &iio_sw_ring_preenable;
|
||||
ring->postenable = &iio_triggered_ring_postenable;
|
||||
ring->predisable = &iio_triggered_ring_predisable;
|
||||
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);
|
||||
if (ret)
|
||||
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
|
||||
* @mlock: [INTERN] lock used to prevent simultaneous device state
|
||||
* 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
|
||||
* @scan_timestamp: [INTERN] does the scan mode include a timestamp
|
||||
* @trig: [INTERN] current device trigger (ring buffer modes)
|
||||
* @pollfunc: [DRIVER] function run on trigger being recieved
|
||||
**/
|
||||
|
@ -118,104 +113,11 @@ struct iio_dev {
|
|||
struct iio_ring_buffer *ring;
|
||||
struct mutex mlock;
|
||||
|
||||
struct attribute_group *scan_el_attrs;
|
||||
int scan_count;
|
||||
|
||||
u32 scan_mask;
|
||||
u32 *available_scan_masks;
|
||||
bool scan_timestamp;
|
||||
struct iio_trigger *trig;
|
||||
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
|
||||
* @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
|
||||
= container_of(work_s, struct adis16300_state,
|
||||
work_trigger_to_ring);
|
||||
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||
|
||||
int i = 0;
|
||||
s16 *data;
|
||||
size_t datasize = st->indio_dev
|
||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
||||
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||
|
||||
data = kmalloc(datasize , GFP_KERNEL);
|
||||
if (data == NULL) {
|
||||
|
@ -146,19 +146,19 @@ static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
|
|||
return;
|
||||
}
|
||||
|
||||
if (st->indio_dev->scan_count)
|
||||
if (ring->scan_count)
|
||||
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(
|
||||
(__be16 *)&(st->rx[i*2]));
|
||||
|
||||
/* 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;
|
||||
|
||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
||||
(u8 *)data,
|
||||
st->last_timestamp);
|
||||
ring->access.store_to(ring,
|
||||
(u8 *)data,
|
||||
st->last_timestamp);
|
||||
|
||||
iio_trigger_notify_done(st->indio_dev->trig);
|
||||
kfree(data);
|
||||
|
@ -178,20 +178,6 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
|
|||
struct adis16300_state *st = indio_dev->dev_data;
|
||||
struct iio_ring_buffer *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);
|
||||
if (!ring) {
|
||||
|
@ -202,11 +188,24 @@ int adis16300_configure_ring(struct iio_dev *indio_dev)
|
|||
/* Effectively select the ring buffer implementation */
|
||||
iio_ring_sw_register_funcs(&ring->access);
|
||||
ring->bpe = 2;
|
||||
ring->scan_el_attrs = &adis16300_scan_el_group;
|
||||
ring->scan_timestamp = true;
|
||||
ring->preenable = &iio_sw_ring_preenable;
|
||||
ring->postenable = &iio_triggered_ring_postenable;
|
||||
ring->predisable = &iio_triggered_ring_predisable;
|
||||
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);
|
||||
if (ret)
|
||||
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
|
||||
= container_of(work_s, struct adis16350_state,
|
||||
work_trigger_to_ring);
|
||||
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||
|
||||
int i = 0;
|
||||
s16 *data;
|
||||
size_t datasize = st->indio_dev
|
||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
||||
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||
|
||||
data = kmalloc(datasize , GFP_KERNEL);
|
||||
if (data == NULL) {
|
||||
|
@ -146,19 +146,19 @@ static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
|
|||
return;
|
||||
}
|
||||
|
||||
if (st->indio_dev->scan_count)
|
||||
if (ring->scan_count)
|
||||
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(
|
||||
(__be16 *)&(st->rx[i*2]));
|
||||
|
||||
/* 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;
|
||||
|
||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
||||
(u8 *)data,
|
||||
st->last_timestamp);
|
||||
ring->access.store_to(ring,
|
||||
(u8 *)data,
|
||||
st->last_timestamp);
|
||||
|
||||
iio_trigger_notify_done(st->indio_dev->trig);
|
||||
kfree(data);
|
||||
|
@ -178,22 +178,6 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
|
|||
struct adis16350_state *st = indio_dev->dev_data;
|
||||
struct iio_ring_buffer *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);
|
||||
if (!ring) {
|
||||
|
@ -204,11 +188,26 @@ int adis16350_configure_ring(struct iio_dev *indio_dev)
|
|||
/* Effectively select the ring buffer implementation */
|
||||
iio_ring_sw_register_funcs(&ring->access);
|
||||
ring->bpe = 2;
|
||||
ring->scan_el_attrs = &adis16350_scan_el_group;
|
||||
ring->scan_timestamp = true;
|
||||
ring->preenable = &iio_sw_ring_preenable;
|
||||
ring->postenable = &iio_triggered_ring_postenable;
|
||||
ring->predisable = &iio_triggered_ring_predisable;
|
||||
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);
|
||||
if (ret)
|
||||
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
|
||||
= container_of(work_s, struct adis16400_state,
|
||||
work_trigger_to_ring);
|
||||
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||
|
||||
int i = 0;
|
||||
s16 *data;
|
||||
size_t datasize = st->indio_dev
|
||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
||||
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||
|
||||
data = kmalloc(datasize , GFP_KERNEL);
|
||||
if (data == NULL) {
|
||||
|
@ -155,19 +155,19 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
|
|||
return;
|
||||
}
|
||||
|
||||
if (st->indio_dev->scan_count)
|
||||
if (ring->scan_count)
|
||||
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(
|
||||
(__be16 *)&(st->rx[i*2]));
|
||||
|
||||
/* 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;
|
||||
|
||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
||||
(u8 *)data,
|
||||
st->last_timestamp);
|
||||
ring->access.store_to(ring,
|
||||
(u8 *) data,
|
||||
st->last_timestamp);
|
||||
|
||||
iio_trigger_notify_done(st->indio_dev->trig);
|
||||
kfree(data);
|
||||
|
@ -187,23 +187,6 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
|
|||
struct adis16400_state *st = indio_dev->dev_data;
|
||||
struct iio_ring_buffer *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);
|
||||
if (!ring) {
|
||||
|
@ -214,11 +197,27 @@ int adis16400_configure_ring(struct iio_dev *indio_dev)
|
|||
/* Effectively select the ring buffer implementation */
|
||||
iio_ring_sw_register_funcs(&ring->access);
|
||||
ring->bpe = 2;
|
||||
ring->scan_el_attrs = &adis16400_scan_el_group;
|
||||
ring->scan_timestamp = true;
|
||||
ring->preenable = &iio_sw_ring_preenable;
|
||||
ring->postenable = &iio_triggered_ring_postenable;
|
||||
ring->predisable = &iio_triggered_ring_predisable;
|
||||
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);
|
||||
if (ret)
|
||||
goto error_iio_sw_rb_free;
|
||||
|
|
|
@ -507,24 +507,12 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info)
|
|||
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:
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -279,6 +279,16 @@ int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
|
|||
if (ret)
|
||||
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;
|
||||
error_free_ring_buffer_event_chrdev:
|
||||
__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)
|
||||
{
|
||||
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_event_chrdev(ring);
|
||||
device_del(&ring->dev);
|
||||
|
@ -465,10 +479,10 @@ ssize_t iio_scan_el_show(struct device *dev,
|
|||
char *buf)
|
||||
{
|
||||
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);
|
||||
|
||||
ret = iio_scan_mask_query(indio_dev, this_el->number);
|
||||
ret = iio_scan_mask_query(ring, this_el->number);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return sprintf(buf, "%d\n", ret);
|
||||
|
@ -482,7 +496,8 @@ ssize_t iio_scan_el_store(struct device *dev,
|
|||
{
|
||||
int ret = 0;
|
||||
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);
|
||||
|
||||
state = !(buf[0] == '0');
|
||||
|
@ -491,19 +506,17 @@ ssize_t iio_scan_el_store(struct device *dev,
|
|||
ret = -EBUSY;
|
||||
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)
|
||||
goto error_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)
|
||||
goto error_ret;
|
||||
indio_dev->scan_count--;
|
||||
} 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)
|
||||
goto error_ret;
|
||||
indio_dev->scan_count++;
|
||||
}
|
||||
if (this_el->set_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,
|
||||
char *buf)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
return sprintf(buf, "%d\n", indio_dev->scan_timestamp);
|
||||
struct iio_ring_buffer *ring = dev_get_drvdata(dev);
|
||||
return sprintf(buf, "%d\n", ring->scan_timestamp);
|
||||
}
|
||||
EXPORT_SYMBOL(iio_scan_el_ts_show);
|
||||
|
||||
|
@ -530,7 +543,8 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
|
|||
size_t len)
|
||||
{
|
||||
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;
|
||||
state = !(buf[0] == '0');
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
|
@ -538,7 +552,7 @@ ssize_t iio_scan_el_ts_store(struct device *dev,
|
|||
ret = -EBUSY;
|
||||
goto error_ret;
|
||||
}
|
||||
indio_dev->scan_timestamp = state;
|
||||
ring->scan_timestamp = state;
|
||||
error_ret:
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
|
||||
|
|
|
@ -102,6 +102,11 @@ struct iio_ring_access_funcs {
|
|||
* @bytes_per_datum [DEVICE] size of individual datum including timestamp
|
||||
* @bpe: [DEVICE] size of individual channel value
|
||||
* @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
|
||||
* @ev_int: [INTERN] chrdev interface for the event chrdev
|
||||
* @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 bpe;
|
||||
int loopcount;
|
||||
struct attribute_group *scan_el_attrs;
|
||||
int scan_count;
|
||||
u32 scan_mask;
|
||||
bool scan_timestamp;
|
||||
struct iio_handler access_handler;
|
||||
struct iio_event_interface ev_int;
|
||||
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), \
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
put_device(&ring->dev);
|
||||
|
|
|
@ -435,23 +435,24 @@ EXPORT_SYMBOL(iio_sw_rb_free);
|
|||
|
||||
int iio_sw_ring_preenable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct iio_ring_buffer *ring = indio_dev->ring;
|
||||
size_t size;
|
||||
dev_dbg(&indio_dev->dev, "%s\n", __func__);
|
||||
/* 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;
|
||||
if (indio_dev->scan_timestamp)
|
||||
if (indio_dev->scan_count)
|
||||
if (ring->scan_timestamp)
|
||||
if (ring->scan_count)
|
||||
/* 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);
|
||||
else /* Timestamp only */
|
||||
size = sizeof(s64);
|
||||
else /* Data only */
|
||||
size = indio_dev->scan_count * indio_dev->ring->bpe;
|
||||
indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, size);
|
||||
size = ring->scan_count * ring->bpe;
|
||||
ring->access.set_bytes_per_datum(ring, size);
|
||||
|
||||
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
|
||||
= container_of(work_s, struct iio_sw_ring_helper_state,
|
||||
work_trigger_to_ring);
|
||||
struct iio_ring_buffer *ring = st->indio_dev->ring;
|
||||
int len = 0;
|
||||
size_t datasize = st->indio_dev
|
||||
->ring->access.get_bytes_per_datum(st->indio_dev->ring);
|
||||
size_t datasize = ring->access.get_bytes_per_datum(ring);
|
||||
char *data = kmalloc(datasize, GFP_KERNEL);
|
||||
|
||||
if (data == NULL) {
|
||||
|
@ -473,16 +474,16 @@ void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
|
|||
return;
|
||||
}
|
||||
|
||||
if (st->indio_dev->scan_count)
|
||||
if (ring->scan_count)
|
||||
len = st->get_ring_element(st, data);
|
||||
|
||||
/* Guaranteed to be aligned with 8 byte boundary */
|
||||
if (st->indio_dev->scan_timestamp)
|
||||
if (ring->scan_timestamp)
|
||||
*(s64 *)(((phys_addr_t)data + len
|
||||
+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
|
||||
= st->last_timestamp;
|
||||
st->indio_dev->ring->access.store_to(st->indio_dev->ring,
|
||||
(u8 *)data,
|
||||
ring->access.store_to(ring,
|
||||
(u8 *)data,
|
||||
st->last_timestamp);
|
||||
|
||||
iio_trigger_notify_done(st->indio_dev->trig);
|
||||
|
|
Loading…
Reference in a new issue