staging:iio: Remove legacy event handling.
[deliverable/linux.git] / drivers / staging / iio / accel / lis3l02dq_core.c
CommitLineData
66533b48
JC
1/*
2 * lis3l02dq.c support STMicroelectronics LISD02DQ
3 * 3d 2g Linear Accelerometers via SPI
4 *
5 * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.uk>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Settings:
12 * 16 bit left justified mode used.
13 */
14
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/gpio.h>
18#include <linux/workqueue.h>
19#include <linux/mutex.h>
20#include <linux/device.h>
21#include <linux/kernel.h>
22#include <linux/spi/spi.h>
5a0e3ad6 23#include <linux/slab.h>
66533b48
JC
24
25#include <linux/sysfs.h>
26#include <linux/list.h>
27
28#include "../iio.h"
29#include "../sysfs.h"
2662051e 30#include "../ring_generic.h"
73bce12e
JC
31#include "../ring_sw.h"
32
66533b48
JC
33#include "accel.h"
34
35#include "lis3l02dq.h"
36
37/* At the moment the spi framework doesn't allow global setting of cs_change.
38 * It's in the likely to be added comment at the top of spi.h.
39 * This means that use cannot be made of spi_write etc.
40 */
41
1b076b52
JC
42/**
43 * lis3l02dq_spi_read_reg_8() - read single byte from a single register
44 * @indio_dev: iio_dev for this actual device
45 * @reg_address: the address of the register to be read
46 * @val: pass back the resulting value
47 **/
48int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
49 u8 reg_address, u8 *val)
66533b48 50{
1b076b52
JC
51 struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
52 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
66533b48 53 struct spi_message msg;
f3736416 54 int ret;
66533b48
JC
55 struct spi_transfer xfer = {
56 .tx_buf = st->tx,
57 .rx_buf = st->rx,
58 .bits_per_word = 8,
59 .len = 2,
66533b48
JC
60 };
61
62 mutex_lock(&st->buf_lock);
63 st->tx[0] = LIS3L02DQ_READ_REG(reg_address);
64 st->tx[1] = 0;
65
66 spi_message_init(&msg);
67 spi_message_add_tail(&xfer, &msg);
68 ret = spi_sync(st->us, &msg);
69 *val = st->rx[1];
70 mutex_unlock(&st->buf_lock);
71
72 return ret;
73}
74
75/**
76 * lis3l02dq_spi_write_reg_8() - write single byte to a register
1b076b52 77 * @indio_dev: iio_dev for this device
25985edc 78 * @reg_address: the address of the register to be written
66533b48
JC
79 * @val: the value to write
80 **/
1b076b52 81int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
66533b48
JC
82 u8 reg_address,
83 u8 *val)
84{
85 int ret;
73bce12e
JC
86 struct iio_sw_ring_helper_state *h
87 = iio_dev_get_devdata(indio_dev);
88 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
66533b48
JC
89
90 mutex_lock(&st->buf_lock);
91 st->tx[0] = LIS3L02DQ_WRITE_REG(reg_address);
92 st->tx[1] = *val;
1b076b52 93 ret = spi_write(st->us, st->tx, 2);
66533b48
JC
94 mutex_unlock(&st->buf_lock);
95
96 return ret;
97}
98
99/**
100 * lisl302dq_spi_write_reg_s16() - write 2 bytes to a pair of registers
1b076b52
JC
101 * @indio_dev: iio_dev for this device
102 * @lower_reg_address: the address of the lower of the two registers.
103 * Second register is assumed to have address one greater.
104 * @value: value to be written
66533b48 105 **/
1b076b52 106static int lis3l02dq_spi_write_reg_s16(struct iio_dev *indio_dev,
66533b48
JC
107 u8 lower_reg_address,
108 s16 value)
109{
110 int ret;
111 struct spi_message msg;
73bce12e
JC
112 struct iio_sw_ring_helper_state *h
113 = iio_dev_get_devdata(indio_dev);
114 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
66533b48
JC
115 struct spi_transfer xfers[] = { {
116 .tx_buf = st->tx,
117 .bits_per_word = 8,
118 .len = 2,
119 .cs_change = 1,
120 }, {
121 .tx_buf = st->tx + 2,
122 .bits_per_word = 8,
123 .len = 2,
66533b48
JC
124 },
125 };
126
127 mutex_lock(&st->buf_lock);
128 st->tx[0] = LIS3L02DQ_WRITE_REG(lower_reg_address);
129 st->tx[1] = value & 0xFF;
130 st->tx[2] = LIS3L02DQ_WRITE_REG(lower_reg_address + 1);
131 st->tx[3] = (value >> 8) & 0xFF;
132
133 spi_message_init(&msg);
134 spi_message_add_tail(&xfers[0], &msg);
135 spi_message_add_tail(&xfers[1], &msg);
136 ret = spi_sync(st->us, &msg);
137 mutex_unlock(&st->buf_lock);
138
139 return ret;
140}
141
1b076b52 142static int lis3l02dq_read_reg_s16(struct iio_dev *indio_dev,
f3736416
JC
143 u8 lower_reg_address,
144 int *val)
66533b48 145{
1b076b52
JC
146 struct iio_sw_ring_helper_state *h
147 = iio_dev_get_devdata(indio_dev);
148 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
149
66533b48 150 struct spi_message msg;
66533b48 151 int ret;
f3736416 152 s16 tempval;
66533b48
JC
153 struct spi_transfer xfers[] = { {
154 .tx_buf = st->tx,
155 .rx_buf = st->rx,
156 .bits_per_word = 8,
157 .len = 2,
158 .cs_change = 1,
159 }, {
160 .tx_buf = st->tx + 2,
161 .rx_buf = st->rx + 2,
162 .bits_per_word = 8,
163 .len = 2,
66533b48
JC
164 },
165 };
166
167 mutex_lock(&st->buf_lock);
168 st->tx[0] = LIS3L02DQ_READ_REG(lower_reg_address);
169 st->tx[1] = 0;
f3736416 170 st->tx[2] = LIS3L02DQ_READ_REG(lower_reg_address + 1);
66533b48
JC
171 st->tx[3] = 0;
172
173 spi_message_init(&msg);
174 spi_message_add_tail(&xfers[0], &msg);
175 spi_message_add_tail(&xfers[1], &msg);
176 ret = spi_sync(st->us, &msg);
177 if (ret) {
178 dev_err(&st->us->dev, "problem when reading 16 bit register");
179 goto error_ret;
180 }
f3736416 181 tempval = (s16)(st->rx[1]) | ((s16)(st->rx[3]) << 8);
66533b48 182
f3736416 183 *val = tempval;
66533b48
JC
184error_ret:
185 mutex_unlock(&st->buf_lock);
186 return ret;
187}
188
f3736416
JC
189enum lis3l02dq_rm_ind {
190 LIS3L02DQ_ACCEL,
191 LIS3L02DQ_GAIN,
192 LIS3L02DQ_BIAS,
193};
66533b48 194
f3736416
JC
195static u8 lis3l02dq_axis_map[3][3] = {
196 [LIS3L02DQ_ACCEL] = { LIS3L02DQ_REG_OUT_X_L_ADDR,
197 LIS3L02DQ_REG_OUT_Y_L_ADDR,
198 LIS3L02DQ_REG_OUT_Z_L_ADDR },
199 [LIS3L02DQ_GAIN] = { LIS3L02DQ_REG_GAIN_X_ADDR,
200 LIS3L02DQ_REG_GAIN_Y_ADDR,
201 LIS3L02DQ_REG_GAIN_Z_ADDR },
202 [LIS3L02DQ_BIAS] = { LIS3L02DQ_REG_OFFSET_X_ADDR,
203 LIS3L02DQ_REG_OFFSET_Y_ADDR,
204 LIS3L02DQ_REG_OFFSET_Z_ADDR }
205};
66533b48 206
f3736416
JC
207static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
208 int e,
209 int *val)
66533b48 210{
1b076b52 211 return lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
66533b48
JC
212}
213
f3736416
JC
214static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
215 int event_code,
216 int val)
66533b48 217{
f3736416 218 u16 value = val;
1b076b52 219 return lis3l02dq_spi_write_reg_s16(indio_dev,
f3736416
JC
220 LIS3L02DQ_REG_THS_L_ADDR,
221 value);
66533b48
JC
222}
223
f3736416
JC
224static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
225 struct iio_chan_spec const *chan,
226 int *val,
227 int *val2,
228 long mask)
66533b48 229{
f3736416
JC
230 u8 utemp;
231 s8 stemp;
232 ssize_t ret = 0;
f3736416 233 u8 reg;
1b076b52 234
f3736416
JC
235 switch (mask) {
236 case 0:
237 /* Take the iio_dev status lock */
238 mutex_lock(&indio_dev->mlock);
239 if (indio_dev->currentmode == INDIO_RING_TRIGGERED)
240 ret = lis3l02dq_read_accel_from_ring(indio_dev->ring,
241 chan->scan_index,
242 val);
243 else {
244 reg = lis3l02dq_axis_map
245 [LIS3L02DQ_ACCEL][chan->address];
1b076b52 246 ret = lis3l02dq_read_reg_s16(indio_dev, reg, val);
f3736416
JC
247 }
248 mutex_unlock(&indio_dev->mlock);
249 return IIO_VAL_INT;
250 case (1 << IIO_CHAN_INFO_SCALE_SHARED):
251 *val = 0;
252 *val2 = 9580;
253 return IIO_VAL_INT_PLUS_MICRO;
254 case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
255 reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
1b076b52 256 ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, &utemp);
f3736416
JC
257 if (ret)
258 goto error_ret;
259 /* to match with what previous code does */
260 *val = utemp;
261 return IIO_VAL_INT;
262
263 case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
264 reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
1b076b52 265 ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, (u8 *)&stemp);
f3736416
JC
266 /* to match with what previous code does */
267 *val = stemp;
268 return IIO_VAL_INT;
269 }
66533b48 270error_ret:
f3736416 271 return ret;
66533b48
JC
272}
273
274static ssize_t lis3l02dq_read_frequency(struct device *dev,
275 struct device_attribute *attr,
276 char *buf)
277{
1b076b52 278 struct iio_dev *indio_dev = dev_get_drvdata(dev);
66533b48
JC
279 int ret, len = 0;
280 s8 t;
1b076b52 281 ret = lis3l02dq_spi_read_reg_8(indio_dev,
66533b48
JC
282 LIS3L02DQ_REG_CTRL_1_ADDR,
283 (u8 *)&t);
284 if (ret)
285 return ret;
286 t &= LIS3L02DQ_DEC_MASK;
287 switch (t) {
288 case LIS3L02DQ_REG_CTRL_1_DF_128:
289 len = sprintf(buf, "280\n");
290 break;
291 case LIS3L02DQ_REG_CTRL_1_DF_64:
292 len = sprintf(buf, "560\n");
293 break;
294 case LIS3L02DQ_REG_CTRL_1_DF_32:
295 len = sprintf(buf, "1120\n");
296 break;
297 case LIS3L02DQ_REG_CTRL_1_DF_8:
298 len = sprintf(buf, "4480\n");
299 break;
300 }
301 return len;
302}
303
304static ssize_t lis3l02dq_write_frequency(struct device *dev,
305 struct device_attribute *attr,
306 const char *buf,
307 size_t len)
308{
309 struct iio_dev *indio_dev = dev_get_drvdata(dev);
310 long val;
311 int ret;
312 u8 t;
313
314 ret = strict_strtol(buf, 10, &val);
315 if (ret)
316 return ret;
317
318 mutex_lock(&indio_dev->mlock);
1b076b52 319 ret = lis3l02dq_spi_read_reg_8(indio_dev,
66533b48
JC
320 LIS3L02DQ_REG_CTRL_1_ADDR,
321 &t);
322 if (ret)
323 goto error_ret_mutex;
324 /* Wipe the bits clean */
325 t &= ~LIS3L02DQ_DEC_MASK;
326 switch (val) {
327 case 280:
328 t |= LIS3L02DQ_REG_CTRL_1_DF_128;
329 break;
330 case 560:
331 t |= LIS3L02DQ_REG_CTRL_1_DF_64;
332 break;
333 case 1120:
334 t |= LIS3L02DQ_REG_CTRL_1_DF_32;
335 break;
336 case 4480:
337 t |= LIS3L02DQ_REG_CTRL_1_DF_8;
338 break;
339 default:
340 ret = -EINVAL;
341 goto error_ret_mutex;
95cd17c9 342 }
66533b48 343
1b076b52 344 ret = lis3l02dq_spi_write_reg_8(indio_dev,
66533b48
JC
345 LIS3L02DQ_REG_CTRL_1_ADDR,
346 &t);
347
348error_ret_mutex:
349 mutex_unlock(&indio_dev->mlock);
350
351 return ret ? ret : len;
352}
353
354static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
355{
356 int ret;
357 u8 val, valtest;
358
359 st->us->mode = SPI_MODE_3;
360
361 spi_setup(st->us);
362
363 val = LIS3L02DQ_DEFAULT_CTRL1;
364 /* Write suitable defaults to ctrl1 */
1b076b52 365 ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
66533b48
JC
366 LIS3L02DQ_REG_CTRL_1_ADDR,
367 &val);
368 if (ret) {
369 dev_err(&st->us->dev, "problem with setup control register 1");
370 goto err_ret;
371 }
372 /* Repeat as sometimes doesn't work first time?*/
1b076b52 373 ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
66533b48
JC
374 LIS3L02DQ_REG_CTRL_1_ADDR,
375 &val);
376 if (ret) {
377 dev_err(&st->us->dev, "problem with setup control register 1");
378 goto err_ret;
379 }
380
381 /* Read back to check this has worked acts as loose test of correct
382 * chip */
1b076b52 383 ret = lis3l02dq_spi_read_reg_8(st->help.indio_dev,
66533b48
JC
384 LIS3L02DQ_REG_CTRL_1_ADDR,
385 &valtest);
386 if (ret || (valtest != val)) {
1b076b52
JC
387 dev_err(&st->help.indio_dev->dev,
388 "device not playing ball %d %d\n", valtest, val);
66533b48
JC
389 ret = -EINVAL;
390 goto err_ret;
391 }
392
393 val = LIS3L02DQ_DEFAULT_CTRL2;
1b076b52 394 ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
66533b48
JC
395 LIS3L02DQ_REG_CTRL_2_ADDR,
396 &val);
397 if (ret) {
398 dev_err(&st->us->dev, "problem with setup control register 2");
399 goto err_ret;
400 }
401
402 val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
1b076b52 403 ret = lis3l02dq_spi_write_reg_8(st->help.indio_dev,
66533b48
JC
404 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
405 &val);
406 if (ret)
407 dev_err(&st->us->dev, "problem with interrupt cfg register");
408err_ret:
409
410 return ret;
411}
412
66533b48
JC
413static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
414 lis3l02dq_read_frequency,
415 lis3l02dq_write_frequency);
416
f3fb0011 417static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("280 560 1120 4480");
66533b48 418
aaf370db 419static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
66533b48 420{
aaf370db 421 struct iio_dev *indio_dev = private;
f3736416
JC
422 struct iio_sw_ring_helper_state *h
423 = iio_dev_get_devdata(indio_dev);
424 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
66533b48 425
1e3345bc
JC
426 disable_irq_nosync(irq);
427 st->thresh_timestamp = iio_get_time_ns();
f3736416 428 schedule_work(&st->work_thresh);
66533b48 429
1e3345bc 430 return IRQ_HANDLED;
66533b48
JC
431}
432
f3736416
JC
433#define LIS3L02DQ_INFO_MASK \
434 ((1 << IIO_CHAN_INFO_SCALE_SHARED) | \
435 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) | \
436 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE))
437
438#define LIS3L02DQ_EVENT_MASK \
439 (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
440 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
441
442static struct iio_chan_spec lis3l02dq_channels[] = {
443 IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, LIS3L02DQ_INFO_MASK,
aaf370db 444 0, 0, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK),
f3736416 445 IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, LIS3L02DQ_INFO_MASK,
aaf370db 446 1, 1, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK),
f3736416 447 IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, LIS3L02DQ_INFO_MASK,
aaf370db 448 2, 2, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK),
f3736416
JC
449 IIO_CHAN_SOFT_TIMESTAMP(3)
450};
451
452
453static ssize_t lis3l02dq_read_event_config(struct iio_dev *indio_dev,
454 int event_code)
455{
456
457 u8 val;
458 int ret;
459 u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
460 (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
461 IIO_EV_DIR_RISING)));
1b076b52 462 ret = lis3l02dq_spi_read_reg_8(indio_dev,
66533b48 463 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
f3736416
JC
464 &val);
465 if (ret < 0)
466 return ret;
467
468 return !!(val & mask);
469}
66533b48 470
1e3345bc
JC
471int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
472{
473 struct iio_sw_ring_helper_state *h
474 = iio_dev_get_devdata(indio_dev);
475 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
476 int ret;
477 u8 control, val;
478 bool irqtofree;
479
480 ret = lis3l02dq_spi_read_reg_8(indio_dev,
481 LIS3L02DQ_REG_CTRL_2_ADDR,
482 &control);
483
484 irqtofree = !!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
485
486 control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT;
487 ret = lis3l02dq_spi_write_reg_8(indio_dev,
488 LIS3L02DQ_REG_CTRL_2_ADDR,
489 &control);
490 if (ret)
491 goto error_ret;
492 /* Also for consistency clear the mask */
493 ret = lis3l02dq_spi_read_reg_8(indio_dev,
494 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
495 &val);
496 if (ret)
497 goto error_ret;
498 val &= ~0x3f;
499
500 ret = lis3l02dq_spi_write_reg_8(indio_dev,
501 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
502 &val);
503 if (ret)
504 goto error_ret;
505
506 if (irqtofree)
aaf370db 507 free_irq(st->us->irq, indio_dev);
1e3345bc
JC
508
509 ret = control;
510error_ret:
511 return ret;
512}
513
f3736416
JC
514static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
515 int event_code,
f3736416
JC
516 int state)
517{
1e3345bc
JC
518 struct iio_sw_ring_helper_state *h
519 = iio_dev_get_devdata(indio_dev);
520 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
f3736416
JC
521 int ret = 0;
522 u8 val, control;
523 u8 currentlyset;
524 bool changed = false;
525 u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
526 (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
527 IIO_EV_DIR_RISING)));
528
529 mutex_lock(&indio_dev->mlock);
66533b48 530 /* read current control */
1b076b52 531 ret = lis3l02dq_spi_read_reg_8(indio_dev,
66533b48 532 LIS3L02DQ_REG_CTRL_2_ADDR,
f3736416 533 &control);
66533b48 534 if (ret)
f3736416 535 goto error_ret;
1b076b52 536 ret = lis3l02dq_spi_read_reg_8(indio_dev,
f3736416
JC
537 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
538 &val);
539 if (ret < 0)
540 goto error_ret;
541 currentlyset = val & mask;
542
543 if (!currentlyset && state) {
544 changed = true;
545 val |= mask;
f3736416
JC
546 } else if (currentlyset && !state) {
547 changed = true;
548 val &= ~mask;
66533b48 549 }
1e3345bc 550
66533b48 551 if (changed) {
1e3345bc
JC
552 if (!(control & LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT)) {
553 ret = request_irq(st->us->irq,
554 &lis3l02dq_event_handler,
555 IRQF_TRIGGER_RISING,
556 "lis3l02dq_event",
aaf370db 557 indio_dev);
1e3345bc
JC
558 if (ret)
559 goto error_ret;
560 }
561
1b076b52 562 ret = lis3l02dq_spi_write_reg_8(indio_dev,
66533b48 563 LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
f3736416 564 &val);
66533b48 565 if (ret)
f3736416 566 goto error_ret;
1e3345bc 567 control = val & 0x3f ?
f3736416
JC
568 (control | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
569 (control & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
1b076b52 570 ret = lis3l02dq_spi_write_reg_8(indio_dev,
f3736416
JC
571 LIS3L02DQ_REG_CTRL_2_ADDR,
572 &control);
1e3345bc
JC
573 if (ret)
574 goto error_ret;
575
576 /* remove interrupt handler if nothing is still on */
577 if (!(val & 0x3f))
aaf370db 578 free_irq(st->us->irq, indio_dev);
66533b48 579 }
66533b48 580
f3736416
JC
581error_ret:
582 mutex_unlock(&indio_dev->mlock);
583 return ret;
66533b48
JC
584}
585
66533b48
JC
586/* Unforunately it appears the interrupt won't clear unless you read from the
587 * src register.
588 */
589static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
590{
f3736416
JC
591 struct lis3l02dq_state *st
592 = container_of(work_s,
593 struct lis3l02dq_state, work_thresh);
66533b48
JC
594 u8 t;
595
1b076b52 596 lis3l02dq_spi_read_reg_8(st->help.indio_dev,
66533b48
JC
597 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
598 &t);
599
600 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
73bce12e 601 iio_push_event(st->help.indio_dev, 0,
18e69a99
JC
602 IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
603 0,
604 IIO_EV_MOD_Z,
605 IIO_EV_TYPE_THRESH,
606 IIO_EV_DIR_RISING),
b98c9e60 607 st->thresh_timestamp);
66533b48
JC
608
609 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
73bce12e 610 iio_push_event(st->help.indio_dev, 0,
18e69a99
JC
611 IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
612 0,
613 IIO_EV_MOD_Z,
614 IIO_EV_TYPE_THRESH,
615 IIO_EV_DIR_FALLING),
b98c9e60 616 st->thresh_timestamp);
66533b48
JC
617
618 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
73bce12e 619 iio_push_event(st->help.indio_dev, 0,
18e69a99
JC
620 IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
621 0,
622 IIO_EV_MOD_Y,
623 IIO_EV_TYPE_THRESH,
624 IIO_EV_DIR_RISING),
b98c9e60 625 st->thresh_timestamp);
66533b48
JC
626
627 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
73bce12e 628 iio_push_event(st->help.indio_dev, 0,
18e69a99
JC
629 IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
630 0,
631 IIO_EV_MOD_Y,
632 IIO_EV_TYPE_THRESH,
633 IIO_EV_DIR_FALLING),
b98c9e60 634 st->thresh_timestamp);
66533b48
JC
635
636 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
73bce12e 637 iio_push_event(st->help.indio_dev, 0,
18e69a99
JC
638 IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
639 0,
640 IIO_EV_MOD_X,
641 IIO_EV_TYPE_THRESH,
642 IIO_EV_DIR_RISING),
b98c9e60 643 st->thresh_timestamp);
66533b48
JC
644
645 if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
73bce12e 646 iio_push_event(st->help.indio_dev, 0,
18e69a99
JC
647 IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
648 0,
649 IIO_EV_MOD_X,
650 IIO_EV_TYPE_THRESH,
651 IIO_EV_DIR_FALLING),
b98c9e60 652 st->thresh_timestamp);
66533b48
JC
653 /* reenable the irq */
654 enable_irq(st->us->irq);
655 /* Ack and allow for new interrupts */
1b076b52 656 lis3l02dq_spi_read_reg_8(st->help.indio_dev,
66533b48
JC
657 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
658 &t);
659
660 return;
661}
662
51a0a5b0 663static IIO_CONST_ATTR_NAME("lis3l02dq");
66533b48
JC
664
665static struct attribute *lis3l02dq_attributes[] = {
66533b48 666 &iio_dev_attr_sampling_frequency.dev_attr.attr,
f3fb0011 667 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
66533b48
JC
668 &iio_const_attr_name.dev_attr.attr,
669 NULL
670};
671
672static const struct attribute_group lis3l02dq_attribute_group = {
673 .attrs = lis3l02dq_attributes,
674};
675
676static int __devinit lis3l02dq_probe(struct spi_device *spi)
677{
678 int ret, regdone = 0;
679 struct lis3l02dq_state *st = kzalloc(sizeof *st, GFP_KERNEL);
680 if (!st) {
681 ret = -ENOMEM;
682 goto error_ret;
683 }
d0348e50 684 INIT_WORK(&st->work_thresh, lis3l02dq_thresh_handler_bh_no_check);
66533b48
JC
685 /* this is only used tor removal purposes */
686 spi_set_drvdata(spi, st);
687
688 /* Allocate the comms buffers */
689 st->rx = kzalloc(sizeof(*st->rx)*LIS3L02DQ_MAX_RX, GFP_KERNEL);
690 if (st->rx == NULL) {
691 ret = -ENOMEM;
692 goto error_free_st;
693 }
694 st->tx = kzalloc(sizeof(*st->tx)*LIS3L02DQ_MAX_TX, GFP_KERNEL);
695 if (st->tx == NULL) {
696 ret = -ENOMEM;
697 goto error_free_rx;
698 }
699 st->us = spi;
700 mutex_init(&st->buf_lock);
701 /* setup the industrialio driver allocated elements */
6f7c8ee5 702 st->help.indio_dev = iio_allocate_device(0);
73bce12e 703 if (st->help.indio_dev == NULL) {
66533b48
JC
704 ret = -ENOMEM;
705 goto error_free_tx;
706 }
707
73bce12e
JC
708 st->help.indio_dev->dev.parent = &spi->dev;
709 st->help.indio_dev->num_interrupt_lines = 1;
f3736416
JC
710 st->help.indio_dev->channels = lis3l02dq_channels;
711 st->help.indio_dev->num_channels = ARRAY_SIZE(lis3l02dq_channels);
712 st->help.indio_dev->read_raw = &lis3l02dq_read_raw;
713 st->help.indio_dev->read_event_value = &lis3l02dq_read_thresh;
714 st->help.indio_dev->write_event_value = &lis3l02dq_write_thresh;
715 st->help.indio_dev->write_event_config = &lis3l02dq_write_event_config;
716 st->help.indio_dev->read_event_config = &lis3l02dq_read_event_config;
73bce12e
JC
717 st->help.indio_dev->attrs = &lis3l02dq_attribute_group;
718 st->help.indio_dev->dev_data = (void *)(&st->help);
719 st->help.indio_dev->driver_module = THIS_MODULE;
720 st->help.indio_dev->modes = INDIO_DIRECT_MODE;
66533b48 721
73bce12e 722 ret = lis3l02dq_configure_ring(st->help.indio_dev);
66533b48
JC
723 if (ret)
724 goto error_free_dev;
725
73bce12e 726 ret = iio_device_register(st->help.indio_dev);
66533b48
JC
727 if (ret)
728 goto error_unreg_ring_funcs;
729 regdone = 1;
730
f3736416
JC
731 ret = iio_ring_buffer_register_ex(st->help.indio_dev->ring, 0,
732 lis3l02dq_channels,
733 ARRAY_SIZE(lis3l02dq_channels));
66533b48
JC
734 if (ret) {
735 printk(KERN_ERR "failed to initialize the ring\n");
736 goto error_unreg_ring_funcs;
737 }
738
739 if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
66533b48 740 st->inter = 0;
73bce12e 741 ret = lis3l02dq_probe_trigger(st->help.indio_dev);
66533b48 742 if (ret)
aaf370db 743 goto error_uninitialize_ring;
66533b48
JC
744 }
745
746 /* Get the device into a sane initial state */
747 ret = lis3l02dq_initial_setup(st);
748 if (ret)
749 goto error_remove_trigger;
750 return 0;
751
752error_remove_trigger:
73bce12e
JC
753 if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
754 lis3l02dq_remove_trigger(st->help.indio_dev);
66533b48 755error_uninitialize_ring:
73bce12e 756 iio_ring_buffer_unregister(st->help.indio_dev->ring);
66533b48 757error_unreg_ring_funcs:
73bce12e 758 lis3l02dq_unconfigure_ring(st->help.indio_dev);
66533b48
JC
759error_free_dev:
760 if (regdone)
73bce12e 761 iio_device_unregister(st->help.indio_dev);
66533b48 762 else
73bce12e 763 iio_free_device(st->help.indio_dev);
66533b48
JC
764error_free_tx:
765 kfree(st->tx);
766error_free_rx:
767 kfree(st->rx);
768error_free_st:
769 kfree(st);
770error_ret:
771 return ret;
772}
773
774/* Power down the device */
775static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
776{
777 int ret;
73bce12e
JC
778 struct iio_sw_ring_helper_state *h
779 = iio_dev_get_devdata(indio_dev);
780 struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
66533b48
JC
781 u8 val = 0;
782
783 mutex_lock(&indio_dev->mlock);
1b076b52 784 ret = lis3l02dq_spi_write_reg_8(indio_dev,
66533b48
JC
785 LIS3L02DQ_REG_CTRL_1_ADDR,
786 &val);
787 if (ret) {
788 dev_err(&st->us->dev, "problem with turning device off: ctrl1");
789 goto err_ret;
790 }
791
1b076b52 792 ret = lis3l02dq_spi_write_reg_8(indio_dev,
66533b48
JC
793 LIS3L02DQ_REG_CTRL_2_ADDR,
794 &val);
795 if (ret)
796 dev_err(&st->us->dev, "problem with turning device off: ctrl2");
797err_ret:
798 mutex_unlock(&indio_dev->mlock);
799 return ret;
800}
801
802/* fixme, confirm ordering in this function */
803static int lis3l02dq_remove(struct spi_device *spi)
804{
805 int ret;
806 struct lis3l02dq_state *st = spi_get_drvdata(spi);
73bce12e 807 struct iio_dev *indio_dev = st->help.indio_dev;
1e3345bc
JC
808 ret = lis3l02dq_disable_all_events(indio_dev);
809 if (ret)
810 goto err_ret;
66533b48
JC
811
812 ret = lis3l02dq_stop_device(indio_dev);
813 if (ret)
814 goto err_ret;
815
816 flush_scheduled_work();
817
818 lis3l02dq_remove_trigger(indio_dev);
2662051e 819 iio_ring_buffer_unregister(indio_dev->ring);
66533b48
JC
820 lis3l02dq_unconfigure_ring(indio_dev);
821 iio_device_unregister(indio_dev);
822 kfree(st->tx);
823 kfree(st->rx);
824 kfree(st);
825
826 return 0;
827
828err_ret:
829 return ret;
830}
831
832static struct spi_driver lis3l02dq_driver = {
833 .driver = {
834 .name = "lis3l02dq",
835 .owner = THIS_MODULE,
836 },
837 .probe = lis3l02dq_probe,
838 .remove = __devexit_p(lis3l02dq_remove),
839};
840
841static __init int lis3l02dq_init(void)
842{
843 return spi_register_driver(&lis3l02dq_driver);
844}
845module_init(lis3l02dq_init);
846
847static __exit void lis3l02dq_exit(void)
848{
849 spi_unregister_driver(&lis3l02dq_driver);
850}
851module_exit(lis3l02dq_exit);
852
853MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
854MODULE_DESCRIPTION("ST LIS3L02DQ Accelerometer SPI driver");
855MODULE_LICENSE("GPL v2");
This page took 0.227828 seconds and 5 git commands to generate.