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) {
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);
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) {
/* 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;
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) {
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);
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) {
/* 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;
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;
**/
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;
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];
* 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);
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);
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)
/* 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;;
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;
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;
/* 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;
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 */
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;
* 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;
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;
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;
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);
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;
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) {
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);
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) {
/* 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;
* @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
**/
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
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) {
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);
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) {
/* 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;
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) {
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);
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) {
/* 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;
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) {
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);
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) {
/* 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;
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);
}
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);
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);
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);
{
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');
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);
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);
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);
ret = -EBUSY;
goto error_ret;
}
- indio_dev->scan_timestamp = state;
+ ring->scan_timestamp = state;
error_ret:
mutex_unlock(&indio_dev->mlock);
* @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
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;
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);
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;
}
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) {
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);