]>
Commit | Line | Data |
---|---|---|
14cd9a73 JC |
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> | |
5a0e3ad6 | 11 | #include <linux/slab.h> |
14cd9a73 JC |
12 | |
13 | #include "../iio.h" | |
14 | #include "../sysfs.h" | |
15 | #include "../ring_sw.h" | |
b949793b | 16 | #include "../kfifo_buf.h" |
14cd9a73 JC |
17 | #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 | **/ | |
24 | static 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 | /** | |
32 | * lis3l02dq_scan_el_set_state() set whether a scan contains a given channel | |
33 | * @scan_el: associtate iio scan element attribute | |
34 | * @indio_dev: the device structure | |
35 | * @bool: desired state | |
36 | * | |
37 | * mlock already held when this is called. | |
38 | **/ | |
39 | static int lis3l02dq_scan_el_set_state(struct iio_scan_el *scan_el, | |
40 | struct iio_dev *indio_dev, | |
41 | bool state) | |
42 | { | |
43 | u8 t, mask; | |
44 | int ret; | |
45 | ||
46 | ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev, | |
47 | LIS3L02DQ_REG_CTRL_1_ADDR, | |
48 | &t); | |
49 | if (ret) | |
50 | goto error_ret; | |
51 | switch (scan_el->label) { | |
52 | case LIS3L02DQ_REG_OUT_X_L_ADDR: | |
53 | mask = LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE; | |
54 | break; | |
55 | case LIS3L02DQ_REG_OUT_Y_L_ADDR: | |
56 | mask = LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE; | |
57 | break; | |
58 | case LIS3L02DQ_REG_OUT_Z_L_ADDR: | |
59 | mask = LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE; | |
60 | break; | |
61 | default: | |
62 | ret = -EINVAL; | |
63 | goto error_ret; | |
64 | } | |
65 | ||
66 | if (!(mask & t) == state) { | |
67 | if (state) | |
68 | t |= mask; | |
69 | else | |
70 | t &= ~mask; | |
71 | ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev, | |
72 | LIS3L02DQ_REG_CTRL_1_ADDR, | |
73 | &t); | |
74 | } | |
75 | error_ret: | |
76 | return ret; | |
77 | ||
78 | } | |
44f270de | 79 | static IIO_SCAN_EL_C(accel_x, 0, |
14cd9a73 JC |
80 | LIS3L02DQ_REG_OUT_X_L_ADDR, |
81 | &lis3l02dq_scan_el_set_state); | |
44f270de | 82 | static IIO_SCAN_EL_C(accel_y, 1, |
14cd9a73 JC |
83 | LIS3L02DQ_REG_OUT_Y_L_ADDR, |
84 | &lis3l02dq_scan_el_set_state); | |
44f270de | 85 | static IIO_SCAN_EL_C(accel_z, 2, |
14cd9a73 JC |
86 | LIS3L02DQ_REG_OUT_Z_L_ADDR, |
87 | &lis3l02dq_scan_el_set_state); | |
6a36e618 | 88 | static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 12, 16); |
f3fb0011 | 89 | static IIO_SCAN_EL_TIMESTAMP(3); |
6a36e618 | 90 | static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); |
14cd9a73 JC |
91 | |
92 | static struct attribute *lis3l02dq_scan_el_attrs[] = { | |
93 | &iio_scan_el_accel_x.dev_attr.attr, | |
13a091ab | 94 | &iio_const_attr_accel_x_index.dev_attr.attr, |
14cd9a73 | 95 | &iio_scan_el_accel_y.dev_attr.attr, |
13a091ab | 96 | &iio_const_attr_accel_y_index.dev_attr.attr, |
14cd9a73 | 97 | &iio_scan_el_accel_z.dev_attr.attr, |
13a091ab | 98 | &iio_const_attr_accel_z_index.dev_attr.attr, |
6a36e618 | 99 | &iio_const_attr_accel_type.dev_attr.attr, |
14cd9a73 | 100 | &iio_scan_el_timestamp.dev_attr.attr, |
13a091ab | 101 | &iio_const_attr_timestamp_index.dev_attr.attr, |
6a36e618 | 102 | &iio_const_attr_timestamp_type.dev_attr.attr, |
14cd9a73 JC |
103 | NULL, |
104 | }; | |
105 | ||
106 | static struct attribute_group lis3l02dq_scan_el_group = { | |
107 | .attrs = lis3l02dq_scan_el_attrs, | |
108 | .name = "scan_elements", | |
109 | }; | |
110 | ||
111 | /** | |
112 | * lis3l02dq_poll_func_th() top half interrupt handler called by trigger | |
113 | * @private_data: iio_dev | |
114 | **/ | |
7b2c33b1 | 115 | static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev, s64 time) |
14cd9a73 | 116 | { |
73bce12e JC |
117 | struct iio_sw_ring_helper_state *h |
118 | = iio_dev_get_devdata(indio_dev); | |
119 | struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); | |
120 | /* in this case we need to slightly extend the helper function */ | |
121 | iio_sw_poll_func_th(indio_dev, time); | |
14cd9a73 | 122 | |
73bce12e | 123 | /* Indicate that this interrupt is being handled */ |
14cd9a73 JC |
124 | /* Technically this is trigger related, but without this |
125 | * handler running there is currently now way for the interrupt | |
126 | * to clear. | |
127 | */ | |
128 | st->inter = 1; | |
129 | } | |
130 | ||
131 | /** | |
132 | * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig | |
133 | **/ | |
73bce12e | 134 | static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *indio_dev, |
14cd9a73 JC |
135 | int index, |
136 | s64 timestamp, | |
137 | int no_test) | |
138 | { | |
73bce12e JC |
139 | struct iio_sw_ring_helper_state *h |
140 | = iio_dev_get_devdata(indio_dev); | |
141 | struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); | |
14cd9a73 | 142 | |
73bce12e | 143 | iio_trigger_poll(st->trig, timestamp); |
14cd9a73 JC |
144 | |
145 | return IRQ_HANDLED; | |
146 | } | |
147 | ||
148 | /* This is an event as it is a response to a physical interrupt */ | |
149 | IIO_EVENT_SH(data_rdy_trig, &lis3l02dq_data_rdy_trig_poll); | |
150 | ||
151 | /** | |
152 | * lis3l02dq_read_accel_from_ring() individual acceleration read from ring | |
153 | **/ | |
154 | ssize_t lis3l02dq_read_accel_from_ring(struct device *dev, | |
155 | struct device_attribute *attr, | |
156 | char *buf) | |
157 | { | |
158 | struct iio_scan_el *el = NULL; | |
159 | int ret, len = 0, i = 0; | |
160 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | |
161 | struct iio_dev *dev_info = dev_get_drvdata(dev); | |
bf32963c MS |
162 | struct iio_ring_buffer *ring = dev_info->ring; |
163 | struct attribute_group *scan_el_attrs = ring->scan_el_attrs; | |
14cd9a73 JC |
164 | s16 *data; |
165 | ||
bf32963c | 166 | while (scan_el_attrs->attrs[i]) { |
14cd9a73 | 167 | el = to_iio_scan_el((struct device_attribute *) |
bf32963c | 168 | (scan_el_attrs->attrs[i])); |
14cd9a73 JC |
169 | /* label is in fact the address */ |
170 | if (el->label == this_attr->address) | |
171 | break; | |
172 | i++; | |
173 | } | |
bf32963c | 174 | if (!scan_el_attrs->attrs[i]) { |
14cd9a73 JC |
175 | ret = -EINVAL; |
176 | goto error_ret; | |
177 | } | |
178 | /* If this element is in the scan mask */ | |
bf32963c | 179 | ret = iio_scan_mask_query(ring, el->number); |
14cd9a73 JC |
180 | if (ret < 0) |
181 | goto error_ret; | |
182 | if (ret) { | |
bf32963c | 183 | data = kmalloc(ring->access.get_bytes_per_datum(ring), |
14cd9a73 JC |
184 | GFP_KERNEL); |
185 | if (data == NULL) | |
186 | return -ENOMEM; | |
bf32963c MS |
187 | ret = ring->access.read_last(ring, |
188 | (u8 *)data); | |
14cd9a73 JC |
189 | if (ret) |
190 | goto error_free_data; | |
191 | } else { | |
192 | ret = -EINVAL; | |
193 | goto error_ret; | |
194 | } | |
bf32963c | 195 | len = iio_scan_mask_count_to_right(ring, el->number); |
14cd9a73 JC |
196 | if (len < 0) { |
197 | ret = len; | |
198 | goto error_free_data; | |
199 | } | |
200 | len = sprintf(buf, "ring %d\n", data[len]); | |
201 | error_free_data: | |
202 | kfree(data); | |
203 | error_ret: | |
204 | return ret ? ret : len; | |
205 | ||
206 | } | |
207 | ||
26de7208 | 208 | static const u8 read_all_tx_array[] = { |
14cd9a73 JC |
209 | LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_L_ADDR), 0, |
210 | LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_H_ADDR), 0, | |
211 | LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Y_L_ADDR), 0, | |
212 | LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Y_H_ADDR), 0, | |
213 | LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Z_L_ADDR), 0, | |
214 | LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Z_H_ADDR), 0, | |
215 | }; | |
216 | ||
217 | /** | |
218 | * lis3l02dq_read_all() Reads all channels currently selected | |
219 | * @st: device specific state | |
25985edc | 220 | * @rx_array: (dma capable) receive array, must be at least |
14cd9a73 JC |
221 | * 4*number of channels |
222 | **/ | |
7cfce527 | 223 | static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array) |
14cd9a73 | 224 | { |
bf32963c | 225 | struct iio_ring_buffer *ring = st->help.indio_dev->ring; |
14cd9a73 JC |
226 | struct spi_transfer *xfers; |
227 | struct spi_message msg; | |
228 | int ret, i, j = 0; | |
229 | ||
bf32963c | 230 | xfers = kzalloc((ring->scan_count) * 2 |
14cd9a73 JC |
231 | * sizeof(*xfers), GFP_KERNEL); |
232 | if (!xfers) | |
233 | return -ENOMEM; | |
234 | ||
235 | mutex_lock(&st->buf_lock); | |
236 | ||
237 | for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) { | |
bf32963c | 238 | if (ring->scan_mask & (1 << i)) { |
14cd9a73 JC |
239 | /* lower byte */ |
240 | xfers[j].tx_buf = st->tx + 2*j; | |
241 | st->tx[2*j] = read_all_tx_array[i*4]; | |
242 | st->tx[2*j + 1] = 0; | |
243 | if (rx_array) | |
244 | xfers[j].rx_buf = rx_array + j*2; | |
245 | xfers[j].bits_per_word = 8; | |
246 | xfers[j].len = 2; | |
247 | xfers[j].cs_change = 1; | |
248 | j++; | |
249 | ||
250 | /* upper byte */ | |
251 | xfers[j].tx_buf = st->tx + 2*j; | |
252 | st->tx[2*j] = read_all_tx_array[i*4 + 2]; | |
253 | st->tx[2*j + 1] = 0; | |
254 | if (rx_array) | |
255 | xfers[j].rx_buf = rx_array + j*2; | |
256 | xfers[j].bits_per_word = 8; | |
257 | xfers[j].len = 2; | |
258 | xfers[j].cs_change = 1; | |
259 | j++; | |
260 | } | |
261 | } | |
262 | /* After these are transmitted, the rx_buff should have | |
263 | * values in alternate bytes | |
264 | */ | |
265 | spi_message_init(&msg); | |
bf32963c | 266 | for (j = 0; j < ring->scan_count * 2; j++) |
14cd9a73 JC |
267 | spi_message_add_tail(&xfers[j], &msg); |
268 | ||
269 | ret = spi_sync(st->us, &msg); | |
270 | mutex_unlock(&st->buf_lock); | |
271 | kfree(xfers); | |
272 | ||
273 | return ret; | |
274 | } | |
275 | ||
14cd9a73 JC |
276 | static void lis3l02dq_trigger_bh_to_ring(struct work_struct *work_s) |
277 | { | |
73bce12e JC |
278 | struct iio_sw_ring_helper_state *h |
279 | = container_of(work_s, struct iio_sw_ring_helper_state, | |
280 | work_trigger_to_ring); | |
281 | struct lis3l02dq_state *st = lis3l02dq_h_to_s(h); | |
14cd9a73 | 282 | |
14cd9a73 | 283 | st->inter = 0; |
73bce12e JC |
284 | iio_sw_trigger_bh_to_ring(work_s); |
285 | } | |
14cd9a73 | 286 | |
73bce12e JC |
287 | static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h, |
288 | u8 *buf) | |
289 | { | |
290 | int ret, i; | |
291 | u8 *rx_array ; | |
292 | s16 *data = (s16 *)buf; | |
14cd9a73 | 293 | |
bf32963c | 294 | rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL); |
73bce12e JC |
295 | if (rx_array == NULL) |
296 | return -ENOMEM; | |
297 | ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array); | |
298 | if (ret < 0) | |
299 | return ret; | |
bf32963c | 300 | for (i = 0; i < h->indio_dev->ring->scan_count; i++) |
73bce12e JC |
301 | data[i] = combine_8_to_16(rx_array[i*4+1], |
302 | rx_array[i*4+3]); | |
14cd9a73 | 303 | kfree(rx_array); |
14cd9a73 | 304 | |
73bce12e | 305 | return i*sizeof(data[0]); |
14cd9a73 | 306 | } |
14cd9a73 | 307 | |
14cd9a73 | 308 | /* Caller responsible for locking as necessary. */ |
26de7208 JC |
309 | static int |
310 | __lis3l02dq_write_data_ready_config(struct device *dev, | |
311 | struct iio_event_handler_list *list, | |
312 | bool state) | |
14cd9a73 JC |
313 | { |
314 | int ret; | |
315 | u8 valold; | |
316 | bool currentlyset; | |
317 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | |
318 | ||
319 | /* Get the current event mask register */ | |
320 | ret = lis3l02dq_spi_read_reg_8(dev, | |
321 | LIS3L02DQ_REG_CTRL_2_ADDR, | |
322 | &valold); | |
323 | if (ret) | |
324 | goto error_ret; | |
325 | /* Find out if data ready is already on */ | |
326 | currentlyset | |
327 | = valold & LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION; | |
328 | ||
329 | /* Disable requested */ | |
330 | if (!state && currentlyset) { | |
331 | ||
332 | valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION; | |
333 | /* The double write is to overcome a hardware bug?*/ | |
334 | ret = lis3l02dq_spi_write_reg_8(dev, | |
335 | LIS3L02DQ_REG_CTRL_2_ADDR, | |
336 | &valold); | |
337 | if (ret) | |
338 | goto error_ret; | |
339 | ret = lis3l02dq_spi_write_reg_8(dev, | |
340 | LIS3L02DQ_REG_CTRL_2_ADDR, | |
341 | &valold); | |
342 | if (ret) | |
343 | goto error_ret; | |
344 | ||
345 | iio_remove_event_from_list(list, | |
346 | &indio_dev->interrupts[0] | |
347 | ->ev_list); | |
348 | ||
349 | /* Enable requested */ | |
350 | } else if (state && !currentlyset) { | |
351 | /* if not set, enable requested */ | |
352 | valold |= LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION; | |
353 | iio_add_event_to_list(list, &indio_dev->interrupts[0]->ev_list); | |
354 | ret = lis3l02dq_spi_write_reg_8(dev, | |
355 | LIS3L02DQ_REG_CTRL_2_ADDR, | |
356 | &valold); | |
357 | if (ret) | |
358 | goto error_ret; | |
359 | } | |
360 | ||
361 | return 0; | |
362 | error_ret: | |
363 | return ret; | |
364 | } | |
365 | ||
366 | /** | |
367 | * lis3l02dq_data_rdy_trigger_set_state() set datardy interrupt state | |
368 | * | |
369 | * If disabling the interrupt also does a final read to ensure it is clear. | |
370 | * This is only important in some cases where the scan enable elements are | |
371 | * switched before the ring is reenabled. | |
372 | **/ | |
373 | static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, | |
374 | bool state) | |
375 | { | |
376 | struct lis3l02dq_state *st = trig->private_data; | |
377 | int ret = 0; | |
378 | u8 t; | |
73bce12e | 379 | __lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev, |
14cd9a73 JC |
380 | &iio_event_data_rdy_trig, |
381 | state); | |
382 | if (state == false) { | |
383 | /* possible quirk with handler currently worked around | |
384 | by ensuring the work queue is empty */ | |
385 | flush_scheduled_work(); | |
386 | /* Clear any outstanding ready events */ | |
387 | ret = lis3l02dq_read_all(st, NULL); | |
388 | } | |
73bce12e | 389 | lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev, |
14cd9a73 JC |
390 | LIS3L02DQ_REG_WAKE_UP_SRC_ADDR, |
391 | &t); | |
392 | return ret; | |
393 | } | |
9dbfb6f1 JC |
394 | |
395 | static IIO_TRIGGER_NAME_ATTR; | |
14cd9a73 JC |
396 | |
397 | static struct attribute *lis3l02dq_trigger_attrs[] = { | |
398 | &dev_attr_name.attr, | |
399 | NULL, | |
400 | }; | |
401 | ||
402 | static const struct attribute_group lis3l02dq_trigger_attr_group = { | |
403 | .attrs = lis3l02dq_trigger_attrs, | |
404 | }; | |
405 | ||
406 | /** | |
407 | * lis3l02dq_trig_try_reen() try renabling irq for data rdy trigger | |
408 | * @trig: the datardy trigger | |
409 | * | |
410 | * As the trigger may occur on any data element being updated it is | |
411 | * really rather likely to occur during the read from the previous | |
25985edc | 412 | * trigger event. The only way to discover if this has occurred on |
14cd9a73 JC |
413 | * boards not supporting level interrupts is to take a look at the line. |
414 | * If it is indicating another interrupt and we don't seem to have a | |
415 | * handler looking at it, then we need to notify the core that we need | |
416 | * to tell the triggering core to try reading all these again. | |
417 | **/ | |
418 | static int lis3l02dq_trig_try_reen(struct iio_trigger *trig) | |
419 | { | |
420 | struct lis3l02dq_state *st = trig->private_data; | |
421 | enable_irq(st->us->irq); | |
422 | /* If gpio still high (or high again) */ | |
423 | if (gpio_get_value(irq_to_gpio(st->us->irq))) | |
424 | if (st->inter == 0) { | |
425 | /* already interrupt handler dealing with it */ | |
426 | disable_irq_nosync(st->us->irq); | |
427 | if (st->inter == 1) { | |
428 | /* interrupt handler snuck in between test | |
429 | * and disable */ | |
430 | enable_irq(st->us->irq); | |
431 | return 0; | |
432 | } | |
433 | return -EAGAIN; | |
434 | } | |
435 | /* irq reenabled so success! */ | |
436 | return 0; | |
437 | } | |
438 | ||
439 | int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) | |
440 | { | |
441 | int ret; | |
442 | struct lis3l02dq_state *state = indio_dev->dev_data; | |
443 | ||
444 | state->trig = iio_allocate_trigger(); | |
ef6d4f54 DC |
445 | if (!state->trig) |
446 | return -ENOMEM; | |
447 | ||
3c9bbf58 JC |
448 | state->trig->name = kasprintf(GFP_KERNEL, |
449 | "lis3l02dq-dev%d", | |
450 | indio_dev->id); | |
14cd9a73 JC |
451 | if (!state->trig->name) { |
452 | ret = -ENOMEM; | |
453 | goto error_free_trig; | |
454 | } | |
3c9bbf58 | 455 | |
14cd9a73 JC |
456 | state->trig->dev.parent = &state->us->dev; |
457 | state->trig->owner = THIS_MODULE; | |
458 | state->trig->private_data = state; | |
459 | state->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state; | |
460 | state->trig->try_reenable = &lis3l02dq_trig_try_reen; | |
461 | state->trig->control_attrs = &lis3l02dq_trigger_attr_group; | |
462 | ret = iio_trigger_register(state->trig); | |
463 | if (ret) | |
464 | goto error_free_trig_name; | |
465 | ||
466 | return 0; | |
467 | ||
468 | error_free_trig_name: | |
469 | kfree(state->trig->name); | |
470 | error_free_trig: | |
471 | iio_free_trigger(state->trig); | |
472 | ||
473 | return ret; | |
474 | } | |
475 | ||
476 | void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) | |
477 | { | |
478 | struct lis3l02dq_state *state = indio_dev->dev_data; | |
479 | ||
480 | iio_trigger_unregister(state->trig); | |
481 | kfree(state->trig->name); | |
482 | iio_free_trigger(state->trig); | |
483 | } | |
484 | ||
485 | void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev) | |
486 | { | |
487 | kfree(indio_dev->pollfunc); | |
b949793b | 488 | lis3l02dq_free_buf(indio_dev->ring); |
14cd9a73 JC |
489 | } |
490 | ||
491 | int lis3l02dq_configure_ring(struct iio_dev *indio_dev) | |
492 | { | |
73bce12e JC |
493 | int ret; |
494 | struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev); | |
07e6229e | 495 | struct iio_ring_buffer *ring; |
73bce12e | 496 | INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring); |
73bce12e | 497 | h->get_ring_element = &lis3l02dq_get_ring_element; |
14cd9a73 | 498 | |
b949793b | 499 | ring = lis3l02dq_alloc_buf(indio_dev); |
07e6229e | 500 | if (!ring) |
73bce12e JC |
501 | return -ENOMEM; |
502 | ||
07e6229e | 503 | indio_dev->ring = ring; |
14cd9a73 | 504 | /* Effectively select the ring buffer implementation */ |
b949793b | 505 | lis3l02dq_register_buf_funcs(&ring->access); |
07e6229e | 506 | ring->bpe = 2; |
bf32963c MS |
507 | ring->scan_el_attrs = &lis3l02dq_scan_el_group; |
508 | ring->scan_timestamp = true; | |
07e6229e MS |
509 | ring->preenable = &iio_sw_ring_preenable; |
510 | ring->postenable = &iio_triggered_ring_postenable; | |
511 | ring->predisable = &iio_triggered_ring_predisable; | |
512 | ring->owner = THIS_MODULE; | |
14cd9a73 | 513 | |
bf32963c MS |
514 | /* Set default scan mode */ |
515 | iio_scan_mask_set(ring, iio_scan_el_accel_x.number); | |
516 | iio_scan_mask_set(ring, iio_scan_el_accel_y.number); | |
517 | iio_scan_mask_set(ring, iio_scan_el_accel_z.number); | |
518 | ||
15744090 JC |
519 | ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th); |
520 | if (ret) | |
859171ca | 521 | goto error_iio_sw_rb_free; |
14cd9a73 JC |
522 | indio_dev->modes |= INDIO_RING_TRIGGERED; |
523 | return 0; | |
524 | ||
525 | error_iio_sw_rb_free: | |
b949793b | 526 | lis3l02dq_free_buf(indio_dev->ring); |
14cd9a73 JC |
527 | return ret; |
528 | } |