Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
adis16220_core.c
Go to the documentation of this file.
1 /*
2  * ADIS16220 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/delay.h>
10 #include <linux/mutex.h>
11 #include <linux/device.h>
12 #include <linux/kernel.h>
13 #include <linux/spi/spi.h>
14 #include <linux/slab.h>
15 #include <linux/sysfs.h>
16 #include <linux/module.h>
17 
18 #include <linux/iio/iio.h>
19 #include <linux/iio/sysfs.h>
20 
21 #include "adis16220.h"
22 
23 #define DRIVER_NAME "adis16220"
24 
31 static int adis16220_spi_write_reg_8(struct iio_dev *indio_dev,
32  u8 reg_address,
33  u8 val)
34 {
35  int ret;
36  struct adis16220_state *st = iio_priv(indio_dev);
37 
38  mutex_lock(&st->buf_lock);
39  st->tx[0] = ADIS16220_WRITE_REG(reg_address);
40  st->tx[1] = val;
41 
42  ret = spi_write(st->us, st->tx, 2);
43  mutex_unlock(&st->buf_lock);
44 
45  return ret;
46 }
47 
55 static int adis16220_spi_write_reg_16(struct iio_dev *indio_dev,
56  u8 lower_reg_address,
57  u16 value)
58 {
59  int ret;
60  struct spi_message msg;
61  struct adis16220_state *st = iio_priv(indio_dev);
62  struct spi_transfer xfers[] = {
63  {
64  .tx_buf = st->tx,
65  .bits_per_word = 8,
66  .len = 2,
67  .cs_change = 1,
68  .delay_usecs = 35,
69  }, {
70  .tx_buf = st->tx + 2,
71  .bits_per_word = 8,
72  .len = 2,
73  .delay_usecs = 35,
74  },
75  };
76 
77  mutex_lock(&st->buf_lock);
78  st->tx[0] = ADIS16220_WRITE_REG(lower_reg_address);
79  st->tx[1] = value & 0xFF;
80  st->tx[2] = ADIS16220_WRITE_REG(lower_reg_address + 1);
81  st->tx[3] = (value >> 8) & 0xFF;
82 
83  spi_message_init(&msg);
84  spi_message_add_tail(&xfers[0], &msg);
85  spi_message_add_tail(&xfers[1], &msg);
86  ret = spi_sync(st->us, &msg);
87  mutex_unlock(&st->buf_lock);
88 
89  return ret;
90 }
91 
99 static int adis16220_spi_read_reg_16(struct iio_dev *indio_dev,
100  u8 lower_reg_address,
101  u16 *val)
102 {
103  struct spi_message msg;
104  struct adis16220_state *st = iio_priv(indio_dev);
105  int ret;
106  struct spi_transfer xfers[] = {
107  {
108  .tx_buf = st->tx,
109  .bits_per_word = 8,
110  .len = 2,
111  .cs_change = 1,
112  .delay_usecs = 35,
113  }, {
114  .rx_buf = st->rx,
115  .bits_per_word = 8,
116  .len = 2,
117  .cs_change = 1,
118  .delay_usecs = 35,
119  },
120  };
121 
122  mutex_lock(&st->buf_lock);
123  st->tx[0] = ADIS16220_READ_REG(lower_reg_address);
124  st->tx[1] = 0;
125 
126  spi_message_init(&msg);
127  spi_message_add_tail(&xfers[0], &msg);
128  spi_message_add_tail(&xfers[1], &msg);
129  ret = spi_sync(st->us, &msg);
130  if (ret) {
131  dev_err(&st->us->dev,
132  "problem when reading 16 bit register 0x%02X",
133  lower_reg_address);
134  goto error_ret;
135  }
136  *val = (st->rx[0] << 8) | st->rx[1];
137 
138 error_ret:
139  mutex_unlock(&st->buf_lock);
140  return ret;
141 }
142 
143 static ssize_t adis16220_read_16bit(struct device *dev,
144  struct device_attribute *attr,
145  char *buf)
146 {
147  struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
148  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
149  ssize_t ret;
150  s16 val = 0;
151 
152  /* Take the iio_dev status lock */
153  mutex_lock(&indio_dev->mlock);
154  ret = adis16220_spi_read_reg_16(indio_dev, this_attr->address,
155  (u16 *)&val);
156  mutex_unlock(&indio_dev->mlock);
157  if (ret)
158  return ret;
159  return sprintf(buf, "%d\n", val);
160 }
161 
162 static ssize_t adis16220_write_16bit(struct device *dev,
163  struct device_attribute *attr,
164  const char *buf,
165  size_t len)
166 {
167  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
168  struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
169  int ret;
170  u16 val;
171 
172  ret = kstrtou16(buf, 10, &val);
173  if (ret)
174  goto error_ret;
175  ret = adis16220_spi_write_reg_16(indio_dev, this_attr->address, val);
176 
177 error_ret:
178  return ret ? ret : len;
179 }
180 
181 static int adis16220_capture(struct iio_dev *indio_dev)
182 {
183  int ret;
184  ret = adis16220_spi_write_reg_16(indio_dev,
186  0xBF08); /* initiates a manual data capture */
187  if (ret)
188  dev_err(&indio_dev->dev, "problem beginning capture");
189 
190  msleep(10); /* delay for capture to finish */
191 
192  return ret;
193 }
194 
195 static int adis16220_reset(struct iio_dev *indio_dev)
196 {
197  int ret;
198  ret = adis16220_spi_write_reg_8(indio_dev,
201  if (ret)
202  dev_err(&indio_dev->dev, "problem resetting device");
203 
204  return ret;
205 }
206 
207 static ssize_t adis16220_write_capture(struct device *dev,
208  struct device_attribute *attr,
209  const char *buf, size_t len)
210 {
211  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
212  bool val;
213  int ret;
214 
215  ret = strtobool(buf, &val);
216  if (ret)
217  return ret;
218  if (!val)
219  return -EINVAL;
220  ret = adis16220_capture(indio_dev);
221  if (ret)
222  return ret;
223 
224  return len;
225 }
226 
227 static int adis16220_check_status(struct iio_dev *indio_dev)
228 {
229  u16 status;
230  int ret;
231 
232  ret = adis16220_spi_read_reg_16(indio_dev, ADIS16220_DIAG_STAT,
233  &status);
234 
235  if (ret < 0) {
236  dev_err(&indio_dev->dev, "Reading status failed\n");
237  goto error_ret;
238  }
239  ret = status & 0x7F;
240 
241  if (status & ADIS16220_DIAG_STAT_VIOLATION)
242  dev_err(&indio_dev->dev,
243  "Capture period violation/interruption\n");
244  if (status & ADIS16220_DIAG_STAT_SPI_FAIL)
245  dev_err(&indio_dev->dev, "SPI failure\n");
246  if (status & ADIS16220_DIAG_STAT_FLASH_UPT)
247  dev_err(&indio_dev->dev, "Flash update failed\n");
248  if (status & ADIS16220_DIAG_STAT_POWER_HIGH)
249  dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
250  if (status & ADIS16220_DIAG_STAT_POWER_LOW)
251  dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
252 
253 error_ret:
254  return ret;
255 }
256 
257 static int adis16220_self_test(struct iio_dev *indio_dev)
258 {
259  int ret;
260  ret = adis16220_spi_write_reg_16(indio_dev,
263  if (ret) {
264  dev_err(&indio_dev->dev, "problem starting self test");
265  goto err_ret;
266  }
267 
268  adis16220_check_status(indio_dev);
269 
270 err_ret:
271  return ret;
272 }
273 
274 static int adis16220_initial_setup(struct iio_dev *indio_dev)
275 {
276  int ret;
277 
278  /* Do self test */
279  ret = adis16220_self_test(indio_dev);
280  if (ret) {
281  dev_err(&indio_dev->dev, "self test failure");
282  goto err_ret;
283  }
284 
285  /* Read status register to check the result */
286  ret = adis16220_check_status(indio_dev);
287  if (ret) {
288  adis16220_reset(indio_dev);
289  dev_err(&indio_dev->dev, "device not playing ball -> reset");
291  ret = adis16220_check_status(indio_dev);
292  if (ret) {
293  dev_err(&indio_dev->dev, "giving up");
294  goto err_ret;
295  }
296  }
297 
298 err_ret:
299  return ret;
300 }
301 
302 static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
303  char *buf,
304  loff_t off,
305  size_t count,
306  int addr)
307 {
308  struct adis16220_state *st = iio_priv(indio_dev);
309  struct spi_message msg;
310  struct spi_transfer xfers[] = {
311  {
312  .tx_buf = st->tx,
313  .bits_per_word = 8,
314  .len = 2,
315  .cs_change = 1,
316  .delay_usecs = 25,
317  }, {
318  .tx_buf = st->tx,
319  .rx_buf = st->rx,
320  .bits_per_word = 8,
321  .cs_change = 1,
322  .delay_usecs = 25,
323  },
324  };
325  int ret;
326  int i;
327 
328  if (unlikely(!count))
329  return count;
330 
331  if ((off >= ADIS16220_CAPTURE_SIZE) || (count & 1) || (off & 1))
332  return -EINVAL;
333 
334  if (off + count > ADIS16220_CAPTURE_SIZE)
335  count = ADIS16220_CAPTURE_SIZE - off;
336 
337  /* write the begin position of capture buffer */
338  ret = adis16220_spi_write_reg_16(indio_dev,
340  off > 1);
341  if (ret)
342  return -EIO;
343 
344  /* read count/2 values from capture buffer */
345  mutex_lock(&st->buf_lock);
346 
347  for (i = 0; i < count; i += 2) {
348  st->tx[i] = ADIS16220_READ_REG(addr);
349  st->tx[i + 1] = 0;
350  }
351  xfers[1].len = count;
352 
353  spi_message_init(&msg);
354  spi_message_add_tail(&xfers[0], &msg);
355  spi_message_add_tail(&xfers[1], &msg);
356  ret = spi_sync(st->us, &msg);
357  if (ret) {
358 
359  mutex_unlock(&st->buf_lock);
360  return -EIO;
361  }
362 
363  memcpy(buf, st->rx, count);
364 
365  mutex_unlock(&st->buf_lock);
366  return count;
367 }
368 
369 static ssize_t adis16220_accel_bin_read(struct file *filp, struct kobject *kobj,
370  struct bin_attribute *attr,
371  char *buf,
372  loff_t off,
373  size_t count)
374 {
375  struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj));
376 
377  return adis16220_capture_buffer_read(indio_dev, buf,
378  off, count,
380 }
381 
382 static struct bin_attribute accel_bin = {
383  .attr = {
384  .name = "accel_bin",
385  .mode = S_IRUGO,
386  },
387  .read = adis16220_accel_bin_read,
388  .size = ADIS16220_CAPTURE_SIZE,
389 };
390 
391 static ssize_t adis16220_adc1_bin_read(struct file *filp, struct kobject *kobj,
392  struct bin_attribute *attr,
393  char *buf, loff_t off,
394  size_t count)
395 {
396  struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj));
397 
398  return adis16220_capture_buffer_read(indio_dev, buf,
399  off, count,
401 }
402 
403 static struct bin_attribute adc1_bin = {
404  .attr = {
405  .name = "in0_bin",
406  .mode = S_IRUGO,
407  },
408  .read = adis16220_adc1_bin_read,
409  .size = ADIS16220_CAPTURE_SIZE,
410 };
411 
412 static ssize_t adis16220_adc2_bin_read(struct file *filp, struct kobject *kobj,
413  struct bin_attribute *attr,
414  char *buf, loff_t off,
415  size_t count)
416 {
417  struct iio_dev *indio_dev = dev_to_iio_dev(kobj_to_dev(kobj));
418 
419  return adis16220_capture_buffer_read(indio_dev, buf,
420  off, count,
422 }
423 
424 
425 static struct bin_attribute adc2_bin = {
426  .attr = {
427  .name = "in1_bin",
428  .mode = S_IRUGO,
429  },
430  .read = adis16220_adc2_bin_read,
431  .size = ADIS16220_CAPTURE_SIZE,
432 };
433 
434 #define IIO_DEV_ATTR_CAPTURE(_store) \
435  IIO_DEVICE_ATTR(capture, S_IWUSR, NULL, _store, 0)
436 
437 static IIO_DEV_ATTR_CAPTURE(adis16220_write_capture);
438 
439 #define IIO_DEV_ATTR_CAPTURE_COUNT(_mode, _show, _store, _addr) \
440  IIO_DEVICE_ATTR(capture_count, _mode, _show, _store, _addr)
441 
443  adis16220_read_16bit,
444  adis16220_write_16bit,
446 
449 };
450 
454  bool sign;
455 };
456 
457 /* Address / bits / signed */
458 static const struct adis16220_address_spec adis16220_addresses[][3] = {
459  [in_supply] = { { ADIS16220_CAPT_SUPPLY, 12, 0 }, },
460  [in_1] = { { ADIS16220_CAPT_BUF1, 16, 1 },
461  { ADIS16220_AIN1_NULL, 16, 1 },
462  { ADIS16220_CAPT_PEAK1, 16, 1 }, },
463  [in_2] = { { ADIS16220_CAPT_BUF2, 16, 1 },
464  { ADIS16220_AIN2_NULL, 16, 1 },
465  { ADIS16220_CAPT_PEAK2, 16, 1 }, },
466  [accel] = { { ADIS16220_CAPT_BUFA, 16, 1 },
467  { ADIS16220_ACCL_NULL, 16, 1 },
468  { ADIS16220_CAPT_PEAKA, 16, 1 }, },
469  [temp] = { { ADIS16220_CAPT_TEMP, 12, 0 }, }
470 };
471 
472 static int adis16220_read_raw(struct iio_dev *indio_dev,
473  struct iio_chan_spec const *chan,
474  int *val, int *val2,
475  long mask)
476 {
477  int ret = -EINVAL;
478  int addrind = 0;
479  u16 uval;
480  s16 sval;
481  u8 bits;
482 
483  switch (mask) {
484  case IIO_CHAN_INFO_RAW:
485  addrind = 0;
486  break;
488  if (chan->type == IIO_TEMP) {
489  *val = 25000 / -470 - 1278; /* 25 C = 1278 */
490  return IIO_VAL_INT;
491  }
492  addrind = 1;
493  break;
494  case IIO_CHAN_INFO_PEAK:
495  addrind = 2;
496  break;
497  case IIO_CHAN_INFO_SCALE:
498  switch (chan->type) {
499  case IIO_TEMP:
500  *val = -470; /* -0.47 C */
501  *val2 = 0;
502  return IIO_VAL_INT_PLUS_MICRO;
503  case IIO_ACCEL:
504  *val2 = IIO_G_TO_M_S_2(19073); /* 19.073 g */
505  return IIO_VAL_INT_PLUS_MICRO;
506  case IIO_VOLTAGE:
507  if (chan->channel == 0) {
508  *val = 1;
509  *val2 = 220700; /* 1.2207 mV */
510  } else {
511  /* Should really be dependent on VDD */
512  *val2 = 305180; /* 305.18 uV */
513  }
514  return IIO_VAL_INT_PLUS_MICRO;
515  default:
516  return -EINVAL;
517  }
518  default:
519  return -EINVAL;
520  }
521  if (adis16220_addresses[chan->address][addrind].sign) {
522  ret = adis16220_spi_read_reg_16(indio_dev,
523  adis16220_addresses[chan
524  ->address]
525  [addrind].addr,
526  &sval);
527  if (ret)
528  return ret;
529  bits = adis16220_addresses[chan->address][addrind].bits;
530  sval &= (1 << bits) - 1;
531  sval = (s16)(sval << (16 - bits)) >> (16 - bits);
532  *val = sval;
533  return IIO_VAL_INT;
534  } else {
535  ret = adis16220_spi_read_reg_16(indio_dev,
536  adis16220_addresses[chan
537  ->address]
538  [addrind].addr,
539  &uval);
540  if (ret)
541  return ret;
542  bits = adis16220_addresses[chan->address][addrind].bits;
543  uval &= (1 << bits) - 1;
544  *val = uval;
545  return IIO_VAL_INT;
546  }
547 }
548 
549 static const struct iio_chan_spec adis16220_channels[] = {
550  {
551  .type = IIO_VOLTAGE,
552  .indexed = 1,
553  .channel = 0,
554  .extend_name = "supply",
555  .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
557  .address = in_supply,
558  }, {
559  .type = IIO_ACCEL,
560  .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
564  .address = accel,
565  }, {
566  .type = IIO_TEMP,
567  .indexed = 1,
568  .channel = 0,
569  .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
572  .address = temp,
573  }, {
574  .type = IIO_VOLTAGE,
575  .indexed = 1,
576  .channel = 1,
577  .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |
580  .address = in_1,
581  }, {
582  .type = IIO_VOLTAGE,
583  .indexed = 1,
584  .channel = 2,
585  .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
586  .address = in_2,
587  }
588 };
589 
590 static struct attribute *adis16220_attributes[] = {
591  &iio_dev_attr_capture.dev_attr.attr,
592  &iio_dev_attr_capture_count.dev_attr.attr,
593  NULL
594 };
595 
596 static const struct attribute_group adis16220_attribute_group = {
597  .attrs = adis16220_attributes,
598 };
599 
600 static const struct iio_info adis16220_info = {
601  .attrs = &adis16220_attribute_group,
602  .driver_module = THIS_MODULE,
603  .read_raw = &adis16220_read_raw,
604 };
605 
606 static int __devinit adis16220_probe(struct spi_device *spi)
607 {
608  int ret;
609  struct adis16220_state *st;
610  struct iio_dev *indio_dev;
611 
612  /* setup the industrialio driver allocated elements */
613  indio_dev = iio_device_alloc(sizeof(*st));
614  if (indio_dev == NULL) {
615  ret = -ENOMEM;
616  goto error_ret;
617  }
618 
619  st = iio_priv(indio_dev);
620  /* this is only used for removal purposes */
621  spi_set_drvdata(spi, indio_dev);
622 
623  st->us = spi;
624  mutex_init(&st->buf_lock);
625 
626  indio_dev->name = spi->dev.driver->name;
627  indio_dev->dev.parent = &spi->dev;
628  indio_dev->info = &adis16220_info;
629  indio_dev->modes = INDIO_DIRECT_MODE;
630  indio_dev->channels = adis16220_channels;
631  indio_dev->num_channels = ARRAY_SIZE(adis16220_channels);
632 
633  ret = iio_device_register(indio_dev);
634  if (ret)
635  goto error_free_dev;
636 
637  ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &accel_bin);
638  if (ret)
639  goto error_unregister_dev;
640 
641  ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc1_bin);
642  if (ret)
643  goto error_rm_accel_bin;
644 
645  ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc2_bin);
646  if (ret)
647  goto error_rm_adc1_bin;
648 
649  /* Get the device into a sane initial state */
650  ret = adis16220_initial_setup(indio_dev);
651  if (ret)
652  goto error_rm_adc2_bin;
653  return 0;
654 
655 error_rm_adc2_bin:
656  sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin);
657 error_rm_adc1_bin:
658  sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin);
659 error_rm_accel_bin:
660  sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin);
661 error_unregister_dev:
662  iio_device_unregister(indio_dev);
663 error_free_dev:
664  iio_device_free(indio_dev);
665 error_ret:
666  return ret;
667 }
668 
669 static int __devexit adis16220_remove(struct spi_device *spi)
670 {
671  struct iio_dev *indio_dev = spi_get_drvdata(spi);
672 
673  sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin);
674  sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin);
675  sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin);
676  iio_device_unregister(indio_dev);
677  iio_device_free(indio_dev);
678 
679  return 0;
680 }
681 
682 static struct spi_driver adis16220_driver = {
683  .driver = {
684  .name = "adis16220",
685  .owner = THIS_MODULE,
686  },
687  .probe = adis16220_probe,
688  .remove = __devexit_p(adis16220_remove),
689 };
690 module_spi_driver(adis16220_driver);
691 
692 MODULE_AUTHOR("Barry Song <[email protected]>");
693 MODULE_DESCRIPTION("Analog Devices ADIS16220 Digital Vibration Sensor");
694 MODULE_LICENSE("GPL v2");
695 MODULE_ALIAS("spi:adis16220");