2 * Copyright 2010-2012 Analog Devices Inc.
3 * Copyright (C) 2008 Jonathan Cameron
5 * Licensed under the GPL-2 or later.
10 #include <linux/interrupt.h>
11 #include <linux/device.h>
12 #include <linux/kernel.h>
13 #include <linux/slab.h>
14 #include <linux/spi/spi.h>
16 #include <linux/iio/iio.h>
17 #include <linux/iio/buffer.h>
18 #include <linux/iio/kfifo_buf.h>
19 #include <linux/iio/trigger_consumer.h>
23 static irqreturn_t ad7476_trigger_handler(int irq, void *p)
25 struct iio_poll_func *pf = p;
26 struct iio_dev *indio_dev = pf->indio_dev;
27 struct ad7476_state *st = iio_priv(indio_dev);
32 rxbuf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
36 b_sent = spi_read(st->spi, rxbuf,
37 st->chip_info->channel[0].scan_type.storagebits / 8);
41 time_ns = iio_get_time_ns();
43 if (indio_dev->scan_timestamp)
44 memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64),
45 &time_ns, sizeof(time_ns));
47 indio_dev->buffer->access->store_to(indio_dev->buffer, rxbuf, time_ns);
49 iio_trigger_notify_done(indio_dev->trig);
55 static const struct iio_buffer_setup_ops ad7476_ring_setup_ops = {
56 .preenable = &iio_sw_buffer_preenable,
57 .postenable = &iio_triggered_buffer_postenable,
58 .predisable = &iio_triggered_buffer_predisable,
61 int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
63 struct ad7476_state *st = iio_priv(indio_dev);
66 indio_dev->buffer = iio_kfifo_allocate(indio_dev);
67 if (!indio_dev->buffer) {
72 = iio_alloc_pollfunc(NULL,
73 &ad7476_trigger_handler,
77 spi_get_device_id(st->spi)->name,
79 if (indio_dev->pollfunc == NULL) {
81 goto error_deallocate_kfifo;
84 /* Ring buffer functions - here trigger setup related */
85 indio_dev->setup_ops = &ad7476_ring_setup_ops;
86 indio_dev->buffer->scan_timestamp = true;
88 /* Flag that polled ring buffering is possible */
89 indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
92 error_deallocate_kfifo:
93 iio_kfifo_free(indio_dev->buffer);
98 void ad7476_ring_cleanup(struct iio_dev *indio_dev)
100 iio_dealloc_pollfunc(indio_dev->pollfunc);
101 iio_kfifo_free(indio_dev->buffer);