]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/iio/accel/adis16209_core.c
Staging: iio: adis16209/220/240/350: tuning spi delay to make hardware more stable
[net-next-2.6.git] / drivers / staging / iio / accel / adis16209_core.c
CommitLineData
671ece14
BS
1/*
2 * ADIS16209 Programmable Digital Vibration Sensor driver
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/irq.h>
11#include <linux/gpio.h>
12#include <linux/delay.h>
13#include <linux/mutex.h>
14#include <linux/device.h>
15#include <linux/kernel.h>
16#include <linux/spi/spi.h>
1cb6c1f5 17#include <linux/slab.h>
671ece14
BS
18#include <linux/sysfs.h>
19#include <linux/list.h>
20
21#include "../iio.h"
22#include "../sysfs.h"
23#include "accel.h"
24#include "inclinometer.h"
25#include "../gyro/gyro.h"
26#include "../adc/adc.h"
27
28#include "adis16209.h"
29
30#define DRIVER_NAME "adis16209"
31
32static int adis16209_check_status(struct device *dev);
33
34/**
35 * adis16209_spi_write_reg_8() - write single byte to a register
36 * @dev: device associated with child of actual device (iio_dev or iio_trig)
37 * @reg_address: the address of the register to be written
38 * @val: the value to write
39 **/
40static int adis16209_spi_write_reg_8(struct device *dev,
41 u8 reg_address,
42 u8 val)
43{
44 int ret;
45 struct iio_dev *indio_dev = dev_get_drvdata(dev);
46 struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
47
48 mutex_lock(&st->buf_lock);
49 st->tx[0] = ADIS16209_WRITE_REG(reg_address);
50 st->tx[1] = val;
51
52 ret = spi_write(st->us, st->tx, 2);
53 mutex_unlock(&st->buf_lock);
54
55 return ret;
56}
57
58/**
59 * adis16209_spi_write_reg_16() - write 2 bytes to a pair of registers
60 * @dev: device associated with child of actual device (iio_dev or iio_trig)
61 * @reg_address: the address of the lower of the two registers. Second register
62 * is assumed to have address one greater.
63 * @val: value to be written
64 **/
65static int adis16209_spi_write_reg_16(struct device *dev,
66 u8 lower_reg_address,
67 u16 value)
68{
69 int ret;
70 struct spi_message msg;
71 struct iio_dev *indio_dev = dev_get_drvdata(dev);
72 struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
73 struct spi_transfer xfers[] = {
74 {
75 .tx_buf = st->tx,
76 .bits_per_word = 8,
77 .len = 2,
78 .cs_change = 1,
00ae7946 79 .delay_usecs = 30,
671ece14
BS
80 }, {
81 .tx_buf = st->tx + 2,
82 .bits_per_word = 8,
83 .len = 2,
84 .cs_change = 1,
00ae7946 85 .delay_usecs = 30,
671ece14
BS
86 },
87 };
88
89 mutex_lock(&st->buf_lock);
90 st->tx[0] = ADIS16209_WRITE_REG(lower_reg_address);
91 st->tx[1] = value & 0xFF;
92 st->tx[2] = ADIS16209_WRITE_REG(lower_reg_address + 1);
93 st->tx[3] = (value >> 8) & 0xFF;
94
95 spi_message_init(&msg);
96 spi_message_add_tail(&xfers[0], &msg);
97 spi_message_add_tail(&xfers[1], &msg);
98 ret = spi_sync(st->us, &msg);
99 mutex_unlock(&st->buf_lock);
100
101 return ret;
102}
103
104/**
105 * adis16209_spi_read_reg_16() - read 2 bytes from a 16-bit register
106 * @dev: device associated with child of actual device (iio_dev or iio_trig)
107 * @reg_address: the address of the lower of the two registers. Second register
108 * is assumed to have address one greater.
109 * @val: somewhere to pass back the value read
110 **/
111static int adis16209_spi_read_reg_16(struct device *dev,
112 u8 lower_reg_address,
113 u16 *val)
114{
115 struct spi_message msg;
116 struct iio_dev *indio_dev = dev_get_drvdata(dev);
117 struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
118 int ret;
119 struct spi_transfer xfers[] = {
120 {
121 .tx_buf = st->tx,
122 .bits_per_word = 8,
123 .len = 2,
124 .cs_change = 1,
00ae7946 125 .delay_usecs = 30,
671ece14
BS
126 }, {
127 .rx_buf = st->rx,
128 .bits_per_word = 8,
129 .len = 2,
130 .cs_change = 1,
00ae7946 131 .delay_usecs = 30,
671ece14
BS
132 },
133 };
134
135 mutex_lock(&st->buf_lock);
136 st->tx[0] = ADIS16209_READ_REG(lower_reg_address);
137 st->tx[1] = 0;
138
139 spi_message_init(&msg);
140 spi_message_add_tail(&xfers[0], &msg);
141 spi_message_add_tail(&xfers[1], &msg);
142 ret = spi_sync(st->us, &msg);
143 if (ret) {
144 dev_err(&st->us->dev,
145 "problem when reading 16 bit register 0x%02X",
146 lower_reg_address);
147 goto error_ret;
148 }
149 *val = (st->rx[0] << 8) | st->rx[1];
150
151error_ret:
152 mutex_unlock(&st->buf_lock);
153 return ret;
154}
155
156static ssize_t adis16209_read_12bit_unsigned(struct device *dev,
157 struct device_attribute *attr,
158 char *buf)
159{
160 int ret;
161 u16 val = 0;
162 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
163
164 ret = adis16209_spi_read_reg_16(dev, this_attr->address, &val);
165 if (ret)
166 return ret;
167
168 if (val & ADIS16209_ERROR_ACTIVE)
169 adis16209_check_status(dev);
170
171 return sprintf(buf, "%u\n", val & 0x0FFF);
172}
173
174static ssize_t adis16209_read_14bit_unsigned(struct device *dev,
175 struct device_attribute *attr,
176 char *buf)
177{
178 int ret;
179 u16 val = 0;
180 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
181
182 ret = adis16209_spi_read_reg_16(dev, this_attr->address, &val);
183 if (ret)
184 return ret;
185
186 if (val & ADIS16209_ERROR_ACTIVE)
187 adis16209_check_status(dev);
188
189 return sprintf(buf, "%u\n", val & 0x3FFF);
190}
191
192static ssize_t adis16209_read_temp(struct device *dev,
193 struct device_attribute *attr,
194 char *buf)
195{
196 struct iio_dev *indio_dev = dev_get_drvdata(dev);
197 ssize_t ret;
198 u16 val;
199
200 /* Take the iio_dev status lock */
201 mutex_lock(&indio_dev->mlock);
202
203 ret = adis16209_spi_read_reg_16(dev, ADIS16209_TEMP_OUT, (u16 *)&val);
204 if (ret)
205 goto error_ret;
206
207 if (val & ADIS16209_ERROR_ACTIVE)
208 adis16209_check_status(dev);
209
210 val &= 0xFFF;
211 ret = sprintf(buf, "%d\n", val);
212
213error_ret:
214 mutex_unlock(&indio_dev->mlock);
215 return ret;
216}
217
218static ssize_t adis16209_read_14bit_signed(struct device *dev,
219 struct device_attribute *attr,
220 char *buf)
221{
222 struct iio_dev *indio_dev = dev_get_drvdata(dev);
223 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
224 s16 val = 0;
225 ssize_t ret;
226
227 mutex_lock(&indio_dev->mlock);
228
229 ret = adis16209_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
230 if (!ret) {
231 if (val & ADIS16209_ERROR_ACTIVE)
232 adis16209_check_status(dev);
233
234 val = ((s16)(val << 2) >> 2);
235 ret = sprintf(buf, "%d\n", val);
236 }
237
238 mutex_unlock(&indio_dev->mlock);
239
240 return ret;
241}
242
243static ssize_t adis16209_write_16bit(struct device *dev,
244 struct device_attribute *attr,
245 const char *buf,
246 size_t len)
247{
248 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
249 int ret;
250 long val;
251
252 ret = strict_strtol(buf, 10, &val);
253 if (ret)
254 goto error_ret;
255 ret = adis16209_spi_write_reg_16(dev, this_attr->address, val);
256
257error_ret:
258 return ret ? ret : len;
259}
260
261static int adis16209_reset(struct device *dev)
262{
263 int ret;
264 ret = adis16209_spi_write_reg_8(dev,
265 ADIS16209_GLOB_CMD,
266 ADIS16209_GLOB_CMD_SW_RESET);
267 if (ret)
268 dev_err(dev, "problem resetting device");
269
270 return ret;
271}
272
273static ssize_t adis16209_write_reset(struct device *dev,
274 struct device_attribute *attr,
275 const char *buf, size_t len)
276{
277 if (len < 1)
278 return -EINVAL;
279 switch (buf[0]) {
280 case '1':
281 case 'y':
282 case 'Y':
283 return adis16209_reset(dev);
284 }
285 return -EINVAL;
286}
287
288int adis16209_set_irq(struct device *dev, bool enable)
289{
290 int ret = 0;
291 u16 msc;
292
293 ret = adis16209_spi_read_reg_16(dev, ADIS16209_MSC_CTRL, &msc);
294 if (ret)
295 goto error_ret;
296
297 msc |= ADIS16209_MSC_CTRL_ACTIVE_HIGH;
298 msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_DIO2;
299 if (enable)
300 msc |= ADIS16209_MSC_CTRL_DATA_RDY_EN;
301 else
302 msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_EN;
303
304 ret = adis16209_spi_write_reg_16(dev, ADIS16209_MSC_CTRL, msc);
305
306error_ret:
307 return ret;
308}
309
310static int adis16209_check_status(struct device *dev)
311{
312 u16 status;
313 int ret;
314
315 ret = adis16209_spi_read_reg_16(dev, ADIS16209_DIAG_STAT, &status);
316 if (ret < 0) {
317 dev_err(dev, "Reading status failed\n");
318 goto error_ret;
319 }
320 ret = status & 0x1F;
321
322 if (status & ADIS16209_DIAG_STAT_SELFTEST_FAIL)
323 dev_err(dev, "Self test failure\n");
324 if (status & ADIS16209_DIAG_STAT_SPI_FAIL)
325 dev_err(dev, "SPI failure\n");
326 if (status & ADIS16209_DIAG_STAT_FLASH_UPT)
327 dev_err(dev, "Flash update failed\n");
328 if (status & ADIS16209_DIAG_STAT_POWER_HIGH)
329 dev_err(dev, "Power supply above 3.625V\n");
330 if (status & ADIS16209_DIAG_STAT_POWER_LOW)
331 dev_err(dev, "Power supply below 3.15V\n");
332
333error_ret:
334 return ret;
335}
336
337static int adis16209_self_test(struct device *dev)
338{
339 int ret;
340 ret = adis16209_spi_write_reg_16(dev,
341 ADIS16209_MSC_CTRL,
342 ADIS16209_MSC_CTRL_SELF_TEST_EN);
343 if (ret) {
344 dev_err(dev, "problem starting self test");
345 goto err_ret;
346 }
347
348 adis16209_check_status(dev);
349
350err_ret:
351 return ret;
352}
353
354static int adis16209_initial_setup(struct adis16209_state *st)
355{
356 int ret;
357 struct device *dev = &st->indio_dev->dev;
358
359 /* Disable IRQ */
360 ret = adis16209_set_irq(dev, false);
361 if (ret) {
362 dev_err(dev, "disable irq failed");
363 goto err_ret;
364 }
365
366 /* Do self test */
367 ret = adis16209_self_test(dev);
368 if (ret) {
369 dev_err(dev, "self test failure");
370 goto err_ret;
371 }
372
373 /* Read status register to check the result */
374 ret = adis16209_check_status(dev);
375 if (ret) {
376 adis16209_reset(dev);
377 dev_err(dev, "device not playing ball -> reset");
378 msleep(ADIS16209_STARTUP_DELAY);
379 ret = adis16209_check_status(dev);
380 if (ret) {
381 dev_err(dev, "giving up");
382 goto err_ret;
383 }
384 }
385
386 printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
387 st->us->chip_select, st->us->irq);
388
389err_ret:
390 return ret;
391}
392
393static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16209_read_14bit_unsigned,
394 ADIS16209_SUPPLY_OUT);
395static IIO_CONST_ATTR(in_supply_scale, "0.30518");
396static IIO_DEV_ATTR_IN_RAW(0, adis16209_read_12bit_unsigned,
397 ADIS16209_AUX_ADC);
398static IIO_CONST_ATTR(in0_scale, "0.6105");
399
400static IIO_DEV_ATTR_ACCEL_X(adis16209_read_14bit_signed,
401 ADIS16209_XACCL_OUT);
402static IIO_DEV_ATTR_ACCEL_Y(adis16209_read_14bit_signed,
403 ADIS16209_YACCL_OUT);
404static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
405 adis16209_read_14bit_signed,
406 adis16209_write_16bit,
407 ADIS16209_XACCL_NULL);
408static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
409 adis16209_read_14bit_signed,
410 adis16209_write_16bit,
411 ADIS16209_YACCL_NULL);
412static IIO_CONST_ATTR(accel_scale, "0.24414");
413
414static IIO_DEV_ATTR_INCLI_X(adis16209_read_14bit_signed,
415 ADIS16209_XINCL_OUT);
416static IIO_DEV_ATTR_INCLI_Y(adis16209_read_14bit_signed,
417 ADIS16209_YINCL_OUT);
418static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO,
419 adis16209_read_14bit_signed,
420 adis16209_write_16bit,
421 ADIS16209_XACCL_NULL);
422static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO,
423 adis16209_read_14bit_signed,
424 adis16209_write_16bit,
425 ADIS16209_YACCL_NULL);
426static IIO_CONST_ATTR(incli_scale, "0.025");
427
428static IIO_DEVICE_ATTR(rot_raw, S_IRUGO, adis16209_read_14bit_signed,
429 NULL, ADIS16209_ROT_OUT);
430
431static IIO_DEV_ATTR_TEMP(adis16209_read_temp);
432static IIO_CONST_ATTR(temp_offset, "25");
433static IIO_CONST_ATTR(temp_scale, "-0.47");
434
435static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0);
436
437static IIO_CONST_ATTR(name, "adis16209");
438
439static struct attribute *adis16209_event_attributes[] = {
440 NULL
441};
442
443static struct attribute_group adis16209_event_attribute_group = {
444 .attrs = adis16209_event_attributes,
445};
446
447static struct attribute *adis16209_attributes[] = {
448 &iio_dev_attr_in_supply_raw.dev_attr.attr,
449 &iio_const_attr_in_supply_scale.dev_attr.attr,
450 &iio_dev_attr_temp.dev_attr.attr,
451 &iio_const_attr_temp_offset.dev_attr.attr,
452 &iio_const_attr_temp_scale.dev_attr.attr,
453 &iio_dev_attr_reset.dev_attr.attr,
454 &iio_const_attr_name.dev_attr.attr,
455 &iio_dev_attr_in0_raw.dev_attr.attr,
456 &iio_const_attr_in0_scale.dev_attr.attr,
457 &iio_dev_attr_accel_x_raw.dev_attr.attr,
458 &iio_dev_attr_accel_y_raw.dev_attr.attr,
459 &iio_dev_attr_accel_x_offset.dev_attr.attr,
460 &iio_dev_attr_accel_y_offset.dev_attr.attr,
461 &iio_const_attr_accel_scale.dev_attr.attr,
462 &iio_dev_attr_incli_x_raw.dev_attr.attr,
463 &iio_dev_attr_incli_y_raw.dev_attr.attr,
464 &iio_dev_attr_incli_x_offset.dev_attr.attr,
465 &iio_dev_attr_incli_y_offset.dev_attr.attr,
466 &iio_const_attr_incli_scale.dev_attr.attr,
467 &iio_dev_attr_rot_raw.dev_attr.attr,
468 NULL
469};
470
471static const struct attribute_group adis16209_attribute_group = {
472 .attrs = adis16209_attributes,
473};
474
475static int __devinit adis16209_probe(struct spi_device *spi)
476{
477 int ret, regdone = 0;
478 struct adis16209_state *st = kzalloc(sizeof *st, GFP_KERNEL);
479 if (!st) {
480 ret = -ENOMEM;
481 goto error_ret;
482 }
483 /* this is only used for removal purposes */
484 spi_set_drvdata(spi, st);
485
486 /* Allocate the comms buffers */
487 st->rx = kzalloc(sizeof(*st->rx)*ADIS16209_MAX_RX, GFP_KERNEL);
488 if (st->rx == NULL) {
489 ret = -ENOMEM;
490 goto error_free_st;
491 }
492 st->tx = kzalloc(sizeof(*st->tx)*ADIS16209_MAX_TX, GFP_KERNEL);
493 if (st->tx == NULL) {
494 ret = -ENOMEM;
495 goto error_free_rx;
496 }
497 st->us = spi;
498 mutex_init(&st->buf_lock);
499 /* setup the industrialio driver allocated elements */
500 st->indio_dev = iio_allocate_device();
501 if (st->indio_dev == NULL) {
502 ret = -ENOMEM;
503 goto error_free_tx;
504 }
505
506 st->indio_dev->dev.parent = &spi->dev;
507 st->indio_dev->num_interrupt_lines = 1;
508 st->indio_dev->event_attrs = &adis16209_event_attribute_group;
509 st->indio_dev->attrs = &adis16209_attribute_group;
510 st->indio_dev->dev_data = (void *)(st);
511 st->indio_dev->driver_module = THIS_MODULE;
512 st->indio_dev->modes = INDIO_DIRECT_MODE;
513
514 ret = adis16209_configure_ring(st->indio_dev);
515 if (ret)
516 goto error_free_dev;
517
518 ret = iio_device_register(st->indio_dev);
519 if (ret)
520 goto error_unreg_ring_funcs;
521 regdone = 1;
522
523 ret = adis16209_initialize_ring(st->indio_dev->ring);
524 if (ret) {
525 printk(KERN_ERR "failed to initialize the ring\n");
526 goto error_unreg_ring_funcs;
527 }
528
529 if (spi->irq) {
530 ret = iio_register_interrupt_line(spi->irq,
531 st->indio_dev,
532 0,
533 IRQF_TRIGGER_RISING,
534 "adis16209");
535 if (ret)
536 goto error_uninitialize_ring;
537
538 ret = adis16209_probe_trigger(st->indio_dev);
539 if (ret)
540 goto error_unregister_line;
541 }
542
543 /* Get the device into a sane initial state */
544 ret = adis16209_initial_setup(st);
545 if (ret)
546 goto error_remove_trigger;
547 return 0;
548
549error_remove_trigger:
550 adis16209_remove_trigger(st->indio_dev);
551error_unregister_line:
552 if (spi->irq)
553 iio_unregister_interrupt_line(st->indio_dev, 0);
554error_uninitialize_ring:
555 adis16209_uninitialize_ring(st->indio_dev->ring);
556error_unreg_ring_funcs:
557 adis16209_unconfigure_ring(st->indio_dev);
558error_free_dev:
559 if (regdone)
560 iio_device_unregister(st->indio_dev);
561 else
562 iio_free_device(st->indio_dev);
563error_free_tx:
564 kfree(st->tx);
565error_free_rx:
566 kfree(st->rx);
567error_free_st:
568 kfree(st);
569error_ret:
570 return ret;
571}
572
573static int adis16209_remove(struct spi_device *spi)
574{
575 struct adis16209_state *st = spi_get_drvdata(spi);
576 struct iio_dev *indio_dev = st->indio_dev;
577
578 flush_scheduled_work();
579
580 adis16209_remove_trigger(indio_dev);
581 if (spi->irq)
582 iio_unregister_interrupt_line(indio_dev, 0);
583
584 adis16209_uninitialize_ring(indio_dev->ring);
585 iio_device_unregister(indio_dev);
586 adis16209_unconfigure_ring(indio_dev);
587 kfree(st->tx);
588 kfree(st->rx);
589 kfree(st);
590
591 return 0;
592}
593
594static struct spi_driver adis16209_driver = {
595 .driver = {
596 .name = "adis16209",
597 .owner = THIS_MODULE,
598 },
599 .probe = adis16209_probe,
600 .remove = __devexit_p(adis16209_remove),
601};
602
603static __init int adis16209_init(void)
604{
605 return spi_register_driver(&adis16209_driver);
606}
607module_init(adis16209_init);
608
609static __exit void adis16209_exit(void)
610{
611 spi_unregister_driver(&adis16209_driver);
612}
613module_exit(adis16209_exit);
614
615MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
616MODULE_DESCRIPTION("Analog Devices ADIS16209 Digital Vibration Sensor driver");
617MODULE_LICENSE("GPL v2");