2 * Common library for ADIS16XXX devices
4 * Copyright 2012 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
7 * Licensed under the GPL-2 or later.
10 #include <linux/delay.h>
11 #include <linux/mutex.h>
12 #include <linux/device.h>
13 #include <linux/kernel.h>
14 #include <linux/spi/spi.h>
15 #include <linux/slab.h>
16 #include <linux/sysfs.h>
17 #include <linux/module.h>
18 #include <asm/unaligned.h>
20 #include <linux/iio/iio.h>
21 #include <linux/iio/sysfs.h>
22 #include <linux/iio/buffer.h>
23 #include <linux/iio/imu/adis.h>
25 #define ADIS_MSC_CTRL_DATA_RDY_EN BIT(2)
26 #define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH BIT(1)
27 #define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0)
28 #define ADIS_GLOB_CMD_SW_RESET BIT(7)
30 int adis_write_reg(struct adis
*adis
, unsigned int reg
,
31 unsigned int value
, unsigned int size
)
33 unsigned int page
= reg
/ ADIS_PAGE_SIZE
;
35 struct spi_message msg
;
36 struct spi_transfer xfers
[] = {
42 .delay_usecs
= adis
->data
->write_delay
,
44 .tx_buf
= adis
->tx
+ 2,
48 .delay_usecs
= adis
->data
->write_delay
,
50 .tx_buf
= adis
->tx
+ 4,
54 .delay_usecs
= adis
->data
->write_delay
,
56 .tx_buf
= adis
->tx
+ 6,
59 .delay_usecs
= adis
->data
->write_delay
,
61 .tx_buf
= adis
->tx
+ 8,
64 .delay_usecs
= adis
->data
->write_delay
,
68 mutex_lock(&adis
->txrx_lock
);
70 spi_message_init(&msg
);
72 if (adis
->current_page
!= page
) {
73 adis
->tx
[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID
);
75 spi_message_add_tail(&xfers
[0], &msg
);
80 adis
->tx
[8] = ADIS_WRITE_REG(reg
+ 3);
81 adis
->tx
[9] = (value
>> 24) & 0xff;
82 adis
->tx
[6] = ADIS_WRITE_REG(reg
+ 2);
83 adis
->tx
[7] = (value
>> 16) & 0xff;
86 adis
->tx
[4] = ADIS_WRITE_REG(reg
+ 1);
87 adis
->tx
[5] = (value
>> 8) & 0xff;
90 adis
->tx
[2] = ADIS_WRITE_REG(reg
);
91 adis
->tx
[3] = value
& 0xff;
98 xfers
[size
].cs_change
= 0;
100 for (i
= 1; i
<= size
; i
++)
101 spi_message_add_tail(&xfers
[i
], &msg
);
103 ret
= spi_sync(adis
->spi
, &msg
);
105 dev_err(&adis
->spi
->dev
, "Failed to write register 0x%02X: %d\n",
108 adis
->current_page
= page
;
112 mutex_unlock(&adis
->txrx_lock
);
116 EXPORT_SYMBOL_GPL(adis_write_reg
);
119 * adis_read_reg() - read 2 bytes from a 16-bit register
120 * @adis: The adis device
121 * @reg: The address of the lower of the two registers
122 * @val: The value read back from the device
124 int adis_read_reg(struct adis
*adis
, unsigned int reg
,
125 unsigned int *val
, unsigned int size
)
127 unsigned int page
= reg
/ ADIS_PAGE_SIZE
;
128 struct spi_message msg
;
130 struct spi_transfer xfers
[] = {
136 .delay_usecs
= adis
->data
->write_delay
,
138 .tx_buf
= adis
->tx
+ 2,
142 .delay_usecs
= adis
->data
->read_delay
,
144 .tx_buf
= adis
->tx
+ 4,
149 .delay_usecs
= adis
->data
->read_delay
,
151 .rx_buf
= adis
->rx
+ 2,
154 .delay_usecs
= adis
->data
->read_delay
,
158 mutex_lock(&adis
->txrx_lock
);
159 spi_message_init(&msg
);
161 if (adis
->current_page
!= page
) {
162 adis
->tx
[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID
);
164 spi_message_add_tail(&xfers
[0], &msg
);
169 adis
->tx
[2] = ADIS_READ_REG(reg
+ 2);
171 spi_message_add_tail(&xfers
[1], &msg
);
174 adis
->tx
[4] = ADIS_READ_REG(reg
);
176 spi_message_add_tail(&xfers
[2], &msg
);
177 spi_message_add_tail(&xfers
[3], &msg
);
184 ret
= spi_sync(adis
->spi
, &msg
);
186 dev_err(&adis
->spi
->dev
, "Failed to read register 0x%02X: %d\n",
190 adis
->current_page
= page
;
195 *val
= get_unaligned_be32(adis
->rx
);
198 *val
= get_unaligned_be16(adis
->rx
+ 2);
203 mutex_unlock(&adis
->txrx_lock
);
207 EXPORT_SYMBOL_GPL(adis_read_reg
);
209 #ifdef CONFIG_DEBUG_FS
211 int adis_debugfs_reg_access(struct iio_dev
*indio_dev
,
212 unsigned int reg
, unsigned int writeval
, unsigned int *readval
)
214 struct adis
*adis
= iio_device_get_drvdata(indio_dev
);
220 ret
= adis_read_reg_16(adis
, reg
, &val16
);
225 return adis_write_reg_16(adis
, reg
, writeval
);
228 EXPORT_SYMBOL(adis_debugfs_reg_access
);
233 * adis_enable_irq() - Enable or disable data ready IRQ
234 * @adis: The adis device
235 * @enable: Whether to enable the IRQ
237 * Returns 0 on success, negative error code otherwise
239 int adis_enable_irq(struct adis
*adis
, bool enable
)
244 if (adis
->data
->enable_irq
)
245 return adis
->data
->enable_irq(adis
, enable
);
247 ret
= adis_read_reg_16(adis
, adis
->data
->msc_ctrl_reg
, &msc
);
251 msc
|= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH
;
252 msc
&= ~ADIS_MSC_CTRL_DATA_RDY_DIO2
;
254 msc
|= ADIS_MSC_CTRL_DATA_RDY_EN
;
256 msc
&= ~ADIS_MSC_CTRL_DATA_RDY_EN
;
258 ret
= adis_write_reg_16(adis
, adis
->data
->msc_ctrl_reg
, msc
);
263 EXPORT_SYMBOL(adis_enable_irq
);
266 * adis_check_status() - Check the device for error conditions
267 * @adis: The adis device
269 * Returns 0 on success, a negative error code otherwise
271 int adis_check_status(struct adis
*adis
)
277 ret
= adis_read_reg_16(adis
, adis
->data
->diag_stat_reg
, &status
);
281 status
&= adis
->data
->status_error_mask
;
286 for (i
= 0; i
< 16; ++i
) {
287 if (status
& BIT(i
)) {
288 dev_err(&adis
->spi
->dev
, "%s.\n",
289 adis
->data
->status_error_msgs
[i
]);
295 EXPORT_SYMBOL_GPL(adis_check_status
);
298 * adis_reset() - Reset the device
299 * @adis: The adis device
301 * Returns 0 on success, a negative error code otherwise
303 int adis_reset(struct adis
*adis
)
307 ret
= adis_write_reg_8(adis
, adis
->data
->glob_cmd_reg
,
308 ADIS_GLOB_CMD_SW_RESET
);
310 dev_err(&adis
->spi
->dev
, "Failed to reset device: %d\n", ret
);
314 EXPORT_SYMBOL_GPL(adis_reset
);
316 static int adis_self_test(struct adis
*adis
)
320 ret
= adis_write_reg_16(adis
, adis
->data
->msc_ctrl_reg
,
321 adis
->data
->self_test_mask
);
323 dev_err(&adis
->spi
->dev
, "Failed to initiate self test: %d\n",
328 msleep(adis
->data
->startup_delay
);
330 ret
= adis_check_status(adis
);
332 if (adis
->data
->self_test_no_autoclear
)
333 adis_write_reg_16(adis
, adis
->data
->msc_ctrl_reg
, 0x00);
339 * adis_inital_startup() - Performs device self-test
340 * @adis: The adis device
342 * Returns 0 if the device is operational, a negative error code otherwise.
344 * This function should be called early on in the device initialization sequence
345 * to ensure that the device is in a sane and known state and that it is usable.
347 int adis_initial_startup(struct adis
*adis
)
351 ret
= adis_self_test(adis
);
353 dev_err(&adis
->spi
->dev
, "Self-test failed, trying reset.\n");
355 msleep(adis
->data
->startup_delay
);
356 ret
= adis_self_test(adis
);
358 dev_err(&adis
->spi
->dev
, "Second self-test failed, giving up.\n");
365 EXPORT_SYMBOL_GPL(adis_initial_startup
);
368 * adis_single_conversion() - Performs a single sample conversion
369 * @indio_dev: The IIO device
370 * @chan: The IIO channel
371 * @error_mask: Mask for the error bit
372 * @val: Result of the conversion
374 * Returns IIO_VAL_INT on success, a negative error code otherwise.
376 * The function performs a single conversion on a given channel and post
377 * processes the value accordingly to the channel spec. If a error_mask is given
378 * the function will check if the mask is set in the returned raw value. If it
379 * is set the function will perform a self-check. If the device does not report
380 * a error bit in the channels raw value set error_mask to 0.
382 int adis_single_conversion(struct iio_dev
*indio_dev
,
383 const struct iio_chan_spec
*chan
, unsigned int error_mask
, int *val
)
385 struct adis
*adis
= iio_device_get_drvdata(indio_dev
);
389 mutex_lock(&indio_dev
->mlock
);
391 ret
= adis_read_reg(adis
, chan
->address
, &uval
,
392 chan
->scan_type
.storagebits
/ 8);
396 if (uval
& error_mask
) {
397 ret
= adis_check_status(adis
);
402 if (chan
->scan_type
.sign
== 's')
403 *val
= sign_extend32(uval
, chan
->scan_type
.realbits
- 1);
405 *val
= uval
& ((1 << chan
->scan_type
.realbits
) - 1);
409 mutex_unlock(&indio_dev
->mlock
);
412 EXPORT_SYMBOL_GPL(adis_single_conversion
);
415 * adis_init() - Initialize adis device structure
416 * @adis: The adis device
417 * @indio_dev: The iio device
418 * @spi: The spi device
419 * @data: Chip specific data
421 * Returns 0 on success, a negative error code otherwise.
423 * This function must be called, before any other adis helper function may be
426 int adis_init(struct adis
*adis
, struct iio_dev
*indio_dev
,
427 struct spi_device
*spi
, const struct adis_data
*data
)
429 mutex_init(&adis
->txrx_lock
);
432 iio_device_set_drvdata(indio_dev
, adis
);
434 if (data
->has_paging
) {
435 /* Need to set the page before first read/write */
436 adis
->current_page
= -1;
438 /* Page will always be 0 */
439 adis
->current_page
= 0;
442 return adis_enable_irq(adis
, false);
444 EXPORT_SYMBOL_GPL(adis_init
);
446 MODULE_LICENSE("GPL");
447 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
448 MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");