Merge branch 'for-chris' of git://git.jan-o-sch.net/btrfs-unstable into integration
[deliverable/linux.git] / drivers / staging / iio / gyro / adis16260_ring.c
CommitLineData
8e336a72 1#include <linux/export.h>
089a4198 2#include <linux/interrupt.h>
089a4198 3#include <linux/mutex.h>
089a4198
BS
4#include <linux/kernel.h>
5#include <linux/spi/spi.h>
1cb6c1f5 6#include <linux/slab.h>
089a4198
BS
7
8#include "../iio.h"
089a4198 9#include "../ring_sw.h"
3f72395e 10#include "../trigger_consumer.h"
089a4198
BS
11#include "adis16260.h"
12
089a4198
BS
13/**
14 * adis16260_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 adis16260_read_ring_data(struct device *dev, u8 *rx)
19{
20 struct spi_message msg;
21 struct iio_dev *indio_dev = dev_get_drvdata(dev);
d088ab83 22 struct adis16260_state *st = iio_priv(indio_dev);
089a4198
BS
23 struct spi_transfer xfers[ADIS16260_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 <= ADIS16260_OUTPUTS; i++) {
33 xfers[i].bits_per_word = 8;
34 xfers[i].cs_change = 1;
35 xfers[i].len = 2;
36 xfers[i].delay_usecs = 30;
37 xfers[i].tx_buf = st->tx + 2 * i;
38 if (i < 2) /* SUPPLY_OUT:0x02 GYRO_OUT:0x04 */
39 st->tx[2 * i]
40 = ADIS16260_READ_REG(ADIS16260_SUPPLY_OUT
41 + 2 * i);
42 else /* 0x06 to 0x09 is reserved */
43 st->tx[2 * i]
44 = ADIS16260_READ_REG(ADIS16260_SUPPLY_OUT
45 + 2 * i + 4);
46 st->tx[2 * i + 1] = 0;
47 if (i >= 1)
48 xfers[i].rx_buf = rx + 2 * (i - 1);
49 spi_message_add_tail(&xfers[i], &msg);
50 }
51
52 ret = spi_sync(st->us, &msg);
53 if (ret)
54 dev_err(&st->us->dev, "problem when burst reading");
55
56 mutex_unlock(&st->buf_lock);
57
58 return ret;
59}
60
504b4958 61static irqreturn_t adis16260_trigger_handler(int irq, void *p)
089a4198 62{
504b4958 63 struct iio_poll_func *pf = p;
e65bc6ac 64 struct iio_dev *indio_dev = pf->indio_dev;
d088ab83 65 struct adis16260_state *st = iio_priv(indio_dev);
14555b14 66 struct iio_buffer *ring = indio_dev->buffer;
089a4198
BS
67 int i = 0;
68 s16 *data;
5565a450 69 size_t datasize = ring->access->get_bytes_per_datum(ring);
089a4198
BS
70
71 data = kmalloc(datasize , GFP_KERNEL);
72 if (data == NULL) {
73 dev_err(&st->us->dev, "memory alloc failed in ring bh");
504b4958 74 return -ENOMEM;
089a4198
BS
75 }
76
504b4958 77 if (ring->scan_count &&
d088ab83 78 adis16260_read_ring_data(&indio_dev->dev, st->rx) >= 0)
504b4958
JC
79 for (; i < ring->scan_count; i++)
80 data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
089a4198
BS
81
82 /* Guaranteed to be aligned with 8 byte boundary */
bf32963c 83 if (ring->scan_timestamp)
504b4958 84 *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
089a4198 85
5565a450 86 ring->access->store_to(ring, (u8 *)data, pf->timestamp);
089a4198 87
d088ab83 88 iio_trigger_notify_done(indio_dev->trig);
089a4198
BS
89 kfree(data);
90
504b4958 91 return IRQ_HANDLED;
089a4198
BS
92}
93
089a4198
BS
94void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
95{
0ed731d2 96 iio_dealloc_pollfunc(indio_dev->pollfunc);
14555b14 97 iio_sw_rb_free(indio_dev->buffer);
089a4198
BS
98}
99
14555b14
JC
100static const struct iio_buffer_setup_ops adis16260_ring_setup_ops = {
101 .preenable = &iio_sw_buffer_preenable,
3b99fb76
JC
102 .postenable = &iio_triggered_buffer_postenable,
103 .predisable = &iio_triggered_buffer_predisable,
5565a450
JC
104};
105
089a4198
BS
106int adis16260_configure_ring(struct iio_dev *indio_dev)
107{
108 int ret = 0;
14555b14 109 struct iio_buffer *ring;
089a4198
BS
110
111 ring = iio_sw_rb_allocate(indio_dev);
112 if (!ring) {
113 ret = -ENOMEM;
114 return ret;
115 }
14555b14 116 indio_dev->buffer = ring;
089a4198 117 /* Effectively select the ring buffer implementation */
5565a450 118 ring->access = &ring_sw_access_funcs;
43c11b43 119 ring->bpe = 2;
bf32963c 120 ring->scan_timestamp = true;
5565a450 121 ring->setup_ops = &adis16260_ring_setup_ops;
089a4198
BS
122 ring->owner = THIS_MODULE;
123
0ed731d2
JC
124 indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
125 &adis16260_trigger_handler,
126 IRQF_ONESHOT,
127 indio_dev,
128 "adis16260_consumer%d",
129 indio_dev->id);
504b4958
JC
130 if (indio_dev->pollfunc == NULL) {
131 ret = -ENOMEM;
15744090 132 goto error_iio_sw_rb_free;
504b4958 133 }
15744090 134
ec3afa40 135 indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
089a4198 136 return 0;
0ed731d2 137
089a4198 138error_iio_sw_rb_free:
14555b14 139 iio_sw_rb_free(indio_dev->buffer);
089a4198
BS
140 return ret;
141}
This page took 0.193748 seconds and 5 git commands to generate.