blob: 2c666f22f4d1821b0098372d33f5d51f80579aa3 [file] [log] [blame]
Jonathan Cameron14cd9a72009-08-18 18:06:28 +01001#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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090011#include <linux/slab.h>
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010012
13#include "../iio.h"
14#include "../sysfs.h"
15#include "../ring_sw.h"
Jonathan Cameronb9497932011-02-11 13:09:11 +000016#include "../kfifo_buf.h"
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010017#include "accel.h"
18#include "../trigger.h"
19#include "lis3l02dq.h"
20
21/**
22 * combine_8_to_16() utility function to munge to u8s into u16
23 **/
24static inline u16 combine_8_to_16(u8 lower, u8 upper)
25{
26 u16 _lower = lower;
27 u16 _upper = upper;
28 return _lower | (_upper << 8);
29}
30
31/**
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010032 * lis3l02dq_poll_func_th() top half interrupt handler called by trigger
33 * @private_data: iio_dev
34 **/
Jonathan Cameron7b2c33b2010-07-11 16:39:11 +010035static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev, s64 time)
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010036{
Jonathan Cameron73bce122010-07-11 16:39:19 +010037 struct iio_sw_ring_helper_state *h
38 = iio_dev_get_devdata(indio_dev);
39 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
40 /* in this case we need to slightly extend the helper function */
41 iio_sw_poll_func_th(indio_dev, time);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010042
Jonathan Cameron73bce122010-07-11 16:39:19 +010043 /* Indicate that this interrupt is being handled */
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010044 /* Technically this is trigger related, but without this
45 * handler running there is currently now way for the interrupt
46 * to clear.
47 */
48 st->inter = 1;
49}
50
51/**
52 * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
53 **/
Jonathan Cameron73bce122010-07-11 16:39:19 +010054static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *indio_dev,
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010055 int index,
56 s64 timestamp,
57 int no_test)
58{
Jonathan Cameron73bce122010-07-11 16:39:19 +010059 struct iio_sw_ring_helper_state *h
60 = iio_dev_get_devdata(indio_dev);
61 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010062
Jonathan Cameron73bce122010-07-11 16:39:19 +010063 iio_trigger_poll(st->trig, timestamp);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010064
65 return IRQ_HANDLED;
66}
67
68/* This is an event as it is a response to a physical interrupt */
69IIO_EVENT_SH(data_rdy_trig, &lis3l02dq_data_rdy_trig_poll);
70
71/**
72 * lis3l02dq_read_accel_from_ring() individual acceleration read from ring
73 **/
Jonathan Cameronf3736412011-05-18 14:40:52 +010074ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
75 int index,
76 int *val)
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010077{
Jonathan Cameronf3736412011-05-18 14:40:52 +010078 int ret;
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010079 s16 *data;
Jonathan Cameronf3736412011-05-18 14:40:52 +010080 if (!iio_scan_mask_query(ring, index))
81 return -EINVAL;
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010082
Jonathan Cameronf3736412011-05-18 14:40:52 +010083 data = kmalloc(ring->access.get_bytes_per_datum(ring),
84 GFP_KERNEL);
85 if (data == NULL)
86 return -ENOMEM;
87
88 ret = ring->access.read_last(ring, (u8 *)data);
89 if (ret)
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010090 goto error_free_data;
Jonathan Cameronf3736412011-05-18 14:40:52 +010091 *val = data[iio_scan_mask_count_to_right(ring, index)];
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010092error_free_data:
93 kfree(data);
Jonathan Cameronf3736412011-05-18 14:40:52 +010094 return ret;
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010095}
96
Jonathan Cameron26de7202010-05-04 22:34:36 +010097static const u8 read_all_tx_array[] = {
Jonathan Cameron14cd9a72009-08-18 18:06:28 +010098 LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_L_ADDR), 0,
99 LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_H_ADDR), 0,
100 LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Y_L_ADDR), 0,
101 LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Y_H_ADDR), 0,
102 LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Z_L_ADDR), 0,
103 LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Z_H_ADDR), 0,
104};
105
106/**
107 * lis3l02dq_read_all() Reads all channels currently selected
108 * @st: device specific state
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300109 * @rx_array: (dma capable) receive array, must be at least
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100110 * 4*number of channels
111 **/
Greg Kroah-Hartman7cfce522010-05-04 22:32:01 -0700112static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100113{
Manuel Stahlbf329632010-08-31 11:32:52 +0200114 struct iio_ring_buffer *ring = st->help.indio_dev->ring;
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100115 struct spi_transfer *xfers;
116 struct spi_message msg;
117 int ret, i, j = 0;
118
Manuel Stahlbf329632010-08-31 11:32:52 +0200119 xfers = kzalloc((ring->scan_count) * 2
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100120 * sizeof(*xfers), GFP_KERNEL);
121 if (!xfers)
122 return -ENOMEM;
123
124 mutex_lock(&st->buf_lock);
125
Jonathan Cameronf3736412011-05-18 14:40:52 +0100126 for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++)
Manuel Stahlbf329632010-08-31 11:32:52 +0200127 if (ring->scan_mask & (1 << i)) {
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100128 /* lower byte */
129 xfers[j].tx_buf = st->tx + 2*j;
130 st->tx[2*j] = read_all_tx_array[i*4];
131 st->tx[2*j + 1] = 0;
132 if (rx_array)
133 xfers[j].rx_buf = rx_array + j*2;
134 xfers[j].bits_per_word = 8;
135 xfers[j].len = 2;
136 xfers[j].cs_change = 1;
137 j++;
138
139 /* upper byte */
140 xfers[j].tx_buf = st->tx + 2*j;
141 st->tx[2*j] = read_all_tx_array[i*4 + 2];
142 st->tx[2*j + 1] = 0;
143 if (rx_array)
144 xfers[j].rx_buf = rx_array + j*2;
145 xfers[j].bits_per_word = 8;
146 xfers[j].len = 2;
147 xfers[j].cs_change = 1;
148 j++;
149 }
Jonathan Cameronf3736412011-05-18 14:40:52 +0100150
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100151 /* After these are transmitted, the rx_buff should have
152 * values in alternate bytes
153 */
154 spi_message_init(&msg);
Manuel Stahlbf329632010-08-31 11:32:52 +0200155 for (j = 0; j < ring->scan_count * 2; j++)
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100156 spi_message_add_tail(&xfers[j], &msg);
157
158 ret = spi_sync(st->us, &msg);
159 mutex_unlock(&st->buf_lock);
160 kfree(xfers);
161
162 return ret;
163}
164
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100165static void lis3l02dq_trigger_bh_to_ring(struct work_struct *work_s)
166{
Jonathan Cameron73bce122010-07-11 16:39:19 +0100167 struct iio_sw_ring_helper_state *h
168 = container_of(work_s, struct iio_sw_ring_helper_state,
169 work_trigger_to_ring);
170 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100171
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100172 st->inter = 0;
Jonathan Cameron73bce122010-07-11 16:39:19 +0100173 iio_sw_trigger_bh_to_ring(work_s);
174}
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100175
Jonathan Cameron73bce122010-07-11 16:39:19 +0100176static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
177 u8 *buf)
178{
179 int ret, i;
180 u8 *rx_array ;
181 s16 *data = (s16 *)buf;
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100182
Manuel Stahlbf329632010-08-31 11:32:52 +0200183 rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
Jonathan Cameron73bce122010-07-11 16:39:19 +0100184 if (rx_array == NULL)
185 return -ENOMEM;
186 ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
187 if (ret < 0)
188 return ret;
Manuel Stahlbf329632010-08-31 11:32:52 +0200189 for (i = 0; i < h->indio_dev->ring->scan_count; i++)
Jonathan Cameron73bce122010-07-11 16:39:19 +0100190 data[i] = combine_8_to_16(rx_array[i*4+1],
191 rx_array[i*4+3]);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100192 kfree(rx_array);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100193
Jonathan Cameron73bce122010-07-11 16:39:19 +0100194 return i*sizeof(data[0]);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100195}
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100196
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100197/* Caller responsible for locking as necessary. */
Jonathan Cameron26de7202010-05-04 22:34:36 +0100198static int
199__lis3l02dq_write_data_ready_config(struct device *dev,
200 struct iio_event_handler_list *list,
201 bool state)
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100202{
203 int ret;
204 u8 valold;
205 bool currentlyset;
206 struct iio_dev *indio_dev = dev_get_drvdata(dev);
207
208/* Get the current event mask register */
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100209 ret = lis3l02dq_spi_read_reg_8(indio_dev,
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100210 LIS3L02DQ_REG_CTRL_2_ADDR,
211 &valold);
212 if (ret)
213 goto error_ret;
214/* Find out if data ready is already on */
215 currentlyset
216 = valold & LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
217
218/* Disable requested */
219 if (!state && currentlyset) {
220
221 valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
222 /* The double write is to overcome a hardware bug?*/
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100223 ret = lis3l02dq_spi_write_reg_8(indio_dev,
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100224 LIS3L02DQ_REG_CTRL_2_ADDR,
225 &valold);
226 if (ret)
227 goto error_ret;
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100228 ret = lis3l02dq_spi_write_reg_8(indio_dev,
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100229 LIS3L02DQ_REG_CTRL_2_ADDR,
230 &valold);
231 if (ret)
232 goto error_ret;
233
234 iio_remove_event_from_list(list,
235 &indio_dev->interrupts[0]
236 ->ev_list);
237
238/* Enable requested */
239 } else if (state && !currentlyset) {
240 /* if not set, enable requested */
241 valold |= LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
242 iio_add_event_to_list(list, &indio_dev->interrupts[0]->ev_list);
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100243 ret = lis3l02dq_spi_write_reg_8(indio_dev,
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100244 LIS3L02DQ_REG_CTRL_2_ADDR,
245 &valold);
246 if (ret)
247 goto error_ret;
248 }
249
250 return 0;
251error_ret:
252 return ret;
253}
254
255/**
256 * lis3l02dq_data_rdy_trigger_set_state() set datardy interrupt state
257 *
258 * If disabling the interrupt also does a final read to ensure it is clear.
259 * This is only important in some cases where the scan enable elements are
260 * switched before the ring is reenabled.
261 **/
262static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
263 bool state)
264{
265 struct lis3l02dq_state *st = trig->private_data;
266 int ret = 0;
267 u8 t;
Jonathan Cameron73bce122010-07-11 16:39:19 +0100268 __lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev,
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100269 &iio_event_data_rdy_trig,
270 state);
271 if (state == false) {
272 /* possible quirk with handler currently worked around
273 by ensuring the work queue is empty */
274 flush_scheduled_work();
275 /* Clear any outstanding ready events */
276 ret = lis3l02dq_read_all(st, NULL);
277 }
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100278 lis3l02dq_spi_read_reg_8(st->help.indio_dev,
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100279 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
280 &t);
281 return ret;
282}
Jonathan Cameron9dbfb6f2010-09-04 17:54:48 +0100283
284static IIO_TRIGGER_NAME_ATTR;
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100285
286static struct attribute *lis3l02dq_trigger_attrs[] = {
287 &dev_attr_name.attr,
288 NULL,
289};
290
291static const struct attribute_group lis3l02dq_trigger_attr_group = {
292 .attrs = lis3l02dq_trigger_attrs,
293};
294
295/**
296 * lis3l02dq_trig_try_reen() try renabling irq for data rdy trigger
297 * @trig: the datardy trigger
298 *
299 * As the trigger may occur on any data element being updated it is
300 * really rather likely to occur during the read from the previous
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300301 * trigger event. The only way to discover if this has occurred on
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100302 * boards not supporting level interrupts is to take a look at the line.
303 * If it is indicating another interrupt and we don't seem to have a
304 * handler looking at it, then we need to notify the core that we need
305 * to tell the triggering core to try reading all these again.
306 **/
307static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
308{
309 struct lis3l02dq_state *st = trig->private_data;
310 enable_irq(st->us->irq);
311 /* If gpio still high (or high again) */
312 if (gpio_get_value(irq_to_gpio(st->us->irq)))
313 if (st->inter == 0) {
314 /* already interrupt handler dealing with it */
315 disable_irq_nosync(st->us->irq);
316 if (st->inter == 1) {
317 /* interrupt handler snuck in between test
318 * and disable */
319 enable_irq(st->us->irq);
320 return 0;
321 }
322 return -EAGAIN;
323 }
324 /* irq reenabled so success! */
325 return 0;
326}
327
328int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
329{
330 int ret;
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100331 struct iio_sw_ring_helper_state *h
332 = iio_dev_get_devdata(indio_dev);
333 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100334
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100335 st->trig = iio_allocate_trigger();
336 if (!st->trig)
Dan Carpenteref6d4f52010-03-16 13:03:49 +0300337 return -ENOMEM;
338
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100339 st->trig->name = kasprintf(GFP_KERNEL,
340 "lis3l02dq-dev%d",
341 indio_dev->id);
342 if (!st->trig->name) {
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100343 ret = -ENOMEM;
344 goto error_free_trig;
345 }
Jonathan Cameron3c9bbf52010-07-11 16:39:08 +0100346
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100347 st->trig->dev.parent = &st->us->dev;
348 st->trig->owner = THIS_MODULE;
349 st->trig->private_data = st;
350 st->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state;
351 st->trig->try_reenable = &lis3l02dq_trig_try_reen;
352 st->trig->control_attrs = &lis3l02dq_trigger_attr_group;
353 ret = iio_trigger_register(st->trig);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100354 if (ret)
355 goto error_free_trig_name;
356
357 return 0;
358
359error_free_trig_name:
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100360 kfree(st->trig->name);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100361error_free_trig:
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100362 iio_free_trigger(st->trig);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100363
364 return ret;
365}
366
367void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
368{
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100369 struct iio_sw_ring_helper_state *h
370 = iio_dev_get_devdata(indio_dev);
371 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100372
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100373 iio_trigger_unregister(st->trig);
374 kfree(st->trig->name);
375 iio_free_trigger(st->trig);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100376}
377
378void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
379{
380 kfree(indio_dev->pollfunc);
Jonathan Cameronb9497932011-02-11 13:09:11 +0000381 lis3l02dq_free_buf(indio_dev->ring);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100382}
383
Jonathan Cameronf3736412011-05-18 14:40:52 +0100384static int lis3l02dq_ring_postenable(struct iio_dev *indio_dev)
385{
386 /* Disable unwanted channels otherwise the interrupt will not clear */
387 u8 t;
388 int ret;
389 bool oneenabled = false;
390
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100391 ret = lis3l02dq_spi_read_reg_8(indio_dev,
Jonathan Cameronf3736412011-05-18 14:40:52 +0100392 LIS3L02DQ_REG_CTRL_1_ADDR,
393 &t);
394 if (ret)
395 goto error_ret;
396
397 if (iio_scan_mask_query(indio_dev->ring, 0)) {
398 t |= LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
399 oneenabled = true;
400 } else
401 t &= ~LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
402 if (iio_scan_mask_query(indio_dev->ring, 1)) {
403 t |= LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
404 oneenabled = true;
405 } else
406 t &= ~LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
407 if (iio_scan_mask_query(indio_dev->ring, 2)) {
408 t |= LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
409 oneenabled = true;
410 } else
411 t &= ~LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
412
413 if (!oneenabled) /* what happens in this case is unknown */
414 return -EINVAL;
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100415 ret = lis3l02dq_spi_write_reg_8(indio_dev,
Jonathan Cameronf3736412011-05-18 14:40:52 +0100416 LIS3L02DQ_REG_CTRL_1_ADDR,
417 &t);
418 if (ret)
419 goto error_ret;
420
421 return iio_triggered_ring_postenable(indio_dev);
422error_ret:
423 return ret;
424}
425
426/* Turn all channels on again */
427static int lis3l02dq_ring_predisable(struct iio_dev *indio_dev)
428{
429 u8 t;
430 int ret;
431
432 ret = iio_triggered_ring_predisable(indio_dev);
433 if (ret)
434 goto error_ret;
435
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100436 ret = lis3l02dq_spi_read_reg_8(indio_dev,
Jonathan Cameronf3736412011-05-18 14:40:52 +0100437 LIS3L02DQ_REG_CTRL_1_ADDR,
438 &t);
439 if (ret)
440 goto error_ret;
441 t |= LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE |
442 LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE |
443 LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
444
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100445 ret = lis3l02dq_spi_write_reg_8(indio_dev,
Jonathan Cameronf3736412011-05-18 14:40:52 +0100446 LIS3L02DQ_REG_CTRL_1_ADDR,
447 &t);
448
449error_ret:
450 return ret;
451}
452
453
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100454int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
455{
Jonathan Cameron73bce122010-07-11 16:39:19 +0100456 int ret;
457 struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
Manuel Stahl07e62292010-08-31 11:32:51 +0200458 struct iio_ring_buffer *ring;
Jonathan Cameron73bce122010-07-11 16:39:19 +0100459 INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
Jonathan Cameron73bce122010-07-11 16:39:19 +0100460 h->get_ring_element = &lis3l02dq_get_ring_element;
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100461
Jonathan Cameronb9497932011-02-11 13:09:11 +0000462 ring = lis3l02dq_alloc_buf(indio_dev);
Manuel Stahl07e62292010-08-31 11:32:51 +0200463 if (!ring)
Jonathan Cameron73bce122010-07-11 16:39:19 +0100464 return -ENOMEM;
465
Manuel Stahl07e62292010-08-31 11:32:51 +0200466 indio_dev->ring = ring;
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100467 /* Effectively select the ring buffer implementation */
Jonathan Cameronb9497932011-02-11 13:09:11 +0000468 lis3l02dq_register_buf_funcs(&ring->access);
Manuel Stahl07e62292010-08-31 11:32:51 +0200469 ring->bpe = 2;
Jonathan Cameronf3736412011-05-18 14:40:52 +0100470
Manuel Stahlbf329632010-08-31 11:32:52 +0200471 ring->scan_timestamp = true;
Manuel Stahl07e62292010-08-31 11:32:51 +0200472 ring->preenable = &iio_sw_ring_preenable;
Jonathan Cameronf3736412011-05-18 14:40:52 +0100473 ring->postenable = &lis3l02dq_ring_postenable;
474 ring->predisable = &lis3l02dq_ring_predisable;
Manuel Stahl07e62292010-08-31 11:32:51 +0200475 ring->owner = THIS_MODULE;
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100476
Manuel Stahlbf329632010-08-31 11:32:52 +0200477 /* Set default scan mode */
Jonathan Cameronf3736412011-05-18 14:40:52 +0100478 iio_scan_mask_set(ring, 0);
479 iio_scan_mask_set(ring, 1);
480 iio_scan_mask_set(ring, 2);
Manuel Stahlbf329632010-08-31 11:32:52 +0200481
Jonathan Cameron15744092010-07-11 16:39:09 +0100482 ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
483 if (ret)
Joe Perches859171c2010-11-14 19:04:48 -0800484 goto error_iio_sw_rb_free;
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100485 indio_dev->modes |= INDIO_RING_TRIGGERED;
486 return 0;
487
488error_iio_sw_rb_free:
Jonathan Cameronb9497932011-02-11 13:09:11 +0000489 lis3l02dq_free_buf(indio_dev->ring);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100490 return ret;
491}