]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/iio/gyro/adis16080_core.c
staging:iio:gyro:adis16080 unused stub removal and cleanup
[karo-tx-linux.git] / drivers / staging / iio / gyro / adis16080_core.c
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
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 "adis16080.h"
27
28 static int adis16080_spi_write(struct device *dev,
29                 u16 val)
30 {
31         int ret;
32         struct iio_dev *indio_dev = dev_get_drvdata(dev);
33         struct adis16080_state *st = iio_dev_get_devdata(indio_dev);
34
35         mutex_lock(&st->buf_lock);
36         st->tx[0] = val >> 8;
37         st->tx[1] = val;
38
39         ret = spi_write(st->us, st->tx, 2);
40         mutex_unlock(&st->buf_lock);
41
42         return ret;
43 }
44
45 static int adis16080_spi_read(struct device *dev,
46                 u16 *val)
47 {
48         int ret;
49         struct iio_dev *indio_dev = dev_get_drvdata(dev);
50         struct adis16080_state *st = iio_dev_get_devdata(indio_dev);
51
52         mutex_lock(&st->buf_lock);
53
54         ret = spi_read(st->us, st->rx, 2);
55
56         if (ret == 0)
57                 *val = ((st->rx[0] & 0xF) << 8) | st->rx[1];
58         mutex_unlock(&st->buf_lock);
59
60         return ret;
61 }
62
63 static ssize_t adis16080_read(struct device *dev,
64                 struct device_attribute *attr,
65                 char *buf)
66 {
67         struct iio_dev *indio_dev = dev_get_drvdata(dev);
68         u16 val = 0;
69         ssize_t ret;
70
71         /* Take the iio_dev status lock */
72         mutex_lock(&indio_dev->mlock);
73         ret =  adis16080_spi_read(dev, &val);
74         mutex_unlock(&indio_dev->mlock);
75
76         if (ret == 0)
77                 return sprintf(buf, "%d\n", val);
78         else
79                 return ret;
80 }
81
82 static ssize_t adis16080_write(struct device *dev,
83                 struct device_attribute *attr,
84                 const char *buf,
85                 size_t len)
86 {
87         int ret;
88         long val;
89
90         ret = strict_strtol(buf, 16, &val);
91         if (ret)
92                 goto error_ret;
93         ret = adis16080_spi_write(dev, val);
94
95 error_ret:
96         return ret ? ret : len;
97 }
98
99 #define IIO_DEV_ATTR_IN(_show)                          \
100         IIO_DEVICE_ATTR(in, S_IRUGO, _show, NULL, 0)
101
102 #define IIO_DEV_ATTR_OUT(_store)                                \
103         IIO_DEVICE_ATTR(out, S_IRUGO, NULL, _store, 0)
104
105 static IIO_DEV_ATTR_IN(adis16080_read);
106 static IIO_DEV_ATTR_OUT(adis16080_write);
107
108 static IIO_CONST_ATTR(name, "adis16080");
109
110 static struct attribute *adis16080_event_attributes[] = {
111         NULL
112 };
113
114 static struct attribute_group adis16080_event_attribute_group = {
115         .attrs = adis16080_event_attributes,
116 };
117
118 static struct attribute *adis16080_attributes[] = {
119         &iio_dev_attr_in.dev_attr.attr,
120         &iio_dev_attr_out.dev_attr.attr,
121         &iio_const_attr_name.dev_attr.attr,
122         NULL
123 };
124
125 static const struct attribute_group adis16080_attribute_group = {
126         .attrs = adis16080_attributes,
127 };
128
129 static int __devinit adis16080_probe(struct spi_device *spi)
130 {
131         int ret, regdone = 0;
132         struct adis16080_state *st = kzalloc(sizeof *st, GFP_KERNEL);
133         if (!st) {
134                 ret =  -ENOMEM;
135                 goto error_ret;
136         }
137         /* this is only used for removal purposes */
138         spi_set_drvdata(spi, st);
139
140         /* Allocate the comms buffers */
141         st->rx = kzalloc(sizeof(*st->rx)*ADIS16080_MAX_RX, GFP_KERNEL);
142         if (st->rx == NULL) {
143                 ret = -ENOMEM;
144                 goto error_free_st;
145         }
146         st->tx = kzalloc(sizeof(*st->tx)*ADIS16080_MAX_TX, GFP_KERNEL);
147         if (st->tx == NULL) {
148                 ret = -ENOMEM;
149                 goto error_free_rx;
150         }
151         st->us = spi;
152         mutex_init(&st->buf_lock);
153         /* setup the industrialio driver allocated elements */
154         st->indio_dev = iio_allocate_device();
155         if (st->indio_dev == NULL) {
156                 ret = -ENOMEM;
157                 goto error_free_tx;
158         }
159
160         st->indio_dev->dev.parent = &spi->dev;
161         st->indio_dev->num_interrupt_lines = 1;
162         st->indio_dev->event_attrs = &adis16080_event_attribute_group;
163         st->indio_dev->attrs = &adis16080_attribute_group;
164         st->indio_dev->dev_data = (void *)(st);
165         st->indio_dev->driver_module = THIS_MODULE;
166         st->indio_dev->modes = INDIO_DIRECT_MODE;
167
168         ret = iio_device_register(st->indio_dev);
169         if (ret)
170                 goto error_free_dev;
171         regdone = 1;
172
173         return 0;
174
175 error_free_dev:
176         if (regdone)
177                 iio_device_unregister(st->indio_dev);
178         else
179                 iio_free_device(st->indio_dev);
180 error_free_tx:
181         kfree(st->tx);
182 error_free_rx:
183         kfree(st->rx);
184 error_free_st:
185         kfree(st);
186 error_ret:
187         return ret;
188 }
189
190 /* fixme, confirm ordering in this function */
191 static int adis16080_remove(struct spi_device *spi)
192 {
193         struct adis16080_state *st = spi_get_drvdata(spi);
194         struct iio_dev *indio_dev = st->indio_dev;
195
196         iio_device_unregister(indio_dev);
197         kfree(st->tx);
198         kfree(st->rx);
199         kfree(st);
200
201         return 0;
202 }
203
204 static struct spi_driver adis16080_driver = {
205         .driver = {
206                 .name = "adis16080",
207                 .owner = THIS_MODULE,
208         },
209         .probe = adis16080_probe,
210         .remove = __devexit_p(adis16080_remove),
211 };
212
213 static __init int adis16080_init(void)
214 {
215         return spi_register_driver(&adis16080_driver);
216 }
217 module_init(adis16080_init);
218
219 static __exit void adis16080_exit(void)
220 {
221         spi_unregister_driver(&adis16080_driver);
222 }
223 module_exit(adis16080_exit);
224
225 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
226 MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope Driver");
227 MODULE_LICENSE("GPL v2");