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