blob: 8259b774078f98babfdf0195c2a97042058ce960 [file] [log] [blame]
Lars-Peter Clausenccd2b522012-11-13 13:28:00 +00001/*
2 * Common library for ADIS16XXX devices
3 *
4 * Copyright 2012 Analog Devices Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Licensed under the GPL-2 or later.
8 */
9
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>
19
20#include <linux/iio/iio.h>
21#include <linux/iio/sysfs.h>
22#include <linux/iio/buffer.h>
Lars-Peter Clausenec04cb02012-11-13 13:28:00 +000023#include <linux/iio/imu/adis.h>
Lars-Peter Clausenccd2b522012-11-13 13:28:00 +000024
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)
29
30/**
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
35 */
36int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val)
37{
38 int ret;
39
40 mutex_lock(&adis->txrx_lock);
41 adis->tx[0] = ADIS_WRITE_REG(reg);
42 adis->tx[1] = val;
43
44 ret = spi_write(adis->spi, adis->tx, 2);
45 mutex_unlock(&adis->txrx_lock);
46
47 return ret;
48}
49EXPORT_SYMBOL_GPL(adis_write_reg_8);
50
51/**
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
56 */
57int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t value)
58{
59 int ret;
60 struct spi_message msg;
61 struct spi_transfer xfers[] = {
62 {
63 .tx_buf = adis->tx,
64 .bits_per_word = 8,
65 .len = 2,
66 .cs_change = 1,
67 .delay_usecs = adis->data->write_delay,
68 }, {
69 .tx_buf = adis->tx + 2,
70 .bits_per_word = 8,
71 .len = 2,
72 .delay_usecs = adis->data->write_delay,
73 },
74 };
75
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;
81
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);
87
88 return ret;
89}
90EXPORT_SYMBOL_GPL(adis_write_reg_16);
91
92/**
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
97 */
98int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val)
99{
100 struct spi_message msg;
101 int ret;
102 struct spi_transfer xfers[] = {
103 {
104 .tx_buf = adis->tx,
105 .bits_per_word = 8,
106 .len = 2,
107 .cs_change = 1,
108 .delay_usecs = adis->data->read_delay,
109 }, {
110 .rx_buf = adis->rx,
111 .bits_per_word = 8,
112 .len = 2,
113 .delay_usecs = adis->data->read_delay,
114 },
115 };
116
117 mutex_lock(&adis->txrx_lock);
118 adis->tx[0] = ADIS_READ_REG(reg);
119 adis->tx[1] = 0;
120
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);
125 if (ret) {
126 dev_err(&adis->spi->dev, "Failed to read 16 bit register 0x%02X: %d\n",
127 reg, ret);
128 goto error_ret;
129 }
130 *val = get_unaligned_be16(adis->rx);
131
132error_ret:
133 mutex_unlock(&adis->txrx_lock);
134 return ret;
135}
136EXPORT_SYMBOL_GPL(adis_read_reg_16);
137
138/**
139 * adis_enable_irq() - Enable or disable data ready IRQ
140 * @adis: The adis device
141 * @enable: Whether to enable the IRQ
142 *
143 * Returns 0 on success, negative error code otherwise
144 */
145int adis_enable_irq(struct adis *adis, bool enable)
146{
147 int ret = 0;
148 uint16_t msc;
149
150 ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
151 if (ret)
152 goto error_ret;
153
154 msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
155 msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
156 if (enable)
157 msc |= ADIS_MSC_CTRL_DATA_RDY_EN;
158 else
159 msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
160
161 ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
162
163error_ret:
164 return ret;
165}
166EXPORT_SYMBOL(adis_enable_irq);
167
168/**
169 * adis_check_status() - Check the device for error conditions
170 * @adis: The adis device
171 *
172 * Returns 0 on success, a negative error code otherwise
173 */
174int adis_check_status(struct adis *adis)
175{
176 uint16_t status;
177 int ret;
178 int i;
179
180 ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
181 if (ret < 0)
182 return ret;
183
184 status &= adis->data->status_error_mask;
185
186 if (status == 0)
187 return 0;
188
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]);
193 }
194 }
195
196 return -EIO;
197}
198EXPORT_SYMBOL_GPL(adis_check_status);
199
200/**
201 * adis_reset() - Reset the device
202 * @adis: The adis device
203 *
204 * Returns 0 on success, a negative error code otherwise
205 */
206int adis_reset(struct adis *adis)
207{
208 int ret;
209
210 ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg,
211 ADIS_GLOB_CMD_SW_RESET);
212 if (ret)
213 dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
214
215 return ret;
216}
217EXPORT_SYMBOL_GPL(adis_reset);
218
219static int adis_self_test(struct adis *adis)
220{
221 int ret;
222
223 ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
224 adis->data->self_test_mask);
225 if (ret) {
226 dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
227 ret);
228 return ret;
229 }
230
231 msleep(adis->data->startup_delay);
232
233 return adis_check_status(adis);
234}
235
236/**
237 * adis_inital_startup() - Performs device self-test
238 * @adis: The adis device
239 *
240 * Returns 0 if the device is operational, a negative error code otherwise.
241 *
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.
244 */
245int adis_initial_startup(struct adis *adis)
246{
247 int ret;
248
249 ret = adis_self_test(adis);
250 if (ret) {
251 dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n");
252 adis_reset(adis);
253 msleep(adis->data->startup_delay);
254 ret = adis_self_test(adis);
255 if (ret) {
256 dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n");
257 return ret;
258 }
259 }
260
261 return 0;
262}
263EXPORT_SYMBOL_GPL(adis_initial_startup);
264
265/**
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
271 *
272 * Returns IIO_VAL_INT on success, a negative error code otherwise.
273 *
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.
279 */
280int adis_single_conversion(struct iio_dev *indio_dev,
281 const struct iio_chan_spec *chan, unsigned int error_mask, int *val)
282{
283 struct adis *adis = iio_device_get_drvdata(indio_dev);
284 uint16_t val16;
285 int ret;
286
287 mutex_lock(&indio_dev->mlock);
288
289 ret = adis_read_reg_16(adis, chan->address, &val16);
290 if (ret)
291 goto err_unlock;
292
293 if (val16 & error_mask) {
294 ret = adis_check_status(adis);
295 if (ret)
296 goto err_unlock;
297 }
298
299 if (chan->scan_type.sign == 's')
300 *val = sign_extend32(val16, chan->scan_type.realbits - 1);
301 else
302 *val = val16 & ((1 << chan->scan_type.realbits) - 1);
303
304 ret = IIO_VAL_INT;
305err_unlock:
306 mutex_unlock(&indio_dev->mlock);
307 return ret;
308}
309EXPORT_SYMBOL_GPL(adis_single_conversion);
310
311/**
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
317 *
318 * Returns 0 on success, a negative error code otherwise.
319 *
320 * This function must be called, before any other adis helper function may be
321 * called.
322 */
323int adis_init(struct adis *adis, struct iio_dev *indio_dev,
324 struct spi_device *spi, const struct adis_data *data)
325{
326 mutex_init(&adis->txrx_lock);
327 adis->spi = spi;
328 adis->data = data;
329 iio_device_set_drvdata(indio_dev, adis);
330
331 return adis_enable_irq(adis, false);
332}
333EXPORT_SYMBOL_GPL(adis_init);
334
335MODULE_LICENSE("GPL");
336MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
337MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");