Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / iio / gyro / adis16060_core.c
1 /*
2  * ADIS16060 Wide Bandwidth Yaw Rate Gyroscope with SPI 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>
17 #include <linux/slab.h>
18 #include <linux/sysfs.h>
19 #include <linux/list.h>
20
21 #include "../iio.h"
22 #include "../sysfs.h"
23 #include "gyro.h"
24 #include "../adc/adc.h"
25
26 #include "adis16060.h"
27
28 #define DRIVER_NAME             "adis16060"
29
30 struct adis16060_state *adis16060_st;
31
32 int adis16060_spi_write(struct device *dev,
33                 u8 val)
34 {
35         int ret;
36         struct iio_dev *indio_dev = dev_get_drvdata(dev);
37         struct adis16060_state *st = iio_dev_get_devdata(indio_dev);
38
39         mutex_lock(&st->buf_lock);
40         st->tx[0] = 0;
41         st->tx[1] = 0;
42         st->tx[2] = val; /* The last 8 bits clocked in are latched */
43
44         ret = spi_write(st->us_w, st->tx, 3);
45         mutex_unlock(&st->buf_lock);
46
47         return ret;
48 }
49
50 int adis16060_spi_read(struct device *dev,
51                 u16 *val)
52 {
53         int ret;
54         struct iio_dev *indio_dev = dev_get_drvdata(dev);
55         struct adis16060_state *st = iio_dev_get_devdata(indio_dev);
56
57         mutex_lock(&st->buf_lock);
58
59         ret = spi_read(st->us_r, st->rx, 3);
60
61         /* The internal successive approximation ADC begins the conversion process
62          * on the falling edge of MSEL1 and starts to place data MSB first on the
63          * DOUT line at the 6th falling edge of SCLK
64          */
65         if (ret == 0)
66                 *val = ((st->rx[0] & 0x3) << 12) | (st->rx[1] << 4) | ((st->rx[2] >> 4) & 0xF);
67         mutex_unlock(&st->buf_lock);
68
69         return ret;
70 }
71
72 static ssize_t adis16060_read(struct device *dev,
73                 struct device_attribute *attr,
74                 char *buf)
75 {
76         struct iio_dev *indio_dev = dev_get_drvdata(dev);
77         u16 val;
78         ssize_t ret;
79
80         /* Take the iio_dev status lock */
81         mutex_lock(&indio_dev->mlock);
82         ret =  adis16060_spi_read(dev, &val);
83         mutex_unlock(&indio_dev->mlock);
84
85         if (ret == 0)
86                 return sprintf(buf, "%d\n", val);
87         else
88                 return ret;
89 }
90
91 static ssize_t adis16060_write(struct device *dev,
92                 struct device_attribute *attr,
93                 const char *buf,
94                 size_t len)
95 {
96         int ret;
97         long val;
98
99         ret = strict_strtol(buf, 16, &val);
100         if (ret)
101                 goto error_ret;
102         ret = adis16060_spi_write(dev, val);
103
104 error_ret:
105         return ret ? ret : len;
106 }
107
108 #define IIO_DEV_ATTR_IN(_show)                          \
109         IIO_DEVICE_ATTR(in, S_IRUGO, _show, NULL, 0)
110
111 #define IIO_DEV_ATTR_OUT(_store)                                \
112         IIO_DEVICE_ATTR(out, S_IRUGO, NULL, _store, 0)
113
114 static IIO_DEV_ATTR_IN(adis16060_read);
115 static IIO_DEV_ATTR_OUT(adis16060_write);
116
117 static IIO_CONST_ATTR(name, "adis16060");
118
119 static struct attribute *adis16060_event_attributes[] = {
120         NULL
121 };
122
123 static struct attribute_group adis16060_event_attribute_group = {
124         .attrs = adis16060_event_attributes,
125 };
126
127 static struct attribute *adis16060_attributes[] = {
128         &iio_dev_attr_in.dev_attr.attr,
129         &iio_dev_attr_out.dev_attr.attr,
130         &iio_const_attr_name.dev_attr.attr,
131         NULL
132 };
133
134 static const struct attribute_group adis16060_attribute_group = {
135         .attrs = adis16060_attributes,
136 };
137
138 static int __devinit adis16060_r_probe(struct spi_device *spi)
139 {
140         int ret, regdone = 0;
141         struct adis16060_state *st = kzalloc(sizeof *st, GFP_KERNEL);
142         if (!st) {
143                 ret =  -ENOMEM;
144                 goto error_ret;
145         }
146         /* this is only used for removal purposes */
147         spi_set_drvdata(spi, st);
148
149         /* Allocate the comms buffers */
150         st->rx = kzalloc(sizeof(*st->rx)*ADIS16060_MAX_RX, GFP_KERNEL);
151         if (st->rx == NULL) {
152                 ret = -ENOMEM;
153                 goto error_free_st;
154         }
155         st->tx = kzalloc(sizeof(*st->tx)*ADIS16060_MAX_TX, GFP_KERNEL);
156         if (st->tx == NULL) {
157                 ret = -ENOMEM;
158                 goto error_free_rx;
159         }
160         st->us_r = spi;
161         mutex_init(&st->buf_lock);
162         /* setup the industrialio driver allocated elements */
163         st->indio_dev = iio_allocate_device();
164         if (st->indio_dev == NULL) {
165                 ret = -ENOMEM;
166                 goto error_free_tx;
167         }
168
169         st->indio_dev->dev.parent = &spi->dev;
170         st->indio_dev->num_interrupt_lines = 1;
171         st->indio_dev->event_attrs = &adis16060_event_attribute_group;
172         st->indio_dev->attrs = &adis16060_attribute_group;
173         st->indio_dev->dev_data = (void *)(st);
174         st->indio_dev->driver_module = THIS_MODULE;
175         st->indio_dev->modes = INDIO_DIRECT_MODE;
176
177         ret = adis16060_configure_ring(st->indio_dev);
178         if (ret)
179                 goto error_free_dev;
180
181         ret = iio_device_register(st->indio_dev);
182         if (ret)
183                 goto error_unreg_ring_funcs;
184         regdone = 1;
185
186         ret = adis16060_initialize_ring(st->indio_dev->ring);
187         if (ret) {
188                 printk(KERN_ERR "failed to initialize the ring\n");
189                 goto error_unreg_ring_funcs;
190         }
191
192         if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
193                 ret = iio_register_interrupt_line(spi->irq,
194                                 st->indio_dev,
195                                 0,
196                                 IRQF_TRIGGER_RISING,
197                                 "adis16060");
198                 if (ret)
199                         goto error_uninitialize_ring;
200
201                 ret = adis16060_probe_trigger(st->indio_dev);
202                 if (ret)
203                         goto error_unregister_line;
204         }
205
206         adis16060_st = st;
207         return 0;
208
209 error_unregister_line:
210         if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
211                 iio_unregister_interrupt_line(st->indio_dev, 0);
212 error_uninitialize_ring:
213         adis16060_uninitialize_ring(st->indio_dev->ring);
214 error_unreg_ring_funcs:
215         adis16060_unconfigure_ring(st->indio_dev);
216 error_free_dev:
217         if (regdone)
218                 iio_device_unregister(st->indio_dev);
219         else
220                 iio_free_device(st->indio_dev);
221 error_free_tx:
222         kfree(st->tx);
223 error_free_rx:
224         kfree(st->rx);
225 error_free_st:
226         kfree(st);
227 error_ret:
228         return ret;
229 }
230
231 /* fixme, confirm ordering in this function */
232 static int adis16060_r_remove(struct spi_device *spi)
233 {
234         struct adis16060_state *st = spi_get_drvdata(spi);
235         struct iio_dev *indio_dev = st->indio_dev;
236
237         flush_scheduled_work();
238
239         adis16060_remove_trigger(indio_dev);
240         if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
241                 iio_unregister_interrupt_line(indio_dev, 0);
242
243         adis16060_uninitialize_ring(indio_dev->ring);
244         adis16060_unconfigure_ring(indio_dev);
245         iio_device_unregister(indio_dev);
246         kfree(st->tx);
247         kfree(st->rx);
248         kfree(st);
249
250         return 0;
251 }
252
253 static int __devinit adis16060_w_probe(struct spi_device *spi)
254 {
255         int ret;
256         struct adis16060_state *st = adis16060_st;
257         if (!st) {
258                 ret =  -ENODEV;
259                 goto error_ret;
260         }
261         spi_set_drvdata(spi, st);
262         st->us_w = spi;
263         return 0;
264
265 error_ret:
266         return ret;
267 }
268
269 static int adis16060_w_remove(struct spi_device *spi)
270 {
271         return 0;
272 }
273
274 static struct spi_driver adis16060_r_driver = {
275         .driver = {
276                 .name = "adis16060_r",
277                 .owner = THIS_MODULE,
278         },
279         .probe = adis16060_r_probe,
280         .remove = __devexit_p(adis16060_r_remove),
281 };
282
283 static struct spi_driver adis16060_w_driver = {
284         .driver = {
285                 .name = "adis16060_w",
286                 .owner = THIS_MODULE,
287         },
288         .probe = adis16060_w_probe,
289         .remove = __devexit_p(adis16060_w_remove),
290 };
291
292 static __init int adis16060_init(void)
293 {
294         int ret;
295
296         ret = spi_register_driver(&adis16060_r_driver);
297         if (ret < 0)
298                 return ret;
299
300         ret = spi_register_driver(&adis16060_w_driver);
301         if (ret < 0) {
302                 spi_unregister_driver(&adis16060_r_driver);
303                 return ret;
304         }
305
306         return 0;
307 }
308 module_init(adis16060_init);
309
310 static __exit void adis16060_exit(void)
311 {
312         spi_unregister_driver(&adis16060_w_driver);
313         spi_unregister_driver(&adis16060_r_driver);
314 }
315 module_exit(adis16060_exit);
316
317 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
318 MODULE_DESCRIPTION("Analog Devices ADIS16060 Yaw Rate Gyroscope with SPI driver");
319 MODULE_LICENSE("GPL v2");