GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / iio / accel / adis16209_ring.c
blob25fde659d09889c5d761cee172989f991095d106
1 #include <linux/interrupt.h>
2 #include <linux/irq.h>
3 #include <linux/gpio.h>
4 #include <linux/workqueue.h>
5 #include <linux/mutex.h>
6 #include <linux/device.h>
7 #include <linux/kernel.h>
8 #include <linux/spi/spi.h>
9 #include <linux/slab.h>
10 #include <linux/sysfs.h>
11 #include <linux/list.h>
13 #include "../iio.h"
14 #include "../sysfs.h"
15 #include "../ring_sw.h"
16 #include "accel.h"
17 #include "../trigger.h"
18 #include "adis16209.h"
20 static IIO_SCAN_EL_C(supply, ADIS16209_SCAN_SUPPLY, IIO_UNSIGNED(14),
21 ADIS16209_SUPPLY_OUT, NULL);
22 static IIO_SCAN_EL_C(accel_x, ADIS16209_SCAN_ACC_X, IIO_SIGNED(14),
23 ADIS16209_XACCL_OUT, NULL);
24 static IIO_SCAN_EL_C(accel_y, ADIS16209_SCAN_ACC_Y, IIO_SIGNED(14),
25 ADIS16209_YACCL_OUT, NULL);
26 static IIO_SCAN_EL_C(aux_adc, ADIS16209_SCAN_AUX_ADC, IIO_UNSIGNED(12),
27 ADIS16209_AUX_ADC, NULL);
28 static IIO_SCAN_EL_C(temp, ADIS16209_SCAN_TEMP, IIO_UNSIGNED(12),
29 ADIS16209_TEMP_OUT, NULL);
30 static IIO_SCAN_EL_C(incli_x, ADIS16209_SCAN_INCLI_X, IIO_SIGNED(14),
31 ADIS16209_XINCL_OUT, NULL);
32 static IIO_SCAN_EL_C(incli_y, ADIS16209_SCAN_INCLI_Y, IIO_SIGNED(14),
33 ADIS16209_YINCL_OUT, NULL);
34 static IIO_SCAN_EL_C(rot, ADIS16209_SCAN_ROT, IIO_SIGNED(14),
35 ADIS16209_ROT_OUT, NULL);
37 static IIO_SCAN_EL_TIMESTAMP(8);
39 static struct attribute *adis16209_scan_el_attrs[] = {
40 &iio_scan_el_supply.dev_attr.attr,
41 &iio_scan_el_accel_x.dev_attr.attr,
42 &iio_scan_el_accel_y.dev_attr.attr,
43 &iio_scan_el_aux_adc.dev_attr.attr,
44 &iio_scan_el_temp.dev_attr.attr,
45 &iio_scan_el_incli_x.dev_attr.attr,
46 &iio_scan_el_incli_y.dev_attr.attr,
47 &iio_scan_el_rot.dev_attr.attr,
48 &iio_scan_el_timestamp.dev_attr.attr,
49 NULL,
52 static struct attribute_group adis16209_scan_el_group = {
53 .attrs = adis16209_scan_el_attrs,
54 .name = "scan_elements",
57 /**
58 * adis16209_poll_func_th() top half interrupt handler called by trigger
59 * @private_data: iio_dev
60 **/
61 static void adis16209_poll_func_th(struct iio_dev *indio_dev, s64 time)
63 struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
64 st->last_timestamp = time;
65 schedule_work(&st->work_trigger_to_ring);
68 /**
69 * adis16209_read_ring_data() read data registers which will be placed into ring
70 * @dev: device associated with child of actual device (iio_dev or iio_trig)
71 * @rx: somewhere to pass back the value read
72 **/
73 static int adis16209_read_ring_data(struct device *dev, u8 *rx)
75 struct spi_message msg;
76 struct iio_dev *indio_dev = dev_get_drvdata(dev);
77 struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
78 struct spi_transfer xfers[ADIS16209_OUTPUTS + 1];
79 int ret;
80 int i;
82 mutex_lock(&st->buf_lock);
84 spi_message_init(&msg);
86 memset(xfers, 0, sizeof(xfers));
87 for (i = 0; i <= ADIS16209_OUTPUTS; i++) {
88 xfers[i].bits_per_word = 8;
89 xfers[i].cs_change = 1;
90 xfers[i].len = 2;
91 xfers[i].delay_usecs = 20;
92 xfers[i].tx_buf = st->tx + 2 * i;
93 st->tx[2 * i]
94 = ADIS16209_READ_REG(ADIS16209_SUPPLY_OUT + 2 * i);
95 st->tx[2 * i + 1] = 0;
96 if (i >= 1)
97 xfers[i].rx_buf = rx + 2 * (i - 1);
98 spi_message_add_tail(&xfers[i], &msg);
101 ret = spi_sync(st->us, &msg);
102 if (ret)
103 dev_err(&st->us->dev, "problem when burst reading");
105 mutex_unlock(&st->buf_lock);
107 return ret;
110 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
111 * specific to be rolled into the core.
113 static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
115 struct adis16209_state *st
116 = container_of(work_s, struct adis16209_state,
117 work_trigger_to_ring);
119 int i = 0;
120 s16 *data;
121 size_t datasize = st->indio_dev
122 ->ring->access.get_bpd(st->indio_dev->ring);
124 data = kmalloc(datasize , GFP_KERNEL);
125 if (data == NULL) {
126 dev_err(&st->us->dev, "memory alloc failed in ring bh");
127 return;
130 if (st->indio_dev->scan_count)
131 if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
132 for (; i < st->indio_dev->scan_count; i++)
133 data[i] = be16_to_cpup(
134 (__be16 *)&(st->rx[i*2]));
136 /* Guaranteed to be aligned with 8 byte boundary */
137 if (st->indio_dev->scan_timestamp)
138 *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
140 st->indio_dev->ring->access.store_to(st->indio_dev->ring,
141 (u8 *)data,
142 st->last_timestamp);
144 iio_trigger_notify_done(st->indio_dev->trig);
145 kfree(data);
147 return;
150 void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
152 kfree(indio_dev->pollfunc);
153 iio_sw_rb_free(indio_dev->ring);
156 int adis16209_configure_ring(struct iio_dev *indio_dev)
158 int ret = 0;
159 struct adis16209_state *st = indio_dev->dev_data;
160 struct iio_ring_buffer *ring;
161 INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring);
162 /* Set default scan mode */
164 iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
165 iio_scan_mask_set(indio_dev, iio_scan_el_rot.number);
166 iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
167 iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
168 iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
169 iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
170 iio_scan_mask_set(indio_dev, iio_scan_el_incli_x.number);
171 iio_scan_mask_set(indio_dev, iio_scan_el_incli_y.number);
172 indio_dev->scan_timestamp = true;
174 indio_dev->scan_el_attrs = &adis16209_scan_el_group;
176 ring = iio_sw_rb_allocate(indio_dev);
177 if (!ring) {
178 ret = -ENOMEM;
179 return ret;
181 indio_dev->ring = ring;
182 /* Effectively select the ring buffer implementation */
183 iio_ring_sw_register_funcs(&ring->access);
184 ring->bpe = 2;
185 ring->preenable = &iio_sw_ring_preenable;
186 ring->postenable = &iio_triggered_ring_postenable;
187 ring->predisable = &iio_triggered_ring_predisable;
188 ring->owner = THIS_MODULE;
190 ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th);
191 if (ret)
192 goto error_iio_sw_rb_free;
194 indio_dev->modes |= INDIO_RING_TRIGGERED;
195 return 0;
197 error_iio_sw_rb_free:
198 iio_sw_rb_free(indio_dev->ring);
199 return ret;