Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
adis16080_core.c
Go to the documentation of this file.
1 /*
2  * ADIS16080/100 Yaw Rate Gyroscope with SPI driver
3  *
4  * Copyright 2010 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2 or later.
7  */
8 #include <linux/delay.h>
9 #include <linux/mutex.h>
10 #include <linux/device.h>
11 #include <linux/kernel.h>
12 #include <linux/spi/spi.h>
13 #include <linux/slab.h>
14 #include <linux/sysfs.h>
15 #include <linux/module.h>
16 
17 #include <linux/iio/iio.h>
18 #include <linux/iio/sysfs.h>
19 
20 #define ADIS16080_DIN_GYRO (0 << 10) /* Gyroscope output */
21 #define ADIS16080_DIN_TEMP (1 << 10) /* Temperature output */
22 #define ADIS16080_DIN_AIN1 (2 << 10)
23 #define ADIS16080_DIN_AIN2 (3 << 10)
24 
25 /*
26  * 1: Write contents on DIN to control register.
27  * 0: No changes to control register.
28  */
29 
30 #define ADIS16080_DIN_WRITE (1 << 15)
31 
39  struct spi_device *us;
40  struct mutex buf_lock;
41 
43 };
44 
45 static int adis16080_spi_write(struct iio_dev *indio_dev,
46  u16 val)
47 {
48  int ret;
49  struct adis16080_state *st = iio_priv(indio_dev);
50 
51  mutex_lock(&st->buf_lock);
52  st->buf[0] = val >> 8;
53  st->buf[1] = val;
54 
55  ret = spi_write(st->us, st->buf, 2);
56  mutex_unlock(&st->buf_lock);
57 
58  return ret;
59 }
60 
61 static int adis16080_spi_read(struct iio_dev *indio_dev,
62  u16 *val)
63 {
64  int ret;
65  struct adis16080_state *st = iio_priv(indio_dev);
66 
67  mutex_lock(&st->buf_lock);
68 
69  ret = spi_read(st->us, st->buf, 2);
70 
71  if (ret == 0)
72  *val = ((st->buf[0] & 0xF) << 8) | st->buf[1];
73  mutex_unlock(&st->buf_lock);
74 
75  return ret;
76 }
77 
78 static int adis16080_read_raw(struct iio_dev *indio_dev,
79  struct iio_chan_spec const *chan,
80  int *val,
81  int *val2,
82  long mask)
83 {
84  int ret = -EINVAL;
85  u16 ut = 0;
86  /* Take the iio_dev status lock */
87 
88  mutex_lock(&indio_dev->mlock);
89  switch (mask) {
90  case IIO_CHAN_INFO_RAW:
91  ret = adis16080_spi_write(indio_dev,
92  chan->address |
94  if (ret < 0)
95  break;
96  ret = adis16080_spi_read(indio_dev, &ut);
97  if (ret < 0)
98  break;
99  *val = ut;
100  ret = IIO_VAL_INT;
101  break;
102  }
103  mutex_unlock(&indio_dev->mlock);
104 
105  return ret;
106 }
107 
108 static const struct iio_chan_spec adis16080_channels[] = {
109  {
110  .type = IIO_ANGL_VEL,
111  .modified = 1,
112  .channel2 = IIO_MOD_Z,
113  .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
114  .address = ADIS16080_DIN_GYRO,
115  }, {
116  .type = IIO_VOLTAGE,
117  .indexed = 1,
118  .channel = 0,
119  .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
120  .address = ADIS16080_DIN_AIN1,
121  }, {
122  .type = IIO_VOLTAGE,
123  .indexed = 1,
124  .channel = 1,
125  .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
126  .address = ADIS16080_DIN_AIN2,
127  }, {
128  .type = IIO_TEMP,
129  .indexed = 1,
130  .channel = 0,
131  .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT,
132  .address = ADIS16080_DIN_TEMP,
133  }
134 };
135 
136 static const struct iio_info adis16080_info = {
137  .read_raw = &adis16080_read_raw,
138  .driver_module = THIS_MODULE,
139 };
140 
141 static int __devinit adis16080_probe(struct spi_device *spi)
142 {
143  int ret;
144  struct adis16080_state *st;
145  struct iio_dev *indio_dev;
146 
147  /* setup the industrialio driver allocated elements */
148  indio_dev = iio_device_alloc(sizeof(*st));
149  if (indio_dev == NULL) {
150  ret = -ENOMEM;
151  goto error_ret;
152  }
153  st = iio_priv(indio_dev);
154  /* this is only used for removal purposes */
155  spi_set_drvdata(spi, indio_dev);
156 
157  /* Allocate the comms buffers */
158  st->us = spi;
159  mutex_init(&st->buf_lock);
160 
161  indio_dev->name = spi->dev.driver->name;
162  indio_dev->channels = adis16080_channels;
163  indio_dev->num_channels = ARRAY_SIZE(adis16080_channels);
164  indio_dev->dev.parent = &spi->dev;
165  indio_dev->info = &adis16080_info;
166  indio_dev->modes = INDIO_DIRECT_MODE;
167 
168  ret = iio_device_register(indio_dev);
169  if (ret)
170  goto error_free_dev;
171  return 0;
172 
173 error_free_dev:
174  iio_device_free(indio_dev);
175 error_ret:
176  return ret;
177 }
178 
179 /* fixme, confirm ordering in this function */
180 static int __devexit adis16080_remove(struct spi_device *spi)
181 {
182  iio_device_unregister(spi_get_drvdata(spi));
183  iio_device_free(spi_get_drvdata(spi));
184 
185  return 0;
186 }
187 
188 static struct spi_driver adis16080_driver = {
189  .driver = {
190  .name = "adis16080",
191  .owner = THIS_MODULE,
192  },
193  .probe = adis16080_probe,
194  .remove = __devexit_p(adis16080_remove),
195 };
196 module_spi_driver(adis16080_driver);
197 
198 MODULE_AUTHOR("Barry Song <[email protected]>");
199 MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope Driver");
200 MODULE_LICENSE("GPL v2");
201 MODULE_ALIAS("spi:adis16080");