diff options
author | Jonathan Cameron <jic23@cam.ac.uk> | 2011-02-26 12:30:18 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-28 20:50:15 -0500 |
commit | 8e67875141b263ada64b7c74f0e593b6686ea8ed (patch) | |
tree | 8eb9acf3f3330db355b2bb8fab7a11aa68cc3efd /drivers/staging | |
parent | a301d425e6cc8b1f7d7449c0e5d72e9463652d90 (diff) |
staging:iio:gyro: adis16130 cleanup, move to abi and bug fixes.
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/iio/gyro/adis16130.h | 42 | ||||
-rw-r--r-- | drivers/staging/iio/gyro/adis16130_core.c | 148 |
2 files changed, 69 insertions, 121 deletions
diff --git a/drivers/staging/iio/gyro/adis16130.h b/drivers/staging/iio/gyro/adis16130.h deleted file mode 100644 index 9efc4c77320..00000000000 --- a/drivers/staging/iio/gyro/adis16130.h +++ /dev/null | |||
@@ -1,42 +0,0 @@ | |||
1 | #ifndef SPI_ADIS16130_H_ | ||
2 | #define SPI_ADIS16130_H_ | ||
3 | |||
4 | #define ADIS16130_CON 0x0 | ||
5 | #define ADIS16130_CON_RD (1 << 6) | ||
6 | #define ADIS16130_IOP 0x1 | ||
7 | |||
8 | /* 1 = data-ready signal low when unread data on all channels; */ | ||
9 | #define ADIS16130_IOP_ALL_RDY (1 << 3) | ||
10 | #define ADIS16130_IOP_SYNC (1 << 0) /* 1 = synchronization enabled */ | ||
11 | #define ADIS16130_RATEDATA 0x8 /* Gyroscope output, rate of rotation */ | ||
12 | #define ADIS16130_TEMPDATA 0xA /* Temperature output */ | ||
13 | #define ADIS16130_RATECS 0x28 /* Gyroscope channel setup */ | ||
14 | #define ADIS16130_RATECS_EN (1 << 3) /* 1 = channel enable; */ | ||
15 | #define ADIS16130_TEMPCS 0x2A /* Temperature channel setup */ | ||
16 | #define ADIS16130_TEMPCS_EN (1 << 3) | ||
17 | #define ADIS16130_RATECONV 0x30 | ||
18 | #define ADIS16130_TEMPCONV 0x32 | ||
19 | #define ADIS16130_MODE 0x38 | ||
20 | #define ADIS16130_MODE_24BIT (1 << 1) /* 1 = 24-bit resolution; */ | ||
21 | |||
22 | #define ADIS16130_MAX_TX 4 | ||
23 | #define ADIS16130_MAX_RX 4 | ||
24 | |||
25 | /** | ||
26 | * struct adis16130_state - device instance specific data | ||
27 | * @us: actual spi_device to write data | ||
28 | * @indio_dev: industrial I/O device structure | ||
29 | * @tx: transmit buffer | ||
30 | * @rx: recieve buffer | ||
31 | * @buf_lock: mutex to protect tx and rx | ||
32 | **/ | ||
33 | struct adis16130_state { | ||
34 | struct spi_device *us; | ||
35 | struct iio_dev *indio_dev; | ||
36 | u8 *tx; | ||
37 | u8 *rx; | ||
38 | u32 mode; /* 1: 24bits mode 0:16bits mode */ | ||
39 | struct mutex buf_lock; | ||
40 | }; | ||
41 | |||
42 | #endif /* SPI_ADIS16130_H_ */ | ||
diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index 04d81d4b2cf..70e2831f8fb 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c | |||
@@ -6,9 +6,6 @@ | |||
6 | * Licensed under the GPL-2 or later. | 6 | * Licensed under the GPL-2 or later. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/irq.h> | ||
11 | #include <linux/gpio.h> | ||
12 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
13 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
14 | #include <linux/device.h> | 11 | #include <linux/device.h> |
@@ -23,7 +20,39 @@ | |||
23 | #include "gyro.h" | 20 | #include "gyro.h" |
24 | #include "../adc/adc.h" | 21 | #include "../adc/adc.h" |
25 | 22 | ||
26 | #include "adis16130.h" | 23 | #define ADIS16130_CON 0x0 |
24 | #define ADIS16130_CON_RD (1 << 6) | ||
25 | #define ADIS16130_IOP 0x1 | ||
26 | |||
27 | /* 1 = data-ready signal low when unread data on all channels; */ | ||
28 | #define ADIS16130_IOP_ALL_RDY (1 << 3) | ||
29 | #define ADIS16130_IOP_SYNC (1 << 0) /* 1 = synchronization enabled */ | ||
30 | #define ADIS16130_RATEDATA 0x8 /* Gyroscope output, rate of rotation */ | ||
31 | #define ADIS16130_TEMPDATA 0xA /* Temperature output */ | ||
32 | #define ADIS16130_RATECS 0x28 /* Gyroscope channel setup */ | ||
33 | #define ADIS16130_RATECS_EN (1 << 3) /* 1 = channel enable; */ | ||
34 | #define ADIS16130_TEMPCS 0x2A /* Temperature channel setup */ | ||
35 | #define ADIS16130_TEMPCS_EN (1 << 3) | ||
36 | #define ADIS16130_RATECONV 0x30 | ||
37 | #define ADIS16130_TEMPCONV 0x32 | ||
38 | #define ADIS16130_MODE 0x38 | ||
39 | #define ADIS16130_MODE_24BIT (1 << 1) /* 1 = 24-bit resolution; */ | ||
40 | |||
41 | /** | ||
42 | * struct adis16130_state - device instance specific data | ||
43 | * @us: actual spi_device to write data | ||
44 | * @indio_dev: industrial I/O device structure | ||
45 | * @mode: 24 bits (1) or 16 bits (0) | ||
46 | * @buf_lock: mutex to protect tx and rx | ||
47 | * @buf: unified tx/rx buffer | ||
48 | **/ | ||
49 | struct adis16130_state { | ||
50 | struct spi_device *us; | ||
51 | struct iio_dev *indio_dev; | ||
52 | u32 mode; | ||
53 | struct mutex buf_lock; | ||
54 | u8 buf[4] ____cacheline_aligned; | ||
55 | }; | ||
27 | 56 | ||
28 | static int adis16130_spi_write(struct device *dev, u8 reg_addr, | 57 | static int adis16130_spi_write(struct device *dev, u8 reg_addr, |
29 | u8 val) | 58 | u8 val) |
@@ -33,10 +62,10 @@ static int adis16130_spi_write(struct device *dev, u8 reg_addr, | |||
33 | struct adis16130_state *st = iio_dev_get_devdata(indio_dev); | 62 | struct adis16130_state *st = iio_dev_get_devdata(indio_dev); |
34 | 63 | ||
35 | mutex_lock(&st->buf_lock); | 64 | mutex_lock(&st->buf_lock); |
36 | st->tx[0] = reg_addr; | 65 | st->buf[0] = reg_addr; |
37 | st->tx[1] = val; | 66 | st->buf[1] = val; |
38 | 67 | ||
39 | ret = spi_write(st->us, st->tx, 2); | 68 | ret = spi_write(st->us, st->buf, 2); |
40 | mutex_unlock(&st->buf_lock); | 69 | mutex_unlock(&st->buf_lock); |
41 | 70 | ||
42 | return ret; | 71 | return ret; |
@@ -51,17 +80,19 @@ static int adis16130_spi_read(struct device *dev, u8 reg_addr, | |||
51 | 80 | ||
52 | mutex_lock(&st->buf_lock); | 81 | mutex_lock(&st->buf_lock); |
53 | 82 | ||
54 | st->tx[0] = ADIS16130_CON_RD | reg_addr; | 83 | st->buf[0] = ADIS16130_CON_RD | reg_addr; |
55 | if (st->mode) | 84 | if (st->mode) |
56 | ret = spi_read(st->us, st->rx, 4); | 85 | ret = spi_read(st->us, st->buf, 4); |
57 | else | 86 | else |
58 | ret = spi_read(st->us, st->rx, 3); | 87 | ret = spi_read(st->us, st->buf, 3); |
59 | 88 | ||
60 | if (ret == 0) { | 89 | if (ret == 0) { |
61 | if (st->mode) | 90 | if (st->mode) |
62 | *val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; | 91 | *val = (st->buf[1] << 16) | |
92 | (st->buf[2] << 8) | | ||
93 | st->buf[3]; | ||
63 | else | 94 | else |
64 | *val = (st->rx[1] << 8) | st->rx[2]; | 95 | *val = (st->buf[1] << 8) | st->buf[2]; |
65 | } | 96 | } |
66 | 97 | ||
67 | mutex_unlock(&st->buf_lock); | 98 | mutex_unlock(&st->buf_lock); |
@@ -69,36 +100,18 @@ static int adis16130_spi_read(struct device *dev, u8 reg_addr, | |||
69 | return ret; | 100 | return ret; |
70 | } | 101 | } |
71 | 102 | ||
72 | static ssize_t adis16130_gyro_read(struct device *dev, | 103 | static ssize_t adis16130_val_read(struct device *dev, |
73 | struct device_attribute *attr, | 104 | struct device_attribute *attr, |
74 | char *buf) | 105 | char *buf) |
75 | { | 106 | { |
107 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
76 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | 108 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
77 | u32 val; | 109 | u32 val; |
78 | ssize_t ret; | 110 | ssize_t ret; |
79 | 111 | ||
80 | /* Take the iio_dev status lock */ | 112 | /* Take the iio_dev status lock */ |
81 | mutex_lock(&indio_dev->mlock); | 113 | mutex_lock(&indio_dev->mlock); |
82 | ret = adis16130_spi_read(dev, ADIS16130_RATEDATA, &val); | 114 | ret = adis16130_spi_read(dev, this_attr->address, &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 adis16130_temp_read(struct device *dev, | ||
92 | struct device_attribute *attr, | ||
93 | char *buf) | ||
94 | { | ||
95 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
96 | u32 val; | ||
97 | ssize_t ret; | ||
98 | |||
99 | /* Take the iio_dev status lock */ | ||
100 | mutex_lock(&indio_dev->mlock); | ||
101 | ret = adis16130_spi_read(dev, ADIS16130_TEMPDATA, &val); | ||
102 | mutex_unlock(&indio_dev->mlock); | 115 | mutex_unlock(&indio_dev->mlock); |
103 | 116 | ||
104 | if (ret == 0) | 117 | if (ret == 0) |
@@ -114,7 +127,10 @@ static ssize_t adis16130_bitsmode_read(struct device *dev, | |||
114 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | 127 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
115 | struct adis16130_state *st = iio_dev_get_devdata(indio_dev); | 128 | struct adis16130_state *st = iio_dev_get_devdata(indio_dev); |
116 | 129 | ||
117 | return sprintf(buf, "%d\n", st->mode); | 130 | if (st->mode == 1) |
131 | return sprintf(buf, "s24\n"); | ||
132 | else | ||
133 | return sprintf(buf, "s16\n"); | ||
118 | } | 134 | } |
119 | 135 | ||
120 | static ssize_t adis16130_bitsmode_write(struct device *dev, | 136 | static ssize_t adis16130_bitsmode_write(struct device *dev, |
@@ -123,44 +139,38 @@ static ssize_t adis16130_bitsmode_write(struct device *dev, | |||
123 | size_t len) | 139 | size_t len) |
124 | { | 140 | { |
125 | int ret; | 141 | int ret; |
126 | long val; | 142 | u8 val; |
127 | 143 | ||
128 | ret = strict_strtol(buf, 16, &val); | 144 | if (sysfs_streq(buf, "s16")) |
129 | if (ret) | 145 | val = 0; |
130 | goto error_ret; | 146 | else if (sysfs_streq(buf, "s24")) |
131 | ret = adis16130_spi_write(dev, ADIS16130_MODE, !!val); | 147 | val = 1; |
148 | else | ||
149 | return -EINVAL; | ||
150 | |||
151 | ret = adis16130_spi_write(dev, ADIS16130_MODE, val); | ||
132 | 152 | ||
133 | error_ret: | ||
134 | return ret ? ret : len; | 153 | return ret ? ret : len; |
135 | } | 154 | } |
136 | 155 | static IIO_DEVICE_ATTR(temp_raw, S_IRUGO, adis16130_val_read, NULL, | |
137 | static IIO_DEV_ATTR_TEMP_RAW(adis16130_temp_read); | 156 | ADIS16130_TEMPDATA); |
138 | 157 | ||
139 | static IIO_CONST_ATTR(name, "adis16130"); | 158 | static IIO_CONST_ATTR(name, "adis16130"); |
140 | 159 | ||
141 | static IIO_DEV_ATTR_GYRO(adis16130_gyro_read, | 160 | static IIO_DEV_ATTR_GYRO_Z(adis16130_val_read, ADIS16130_RATEDATA); |
142 | ADIS16130_RATEDATA); | ||
143 | |||
144 | #define IIO_DEV_ATTR_BITS_MODE(_mode, _show, _store, _addr) \ | ||
145 | IIO_DEVICE_ATTR(bits_mode, _mode, _show, _store, _addr) | ||
146 | 161 | ||
147 | static IIO_DEV_ATTR_BITS_MODE(S_IWUSR | S_IRUGO, adis16130_bitsmode_read, | 162 | static IIO_DEVICE_ATTR(gyro_z_type, S_IWUSR | S_IRUGO, adis16130_bitsmode_read, |
148 | adis16130_bitsmode_write, | 163 | adis16130_bitsmode_write, |
149 | ADIS16130_MODE); | 164 | ADIS16130_MODE); |
150 | 165 | ||
151 | static struct attribute *adis16130_event_attributes[] = { | 166 | static IIO_CONST_ATTR(gyro_z_type_available, "s16 s24"); |
152 | NULL | ||
153 | }; | ||
154 | |||
155 | static struct attribute_group adis16130_event_attribute_group = { | ||
156 | .attrs = adis16130_event_attributes, | ||
157 | }; | ||
158 | 167 | ||
159 | static struct attribute *adis16130_attributes[] = { | 168 | static struct attribute *adis16130_attributes[] = { |
160 | &iio_dev_attr_temp_raw.dev_attr.attr, | 169 | &iio_dev_attr_temp_raw.dev_attr.attr, |
161 | &iio_const_attr_name.dev_attr.attr, | 170 | &iio_const_attr_name.dev_attr.attr, |
162 | &iio_dev_attr_gyro_raw.dev_attr.attr, | 171 | &iio_dev_attr_gyro_z_raw.dev_attr.attr, |
163 | &iio_dev_attr_bits_mode.dev_attr.attr, | 172 | &iio_dev_attr_gyro_z_type.dev_attr.attr, |
173 | &iio_const_attr_gyro_z_type_available.dev_attr.attr, | ||
164 | NULL | 174 | NULL |
165 | }; | 175 | }; |
166 | 176 | ||
@@ -178,30 +188,16 @@ static int __devinit adis16130_probe(struct spi_device *spi) | |||
178 | } | 188 | } |
179 | /* this is only used for removal purposes */ | 189 | /* this is only used for removal purposes */ |
180 | spi_set_drvdata(spi, st); | 190 | spi_set_drvdata(spi, st); |
181 | |||
182 | /* Allocate the comms buffers */ | ||
183 | st->rx = kzalloc(sizeof(*st->rx)*ADIS16130_MAX_RX, GFP_KERNEL); | ||
184 | if (st->rx == NULL) { | ||
185 | ret = -ENOMEM; | ||
186 | goto error_free_st; | ||
187 | } | ||
188 | st->tx = kzalloc(sizeof(*st->tx)*ADIS16130_MAX_TX, GFP_KERNEL); | ||
189 | if (st->tx == NULL) { | ||
190 | ret = -ENOMEM; | ||
191 | goto error_free_rx; | ||
192 | } | ||
193 | st->us = spi; | 191 | st->us = spi; |
194 | mutex_init(&st->buf_lock); | 192 | mutex_init(&st->buf_lock); |
195 | /* setup the industrialio driver allocated elements */ | 193 | /* setup the industrialio driver allocated elements */ |
196 | st->indio_dev = iio_allocate_device(); | 194 | st->indio_dev = iio_allocate_device(); |
197 | if (st->indio_dev == NULL) { | 195 | if (st->indio_dev == NULL) { |
198 | ret = -ENOMEM; | 196 | ret = -ENOMEM; |
199 | goto error_free_tx; | 197 | goto error_free_st; |
200 | } | 198 | } |
201 | 199 | ||
202 | st->indio_dev->dev.parent = &spi->dev; | 200 | st->indio_dev->dev.parent = &spi->dev; |
203 | st->indio_dev->num_interrupt_lines = 1; | ||
204 | st->indio_dev->event_attrs = &adis16130_event_attribute_group; | ||
205 | st->indio_dev->attrs = &adis16130_attribute_group; | 201 | st->indio_dev->attrs = &adis16130_attribute_group; |
206 | st->indio_dev->dev_data = (void *)(st); | 202 | st->indio_dev->dev_data = (void *)(st); |
207 | st->indio_dev->driver_module = THIS_MODULE; | 203 | st->indio_dev->driver_module = THIS_MODULE; |
@@ -216,10 +212,6 @@ static int __devinit adis16130_probe(struct spi_device *spi) | |||
216 | 212 | ||
217 | error_free_dev: | 213 | error_free_dev: |
218 | iio_free_device(st->indio_dev); | 214 | iio_free_device(st->indio_dev); |
219 | error_free_tx: | ||
220 | kfree(st->tx); | ||
221 | error_free_rx: | ||
222 | kfree(st->rx); | ||
223 | error_free_st: | 215 | error_free_st: |
224 | kfree(st); | 216 | kfree(st); |
225 | error_ret: | 217 | error_ret: |
@@ -233,8 +225,6 @@ static int adis16130_remove(struct spi_device *spi) | |||
233 | struct iio_dev *indio_dev = st->indio_dev; | 225 | struct iio_dev *indio_dev = st->indio_dev; |
234 | 226 | ||
235 | iio_device_unregister(indio_dev); | 227 | iio_device_unregister(indio_dev); |
236 | kfree(st->tx); | ||
237 | kfree(st->rx); | ||
238 | kfree(st); | 228 | kfree(st); |
239 | 229 | ||
240 | return 0; | 230 | return 0; |
@@ -262,5 +252,5 @@ static __exit void adis16130_exit(void) | |||
262 | module_exit(adis16130_exit); | 252 | module_exit(adis16130_exit); |
263 | 253 | ||
264 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); | 254 | MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); |
265 | MODULE_DESCRIPTION("Analog Devices ADIS16130 High Precision Angular Rate Sensor driver"); | 255 | MODULE_DESCRIPTION("Analog Devices ADIS16130 High Precision Angular Rate"); |
266 | MODULE_LICENSE("GPL v2"); | 256 | MODULE_LICENSE("GPL v2"); |