GNU Linux-libre 4.19.207-gnu1
[releases.git] / drivers / iio / imu / adis.c
1 /*
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>
23 #include <linux/iio/imu/adis.h>
24
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 int adis_write_reg(struct adis *adis, unsigned int reg,
31         unsigned int value, unsigned int size)
32 {
33         unsigned int page = reg / ADIS_PAGE_SIZE;
34         int ret, i;
35         struct spi_message msg;
36         struct spi_transfer xfers[] = {
37                 {
38                         .tx_buf = adis->tx,
39                         .bits_per_word = 8,
40                         .len = 2,
41                         .cs_change = 1,
42                         .delay_usecs = adis->data->write_delay,
43                 }, {
44                         .tx_buf = adis->tx + 2,
45                         .bits_per_word = 8,
46                         .len = 2,
47                         .cs_change = 1,
48                         .delay_usecs = adis->data->write_delay,
49                 }, {
50                         .tx_buf = adis->tx + 4,
51                         .bits_per_word = 8,
52                         .len = 2,
53                         .cs_change = 1,
54                         .delay_usecs = adis->data->write_delay,
55                 }, {
56                         .tx_buf = adis->tx + 6,
57                         .bits_per_word = 8,
58                         .len = 2,
59                         .delay_usecs = adis->data->write_delay,
60                 }, {
61                         .tx_buf = adis->tx + 8,
62                         .bits_per_word = 8,
63                         .len = 2,
64                         .delay_usecs = adis->data->write_delay,
65                 },
66         };
67
68         mutex_lock(&adis->txrx_lock);
69
70         spi_message_init(&msg);
71
72         if (adis->current_page != page) {
73                 adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
74                 adis->tx[1] = page;
75                 spi_message_add_tail(&xfers[0], &msg);
76         }
77
78         switch (size) {
79         case 4:
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;
84                 /* fall through */
85         case 2:
86                 adis->tx[4] = ADIS_WRITE_REG(reg + 1);
87                 adis->tx[5] = (value >> 8) & 0xff;
88                 /* fall through */
89         case 1:
90                 adis->tx[2] = ADIS_WRITE_REG(reg);
91                 adis->tx[3] = value & 0xff;
92                 break;
93         default:
94                 ret = -EINVAL;
95                 goto out_unlock;
96         }
97
98         xfers[size].cs_change = 0;
99
100         for (i = 1; i <= size; i++)
101                 spi_message_add_tail(&xfers[i], &msg);
102
103         ret = spi_sync(adis->spi, &msg);
104         if (ret) {
105                 dev_err(&adis->spi->dev, "Failed to write register 0x%02X: %d\n",
106                                 reg, ret);
107         } else {
108                 adis->current_page = page;
109         }
110
111 out_unlock:
112         mutex_unlock(&adis->txrx_lock);
113
114         return ret;
115 }
116 EXPORT_SYMBOL_GPL(adis_write_reg);
117
118 /**
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
123  */
124 int adis_read_reg(struct adis *adis, unsigned int reg,
125         unsigned int *val, unsigned int size)
126 {
127         unsigned int page = reg / ADIS_PAGE_SIZE;
128         struct spi_message msg;
129         int ret;
130         struct spi_transfer xfers[] = {
131                 {
132                         .tx_buf = adis->tx,
133                         .bits_per_word = 8,
134                         .len = 2,
135                         .cs_change = 1,
136                         .delay_usecs = adis->data->write_delay,
137                 }, {
138                         .tx_buf = adis->tx + 2,
139                         .bits_per_word = 8,
140                         .len = 2,
141                         .cs_change = 1,
142                         .delay_usecs = adis->data->read_delay,
143                 }, {
144                         .tx_buf = adis->tx + 4,
145                         .rx_buf = adis->rx,
146                         .bits_per_word = 8,
147                         .len = 2,
148                         .cs_change = 1,
149                         .delay_usecs = adis->data->read_delay,
150                 }, {
151                         .rx_buf = adis->rx + 2,
152                         .bits_per_word = 8,
153                         .len = 2,
154                         .delay_usecs = adis->data->read_delay,
155                 },
156         };
157
158         mutex_lock(&adis->txrx_lock);
159         spi_message_init(&msg);
160
161         if (adis->current_page != page) {
162                 adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
163                 adis->tx[1] = page;
164                 spi_message_add_tail(&xfers[0], &msg);
165         }
166
167         switch (size) {
168         case 4:
169                 adis->tx[2] = ADIS_READ_REG(reg + 2);
170                 adis->tx[3] = 0;
171                 spi_message_add_tail(&xfers[1], &msg);
172                 /* fall through */
173         case 2:
174                 adis->tx[4] = ADIS_READ_REG(reg);
175                 adis->tx[5] = 0;
176                 spi_message_add_tail(&xfers[2], &msg);
177                 spi_message_add_tail(&xfers[3], &msg);
178                 break;
179         default:
180                 ret = -EINVAL;
181                 goto out_unlock;
182         }
183
184         ret = spi_sync(adis->spi, &msg);
185         if (ret) {
186                 dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n",
187                                 reg, ret);
188                 goto out_unlock;
189         } else {
190                 adis->current_page = page;
191         }
192
193         switch (size) {
194         case 4:
195                 *val = get_unaligned_be32(adis->rx);
196                 break;
197         case 2:
198                 *val = get_unaligned_be16(adis->rx + 2);
199                 break;
200         }
201
202 out_unlock:
203         mutex_unlock(&adis->txrx_lock);
204
205         return ret;
206 }
207 EXPORT_SYMBOL_GPL(adis_read_reg);
208
209 #ifdef CONFIG_DEBUG_FS
210
211 int adis_debugfs_reg_access(struct iio_dev *indio_dev,
212         unsigned int reg, unsigned int writeval, unsigned int *readval)
213 {
214         struct adis *adis = iio_device_get_drvdata(indio_dev);
215
216         if (readval) {
217                 uint16_t val16;
218                 int ret;
219
220                 ret = adis_read_reg_16(adis, reg, &val16);
221                 *readval = val16;
222
223                 return ret;
224         } else {
225                 return adis_write_reg_16(adis, reg, writeval);
226         }
227 }
228 EXPORT_SYMBOL(adis_debugfs_reg_access);
229
230 #endif
231
232 /**
233  * adis_enable_irq() - Enable or disable data ready IRQ
234  * @adis: The adis device
235  * @enable: Whether to enable the IRQ
236  *
237  * Returns 0 on success, negative error code otherwise
238  */
239 int adis_enable_irq(struct adis *adis, bool enable)
240 {
241         int ret = 0;
242         uint16_t msc;
243
244         if (adis->data->enable_irq)
245                 return adis->data->enable_irq(adis, enable);
246
247         ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
248         if (ret)
249                 goto error_ret;
250
251         msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
252         msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
253         if (enable)
254                 msc |= ADIS_MSC_CTRL_DATA_RDY_EN;
255         else
256                 msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
257
258         ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
259
260 error_ret:
261         return ret;
262 }
263 EXPORT_SYMBOL(adis_enable_irq);
264
265 /**
266  * adis_check_status() - Check the device for error conditions
267  * @adis: The adis device
268  *
269  * Returns 0 on success, a negative error code otherwise
270  */
271 int adis_check_status(struct adis *adis)
272 {
273         uint16_t status;
274         int ret;
275         int i;
276
277         ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
278         if (ret < 0)
279                 return ret;
280
281         status &= adis->data->status_error_mask;
282
283         if (status == 0)
284                 return 0;
285
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]);
290                 }
291         }
292
293         return -EIO;
294 }
295 EXPORT_SYMBOL_GPL(adis_check_status);
296
297 /**
298  * adis_reset() - Reset the device
299  * @adis: The adis device
300  *
301  * Returns 0 on success, a negative error code otherwise
302  */
303 int adis_reset(struct adis *adis)
304 {
305         int ret;
306
307         ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg,
308                         ADIS_GLOB_CMD_SW_RESET);
309         if (ret)
310                 dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
311
312         return ret;
313 }
314 EXPORT_SYMBOL_GPL(adis_reset);
315
316 static int adis_self_test(struct adis *adis)
317 {
318         int ret;
319
320         ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
321                         adis->data->self_test_mask);
322         if (ret) {
323                 dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
324                         ret);
325                 return ret;
326         }
327
328         msleep(adis->data->startup_delay);
329
330         ret = adis_check_status(adis);
331
332         if (adis->data->self_test_no_autoclear)
333                 adis_write_reg_16(adis, adis->data->msc_ctrl_reg, 0x00);
334
335         return ret;
336 }
337
338 /**
339  * adis_inital_startup() - Performs device self-test
340  * @adis: The adis device
341  *
342  * Returns 0 if the device is operational, a negative error code otherwise.
343  *
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.
346  */
347 int adis_initial_startup(struct adis *adis)
348 {
349         int ret;
350
351         ret = adis_self_test(adis);
352         if (ret) {
353                 dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n");
354                 adis_reset(adis);
355                 msleep(adis->data->startup_delay);
356                 ret = adis_self_test(adis);
357                 if (ret) {
358                         dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n");
359                         return ret;
360                 }
361         }
362
363         return 0;
364 }
365 EXPORT_SYMBOL_GPL(adis_initial_startup);
366
367 /**
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
373  *
374  * Returns IIO_VAL_INT on success, a negative error code otherwise.
375  *
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.
381  */
382 int adis_single_conversion(struct iio_dev *indio_dev,
383         const struct iio_chan_spec *chan, unsigned int error_mask, int *val)
384 {
385         struct adis *adis = iio_device_get_drvdata(indio_dev);
386         unsigned int uval;
387         int ret;
388
389         mutex_lock(&indio_dev->mlock);
390
391         ret = adis_read_reg(adis, chan->address, &uval,
392                         chan->scan_type.storagebits / 8);
393         if (ret)
394                 goto err_unlock;
395
396         if (uval & error_mask) {
397                 ret = adis_check_status(adis);
398                 if (ret)
399                         goto err_unlock;
400         }
401
402         if (chan->scan_type.sign == 's')
403                 *val = sign_extend32(uval, chan->scan_type.realbits - 1);
404         else
405                 *val = uval & ((1 << chan->scan_type.realbits) - 1);
406
407         ret = IIO_VAL_INT;
408 err_unlock:
409         mutex_unlock(&indio_dev->mlock);
410         return ret;
411 }
412 EXPORT_SYMBOL_GPL(adis_single_conversion);
413
414 /**
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
420  *
421  * Returns 0 on success, a negative error code otherwise.
422  *
423  * This function must be called, before any other adis helper function may be
424  * called.
425  */
426 int adis_init(struct adis *adis, struct iio_dev *indio_dev,
427         struct spi_device *spi, const struct adis_data *data)
428 {
429         mutex_init(&adis->txrx_lock);
430         adis->spi = spi;
431         adis->data = data;
432         iio_device_set_drvdata(indio_dev, adis);
433
434         if (data->has_paging) {
435                 /* Need to set the page before first read/write */
436                 adis->current_page = -1;
437         } else {
438                 /* Page will always be 0 */
439                 adis->current_page = 0;
440         }
441
442         return adis_enable_irq(adis, false);
443 }
444 EXPORT_SYMBOL_GPL(adis_init);
445
446 MODULE_LICENSE("GPL");
447 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
448 MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");