1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/gpio.h>
18#include <linux/of_gpio.h>
19#include <linux/mutex.h>
20#include <linux/device.h>
21#include <linux/kernel.h>
22#include <linux/spi/spi.h>
23#include <linux/slab.h>
24#include <linux/sysfs.h>
25#include <linux/module.h>
26
27#include <linux/iio/iio.h>
28#include <linux/iio/sysfs.h>
29#include <linux/iio/events.h>
30#include <linux/iio/buffer.h>
31
32#include "lis3l02dq.h"
33
34
35
36
37
38
39#ifndef CONFIG_IIO_BUFFER
40static irqreturn_t lis3l02dq_nobuffer(int irq, void *private)
41{
42 return IRQ_WAKE_THREAD;
43}
44#endif
45
46
47
48
49
50
51
52int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
53 u8 reg_address, u8 *val)
54{
55 struct lis3l02dq_state *st = iio_priv(indio_dev);
56 int ret;
57 struct spi_transfer xfer = {
58 .tx_buf = st->tx,
59 .rx_buf = st->rx,
60 .bits_per_word = 8,
61 .len = 2,
62 };
63
64 mutex_lock(&st->buf_lock);
65 st->tx[0] = LIS3L02DQ_READ_REG(reg_address);
66 st->tx[1] = 0;
67
68 ret = spi_sync_transfer(st->us, &xfer, 1);
69 *val = st->rx[1];
70 mutex_unlock(&st->buf_lock);
71
72 return ret;
73}
74
75
76
77
78
79
80
81int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
82 u8 reg_address,
83 u8 val)
84{
85 int ret;
86 struct lis3l02dq_state *st = iio_priv(indio_dev);
87
88 mutex_lock(&st->buf_lock);
89 st->tx[0] = LIS3L02DQ_WRITE_REG(reg_address);
90 st->tx[1] = val;
91 ret = spi_write(st->us, st->tx, 2);
92 mutex_unlock(&st->buf_lock);
93
94 return ret;
95}
96
97
98
99
100
101
102
103
104static int lis3l02dq_spi_write_reg_s16(struct iio_dev *indio_dev,
105 u8 lower_reg_address,
106 s16 value)
107{
108 int ret;
109 struct lis3l02dq_state *st = iio_priv(indio_dev);
110 struct spi_transfer xfers[] = { {
111 .tx_buf = st->tx,
112 .bits_per_word = 8,
113 .len = 2,
114 .cs_change = 1,
115 }, {
116 .tx_buf = st->tx + 2,
117 .bits_per_word = 8,
118 .len = 2,
119 },
120 };
121
122 mutex_lock(&st->buf_lock);
123 st->tx[0] = LIS3L02DQ_WRITE_REG(lower_reg_address);
124 st->tx[1] = value & 0xFF;
125 st->tx[2] = LIS3L02DQ_WRITE_REG(lower_reg_address + 1);
126 st->tx[3] = (value >> 8) & 0xFF;
127
128 ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
129 mutex_unlock(&st->buf_lock);
130
131 return ret;
132}
133
134static int lis3l02dq_read_reg_s16(struct iio_dev *indio_dev,
135 u8 lower_reg_address,
136 int *val)
137{
138 struct lis3l02dq_state *st = iio_priv(indio_dev);
139 int ret;
140 s16 tempval;
141 struct spi_transfer xfers[] = { {
142 .tx_buf = st->tx,
143 .rx_buf = st->rx,
144 .bits_per_word = 8,
145 .len = 2,
146 .cs_change = 1,
147 }, {
148 .tx_buf = st->tx + 2,
149 .rx_buf = st->rx + 2,
150 .bits_per_word = 8,
151 .len = 2,
152 },
153 };
154
155 mutex_lock(&st->buf_lock);
156 st->tx[0] = LIS3L02DQ_READ_REG(lower_reg_address);
157 st->tx[1] = 0;
158 st->tx[2] = LIS3L02DQ_READ_REG(lower_reg_address + 1);
159 st->tx[3] = 0;
160
161 ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
162 if (ret) {
163 dev_err(&st->us->dev, "problem when reading 16 bit register");
164 goto error_ret;
165 }
166 tempval = (s16)(st->rx[1]) | ((s16)(st->rx[3]) << 8);
167
168 *val = tempval;
169error_ret:
170 mutex_unlock(&st->buf_lock);
171 return ret;
172}
173
174enum lis3l02dq_rm_ind {
175 LIS3L02DQ_ACCEL,
176 LIS3L02DQ_GAIN,
177 LIS3L02DQ_BIAS,
178};
179
180static u8 lis3l02dq_axis_map[3][3] = {
181 [LIS3L02DQ_ACCEL] = { LIS3L02DQ_REG_OUT_X_L_ADDR,
182 LIS3L02DQ_REG_OUT_Y_L_ADDR,
183 LIS3L02DQ_REG_OUT_Z_L_ADDR },
184 [LIS3L02DQ_GAIN] = { LIS3L02DQ_REG_GAIN_X_ADDR,
185 LIS3L02DQ_REG_GAIN_Y_ADDR,
186 LIS3L02DQ_REG_GAIN_Z_ADDR },
187 [LIS3L02DQ_BIAS] = { LIS3L02DQ_REG_OFFSET_X_ADDR,
188 LIS3L02DQ_REG_OFFSET_Y_ADDR,
189 LIS3L02DQ_REG_OFFSET_Z_ADDR }
190};
191
192static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
193 const struct iio_chan_spec *chan,
194 enum iio_event_type type,
195 enum iio_event_direction dir,
196 enum iio_event_info info,
197 int *val, int *val2)
198{
199 int ret;
200
201 ret = lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
202 if (ret)
203 return ret;
204 return IIO_VAL_INT;
205}
206
207static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
208 const struct iio_chan_spec *chan,
209 enum iio_event_type type,
210 enum iio_event_direction dir,
211 enum iio_event_info info,
212 int val, int val2)
213{
214 u16 value = val;
215 return lis3l02dq_spi_write_reg_s16(indio_dev,
216 LIS3L02DQ_REG_THS_L_ADDR,
217 value);
218}
219
220static int lis3l02dq_write_raw(struct iio_dev *indio_dev,
221 struct iio_chan_spec const *chan,
222 int val,
223 int val2,
224 long mask)
225{
226 int ret = -EINVAL, reg;
227 u8 uval;
228 s8 sval;
229 switch (mask) {
230 case IIO_CHAN_INFO_CALIBBIAS:
231 if (val > 255 || val < -256)
232 return -EINVAL;
233 sval = val;
234 reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
235 ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, sval);
236 break;
237 case IIO_CHAN_INFO_CALIBSCALE:
238 if (val & ~0xFF)
239 return -EINVAL;
240 uval = val;
241 reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
242 ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, uval);
243 break;
244 }
245 return ret;
246}
247
248static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
249 struct iio_chan_spec const *chan,
250 int *val,
251 int *val2,
252 long mask)
253{
254 u8 utemp;
255 s8 stemp;
256 ssize_t ret = 0;
257 u8 reg;
258
259 switch (mask) {
260 case IIO_CHAN_INFO_RAW:
261
262 mutex_lock(&indio_dev->mlock);
263 if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
264 ret = -EBUSY;
265 } else {
266 reg = lis3l02dq_axis_map
267 [LIS3L02DQ_ACCEL][chan->address];
268 ret = lis3l02dq_read_reg_s16(indio_dev, reg, val);
269 }
270 mutex_unlock(&indio_dev->mlock);
271 if (ret < 0)
272 goto error_ret;
273 return IIO_VAL_INT;
274 case IIO_CHAN_INFO_SCALE:
275 *val = 0;
276 *val2 = 9580;
277 return IIO_VAL_INT_PLUS_MICRO;
278 case IIO_CHAN_INFO_CALIBSCALE:
279 reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
280 ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, &utemp);
281 if (ret)
282 goto error_ret;
283
284 *val = utemp;
285 return IIO_VAL_INT;
286
287 case IIO_CHAN_INFO_CALIBBIAS:
288 reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
289 ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, (u8 *)&stemp);
290
291 *val = stemp;
292 return IIO_VAL_INT;
293 }
294error_ret:
295 return ret;
296}
297
298static ssize_t lis3l02dq_read_frequency(struct device *dev,
299 struct device_attribute *attr,
300 char *buf)
301{
302 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
303 int ret, len = 0;
304 s8 t;
305 ret = lis3l02dq_spi_read_reg_8(indio_dev,
306 LIS3L02DQ_REG_CTRL_1_ADDR,
307 (u8 *)&t);
308 if (ret)
309 return ret;
310 t &= LIS3L02DQ_DEC_MASK;
311 switch (t) {
312 case LIS3L02DQ_REG_CTRL_1_DF_128:
313 len = sprintf(buf, "280\n");
314 break;
315 case LIS3L02DQ_REG_CTRL_1_DF_64:
316 len = sprintf(buf, "560\n");
317 break;
318 case LIS3L02DQ_REG_CTRL_1_DF_32:
319 len = sprintf(buf, "1120\n");
320 break;
321 case LIS3L02DQ_REG_CTRL_1_DF_8:
322 len = sprintf(buf, "4480\n");
323 break;
324 }
325 return len;
326}
327
328static ssize_t lis3l02dq_write_frequency(struct device *dev,
329 struct device_attribute *attr,
330 const char *buf,
331 size_t len)
332{
333 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
334 unsigned long val;
335 int ret;
336 u8 t;
337
338 ret = kstrtoul(buf, 10, &val);
339 if (ret)
340 return ret;
341
342 mutex_lock(&indio_dev->mlock);
343 ret = lis3l02dq_spi_read_reg_8(indio_dev,
344 LIS3L02DQ_REG_CTRL_1_ADDR,
345 &t);
346 if (ret)
347 goto error_ret_mutex;
348
349 t &= ~LIS3L02DQ_DEC_MASK;
350 switch (val) {
351 case 280:
352 t |= LIS3L02DQ_REG_CTRL_1_DF_128;
353 break;
354 case 560:
355 t |= LIS3L02DQ_REG_CTRL_1_DF_64;
356 break;
357 case 1120:
358 t |= LIS3L02DQ_REG_CTRL_1_DF_32;
359 break;
360 case 4480:
361 t |= LIS3L02DQ_REG_CTRL_1_DF_8;
362 break;
363 default:
364 ret = -EINVAL;
365 goto error_ret_mutex;
366 }
367
368 ret = lis3l02dq_spi_write_reg_8(indio_dev,
369 LIS3L02DQ_REG_CTRL_1_ADDR,
370 t);
371
372error_ret_mutex:
373 mutex_unlock(&indio_dev->mlock);
374
375 return ret ? ret : len;
376}
377
378static int lis3l02dq_initial_setup(struct iio_dev *indio_dev)
379{
380 struct lis3l02dq_state *st = iio_priv(indio_dev);
381 int ret;
382 u8 val, valtest;
383
384 st->us->mode = SPI_MODE_3;
385
386 spi_setup(st->us);
387
388 val = LIS3L02DQ_DEFAULT_CTRL1;
389
390 ret = lis3l02dq_spi_write_reg_8(indio_dev,
391 LIS3L02DQ_REG_CTRL_1_ADDR,
392 val);
393 if (ret) {
394 dev_err(&st->us->dev, "problem with setup control register 1");
395 goto err_ret;
396 }
397
398 ret = lis3l02dq_spi_write_reg_8(indio_dev,
399 LIS3L02DQ_REG_CTRL_1_ADDR,
400 val);
401 if (ret) {
402 dev_err(&st->us->dev, "problem with setup control register 1");
403 goto err_ret;
404 }
405
406
407
408 ret = lis3l02dq_spi_read_reg_8(indio_dev,
409 LIS3L02DQ_REG_CTRL_1_ADDR,
410 &valtest);
411 if (ret || (valtest != val)) {
412 dev_err(&indio_dev->dev,
413 "device not playing ball %d %d\n", valtest, val);
414 ret = -EINVAL;
415 goto err_ret;
416 }
417
418 val = LIS3L02DQ_DEFAULT_CTRL2;
419 ret = lis3l02dq_spi_write_reg_8(indio_dev,
420 LIS3L02DQ_REG_CTRL_2_ADDR,
421 val);
422 if (ret) {
423 dev_err(&st->us->dev, "problem with setup control register 2");
424 goto err_ret;
425 }
426
427 val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
428 ret = lis3l02dq_spi_write_reg_8(indio_dev,
429 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
430 val);
431 if (ret)
432 dev_err(&st->us->dev, "problem with interrupt cfg register");
433err_ret:
434
435 return ret;
436}
437
438static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
439 lis3l02dq_read_frequency,
440 lis3l02dq_write_frequency);
441
442static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("280 560 1120 4480");
443
444static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
445{
446 struct iio_dev *indio_dev = private;
447 u8 t;
448
449 s64 timestamp = iio_get_time_ns();
450
451 lis3l02dq_spi_read_reg_8(indio_dev,
452 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
453 &t);
454
455 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
456 iio_push_event(indio_dev,
457 IIO_MOD_EVENT_CODE(IIO_ACCEL,
458 0,
459 IIO_MOD_Z,
460 IIO_EV_TYPE_THRESH,
461 IIO_EV_DIR_RISING),
462 timestamp);
463
464 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
465 iio_push_event(indio_dev,
466 IIO_MOD_EVENT_CODE(IIO_ACCEL,
467 0,
468 IIO_MOD_Z,
469 IIO_EV_TYPE_THRESH,
470 IIO_EV_DIR_FALLING),
471 timestamp);
472
473 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
474 iio_push_event(indio_dev,
475 IIO_MOD_EVENT_CODE(IIO_ACCEL,
476 0,
477 IIO_MOD_Y,
478 IIO_EV_TYPE_THRESH,
479 IIO_EV_DIR_RISING),
480 timestamp);
481
482 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
483 iio_push_event(indio_dev,
484 IIO_MOD_EVENT_CODE(IIO_ACCEL,
485 0,
486 IIO_MOD_Y,
487 IIO_EV_TYPE_THRESH,
488 IIO_EV_DIR_FALLING),
489 timestamp);
490
491 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
492 iio_push_event(indio_dev,
493 IIO_MOD_EVENT_CODE(IIO_ACCEL,
494 0,
495 IIO_MOD_X,
496 IIO_EV_TYPE_THRESH,
497 IIO_EV_DIR_RISING),
498 timestamp);
499
500 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
501 iio_push_event(indio_dev,
502 IIO_MOD_EVENT_CODE(IIO_ACCEL,
503 0,
504 IIO_MOD_X,
505 IIO_EV_TYPE_THRESH,
506 IIO_EV_DIR_FALLING),
507 timestamp);
508
509
510 lis3l02dq_spi_read_reg_8(indio_dev,
511 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
512 &t);
513
514 return IRQ_HANDLED;
515}
516
517static const struct iio_event_spec lis3l02dq_event[] = {
518 {
519 .type = IIO_EV_TYPE_THRESH,
520 .dir = IIO_EV_DIR_RISING,
521 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
522 .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
523 }, {
524 .type = IIO_EV_TYPE_THRESH,
525 .dir = IIO_EV_DIR_FALLING,
526 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
527 .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
528 }
529};
530
531#define LIS3L02DQ_CHAN(index, mod) \
532 { \
533 .type = IIO_ACCEL, \
534 .modified = 1, \
535 .channel2 = mod, \
536 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
537 BIT(IIO_CHAN_INFO_CALIBSCALE) | \
538 BIT(IIO_CHAN_INFO_CALIBBIAS), \
539 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
540 .address = index, \
541 .scan_index = index, \
542 .scan_type = { \
543 .sign = 's', \
544 .realbits = 12, \
545 .storagebits = 16, \
546 }, \
547 .event_spec = lis3l02dq_event, \
548 .num_event_specs = ARRAY_SIZE(lis3l02dq_event), \
549 }
550
551static const struct iio_chan_spec lis3l02dq_channels[] = {
552 LIS3L02DQ_CHAN(0, IIO_MOD_X),
553 LIS3L02DQ_CHAN(1, IIO_MOD_Y),
554 LIS3L02DQ_CHAN(2, IIO_MOD_Z),
555 IIO_CHAN_SOFT_TIMESTAMP(3)
556};
557
558
559static int lis3l02dq_read_event_config(struct iio_dev *indio_dev,
560 const struct iio_chan_spec *chan,
561 enum iio_event_type type,
562 enum iio_event_direction dir)
563{
564
565 u8 val;
566 int ret;
567 u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
568 ret = lis3l02dq_spi_read_reg_8(indio_dev,
569 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
570 &val);
571 if (ret < 0)
572 return ret;
573
574 return !!(val & mask);
575}
576
577int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
578{
579 int ret;
580 u8 control, val;
581
582 ret = lis3l02dq_spi_read_reg_8(indio_dev,
583 LIS3L02DQ_REG_CTRL_2_ADDR,
584 &control);
585
586 control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT;
587 ret = lis3l02dq_spi_write_reg_8(indio_dev,
588 LIS3L02DQ_REG_CTRL_2_ADDR,
589 control);
590 if (ret)
591 goto error_ret;
592
593 ret = lis3l02dq_spi_read_reg_8(indio_dev,
594 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
595 &val);
596 if (ret)
597 goto error_ret;
598 val &= ~0x3f;
599
600 ret = lis3l02dq_spi_write_reg_8(indio_dev,
601 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
602 val);
603 if (ret)
604 goto error_ret;
605
606 ret = control;
607error_ret:
608 return ret;
609}
610
611static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
612 const struct iio_chan_spec *chan,
613 enum iio_event_type type,
614 enum iio_event_direction dir,
615 int state)
616{
617 int ret = 0;
618 u8 val, control;
619 u8 currentlyset;
620 bool changed = false;
621 u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
622
623 mutex_lock(&indio_dev->mlock);
624
625 ret = lis3l02dq_spi_read_reg_8(indio_dev,
626 LIS3L02DQ_REG_CTRL_2_ADDR,
627 &control);
628 if (ret)
629 goto error_ret;
630 ret = lis3l02dq_spi_read_reg_8(indio_dev,
631 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
632 &val);
633 if (ret < 0)
634 goto error_ret;
635 currentlyset = val & mask;
636
637 if (!currentlyset && state) {
638 changed = true;
639 val |= mask;
640 } else if (currentlyset && !state) {
641 changed = true;
642 val &= ~mask;
643 }
644
645 if (changed) {
646 ret = lis3l02dq_spi_write_reg_8(indio_dev,
647 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
648 val);
649 if (ret)
650 goto error_ret;
651 control = val & 0x3f ?
652 (control | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
653 (control & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
654 ret = lis3l02dq_spi_write_reg_8(indio_dev,
655 LIS3L02DQ_REG_CTRL_2_ADDR,
656 control);
657 if (ret)
658 goto error_ret;
659 }
660
661error_ret:
662 mutex_unlock(&indio_dev->mlock);
663 return ret;
664}
665
666static struct attribute *lis3l02dq_attributes[] = {
667 &iio_dev_attr_sampling_frequency.dev_attr.attr,
668 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
669 NULL
670};
671
672static const struct attribute_group lis3l02dq_attribute_group = {
673 .attrs = lis3l02dq_attributes,
674};
675
676static const struct iio_info lis3l02dq_info = {
677 .read_raw = &lis3l02dq_read_raw,
678 .write_raw = &lis3l02dq_write_raw,
679 .read_event_value = &lis3l02dq_read_thresh,
680 .write_event_value = &lis3l02dq_write_thresh,
681 .write_event_config = &lis3l02dq_write_event_config,
682 .read_event_config = &lis3l02dq_read_event_config,
683 .driver_module = THIS_MODULE,
684 .attrs = &lis3l02dq_attribute_group,
685};
686
687static int lis3l02dq_probe(struct spi_device *spi)
688{
689 int ret;
690 struct lis3l02dq_state *st;
691 struct iio_dev *indio_dev;
692
693 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
694 if (!indio_dev)
695 return -ENOMEM;
696 st = iio_priv(indio_dev);
697
698 spi_set_drvdata(spi, indio_dev);
699
700 st->us = spi;
701 st->gpio = of_get_gpio(spi->dev.of_node, 0);
702 mutex_init(&st->buf_lock);
703 indio_dev->name = spi->dev.driver->name;
704 indio_dev->dev.parent = &spi->dev;
705 indio_dev->info = &lis3l02dq_info;
706 indio_dev->channels = lis3l02dq_channels;
707 indio_dev->num_channels = ARRAY_SIZE(lis3l02dq_channels);
708
709 indio_dev->modes = INDIO_DIRECT_MODE;
710
711 ret = lis3l02dq_configure_buffer(indio_dev);
712 if (ret)
713 return ret;
714
715 ret = iio_buffer_register(indio_dev,
716 lis3l02dq_channels,
717 ARRAY_SIZE(lis3l02dq_channels));
718 if (ret) {
719 dev_err(&spi->dev, "failed to initialize the buffer\n");
720 goto error_unreg_buffer_funcs;
721 }
722
723 if (spi->irq) {
724 ret = request_threaded_irq(st->us->irq,
725 &lis3l02dq_th,
726 &lis3l02dq_event_handler,
727 IRQF_TRIGGER_RISING,
728 "lis3l02dq",
729 indio_dev);
730 if (ret)
731 goto error_uninitialize_buffer;
732
733 ret = lis3l02dq_probe_trigger(indio_dev);
734 if (ret)
735 goto error_free_interrupt;
736 }
737
738
739 ret = lis3l02dq_initial_setup(indio_dev);
740 if (ret)
741 goto error_remove_trigger;
742
743 ret = iio_device_register(indio_dev);
744 if (ret)
745 goto error_remove_trigger;
746
747 return 0;
748
749error_remove_trigger:
750 if (spi->irq)
751 lis3l02dq_remove_trigger(indio_dev);
752error_free_interrupt:
753 if (spi->irq)
754 free_irq(st->us->irq, indio_dev);
755error_uninitialize_buffer:
756 iio_buffer_unregister(indio_dev);
757error_unreg_buffer_funcs:
758 lis3l02dq_unconfigure_buffer(indio_dev);
759 return ret;
760}
761
762
763static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
764{
765 int ret;
766 struct lis3l02dq_state *st = iio_priv(indio_dev);
767 u8 val = 0;
768
769 mutex_lock(&indio_dev->mlock);
770 ret = lis3l02dq_spi_write_reg_8(indio_dev,
771 LIS3L02DQ_REG_CTRL_1_ADDR,
772 val);
773 if (ret) {
774 dev_err(&st->us->dev, "problem with turning device off: ctrl1");
775 goto err_ret;
776 }
777
778 ret = lis3l02dq_spi_write_reg_8(indio_dev,
779 LIS3L02DQ_REG_CTRL_2_ADDR,
780 val);
781 if (ret)
782 dev_err(&st->us->dev, "problem with turning device off: ctrl2");
783err_ret:
784 mutex_unlock(&indio_dev->mlock);
785 return ret;
786}
787
788
789static int lis3l02dq_remove(struct spi_device *spi)
790{
791 struct iio_dev *indio_dev = spi_get_drvdata(spi);
792 struct lis3l02dq_state *st = iio_priv(indio_dev);
793
794 iio_device_unregister(indio_dev);
795
796 lis3l02dq_disable_all_events(indio_dev);
797 lis3l02dq_stop_device(indio_dev);
798
799 if (spi->irq)
800 free_irq(st->us->irq, indio_dev);
801
802 lis3l02dq_remove_trigger(indio_dev);
803 iio_buffer_unregister(indio_dev);
804 lis3l02dq_unconfigure_buffer(indio_dev);
805
806 return 0;
807}
808
809static struct spi_driver lis3l02dq_driver = {
810 .driver = {
811 .name = "lis3l02dq",
812 .owner = THIS_MODULE,
813 },
814 .probe = lis3l02dq_probe,
815 .remove = lis3l02dq_remove,
816};
817module_spi_driver(lis3l02dq_driver);
818
819MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
820MODULE_DESCRIPTION("ST LIS3L02DQ Accelerometer SPI driver");
821MODULE_LICENSE("GPL v2");
822MODULE_ALIAS("spi:lis3l02dq");
823