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)
31 * adis_write_reg_8() - Write single byte to a register
32 * @adis: The adis device
33 * @reg: The address of the register to be written
34 * @val: The value to write
36 int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val)
40 mutex_lock(&adis->txrx_lock);
41 adis->tx[0] = ADIS_WRITE_REG(reg);
44 ret = spi_write(adis->spi, adis->tx, 2);
45 mutex_unlock(&adis->txrx_lock);
49 EXPORT_SYMBOL_GPL(adis_write_reg_8);
52 * adis_write_reg_16() - Write 2 bytes to a pair of registers
53 * @adis: The adis device
54 * @reg: The address of the lower of the two registers
55 * @val: Value to be written
57 int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t value)
60 struct spi_message msg;
61 struct spi_transfer xfers[] = {
67 .delay_usecs = adis->data->write_delay,
69 .tx_buf = adis->tx + 2,
72 .delay_usecs = adis->data->write_delay,
76 mutex_lock(&adis->txrx_lock);
77 adis->tx[0] = ADIS_WRITE_REG(reg);
78 adis->tx[1] = value & 0xff;
79 adis->tx[2] = ADIS_WRITE_REG(reg + 1);
80 adis->tx[3] = (value >> 8) & 0xff;
82 spi_message_init(&msg);
83 spi_message_add_tail(&xfers[0], &msg);
84 spi_message_add_tail(&xfers[1], &msg);
85 ret = spi_sync(adis->spi, &msg);
86 mutex_unlock(&adis->txrx_lock);
90 EXPORT_SYMBOL_GPL(adis_write_reg_16);
93 * adis_read_reg_16() - read 2 bytes from a 16-bit register
94 * @adis: The adis device
95 * @reg: The address of the lower of the two registers
96 * @val: The value read back from the device
98 int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val)
100 struct spi_message msg;
102 struct spi_transfer xfers[] = {
108 .delay_usecs = adis->data->read_delay,
113 .delay_usecs = adis->data->read_delay,
117 mutex_lock(&adis->txrx_lock);
118 adis->tx[0] = ADIS_READ_REG(reg);
121 spi_message_init(&msg);
122 spi_message_add_tail(&xfers[0], &msg);
123 spi_message_add_tail(&xfers[1], &msg);
124 ret = spi_sync(adis->spi, &msg);
126 dev_err(&adis->spi->dev, "Failed to read 16 bit register 0x%02X: %d\n",
130 *val = get_unaligned_be16(adis->rx);
133 mutex_unlock(&adis->txrx_lock);
136 EXPORT_SYMBOL_GPL(adis_read_reg_16);
139 * adis_enable_irq() - Enable or disable data ready IRQ
140 * @adis: The adis device
141 * @enable: Whether to enable the IRQ
143 * Returns 0 on success, negative error code otherwise
145 int adis_enable_irq(struct adis *adis, bool enable)
150 ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
154 msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
155 msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
157 msc |= ADIS_MSC_CTRL_DATA_RDY_EN;
159 msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
161 ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
166 EXPORT_SYMBOL(adis_enable_irq);
169 * adis_check_status() - Check the device for error conditions
170 * @adis: The adis device
172 * Returns 0 on success, a negative error code otherwise
174 int adis_check_status(struct adis *adis)
180 ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
184 status &= adis->data->status_error_mask;
189 for (i = 0; i < 16; ++i) {
190 if (status & BIT(i)) {
191 dev_err(&adis->spi->dev, "%s.\n",
192 adis->data->status_error_msgs[i]);
198 EXPORT_SYMBOL_GPL(adis_check_status);
201 * adis_reset() - Reset the device
202 * @adis: The adis device
204 * Returns 0 on success, a negative error code otherwise
206 int adis_reset(struct adis *adis)
210 ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg,
211 ADIS_GLOB_CMD_SW_RESET);
213 dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
217 EXPORT_SYMBOL_GPL(adis_reset);
219 static int adis_self_test(struct adis *adis)
223 ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
224 adis->data->self_test_mask);
226 dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
231 msleep(adis->data->startup_delay);
233 return adis_check_status(adis);
237 * adis_inital_startup() - Performs device self-test
238 * @adis: The adis device
240 * Returns 0 if the device is operational, a negative error code otherwise.
242 * This function should be called early on in the device initialization sequence
243 * to ensure that the device is in a sane and known state and that it is usable.
245 int adis_initial_startup(struct adis *adis)
249 ret = adis_self_test(adis);
251 dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n");
253 msleep(adis->data->startup_delay);
254 ret = adis_self_test(adis);
256 dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n");
263 EXPORT_SYMBOL_GPL(adis_initial_startup);
266 * adis_single_conversion() - Performs a single sample conversion
267 * @indio_dev: The IIO device
268 * @chan: The IIO channel
269 * @error_mask: Mask for the error bit
270 * @val: Result of the conversion
272 * Returns IIO_VAL_INT on success, a negative error code otherwise.
274 * The function performs a single conversion on a given channel and post
275 * processes the value accordingly to the channel spec. If a error_mask is given
276 * the function will check if the mask is set in the returned raw value. If it
277 * is set the function will perform a self-check. If the device does not report
278 * a error bit in the channels raw value set error_mask to 0.
280 int adis_single_conversion(struct iio_dev *indio_dev,
281 const struct iio_chan_spec *chan, unsigned int error_mask, int *val)
283 struct adis *adis = iio_device_get_drvdata(indio_dev);
287 mutex_lock(&indio_dev->mlock);
289 ret = adis_read_reg_16(adis, chan->address, &val16);
293 if (val16 & error_mask) {
294 ret = adis_check_status(adis);
299 if (chan->scan_type.sign == 's')
300 *val = sign_extend32(val16, chan->scan_type.realbits - 1);
302 *val = val16 & ((1 << chan->scan_type.realbits) - 1);
306 mutex_unlock(&indio_dev->mlock);
309 EXPORT_SYMBOL_GPL(adis_single_conversion);
312 * adis_init() - Initialize adis device structure
313 * @adis: The adis device
314 * @indio_dev: The iio device
315 * @spi: The spi device
316 * @data: Chip specific data
318 * Returns 0 on success, a negative error code otherwise.
320 * This function must be called, before any other adis helper function may be
323 int adis_init(struct adis *adis, struct iio_dev *indio_dev,
324 struct spi_device *spi, const struct adis_data *data)
326 mutex_init(&adis->txrx_lock);
329 iio_device_set_drvdata(indio_dev, adis);
331 return adis_enable_irq(adis, false);
333 EXPORT_SYMBOL_GPL(adis_init);
335 MODULE_LICENSE("GPL");
336 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
337 MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");