diff options
author | Jonathan Cameron <jic23@cam.ac.uk> | 2011-05-18 09:41:47 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-19 19:14:54 -0400 |
commit | d37b24b3c033be00f7345b7217d3aae1c662f363 (patch) | |
tree | f750c8aebe39e26faa4601afc2ff9115df4e93e4 /drivers/staging/iio/accel/adis16203_core.c | |
parent | cf96ffd8c2ed7728f8abb2b6122da78319466a2d (diff) |
staging:iio:accel:adis16203 move to chan_spec based setup.
Mainly motivated by wish to remove the remaing users of the
scan helpers.
Some minor cleanups done whilst here.
Untested.
V2: Use IIO_CHAN macro
Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/iio/accel/adis16203_core.c')
-rw-r--r-- | drivers/staging/iio/accel/adis16203_core.c | 376 |
1 files changed, 188 insertions, 188 deletions
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 61623112aca..1694a0c9929 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_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> |
@@ -16,33 +13,29 @@ | |||
16 | #include <linux/spi/spi.h> | 13 | #include <linux/spi/spi.h> |
17 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
18 | #include <linux/sysfs.h> | 15 | #include <linux/sysfs.h> |
19 | #include <linux/list.h> | ||
20 | 16 | ||
21 | #include "../iio.h" | 17 | #include "../iio.h" |
22 | #include "../sysfs.h" | 18 | #include "../sysfs.h" |
23 | #include "accel.h" | 19 | #include "accel.h" |
24 | #include "inclinometer.h" | 20 | #include "inclinometer.h" |
25 | #include "../gyro/gyro.h" | 21 | #include "../ring_generic.h" |
26 | #include "../adc/adc.h" | 22 | #include "../adc/adc.h" |
27 | 23 | ||
28 | #include "adis16203.h" | 24 | #include "adis16203.h" |
29 | 25 | ||
30 | #define DRIVER_NAME "adis16203" | 26 | #define DRIVER_NAME "adis16203" |
31 | 27 | ||
32 | static int adis16203_check_status(struct device *dev); | ||
33 | |||
34 | /** | 28 | /** |
35 | * adis16203_spi_write_reg_8() - write single byte to a register | 29 | * adis16203_spi_write_reg_8() - write single byte to a register |
36 | * @dev: device associated with child of actual device (iio_dev or iio_trig) | 30 | * @indio_dev: iio device associated with child of actual device |
37 | * @reg_address: the address of the register to be written | 31 | * @reg_address: the address of the register to be written |
38 | * @val: the value to write | 32 | * @val: the value to write |
39 | **/ | 33 | **/ |
40 | static int adis16203_spi_write_reg_8(struct device *dev, | 34 | static int adis16203_spi_write_reg_8(struct iio_dev *indio_dev, |
41 | u8 reg_address, | 35 | u8 reg_address, |
42 | u8 val) | 36 | u8 val) |
43 | { | 37 | { |
44 | int ret; | 38 | int ret; |
45 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
46 | struct adis16203_state *st = iio_dev_get_devdata(indio_dev); | 39 | struct adis16203_state *st = iio_dev_get_devdata(indio_dev); |
47 | 40 | ||
48 | mutex_lock(&st->buf_lock); | 41 | mutex_lock(&st->buf_lock); |
@@ -57,18 +50,17 @@ static int adis16203_spi_write_reg_8(struct device *dev, | |||
57 | 50 | ||
58 | /** | 51 | /** |
59 | * adis16203_spi_write_reg_16() - write 2 bytes to a pair of registers | 52 | * adis16203_spi_write_reg_16() - write 2 bytes to a pair of registers |
60 | * @dev: device associated with child of actual device (iio_dev or iio_trig) | 53 | * @indio_dev: iio device associated with child of actual device |
61 | * @reg_address: the address of the lower of the two registers. Second register | 54 | * @reg_address: the address of the lower of the two registers. Second register |
62 | * is assumed to have address one greater. | 55 | * is assumed to have address one greater. |
63 | * @val: value to be written | 56 | * @val: value to be written |
64 | **/ | 57 | **/ |
65 | static int adis16203_spi_write_reg_16(struct device *dev, | 58 | static int adis16203_spi_write_reg_16(struct iio_dev *indio_dev, |
66 | u8 lower_reg_address, | 59 | u8 lower_reg_address, |
67 | u16 value) | 60 | u16 value) |
68 | { | 61 | { |
69 | int ret; | 62 | int ret; |
70 | struct spi_message msg; | 63 | struct spi_message msg; |
71 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
72 | struct adis16203_state *st = iio_dev_get_devdata(indio_dev); | 64 | struct adis16203_state *st = iio_dev_get_devdata(indio_dev); |
73 | struct spi_transfer xfers[] = { | 65 | struct spi_transfer xfers[] = { |
74 | { | 66 | { |
@@ -80,7 +72,6 @@ static int adis16203_spi_write_reg_16(struct device *dev, | |||
80 | .tx_buf = st->tx + 2, | 72 | .tx_buf = st->tx + 2, |
81 | .bits_per_word = 8, | 73 | .bits_per_word = 8, |
82 | .len = 2, | 74 | .len = 2, |
83 | .cs_change = 1, | ||
84 | }, | 75 | }, |
85 | }; | 76 | }; |
86 | 77 | ||
@@ -101,17 +92,16 @@ static int adis16203_spi_write_reg_16(struct device *dev, | |||
101 | 92 | ||
102 | /** | 93 | /** |
103 | * adis16203_spi_read_reg_16() - read 2 bytes from a 16-bit register | 94 | * adis16203_spi_read_reg_16() - read 2 bytes from a 16-bit register |
104 | * @dev: device associated with child of actual device (iio_dev or iio_trig) | 95 | * @indio_dev: iio device associated with child of actual device |
105 | * @reg_address: the address of the lower of the two registers. Second register | 96 | * @reg_address: the address of the lower of the two registers. Second register |
106 | * is assumed to have address one greater. | 97 | * is assumed to have address one greater. |
107 | * @val: somewhere to pass back the value read | 98 | * @val: somewhere to pass back the value read |
108 | **/ | 99 | **/ |
109 | static int adis16203_spi_read_reg_16(struct device *dev, | 100 | static int adis16203_spi_read_reg_16(struct iio_dev *indio_dev, |
110 | u8 lower_reg_address, | 101 | u8 lower_reg_address, |
111 | u16 *val) | 102 | u16 *val) |
112 | { | 103 | { |
113 | struct spi_message msg; | 104 | struct spi_message msg; |
114 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
115 | struct adis16203_state *st = iio_dev_get_devdata(indio_dev); | 105 | struct adis16203_state *st = iio_dev_get_devdata(indio_dev); |
116 | int ret; | 106 | int ret; |
117 | struct spi_transfer xfers[] = { | 107 | struct spi_transfer xfers[] = { |
@@ -125,7 +115,6 @@ static int adis16203_spi_read_reg_16(struct device *dev, | |||
125 | .rx_buf = st->rx, | 115 | .rx_buf = st->rx, |
126 | .bits_per_word = 8, | 116 | .bits_per_word = 8, |
127 | .len = 2, | 117 | .len = 2, |
128 | .cs_change = 1, | ||
129 | .delay_usecs = 20, | 118 | .delay_usecs = 20, |
130 | }, | 119 | }, |
131 | }; | 120 | }; |
@@ -150,101 +139,43 @@ error_ret: | |||
150 | return ret; | 139 | return ret; |
151 | } | 140 | } |
152 | 141 | ||
153 | static ssize_t adis16203_read_12bit_unsigned(struct device *dev, | 142 | static int adis16203_check_status(struct iio_dev *indio_dev) |
154 | struct device_attribute *attr, | ||
155 | char *buf) | ||
156 | { | 143 | { |
144 | u16 status; | ||
157 | int ret; | 145 | int ret; |
158 | u16 val = 0; | ||
159 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
160 | |||
161 | ret = adis16203_spi_read_reg_16(dev, this_attr->address, &val); | ||
162 | if (ret) | ||
163 | return ret; | ||
164 | |||
165 | if (val & ADIS16203_ERROR_ACTIVE) | ||
166 | adis16203_check_status(dev); | ||
167 | 146 | ||
168 | return sprintf(buf, "%u\n", val & 0x0FFF); | 147 | ret = adis16203_spi_read_reg_16(indio_dev, |
169 | } | 148 | ADIS16203_DIAG_STAT, |
170 | 149 | &status); | |
171 | static ssize_t adis16203_read_temp(struct device *dev, | 150 | if (ret < 0) { |
172 | struct device_attribute *attr, | 151 | dev_err(&indio_dev->dev, "Reading status failed\n"); |
173 | char *buf) | ||
174 | { | ||
175 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
176 | ssize_t ret; | ||
177 | u16 val; | ||
178 | |||
179 | /* Take the iio_dev status lock */ | ||
180 | mutex_lock(&indio_dev->mlock); | ||
181 | |||
182 | ret = adis16203_spi_read_reg_16(dev, ADIS16203_TEMP_OUT, (u16 *)&val); | ||
183 | if (ret) | ||
184 | goto error_ret; | 152 | goto error_ret; |
185 | |||
186 | if (val & ADIS16203_ERROR_ACTIVE) | ||
187 | adis16203_check_status(dev); | ||
188 | |||
189 | val &= 0xFFF; | ||
190 | ret = sprintf(buf, "%d\n", val); | ||
191 | |||
192 | error_ret: | ||
193 | mutex_unlock(&indio_dev->mlock); | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static ssize_t adis16203_read_14bit_signed(struct device *dev, | ||
198 | struct device_attribute *attr, | ||
199 | char *buf) | ||
200 | { | ||
201 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
202 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
203 | s16 val = 0; | ||
204 | ssize_t ret; | ||
205 | |||
206 | mutex_lock(&indio_dev->mlock); | ||
207 | |||
208 | ret = adis16203_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); | ||
209 | if (!ret) { | ||
210 | if (val & ADIS16203_ERROR_ACTIVE) | ||
211 | adis16203_check_status(dev); | ||
212 | |||
213 | val = ((s16)(val << 2) >> 2); | ||
214 | ret = sprintf(buf, "%d\n", val); | ||
215 | } | 153 | } |
154 | ret = status & 0x1F; | ||
216 | 155 | ||
217 | mutex_unlock(&indio_dev->mlock); | 156 | if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL) |
218 | 157 | dev_err(&indio_dev->dev, "Self test failure\n"); | |
219 | return ret; | 158 | if (status & ADIS16203_DIAG_STAT_SPI_FAIL) |
220 | } | 159 | dev_err(&indio_dev->dev, "SPI failure\n"); |
221 | 160 | if (status & ADIS16203_DIAG_STAT_FLASH_UPT) | |
222 | static ssize_t adis16203_write_16bit(struct device *dev, | 161 | dev_err(&indio_dev->dev, "Flash update failed\n"); |
223 | struct device_attribute *attr, | 162 | if (status & ADIS16203_DIAG_STAT_POWER_HIGH) |
224 | const char *buf, | 163 | dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); |
225 | size_t len) | 164 | if (status & ADIS16203_DIAG_STAT_POWER_LOW) |
226 | { | 165 | dev_err(&indio_dev->dev, "Power supply below 3.15V\n"); |
227 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | ||
228 | int ret; | ||
229 | long val; | ||
230 | |||
231 | ret = strict_strtol(buf, 10, &val); | ||
232 | if (ret) | ||
233 | goto error_ret; | ||
234 | ret = adis16203_spi_write_reg_16(dev, this_attr->address, val); | ||
235 | 166 | ||
236 | error_ret: | 167 | error_ret: |
237 | return ret ? ret : len; | 168 | return ret; |
238 | } | 169 | } |
239 | 170 | ||
240 | static int adis16203_reset(struct device *dev) | 171 | static int adis16203_reset(struct iio_dev *indio_dev) |
241 | { | 172 | { |
242 | int ret; | 173 | int ret; |
243 | ret = adis16203_spi_write_reg_8(dev, | 174 | ret = adis16203_spi_write_reg_8(indio_dev, |
244 | ADIS16203_GLOB_CMD, | 175 | ADIS16203_GLOB_CMD, |
245 | ADIS16203_GLOB_CMD_SW_RESET); | 176 | ADIS16203_GLOB_CMD_SW_RESET); |
246 | if (ret) | 177 | if (ret) |
247 | dev_err(dev, "problem resetting device"); | 178 | dev_err(&indio_dev->dev, "problem resetting device"); |
248 | 179 | ||
249 | return ret; | 180 | return ret; |
250 | } | 181 | } |
@@ -253,23 +184,24 @@ static ssize_t adis16203_write_reset(struct device *dev, | |||
253 | struct device_attribute *attr, | 184 | struct device_attribute *attr, |
254 | const char *buf, size_t len) | 185 | const char *buf, size_t len) |
255 | { | 186 | { |
187 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
256 | if (len < 1) | 188 | if (len < 1) |
257 | return -EINVAL; | 189 | return -EINVAL; |
258 | switch (buf[0]) { | 190 | switch (buf[0]) { |
259 | case '1': | 191 | case '1': |
260 | case 'y': | 192 | case 'y': |
261 | case 'Y': | 193 | case 'Y': |
262 | return adis16203_reset(dev); | 194 | return adis16203_reset(indio_dev); |
263 | } | 195 | } |
264 | return -EINVAL; | 196 | return -EINVAL; |
265 | } | 197 | } |
266 | 198 | ||
267 | int adis16203_set_irq(struct device *dev, bool enable) | 199 | int adis16203_set_irq(struct iio_dev *indio_dev, bool enable) |
268 | { | 200 | { |
269 | int ret = 0; | 201 | int ret = 0; |
270 | u16 msc; | 202 | u16 msc; |
271 | 203 | ||
272 | ret = adis16203_spi_read_reg_16(dev, ADIS16203_MSC_CTRL, &msc); | 204 | ret = adis16203_spi_read_reg_16(indio_dev, ADIS16203_MSC_CTRL, &msc); |
273 | if (ret) | 205 | if (ret) |
274 | goto error_ret; | 206 | goto error_ret; |
275 | 207 | ||
@@ -280,131 +212,195 @@ int adis16203_set_irq(struct device *dev, bool enable) | |||
280 | else | 212 | else |
281 | msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_EN; | 213 | msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_EN; |
282 | 214 | ||
283 | ret = adis16203_spi_write_reg_16(dev, ADIS16203_MSC_CTRL, msc); | 215 | ret = adis16203_spi_write_reg_16(indio_dev, ADIS16203_MSC_CTRL, msc); |
284 | |||
285 | error_ret: | ||
286 | return ret; | ||
287 | } | ||
288 | |||
289 | static int adis16203_check_status(struct device *dev) | ||
290 | { | ||
291 | u16 status; | ||
292 | int ret; | ||
293 | |||
294 | ret = adis16203_spi_read_reg_16(dev, ADIS16203_DIAG_STAT, &status); | ||
295 | if (ret < 0) { | ||
296 | dev_err(dev, "Reading status failed\n"); | ||
297 | goto error_ret; | ||
298 | } | ||
299 | ret = status & 0x1F; | ||
300 | |||
301 | if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL) | ||
302 | dev_err(dev, "Self test failure\n"); | ||
303 | if (status & ADIS16203_DIAG_STAT_SPI_FAIL) | ||
304 | dev_err(dev, "SPI failure\n"); | ||
305 | if (status & ADIS16203_DIAG_STAT_FLASH_UPT) | ||
306 | dev_err(dev, "Flash update failed\n"); | ||
307 | if (status & ADIS16203_DIAG_STAT_POWER_HIGH) | ||
308 | dev_err(dev, "Power supply above 3.625V\n"); | ||
309 | if (status & ADIS16203_DIAG_STAT_POWER_LOW) | ||
310 | dev_err(dev, "Power supply below 3.15V\n"); | ||
311 | 216 | ||
312 | error_ret: | 217 | error_ret: |
313 | return ret; | 218 | return ret; |
314 | } | 219 | } |
315 | 220 | ||
316 | static int adis16203_self_test(struct device *dev) | 221 | static int adis16203_self_test(struct iio_dev *indio_dev) |
317 | { | 222 | { |
318 | int ret; | 223 | int ret; |
319 | ret = adis16203_spi_write_reg_16(dev, | 224 | ret = adis16203_spi_write_reg_16(indio_dev, |
320 | ADIS16203_MSC_CTRL, | 225 | ADIS16203_MSC_CTRL, |
321 | ADIS16203_MSC_CTRL_SELF_TEST_EN); | 226 | ADIS16203_MSC_CTRL_SELF_TEST_EN); |
322 | if (ret) { | 227 | if (ret) { |
323 | dev_err(dev, "problem starting self test"); | 228 | dev_err(&indio_dev->dev, "problem starting self test"); |
324 | goto err_ret; | 229 | goto err_ret; |
325 | } | 230 | } |
326 | 231 | ||
327 | adis16203_check_status(dev); | 232 | adis16203_check_status(indio_dev); |
328 | 233 | ||
329 | err_ret: | 234 | err_ret: |
330 | return ret; | 235 | return ret; |
331 | } | 236 | } |
332 | 237 | ||
333 | static int adis16203_initial_setup(struct adis16203_state *st) | 238 | static int adis16203_initial_setup(struct iio_dev *indio_dev) |
334 | { | 239 | { |
335 | int ret; | 240 | int ret; |
336 | struct device *dev = &st->indio_dev->dev; | ||
337 | 241 | ||
338 | /* Disable IRQ */ | 242 | /* Disable IRQ */ |
339 | ret = adis16203_set_irq(dev, false); | 243 | ret = adis16203_set_irq(indio_dev, false); |
340 | if (ret) { | 244 | if (ret) { |
341 | dev_err(dev, "disable irq failed"); | 245 | dev_err(&indio_dev->dev, "disable irq failed"); |
342 | goto err_ret; | 246 | goto err_ret; |
343 | } | 247 | } |
344 | 248 | ||
345 | /* Do self test */ | 249 | /* Do self test */ |
346 | ret = adis16203_self_test(dev); | 250 | ret = adis16203_self_test(indio_dev); |
347 | if (ret) { | 251 | if (ret) { |
348 | dev_err(dev, "self test failure"); | 252 | dev_err(&indio_dev->dev, "self test failure"); |
349 | goto err_ret; | 253 | goto err_ret; |
350 | } | 254 | } |
351 | 255 | ||
352 | /* Read status register to check the result */ | 256 | /* Read status register to check the result */ |
353 | ret = adis16203_check_status(dev); | 257 | ret = adis16203_check_status(indio_dev); |
354 | if (ret) { | 258 | if (ret) { |
355 | adis16203_reset(dev); | 259 | adis16203_reset(indio_dev); |
356 | dev_err(dev, "device not playing ball -> reset"); | 260 | dev_err(&indio_dev->dev, "device not playing ball -> reset"); |
357 | msleep(ADIS16203_STARTUP_DELAY); | 261 | msleep(ADIS16203_STARTUP_DELAY); |
358 | ret = adis16203_check_status(dev); | 262 | ret = adis16203_check_status(indio_dev); |
359 | if (ret) { | 263 | if (ret) { |
360 | dev_err(dev, "giving up"); | 264 | dev_err(&indio_dev->dev, "giving up"); |
361 | goto err_ret; | 265 | goto err_ret; |
362 | } | 266 | } |
363 | } | 267 | } |
364 | 268 | ||
365 | printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", | ||
366 | st->us->chip_select, st->us->irq); | ||
367 | |||
368 | err_ret: | 269 | err_ret: |
369 | return ret; | 270 | return ret; |
370 | } | 271 | } |
371 | 272 | ||
372 | static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16203_read_12bit_unsigned, | 273 | enum adis16203_chan { |
373 | ADIS16203_SUPPLY_OUT); | 274 | in_supply, |
374 | static IIO_CONST_ATTR(in0_supply_scale, "0.00122"); | 275 | in_aux, |
375 | static IIO_DEV_ATTR_IN_RAW(1, adis16203_read_12bit_unsigned, | 276 | incli_x, |
376 | ADIS16203_AUX_ADC); | 277 | incli_y, |
377 | static IIO_CONST_ATTR(in1_scale, "0.00061"); | 278 | temp, |
378 | 279 | }; | |
379 | static IIO_DEV_ATTR_INCLI_X(adis16203_read_14bit_signed, | 280 | |
380 | ADIS16203_XINCL_OUT); | 281 | static u8 adis16203_addresses[5][2] = { |
381 | static IIO_DEV_ATTR_INCLI_Y(adis16203_read_14bit_signed, | 282 | [in_supply] = { ADIS16203_SUPPLY_OUT }, |
382 | ADIS16203_YINCL_OUT); | 283 | [in_aux] = { ADIS16203_AUX_ADC }, |
383 | static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO, | 284 | [incli_x] = { ADIS16203_XINCL_OUT, ADIS16203_INCL_NULL}, |
384 | adis16203_read_14bit_signed, | 285 | [incli_y] = { ADIS16203_YINCL_OUT }, |
385 | adis16203_write_16bit, | 286 | [temp] = { ADIS16203_TEMP_OUT } |
386 | ADIS16203_INCL_NULL); | 287 | }; |
387 | static IIO_CONST_ATTR(incli_scale, "0.025"); | 288 | |
388 | 289 | static int adis16203_write_raw(struct iio_dev *indio_dev, | |
389 | static IIO_DEV_ATTR_TEMP_RAW(adis16203_read_temp); | 290 | struct iio_chan_spec const *chan, |
390 | static IIO_CONST_ATTR(temp_offset, "25"); | 291 | int val, |
391 | static IIO_CONST_ATTR(temp_scale, "-0.47"); | 292 | int val2, |
293 | long mask) | ||
294 | { | ||
295 | /* currently only one writable parameter which keeps this simple */ | ||
296 | u8 addr = adis16203_addresses[chan->address][1]; | ||
297 | return adis16203_spi_write_reg_16(indio_dev, addr, val & 0x3FFF); | ||
298 | } | ||
299 | |||
300 | static int adis16203_read_raw(struct iio_dev *indio_dev, | ||
301 | struct iio_chan_spec const *chan, | ||
302 | int *val, int *val2, | ||
303 | long mask) | ||
304 | { | ||
305 | int ret; | ||
306 | int bits; | ||
307 | u8 addr; | ||
308 | s16 val16; | ||
309 | switch (mask) { | ||
310 | case 0: | ||
311 | mutex_lock(&indio_dev->mlock); | ||
312 | addr = adis16203_addresses[chan->address][0]; | ||
313 | ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16); | ||
314 | if (ret) | ||
315 | return ret; | ||
316 | |||
317 | if (val16 & ADIS16203_ERROR_ACTIVE) { | ||
318 | ret = adis16203_check_status(indio_dev); | ||
319 | if (ret) | ||
320 | return ret; | ||
321 | } | ||
322 | val16 = val16 & ((1 << chan->scan_type.realbits) - 1); | ||
323 | if (chan->scan_type.sign == 's') | ||
324 | val16 = (s16)(val16 << | ||
325 | (16 - chan->scan_type.realbits)) >> | ||
326 | (16 - chan->scan_type.realbits); | ||
327 | *val = val16; | ||
328 | mutex_unlock(&indio_dev->mlock); | ||
329 | return IIO_VAL_INT; | ||
330 | case (1 << IIO_CHAN_INFO_SCALE_SEPARATE): | ||
331 | case (1 << IIO_CHAN_INFO_SCALE_SHARED): | ||
332 | switch (chan->type) { | ||
333 | case IIO_IN: | ||
334 | *val = 0; | ||
335 | if (chan->channel == 0) | ||
336 | *val2 = 1220; | ||
337 | else | ||
338 | *val2 = 610; | ||
339 | return IIO_VAL_INT_PLUS_MICRO; | ||
340 | case IIO_TEMP: | ||
341 | *val = 0; | ||
342 | *val2 = -470000; | ||
343 | return IIO_VAL_INT_PLUS_MICRO; | ||
344 | case IIO_INCLI: | ||
345 | *val = 0; | ||
346 | *val2 = 25000; | ||
347 | return IIO_VAL_INT_PLUS_MICRO; | ||
348 | default: | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE): | ||
352 | *val = 25; | ||
353 | return IIO_VAL_INT; | ||
354 | case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE): | ||
355 | bits = 14; | ||
356 | mutex_lock(&indio_dev->mlock); | ||
357 | addr = adis16203_addresses[chan->address][1]; | ||
358 | ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16); | ||
359 | if (ret) { | ||
360 | mutex_unlock(&indio_dev->mlock); | ||
361 | return ret; | ||
362 | } | ||
363 | val16 &= (1 << bits) - 1; | ||
364 | val16 = (s16)(val16 << (16 - bits)) >> (16 - bits); | ||
365 | *val = val16; | ||
366 | mutex_unlock(&indio_dev->mlock); | ||
367 | return IIO_VAL_INT; | ||
368 | default: | ||
369 | return -EINVAL; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | static struct iio_chan_spec adis16203_channels[] = { | ||
374 | IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0, | ||
375 | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), | ||
376 | in_supply, ADIS16203_SCAN_SUPPLY, | ||
377 | IIO_ST('u', 12, 16, 0), 0), | ||
378 | IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, | ||
379 | (1 << IIO_CHAN_INFO_SCALE_SEPARATE), | ||
380 | in_aux, ADIS16203_SCAN_AUX_ADC, | ||
381 | IIO_ST('u', 12, 16, 0), 0), | ||
382 | IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X, | ||
383 | (1 << IIO_CHAN_INFO_SCALE_SHARED) | | ||
384 | (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE), | ||
385 | incli_x, ADIS16203_SCAN_INCLI_X, | ||
386 | IIO_ST('s', 14, 16, 0), 0), | ||
387 | /* Fixme: Not what it appears to be - see data sheet */ | ||
388 | IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y, | ||
389 | (1 << IIO_CHAN_INFO_SCALE_SHARED), | ||
390 | incli_y, ADIS16203_SCAN_INCLI_Y, | ||
391 | IIO_ST('s', 14, 16, 0), 0), | ||
392 | IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, | ||
393 | (1 << IIO_CHAN_INFO_SCALE_SEPARATE) | | ||
394 | (1 << IIO_CHAN_INFO_OFFSET_SEPARATE), | ||
395 | temp, ADIS16203_SCAN_TEMP, | ||
396 | IIO_ST('u', 12, 16, 0), 0), | ||
397 | IIO_CHAN_SOFT_TIMESTAMP(5), | ||
398 | }; | ||
392 | 399 | ||
393 | static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16203_write_reset, 0); | 400 | static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16203_write_reset, 0); |
394 | 401 | ||
395 | static struct attribute *adis16203_attributes[] = { | 402 | static struct attribute *adis16203_attributes[] = { |
396 | &iio_dev_attr_in0_supply_raw.dev_attr.attr, | ||
397 | &iio_const_attr_in0_supply_scale.dev_attr.attr, | ||
398 | &iio_dev_attr_temp_raw.dev_attr.attr, | ||
399 | &iio_const_attr_temp_offset.dev_attr.attr, | ||
400 | &iio_const_attr_temp_scale.dev_attr.attr, | ||
401 | &iio_dev_attr_reset.dev_attr.attr, | 403 | &iio_dev_attr_reset.dev_attr.attr, |
402 | &iio_dev_attr_in1_raw.dev_attr.attr, | ||
403 | &iio_const_attr_in1_scale.dev_attr.attr, | ||
404 | &iio_dev_attr_incli_x_raw.dev_attr.attr, | ||
405 | &iio_dev_attr_incli_y_raw.dev_attr.attr, | ||
406 | &iio_dev_attr_incli_x_offset.dev_attr.attr, | ||
407 | &iio_const_attr_incli_scale.dev_attr.attr, | ||
408 | NULL | 404 | NULL |
409 | }; | 405 | }; |
410 | 406 | ||
@@ -445,6 +441,10 @@ static int __devinit adis16203_probe(struct spi_device *spi) | |||
445 | st->indio_dev->name = spi->dev.driver->name; | 441 | st->indio_dev->name = spi->dev.driver->name; |
446 | st->indio_dev->dev.parent = &spi->dev; | 442 | st->indio_dev->dev.parent = &spi->dev; |
447 | st->indio_dev->attrs = &adis16203_attribute_group; | 443 | st->indio_dev->attrs = &adis16203_attribute_group; |
444 | st->indio_dev->channels = adis16203_channels; | ||
445 | st->indio_dev->num_channels = ARRAY_SIZE(adis16203_channels); | ||
446 | st->indio_dev->read_raw = &adis16203_read_raw; | ||
447 | st->indio_dev->write_raw = &adis16203_write_raw; | ||
448 | st->indio_dev->dev_data = (void *)(st); | 448 | st->indio_dev->dev_data = (void *)(st); |
449 | st->indio_dev->driver_module = THIS_MODULE; | 449 | st->indio_dev->driver_module = THIS_MODULE; |
450 | st->indio_dev->modes = INDIO_DIRECT_MODE; | 450 | st->indio_dev->modes = INDIO_DIRECT_MODE; |
@@ -458,7 +458,9 @@ static int __devinit adis16203_probe(struct spi_device *spi) | |||
458 | goto error_unreg_ring_funcs; | 458 | goto error_unreg_ring_funcs; |
459 | regdone = 1; | 459 | regdone = 1; |
460 | 460 | ||
461 | ret = adis16203_initialize_ring(st->indio_dev->ring); | 461 | ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, |
462 | adis16203_channels, | ||
463 | ARRAY_SIZE(adis16203_channels)); | ||
462 | if (ret) { | 464 | if (ret) { |
463 | printk(KERN_ERR "failed to initialize the ring\n"); | 465 | printk(KERN_ERR "failed to initialize the ring\n"); |
464 | goto error_unreg_ring_funcs; | 466 | goto error_unreg_ring_funcs; |
@@ -471,7 +473,7 @@ static int __devinit adis16203_probe(struct spi_device *spi) | |||
471 | } | 473 | } |
472 | 474 | ||
473 | /* Get the device into a sane initial state */ | 475 | /* Get the device into a sane initial state */ |
474 | ret = adis16203_initial_setup(st); | 476 | ret = adis16203_initial_setup(st->indio_dev); |
475 | if (ret) | 477 | if (ret) |
476 | goto error_remove_trigger; | 478 | goto error_remove_trigger; |
477 | return 0; | 479 | return 0; |
@@ -479,7 +481,7 @@ static int __devinit adis16203_probe(struct spi_device *spi) | |||
479 | error_remove_trigger: | 481 | error_remove_trigger: |
480 | adis16203_remove_trigger(st->indio_dev); | 482 | adis16203_remove_trigger(st->indio_dev); |
481 | error_uninitialize_ring: | 483 | error_uninitialize_ring: |
482 | adis16203_uninitialize_ring(st->indio_dev->ring); | 484 | iio_ring_buffer_unregister(st->indio_dev->ring); |
483 | error_unreg_ring_funcs: | 485 | error_unreg_ring_funcs: |
484 | adis16203_unconfigure_ring(st->indio_dev); | 486 | adis16203_unconfigure_ring(st->indio_dev); |
485 | error_free_dev: | 487 | error_free_dev: |
@@ -502,10 +504,8 @@ static int adis16203_remove(struct spi_device *spi) | |||
502 | struct adis16203_state *st = spi_get_drvdata(spi); | 504 | struct adis16203_state *st = spi_get_drvdata(spi); |
503 | struct iio_dev *indio_dev = st->indio_dev; | 505 | struct iio_dev *indio_dev = st->indio_dev; |
504 | 506 | ||
505 | flush_scheduled_work(); | ||
506 | |||
507 | adis16203_remove_trigger(indio_dev); | 507 | adis16203_remove_trigger(indio_dev); |
508 | adis16203_uninitialize_ring(indio_dev->ring); | 508 | iio_ring_buffer_unregister(indio_dev->ring); |
509 | iio_device_unregister(indio_dev); | 509 | iio_device_unregister(indio_dev); |
510 | adis16203_unconfigure_ring(indio_dev); | 510 | adis16203_unconfigure_ring(indio_dev); |
511 | kfree(st->tx); | 511 | kfree(st->tx); |