2 * Copyright 2010-2011 Analog Devices Inc.
3 * Copyright (C) 2008 Jonathan Cameron
5 * Licensed under the GPL-2.
10 #include <linux/interrupt.h>
11 #include <linux/kernel.h>
12 #include <linux/slab.h>
13 #include <linux/spi/spi.h>
16 #include "../ring_generic.h"
17 #include "../ring_sw.h"
18 #include "../trigger.h"
22 int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
24 struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
28 if (!(ring->scan_mask & mask)) {
33 ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
35 if (ring_data == NULL) {
39 ret = ring->access->read_last(ring, (u8 *) ring_data);
41 goto error_free_ring_data;
43 /* for single channel scan the result is stored with zero offset */
44 if ((ring->scan_mask == ((1 << 1) | (1 << 0))) && (mask == (1 << 1)))
47 ret = be16_to_cpu(ring_data[count]);
56 * ad7887_ring_preenable() setup the parameters of the ring before enabling
58 * The complex nature of the setting of the nuber of bytes per datum is due
59 * to this driver currently ensuring that the timestamp is stored at an 8
62 static int ad7887_ring_preenable(struct iio_dev *indio_dev)
64 struct ad7887_state *st = iio_priv(indio_dev);
65 struct iio_ring_buffer *ring = indio_dev->ring;
67 st->d_size = ring->scan_count *
68 st->chip_info->channel[0].scan_type.storagebits / 8;
70 if (ring->scan_timestamp) {
71 st->d_size += sizeof(s64);
73 if (st->d_size % sizeof(s64))
74 st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
77 if (indio_dev->ring->access->set_bytes_per_datum)
78 indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
81 switch (ring->scan_mask) {
83 st->ring_msg = &st->msg[AD7887_CH0];
86 st->ring_msg = &st->msg[AD7887_CH1];
87 /* Dummy read: push CH1 setting down to hardware */
88 spi_sync(st->spi, st->ring_msg);
90 case ((1 << 1) | (1 << 0)):
91 st->ring_msg = &st->msg[AD7887_CH0_CH1];
98 static int ad7887_ring_postdisable(struct iio_dev *indio_dev)
100 struct ad7887_state *st = iio_priv(indio_dev);
102 /* dummy read: restore default CH0 settin */
103 return spi_sync(st->spi, &st->msg[AD7887_CH0]);
107 * ad7887_trigger_handler() bh of trigger launched polling to ring buffer
109 * Currently there is no option in this driver to disable the saving of
110 * timestamps within the ring.
112 static irqreturn_t ad7887_trigger_handler(int irq, void *p)
114 struct iio_poll_func *pf = p;
115 struct iio_dev *indio_dev = pf->private_data;
116 struct ad7887_state *st = iio_priv(indio_dev);
117 struct iio_ring_buffer *ring = indio_dev->ring;
122 unsigned int bytes = ring->scan_count *
123 st->chip_info->channel[0].scan_type.storagebits / 8;
125 buf = kzalloc(st->d_size, GFP_KERNEL);
129 b_sent = spi_sync(st->spi, st->ring_msg);
133 time_ns = iio_get_time_ns();
135 memcpy(buf, st->data, bytes);
136 if (ring->scan_timestamp)
137 memcpy(buf + st->d_size - sizeof(s64),
138 &time_ns, sizeof(time_ns));
140 indio_dev->ring->access->store_to(indio_dev->ring, buf, time_ns);
143 iio_trigger_notify_done(indio_dev->trig);
148 static const struct iio_ring_setup_ops ad7887_ring_setup_ops = {
149 .preenable = &ad7887_ring_preenable,
150 .postenable = &iio_triggered_ring_postenable,
151 .predisable = &iio_triggered_ring_predisable,
152 .postdisable = &ad7887_ring_postdisable,
155 int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
159 indio_dev->ring = iio_sw_rb_allocate(indio_dev);
160 if (!indio_dev->ring) {
164 /* Effectively select the ring buffer implementation */
165 indio_dev->ring->access = &ring_sw_access_funcs;
166 indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
167 &ad7887_trigger_handler,
172 if (indio_dev->pollfunc == NULL) {
174 goto error_deallocate_sw_rb;
176 /* Ring buffer functions - here trigger setup related */
177 indio_dev->ring->setup_ops = &ad7887_ring_setup_ops;
179 /* Flag that polled ring buffering is possible */
180 indio_dev->modes |= INDIO_RING_TRIGGERED;
183 error_deallocate_sw_rb:
184 iio_sw_rb_free(indio_dev->ring);
189 void ad7887_ring_cleanup(struct iio_dev *indio_dev)
191 /* ensure that the trigger has been detached */
192 if (indio_dev->trig) {
193 iio_put_trigger(indio_dev->trig);
194 iio_trigger_dettach_poll_func(indio_dev->trig,
195 indio_dev->pollfunc);
197 iio_dealloc_pollfunc(indio_dev->pollfunc);
198 iio_sw_rb_free(indio_dev->ring);