IIO: Move core headers to include/linux/iio
[deliverable/linux.git] / drivers / staging / iio / accel / adis16209_ring.c
CommitLineData
8e336a72 1#include <linux/export.h>
671ece14 2#include <linux/interrupt.h>
671ece14 3#include <linux/mutex.h>
671ece14
BS
4#include <linux/kernel.h>
5#include <linux/spi/spi.h>
1cb6c1f5 6#include <linux/slab.h>
671ece14 7
06458e27 8#include <linux/iio/iio.h>
671ece14 9#include "../ring_sw.h"
06458e27 10#include <linux/iio/trigger_consumer.h>
671ece14
BS
11#include "adis16209.h"
12
671ece14
BS
13/**
14 * adis16209_read_ring_data() read data registers which will be placed into ring
15 * @dev: device associated with child of actual device (iio_dev or iio_trig)
16 * @rx: somewhere to pass back the value read
17 **/
18static int adis16209_read_ring_data(struct device *dev, u8 *rx)
19{
20 struct spi_message msg;
21 struct iio_dev *indio_dev = dev_get_drvdata(dev);
35212dfa 22 struct adis16209_state *st = iio_priv(indio_dev);
671ece14
BS
23 struct spi_transfer xfers[ADIS16209_OUTPUTS + 1];
24 int ret;
25 int i;
26
27 mutex_lock(&st->buf_lock);
28
29 spi_message_init(&msg);
30
31 memset(xfers, 0, sizeof(xfers));
32 for (i = 0; i <= ADIS16209_OUTPUTS; i++) {
33 xfers[i].bits_per_word = 8;
34 xfers[i].cs_change = 1;
35 xfers[i].len = 2;
e1ffd62b 36 xfers[i].delay_usecs = 30;
671ece14
BS
37 xfers[i].tx_buf = st->tx + 2 * i;
38 st->tx[2 * i]
39 = ADIS16209_READ_REG(ADIS16209_SUPPLY_OUT + 2 * i);
40 st->tx[2 * i + 1] = 0;
41 if (i >= 1)
42 xfers[i].rx_buf = rx + 2 * (i - 1);
43 spi_message_add_tail(&xfers[i], &msg);
44 }
45
46 ret = spi_sync(st->us, &msg);
47 if (ret)
48 dev_err(&st->us->dev, "problem when burst reading");
49
50 mutex_unlock(&st->buf_lock);
51
52 return ret;
53}
54
55/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
56 * specific to be rolled into the core.
57 */
d7e044f1 58static irqreturn_t adis16209_trigger_handler(int irq, void *p)
671ece14 59{
d7e044f1 60 struct iio_poll_func *pf = p;
e65bc6ac 61 struct iio_dev *indio_dev = pf->indio_dev;
35212dfa 62 struct adis16209_state *st = iio_priv(indio_dev);
14555b14 63 struct iio_buffer *ring = indio_dev->buffer;
671ece14
BS
64 int i = 0;
65 s16 *data;
671ece14 66
420fe2e9 67 data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
671ece14
BS
68 if (data == NULL) {
69 dev_err(&st->us->dev, "memory alloc failed in ring bh");
d7e044f1 70 return -ENOMEM;
671ece14
BS
71 }
72
550268ca 73 if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) &&
35212dfa 74 adis16209_read_ring_data(&indio_dev->dev, st->rx) >= 0)
550268ca
JC
75 for (; i < bitmap_weight(indio_dev->active_scan_mask,
76 indio_dev->masklength); i++)
d7e044f1 77 data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
671ece14
BS
78
79 /* Guaranteed to be aligned with 8 byte boundary */
fd6487f8 80 if (indio_dev->scan_timestamp)
d7e044f1 81 *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
671ece14 82
5565a450 83 ring->access->store_to(ring, (u8 *)data, pf->timestamp);
671ece14 84
35212dfa 85 iio_trigger_notify_done(indio_dev->trig);
671ece14
BS
86 kfree(data);
87
d7e044f1 88 return IRQ_HANDLED;
671ece14
BS
89}
90
671ece14
BS
91void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
92{
21b185f8 93 iio_dealloc_pollfunc(indio_dev->pollfunc);
14555b14 94 iio_sw_rb_free(indio_dev->buffer);
671ece14
BS
95}
96
14555b14
JC
97static const struct iio_buffer_setup_ops adis16209_ring_setup_ops = {
98 .preenable = &iio_sw_buffer_preenable,
3b99fb76
JC
99 .postenable = &iio_triggered_buffer_postenable,
100 .predisable = &iio_triggered_buffer_predisable,
5565a450
JC
101};
102
671ece14
BS
103int adis16209_configure_ring(struct iio_dev *indio_dev)
104{
105 int ret = 0;
14555b14 106 struct iio_buffer *ring;
671ece14
BS
107
108 ring = iio_sw_rb_allocate(indio_dev);
109 if (!ring) {
110 ret = -ENOMEM;
111 return ret;
112 }
14555b14 113 indio_dev->buffer = ring;
bf32963c 114 ring->scan_timestamp = true;
1612244f 115 indio_dev->setup_ops = &adis16209_ring_setup_ops;
671ece14 116
21b185f8
JC
117 indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
118 &adis16209_trigger_handler,
119 IRQF_ONESHOT,
120 indio_dev,
121 "%s_consumer%d",
122 indio_dev->name,
123 indio_dev->id);
d7e044f1
JC
124 if (indio_dev->pollfunc == NULL) {
125 ret = -ENOMEM;
15744090 126 goto error_iio_sw_rb_free;
d7e044f1 127 }
15744090 128
ec3afa40 129 indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
671ece14 130 return 0;
21b185f8 131
671ece14 132error_iio_sw_rb_free:
14555b14 133 iio_sw_rb_free(indio_dev->buffer);
671ece14
BS
134 return ret;
135}
This page took 0.226165 seconds and 5 git commands to generate.