static void lis3l02dq_trigger_bh_to_ring(struct work_struct *work_s) { struct lis3l02dq_state *st = container_of(work_s, struct lis3l02dq_state, work_trigger_to_ring); u8 *rx_array; int i = 0; u16 *data; size_t datasize = st->indio_dev ->ring->access.get_bpd(st->indio_dev->ring); data = kmalloc(datasize , GFP_KERNEL); if (data == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); return; } /* Due to interleaved nature of transmission this buffer must be * twice the number of bytes, or 4 times the number of channels */ rx_array = kmalloc(4 * (st->indio_dev->scan_count), GFP_KERNEL); if (rx_array == NULL) { dev_err(&st->us->dev, "memory alloc failed in ring bh"); kfree(data); return; } /* whilst trigger specific, if this read does nto occur the data ready interrupt will not be cleared. Need to add a mechanism to provide a dummy read function if this is not triggering on the data ready function but something else is. */ st->inter = 0; if (st->indio_dev->scan_count) if (lis3l02dq_read_all(st, rx_array) >= 0) for (; i < st->indio_dev->scan_count; i++) data[i] = combine_8_to_16(rx_array[i*4+1], rx_array[i*4+3]); /* Guaranteed to be aligned with 8 byte boundary */ if (st->indio_dev->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); iio_trigger_notify_done(st->indio_dev->trig); kfree(rx_array); kfree(data); return; }
static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h, u8 *buf) { int ret, i; u8 *rx_array ; s16 *data = (s16 *)buf; 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->ring->scan_count; i++) data[i] = combine_8_to_16(rx_array[i*4+1], rx_array[i*4+3]); kfree(rx_array); return i*sizeof(data[0]); }
static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state) { struct lis3l02dq_state *st = trig->private_data; int ret = 0; u8 t; __lis3l02dq_write_data_ready_config(&st->indio_dev->dev, &iio_event_data_rdy_trig, state); if (state == false) { /* possible quirk with handler currently worked around by ensuring the work queue is empty */ flush_scheduled_work(); /* Clear any outstanding ready events */ ret = lis3l02dq_read_all(st, NULL); } lis3l02dq_spi_read_reg_8(&st->indio_dev->dev, LIS3L02DQ_REG_WAKE_UP_SRC_ADDR, &t); return ret; }