Merge commit 'v2.6.35' into kbuild/kconfig
[pandora-kernel.git] / drivers / staging / iio / accel / adis16240_ring.c
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/sysfs.h>
10 #include <linux/list.h>
11
12 #include "../iio.h"
13 #include "../sysfs.h"
14 #include "../ring_sw.h"
15 #include "accel.h"
16 #include "../trigger.h"
17 #include "adis16240.h"
18
19 /**
20  * combine_8_to_16() utility function to munge to u8s into u16
21  **/
22 static inline u16 combine_8_to_16(u8 lower, u8 upper)
23 {
24         u16 _lower = lower;
25         u16 _upper = upper;
26         return _lower | (_upper << 8);
27 }
28
29 static IIO_SCAN_EL_C(supply, ADIS16240_SCAN_SUPPLY, IIO_UNSIGNED(10),
30                 ADIS16240_SUPPLY_OUT, NULL);
31 static IIO_SCAN_EL_C(accel_x, ADIS16240_SCAN_ACC_X, IIO_SIGNED(10),
32                 ADIS16240_XACCL_OUT, NULL);
33 static IIO_SCAN_EL_C(accel_y, ADIS16240_SCAN_ACC_Y, IIO_SIGNED(10),
34                 ADIS16240_YACCL_OUT, NULL);
35 static IIO_SCAN_EL_C(accel_z, ADIS16240_SCAN_ACC_Z, IIO_SIGNED(10),
36                 ADIS16240_ZACCL_OUT, NULL);
37 static IIO_SCAN_EL_C(aux_adc, ADIS16240_SCAN_AUX_ADC, IIO_UNSIGNED(10),
38                 ADIS16240_AUX_ADC, NULL);
39 static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, IIO_UNSIGNED(10),
40                 ADIS16240_TEMP_OUT, NULL);
41
42 static IIO_SCAN_EL_TIMESTAMP(6);
43
44 static struct attribute *adis16240_scan_el_attrs[] = {
45         &iio_scan_el_supply.dev_attr.attr,
46         &iio_scan_el_accel_x.dev_attr.attr,
47         &iio_scan_el_accel_y.dev_attr.attr,
48         &iio_scan_el_accel_z.dev_attr.attr,
49         &iio_scan_el_aux_adc.dev_attr.attr,
50         &iio_scan_el_temp.dev_attr.attr,
51         &iio_scan_el_timestamp.dev_attr.attr,
52         NULL,
53 };
54
55 static struct attribute_group adis16240_scan_el_group = {
56         .attrs = adis16240_scan_el_attrs,
57         .name = "scan_elements",
58 };
59
60 /**
61  * adis16240_poll_func_th() top half interrupt handler called by trigger
62  * @private_data:       iio_dev
63  **/
64 static void adis16240_poll_func_th(struct iio_dev *indio_dev)
65 {
66         struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
67         st->last_timestamp = indio_dev->trig->timestamp;
68         schedule_work(&st->work_trigger_to_ring);
69 }
70
71 /**
72  * adis16240_read_ring_data() read data registers which will be placed into ring
73  * @dev: device associated with child of actual device (iio_dev or iio_trig)
74  * @rx: somewhere to pass back the value read
75  **/
76 static int adis16240_read_ring_data(struct device *dev, u8 *rx)
77 {
78         struct spi_message msg;
79         struct iio_dev *indio_dev = dev_get_drvdata(dev);
80         struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
81         struct spi_transfer xfers[ADIS16240_OUTPUTS + 1];
82         int ret;
83         int i;
84
85         mutex_lock(&st->buf_lock);
86
87         spi_message_init(&msg);
88
89         memset(xfers, 0, sizeof(xfers));
90         for (i = 0; i <= ADIS16240_OUTPUTS; i++) {
91                 xfers[i].bits_per_word = 8;
92                 xfers[i].cs_change = 1;
93                 xfers[i].len = 2;
94                 xfers[i].delay_usecs = 30;
95                 xfers[i].tx_buf = st->tx + 2 * i;
96                 st->tx[2 * i]
97                         = ADIS16240_READ_REG(ADIS16240_SUPPLY_OUT + 2 * i);
98                 st->tx[2 * i + 1] = 0;
99                 if (i >= 1)
100                         xfers[i].rx_buf = rx + 2 * (i - 1);
101                 spi_message_add_tail(&xfers[i], &msg);
102         }
103
104         ret = spi_sync(st->us, &msg);
105         if (ret)
106                 dev_err(&st->us->dev, "problem when burst reading");
107
108         mutex_unlock(&st->buf_lock);
109
110         return ret;
111 }
112
113
114 static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
115 {
116         struct adis16240_state *st
117                 = container_of(work_s, struct adis16240_state,
118                                 work_trigger_to_ring);
119
120         int i = 0;
121         s16 *data;
122         size_t datasize = st->indio_dev
123                 ->ring->access.get_bpd(st->indio_dev->ring);
124
125         data = kmalloc(datasize , GFP_KERNEL);
126         if (data == NULL) {
127                 dev_err(&st->us->dev, "memory alloc failed in ring bh");
128                 return;
129         }
130
131         if (st->indio_dev->scan_count)
132                 if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
133                         for (; i < st->indio_dev->scan_count; i++) {
134                                 data[i] = combine_8_to_16(st->rx[i*2+1],
135                                                 st->rx[i*2]);
136                         }
137
138         /* Guaranteed to be aligned with 8 byte boundary */
139         if (st->indio_dev->scan_timestamp)
140                 *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
141
142         st->indio_dev->ring->access.store_to(st->indio_dev->ring,
143                         (u8 *)data,
144                         st->last_timestamp);
145
146         iio_trigger_notify_done(st->indio_dev->trig);
147         kfree(data);
148
149         return;
150 }
151
152 static int adis16240_data_rdy_ring_preenable(struct iio_dev *indio_dev)
153 {
154         size_t size;
155         dev_dbg(&indio_dev->dev, "%s\n", __func__);
156         /* Check if there are any scan elements enabled, if not fail*/
157         if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
158                 return -EINVAL;
159
160         if (indio_dev->ring->access.set_bpd) {
161                 if (indio_dev->scan_timestamp)
162                         if (indio_dev->scan_count)
163                                 /* Timestamp (aligned sizeof(s64) and data */
164                                 size = (((indio_dev->scan_count * sizeof(s16))
165                                          + sizeof(s64) - 1)
166                                         & ~(sizeof(s64) - 1))
167                                         + sizeof(s64);
168                         else /* Timestamp only  */
169                                 size = sizeof(s64);
170                 else /* Data only */
171                         size = indio_dev->scan_count*sizeof(s16);
172                 indio_dev->ring->access.set_bpd(indio_dev->ring, size);
173         }
174
175         return 0;
176 }
177
178 static int adis16240_data_rdy_ring_postenable(struct iio_dev *indio_dev)
179 {
180         return indio_dev->trig
181                 ? iio_trigger_attach_poll_func(indio_dev->trig,
182                                 indio_dev->pollfunc)
183                 : 0;
184 }
185
186 static int adis16240_data_rdy_ring_predisable(struct iio_dev *indio_dev)
187 {
188         return indio_dev->trig
189                 ? iio_trigger_dettach_poll_func(indio_dev->trig,
190                                 indio_dev->pollfunc)
191                 : 0;
192 }
193
194 void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
195 {
196         kfree(indio_dev->pollfunc);
197         iio_sw_rb_free(indio_dev->ring);
198 }
199
200 int adis16240_configure_ring(struct iio_dev *indio_dev)
201 {
202         int ret = 0;
203         struct adis16240_state *st = indio_dev->dev_data;
204         struct iio_ring_buffer *ring;
205         INIT_WORK(&st->work_trigger_to_ring, adis16240_trigger_bh_to_ring);
206         /* Set default scan mode */
207
208         iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
209         iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
210         iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
211         iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
212         iio_scan_mask_set(indio_dev, iio_scan_el_temp.number);
213         iio_scan_mask_set(indio_dev, iio_scan_el_aux_adc.number);
214         indio_dev->scan_timestamp = true;
215
216         indio_dev->scan_el_attrs = &adis16240_scan_el_group;
217
218         ring = iio_sw_rb_allocate(indio_dev);
219         if (!ring) {
220                 ret = -ENOMEM;
221                 return ret;
222         }
223         indio_dev->ring = ring;
224         /* Effectively select the ring buffer implementation */
225         iio_ring_sw_register_funcs(&ring->access);
226         ring->preenable = &adis16240_data_rdy_ring_preenable;
227         ring->postenable = &adis16240_data_rdy_ring_postenable;
228         ring->predisable = &adis16240_data_rdy_ring_predisable;
229         ring->owner = THIS_MODULE;
230
231         indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
232         if (indio_dev->pollfunc == NULL) {
233                 ret = -ENOMEM;
234                 goto error_iio_sw_rb_free;;
235         }
236         indio_dev->pollfunc->poll_func_main = &adis16240_poll_func_th;
237         indio_dev->pollfunc->private_data = indio_dev;
238         indio_dev->modes |= INDIO_RING_TRIGGERED;
239         return 0;
240
241 error_iio_sw_rb_free:
242         iio_sw_rb_free(indio_dev->ring);
243         return ret;
244 }
245
246 int adis16240_initialize_ring(struct iio_ring_buffer *ring)
247 {
248         return iio_ring_buffer_register(ring, 0);
249 }
250
251 void adis16240_uninitialize_ring(struct iio_ring_buffer *ring)
252 {
253         iio_ring_buffer_unregister(ring);
254 }