treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / iio / imu / adis.c
blob022bb54fb748af01ef5169c85d14ea1b5ce27f7c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Common library for ADIS16XXX devices
5 * Copyright 2012 Analog Devices Inc.
6 * Author: Lars-Peter Clausen <lars@metafoo.de>
7 */
9 #include <linux/delay.h>
10 #include <linux/mutex.h>
11 #include <linux/device.h>
12 #include <linux/kernel.h>
13 #include <linux/spi/spi.h>
14 #include <linux/slab.h>
15 #include <linux/sysfs.h>
16 #include <linux/module.h>
17 #include <asm/unaligned.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/sysfs.h>
21 #include <linux/iio/buffer.h>
22 #include <linux/iio/imu/adis.h>
24 #define ADIS_MSC_CTRL_DATA_RDY_EN BIT(2)
25 #define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH BIT(1)
26 #define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0)
27 #define ADIS_GLOB_CMD_SW_RESET BIT(7)
29 /**
30 * __adis_write_reg() - write N bytes to register (unlocked version)
31 * @adis: The adis device
32 * @reg: The address of the lower of the two registers
33 * @value: The value to write to device (up to 4 bytes)
34 * @size: The size of the @value (in bytes)
36 int __adis_write_reg(struct adis *adis, unsigned int reg,
37 unsigned int value, unsigned int size)
39 unsigned int page = reg / ADIS_PAGE_SIZE;
40 int ret, i;
41 struct spi_message msg;
42 struct spi_transfer xfers[] = {
44 .tx_buf = adis->tx,
45 .bits_per_word = 8,
46 .len = 2,
47 .cs_change = 1,
48 .delay.value = adis->data->write_delay,
49 .delay.unit = SPI_DELAY_UNIT_USECS,
50 .cs_change_delay.value = adis->data->cs_change_delay,
51 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
52 }, {
53 .tx_buf = adis->tx + 2,
54 .bits_per_word = 8,
55 .len = 2,
56 .cs_change = 1,
57 .delay.value = adis->data->write_delay,
58 .delay.unit = SPI_DELAY_UNIT_USECS,
59 .cs_change_delay.value = adis->data->cs_change_delay,
60 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
61 }, {
62 .tx_buf = adis->tx + 4,
63 .bits_per_word = 8,
64 .len = 2,
65 .cs_change = 1,
66 .delay.value = adis->data->write_delay,
67 .delay.unit = SPI_DELAY_UNIT_USECS,
68 .cs_change_delay.value = adis->data->cs_change_delay,
69 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
70 }, {
71 .tx_buf = adis->tx + 6,
72 .bits_per_word = 8,
73 .len = 2,
74 .delay.value = adis->data->write_delay,
75 .delay.unit = SPI_DELAY_UNIT_USECS,
76 }, {
77 .tx_buf = adis->tx + 8,
78 .bits_per_word = 8,
79 .len = 2,
80 .delay.value = adis->data->write_delay,
81 .delay.unit = SPI_DELAY_UNIT_USECS,
85 spi_message_init(&msg);
87 if (adis->current_page != page) {
88 adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
89 adis->tx[1] = page;
90 spi_message_add_tail(&xfers[0], &msg);
93 switch (size) {
94 case 4:
95 adis->tx[8] = ADIS_WRITE_REG(reg + 3);
96 adis->tx[9] = (value >> 24) & 0xff;
97 adis->tx[6] = ADIS_WRITE_REG(reg + 2);
98 adis->tx[7] = (value >> 16) & 0xff;
99 /* fall through */
100 case 2:
101 adis->tx[4] = ADIS_WRITE_REG(reg + 1);
102 adis->tx[5] = (value >> 8) & 0xff;
103 /* fall through */
104 case 1:
105 adis->tx[2] = ADIS_WRITE_REG(reg);
106 adis->tx[3] = value & 0xff;
107 break;
108 default:
109 return -EINVAL;
112 xfers[size].cs_change = 0;
114 for (i = 1; i <= size; i++)
115 spi_message_add_tail(&xfers[i], &msg);
117 ret = spi_sync(adis->spi, &msg);
118 if (ret) {
119 dev_err(&adis->spi->dev, "Failed to write register 0x%02X: %d\n",
120 reg, ret);
121 } else {
122 adis->current_page = page;
125 return ret;
127 EXPORT_SYMBOL_GPL(__adis_write_reg);
130 * __adis_read_reg() - read N bytes from register (unlocked version)
131 * @adis: The adis device
132 * @reg: The address of the lower of the two registers
133 * @val: The value read back from the device
134 * @size: The size of the @val buffer
136 int __adis_read_reg(struct adis *adis, unsigned int reg,
137 unsigned int *val, unsigned int size)
139 unsigned int page = reg / ADIS_PAGE_SIZE;
140 struct spi_message msg;
141 int ret;
142 struct spi_transfer xfers[] = {
144 .tx_buf = adis->tx,
145 .bits_per_word = 8,
146 .len = 2,
147 .cs_change = 1,
148 .delay.value = adis->data->write_delay,
149 .delay.unit = SPI_DELAY_UNIT_USECS,
150 .cs_change_delay.value = adis->data->cs_change_delay,
151 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
152 }, {
153 .tx_buf = adis->tx + 2,
154 .bits_per_word = 8,
155 .len = 2,
156 .cs_change = 1,
157 .delay.value = adis->data->read_delay,
158 .delay.unit = SPI_DELAY_UNIT_USECS,
159 .cs_change_delay.value = adis->data->cs_change_delay,
160 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
161 }, {
162 .tx_buf = adis->tx + 4,
163 .rx_buf = adis->rx,
164 .bits_per_word = 8,
165 .len = 2,
166 .cs_change = 1,
167 .delay.value = adis->data->read_delay,
168 .delay.unit = SPI_DELAY_UNIT_USECS,
169 .cs_change_delay.value = adis->data->cs_change_delay,
170 .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
171 }, {
172 .rx_buf = adis->rx + 2,
173 .bits_per_word = 8,
174 .len = 2,
175 .delay.value = adis->data->read_delay,
176 .delay.unit = SPI_DELAY_UNIT_USECS,
180 spi_message_init(&msg);
182 if (adis->current_page != page) {
183 adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID);
184 adis->tx[1] = page;
185 spi_message_add_tail(&xfers[0], &msg);
188 switch (size) {
189 case 4:
190 adis->tx[2] = ADIS_READ_REG(reg + 2);
191 adis->tx[3] = 0;
192 spi_message_add_tail(&xfers[1], &msg);
193 /* fall through */
194 case 2:
195 adis->tx[4] = ADIS_READ_REG(reg);
196 adis->tx[5] = 0;
197 spi_message_add_tail(&xfers[2], &msg);
198 spi_message_add_tail(&xfers[3], &msg);
199 break;
200 default:
201 return -EINVAL;
204 ret = spi_sync(adis->spi, &msg);
205 if (ret) {
206 dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n",
207 reg, ret);
208 return ret;
209 } else {
210 adis->current_page = page;
213 switch (size) {
214 case 4:
215 *val = get_unaligned_be32(adis->rx);
216 break;
217 case 2:
218 *val = get_unaligned_be16(adis->rx + 2);
219 break;
222 return ret;
224 EXPORT_SYMBOL_GPL(__adis_read_reg);
226 #ifdef CONFIG_DEBUG_FS
228 int adis_debugfs_reg_access(struct iio_dev *indio_dev,
229 unsigned int reg, unsigned int writeval, unsigned int *readval)
231 struct adis *adis = iio_device_get_drvdata(indio_dev);
233 if (readval) {
234 uint16_t val16;
235 int ret;
237 ret = adis_read_reg_16(adis, reg, &val16);
238 if (ret == 0)
239 *readval = val16;
241 return ret;
242 } else {
243 return adis_write_reg_16(adis, reg, writeval);
246 EXPORT_SYMBOL(adis_debugfs_reg_access);
248 #endif
251 * adis_enable_irq() - Enable or disable data ready IRQ
252 * @adis: The adis device
253 * @enable: Whether to enable the IRQ
255 * Returns 0 on success, negative error code otherwise
257 int adis_enable_irq(struct adis *adis, bool enable)
259 int ret = 0;
260 uint16_t msc;
262 mutex_lock(&adis->state_lock);
264 if (adis->data->enable_irq) {
265 ret = adis->data->enable_irq(adis, enable);
266 goto out_unlock;
269 ret = __adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc);
270 if (ret)
271 goto out_unlock;
273 msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH;
274 msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2;
275 if (enable)
276 msc |= ADIS_MSC_CTRL_DATA_RDY_EN;
277 else
278 msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN;
280 ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc);
282 out_unlock:
283 mutex_unlock(&adis->state_lock);
284 return ret;
286 EXPORT_SYMBOL(adis_enable_irq);
289 * __adis_check_status() - Check the device for error conditions (unlocked)
290 * @adis: The adis device
292 * Returns 0 on success, a negative error code otherwise
294 int __adis_check_status(struct adis *adis)
296 uint16_t status;
297 int ret;
298 int i;
300 ret = __adis_read_reg_16(adis, adis->data->diag_stat_reg, &status);
301 if (ret)
302 return ret;
304 status &= adis->data->status_error_mask;
306 if (status == 0)
307 return 0;
309 for (i = 0; i < 16; ++i) {
310 if (status & BIT(i)) {
311 dev_err(&adis->spi->dev, "%s.\n",
312 adis->data->status_error_msgs[i]);
316 return -EIO;
318 EXPORT_SYMBOL_GPL(__adis_check_status);
321 * __adis_reset() - Reset the device (unlocked version)
322 * @adis: The adis device
324 * Returns 0 on success, a negative error code otherwise
326 int __adis_reset(struct adis *adis)
328 int ret;
329 const struct adis_timeout *timeouts = adis->data->timeouts;
331 ret = __adis_write_reg_8(adis, adis->data->glob_cmd_reg,
332 ADIS_GLOB_CMD_SW_RESET);
333 if (ret) {
334 dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);
335 return ret;
338 msleep(timeouts->sw_reset_ms);
340 return 0;
342 EXPORT_SYMBOL_GPL(__adis_reset);
344 static int adis_self_test(struct adis *adis)
346 int ret;
347 const struct adis_timeout *timeouts = adis->data->timeouts;
349 ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
350 adis->data->self_test_mask);
351 if (ret) {
352 dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n",
353 ret);
354 return ret;
357 msleep(timeouts->self_test_ms);
359 ret = __adis_check_status(adis);
361 if (adis->data->self_test_no_autoclear)
362 __adis_write_reg_16(adis, adis->data->msc_ctrl_reg, 0x00);
364 return ret;
368 * adis_inital_startup() - Performs device self-test
369 * @adis: The adis device
371 * Returns 0 if the device is operational, a negative error code otherwise.
373 * This function should be called early on in the device initialization sequence
374 * to ensure that the device is in a sane and known state and that it is usable.
376 int adis_initial_startup(struct adis *adis)
378 int ret;
380 mutex_lock(&adis->state_lock);
382 ret = adis_self_test(adis);
383 if (ret) {
384 dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n");
385 __adis_reset(adis);
386 ret = adis_self_test(adis);
387 if (ret) {
388 dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n");
389 goto out_unlock;
393 out_unlock:
394 mutex_unlock(&adis->state_lock);
395 return ret;
397 EXPORT_SYMBOL_GPL(adis_initial_startup);
400 * adis_single_conversion() - Performs a single sample conversion
401 * @indio_dev: The IIO device
402 * @chan: The IIO channel
403 * @error_mask: Mask for the error bit
404 * @val: Result of the conversion
406 * Returns IIO_VAL_INT on success, a negative error code otherwise.
408 * The function performs a single conversion on a given channel and post
409 * processes the value accordingly to the channel spec. If a error_mask is given
410 * the function will check if the mask is set in the returned raw value. If it
411 * is set the function will perform a self-check. If the device does not report
412 * a error bit in the channels raw value set error_mask to 0.
414 int adis_single_conversion(struct iio_dev *indio_dev,
415 const struct iio_chan_spec *chan, unsigned int error_mask, int *val)
417 struct adis *adis = iio_device_get_drvdata(indio_dev);
418 unsigned int uval;
419 int ret;
421 mutex_lock(&adis->state_lock);
423 ret = __adis_read_reg(adis, chan->address, &uval,
424 chan->scan_type.storagebits / 8);
425 if (ret)
426 goto err_unlock;
428 if (uval & error_mask) {
429 ret = __adis_check_status(adis);
430 if (ret)
431 goto err_unlock;
434 if (chan->scan_type.sign == 's')
435 *val = sign_extend32(uval, chan->scan_type.realbits - 1);
436 else
437 *val = uval & ((1 << chan->scan_type.realbits) - 1);
439 ret = IIO_VAL_INT;
440 err_unlock:
441 mutex_unlock(&adis->state_lock);
442 return ret;
444 EXPORT_SYMBOL_GPL(adis_single_conversion);
447 * adis_init() - Initialize adis device structure
448 * @adis: The adis device
449 * @indio_dev: The iio device
450 * @spi: The spi device
451 * @data: Chip specific data
453 * Returns 0 on success, a negative error code otherwise.
455 * This function must be called, before any other adis helper function may be
456 * called.
458 int adis_init(struct adis *adis, struct iio_dev *indio_dev,
459 struct spi_device *spi, const struct adis_data *data)
461 if (!data || !data->timeouts) {
462 dev_err(&spi->dev, "No config data or timeouts not defined!\n");
463 return -EINVAL;
466 mutex_init(&adis->state_lock);
467 adis->spi = spi;
468 adis->data = data;
469 iio_device_set_drvdata(indio_dev, adis);
471 if (data->has_paging) {
472 /* Need to set the page before first read/write */
473 adis->current_page = -1;
474 } else {
475 /* Page will always be 0 */
476 adis->current_page = 0;
479 return adis_enable_irq(adis, false);
481 EXPORT_SYMBOL_GPL(adis_init);
483 MODULE_LICENSE("GPL");
484 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
485 MODULE_DESCRIPTION("Common library code for ADIS16XXX devices");