xref: /OK3568_Linux_fs/kernel/include/linux/iio/imu/adis.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Common library for ADIS16XXX devices
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright 2012 Analog Devices Inc.
6*4882a593Smuzhiyun  *   Author: Lars-Peter Clausen <lars@metafoo.de>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #ifndef __IIO_ADIS_H__
10*4882a593Smuzhiyun #define __IIO_ADIS_H__
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/spi/spi.h>
13*4882a593Smuzhiyun #include <linux/interrupt.h>
14*4882a593Smuzhiyun #include <linux/iio/types.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define ADIS_WRITE_REG(reg) ((0x80 | (reg)))
17*4882a593Smuzhiyun #define ADIS_READ_REG(reg) ((reg) & 0x7f)
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define ADIS_PAGE_SIZE 0x80
20*4882a593Smuzhiyun #define ADIS_REG_PAGE_ID 0x00
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun struct adis;
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun /**
25*4882a593Smuzhiyun  * struct adis_timeouts - ADIS chip variant timeouts
26*4882a593Smuzhiyun  * @reset_ms - Wait time after rst pin goes inactive
27*4882a593Smuzhiyun  * @sw_reset_ms - Wait time after sw reset command
28*4882a593Smuzhiyun  * @self_test_ms - Wait time after self test command
29*4882a593Smuzhiyun  */
30*4882a593Smuzhiyun struct adis_timeout {
31*4882a593Smuzhiyun 	u16 reset_ms;
32*4882a593Smuzhiyun 	u16 sw_reset_ms;
33*4882a593Smuzhiyun 	u16 self_test_ms;
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun /**
36*4882a593Smuzhiyun  * struct adis_data - ADIS chip variant specific data
37*4882a593Smuzhiyun  * @read_delay: SPI delay for read operations in us
38*4882a593Smuzhiyun  * @write_delay: SPI delay for write operations in us
39*4882a593Smuzhiyun  * @cs_change_delay: SPI delay between CS changes in us
40*4882a593Smuzhiyun  * @glob_cmd_reg: Register address of the GLOB_CMD register
41*4882a593Smuzhiyun  * @msc_ctrl_reg: Register address of the MSC_CTRL register
42*4882a593Smuzhiyun  * @diag_stat_reg: Register address of the DIAG_STAT register
43*4882a593Smuzhiyun  * @prod_id_reg: Register address of the PROD_ID register
44*4882a593Smuzhiyun  * @prod_id: Product ID code that should be expected when reading @prod_id_reg
45*4882a593Smuzhiyun  * @self_test_mask: Bitmask of supported self-test operations
46*4882a593Smuzhiyun  * @self_test_reg: Register address to request self test command
47*4882a593Smuzhiyun  * @self_test_no_autoclear: True if device's self-test needs clear of ctrl reg
48*4882a593Smuzhiyun  * @status_error_msgs: Array of error messgaes
49*4882a593Smuzhiyun  * @status_error_mask: Bitmask of errors supported by the device
50*4882a593Smuzhiyun  * @timeouts: Chip specific delays
51*4882a593Smuzhiyun  * @enable_irq: Hook for ADIS devices that have a special IRQ enable/disable
52*4882a593Smuzhiyun  * @has_paging: True if ADIS device has paged registers
53*4882a593Smuzhiyun  * @burst_reg_cmd:	Register command that triggers burst
54*4882a593Smuzhiyun  * @burst_len:		Burst size in the SPI RX buffer. If @burst_max_len is defined,
55*4882a593Smuzhiyun  *			this should be the minimum size supported by the device.
56*4882a593Smuzhiyun  * @burst_max_len:	Holds the maximum burst size when the device supports
57*4882a593Smuzhiyun  *			more than one burst mode with different sizes
58*4882a593Smuzhiyun  */
59*4882a593Smuzhiyun struct adis_data {
60*4882a593Smuzhiyun 	unsigned int read_delay;
61*4882a593Smuzhiyun 	unsigned int write_delay;
62*4882a593Smuzhiyun 	unsigned int cs_change_delay;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	unsigned int glob_cmd_reg;
65*4882a593Smuzhiyun 	unsigned int msc_ctrl_reg;
66*4882a593Smuzhiyun 	unsigned int diag_stat_reg;
67*4882a593Smuzhiyun 	unsigned int prod_id_reg;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	unsigned int prod_id;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	unsigned int self_test_mask;
72*4882a593Smuzhiyun 	unsigned int self_test_reg;
73*4882a593Smuzhiyun 	bool self_test_no_autoclear;
74*4882a593Smuzhiyun 	const struct adis_timeout *timeouts;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	const char * const *status_error_msgs;
77*4882a593Smuzhiyun 	unsigned int status_error_mask;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	int (*enable_irq)(struct adis *adis, bool enable);
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	bool has_paging;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	unsigned int burst_reg_cmd;
84*4882a593Smuzhiyun 	unsigned int burst_len;
85*4882a593Smuzhiyun 	unsigned int burst_max_len;
86*4882a593Smuzhiyun };
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /**
89*4882a593Smuzhiyun  * struct adis - ADIS device instance data
90*4882a593Smuzhiyun  * @spi: Reference to SPI device which owns this ADIS IIO device
91*4882a593Smuzhiyun  * @trig: IIO trigger object data
92*4882a593Smuzhiyun  * @data: ADIS chip variant specific data
93*4882a593Smuzhiyun  * @burst: ADIS burst transfer information
94*4882a593Smuzhiyun  * @burst_extra_len: Burst extra length. Should only be used by devices that can
95*4882a593Smuzhiyun  *		     dynamically change their burst mode length.
96*4882a593Smuzhiyun  * @state_lock: Lock used by the device to protect state
97*4882a593Smuzhiyun  * @msg: SPI message object
98*4882a593Smuzhiyun  * @xfer: SPI transfer objects to be used for a @msg
99*4882a593Smuzhiyun  * @current_page: Some ADIS devices have registers, this selects current page
100*4882a593Smuzhiyun  * @irq_flag: IRQ handling flags as passed to request_irq()
101*4882a593Smuzhiyun  * @buffer: Data buffer for information read from the device
102*4882a593Smuzhiyun  * @tx: DMA safe TX buffer for SPI transfers
103*4882a593Smuzhiyun  * @rx: DMA safe RX buffer for SPI transfers
104*4882a593Smuzhiyun  */
105*4882a593Smuzhiyun struct adis {
106*4882a593Smuzhiyun 	struct spi_device	*spi;
107*4882a593Smuzhiyun 	struct iio_trigger	*trig;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	const struct adis_data	*data;
110*4882a593Smuzhiyun 	unsigned int		burst_extra_len;
111*4882a593Smuzhiyun 	/**
112*4882a593Smuzhiyun 	 * The state_lock is meant to be used during operations that require
113*4882a593Smuzhiyun 	 * a sequence of SPI R/W in order to protect the SPI transfer
114*4882a593Smuzhiyun 	 * information (fields 'xfer', 'msg' & 'current_page') between
115*4882a593Smuzhiyun 	 * potential concurrent accesses.
116*4882a593Smuzhiyun 	 * This lock is used by all "adis_{functions}" that have to read/write
117*4882a593Smuzhiyun 	 * registers. These functions also have unlocked variants
118*4882a593Smuzhiyun 	 * (see "__adis_{functions}"), which don't hold this lock.
119*4882a593Smuzhiyun 	 * This allows users of the ADIS library to group SPI R/W into
120*4882a593Smuzhiyun 	 * the drivers, but they also must manage this lock themselves.
121*4882a593Smuzhiyun 	 */
122*4882a593Smuzhiyun 	struct mutex		state_lock;
123*4882a593Smuzhiyun 	struct spi_message	msg;
124*4882a593Smuzhiyun 	struct spi_transfer	*xfer;
125*4882a593Smuzhiyun 	unsigned int		current_page;
126*4882a593Smuzhiyun 	unsigned long		irq_flag;
127*4882a593Smuzhiyun 	void			*buffer;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	uint8_t			tx[10] ____cacheline_aligned;
130*4882a593Smuzhiyun 	uint8_t			rx[4];
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun int adis_init(struct adis *adis, struct iio_dev *indio_dev,
134*4882a593Smuzhiyun 	struct spi_device *spi, const struct adis_data *data);
135*4882a593Smuzhiyun int __adis_reset(struct adis *adis);
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun /**
138*4882a593Smuzhiyun  * adis_reset() - Reset the device
139*4882a593Smuzhiyun  * @adis: The adis device
140*4882a593Smuzhiyun  *
141*4882a593Smuzhiyun  * Returns 0 on success, a negative error code otherwise
142*4882a593Smuzhiyun  */
adis_reset(struct adis * adis)143*4882a593Smuzhiyun static inline int adis_reset(struct adis *adis)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	int ret;
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	mutex_lock(&adis->state_lock);
148*4882a593Smuzhiyun 	ret = __adis_reset(adis);
149*4882a593Smuzhiyun 	mutex_unlock(&adis->state_lock);
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	return ret;
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun int __adis_write_reg(struct adis *adis, unsigned int reg,
155*4882a593Smuzhiyun 	unsigned int val, unsigned int size);
156*4882a593Smuzhiyun int __adis_read_reg(struct adis *adis, unsigned int reg,
157*4882a593Smuzhiyun 	unsigned int *val, unsigned int size);
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun /**
160*4882a593Smuzhiyun  * __adis_write_reg_8() - Write single byte to a register (unlocked)
161*4882a593Smuzhiyun  * @adis: The adis device
162*4882a593Smuzhiyun  * @reg: The address of the register to be written
163*4882a593Smuzhiyun  * @value: The value to write
164*4882a593Smuzhiyun  */
__adis_write_reg_8(struct adis * adis,unsigned int reg,uint8_t val)165*4882a593Smuzhiyun static inline int __adis_write_reg_8(struct adis *adis, unsigned int reg,
166*4882a593Smuzhiyun 	uint8_t val)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	return __adis_write_reg(adis, reg, val, 1);
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun /**
172*4882a593Smuzhiyun  * __adis_write_reg_16() - Write 2 bytes to a pair of registers (unlocked)
173*4882a593Smuzhiyun  * @adis: The adis device
174*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
175*4882a593Smuzhiyun  * @value: Value to be written
176*4882a593Smuzhiyun  */
__adis_write_reg_16(struct adis * adis,unsigned int reg,uint16_t val)177*4882a593Smuzhiyun static inline int __adis_write_reg_16(struct adis *adis, unsigned int reg,
178*4882a593Smuzhiyun 	uint16_t val)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun 	return __adis_write_reg(adis, reg, val, 2);
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun /**
184*4882a593Smuzhiyun  * __adis_write_reg_32() - write 4 bytes to four registers (unlocked)
185*4882a593Smuzhiyun  * @adis: The adis device
186*4882a593Smuzhiyun  * @reg: The address of the lower of the four register
187*4882a593Smuzhiyun  * @value: Value to be written
188*4882a593Smuzhiyun  */
__adis_write_reg_32(struct adis * adis,unsigned int reg,uint32_t val)189*4882a593Smuzhiyun static inline int __adis_write_reg_32(struct adis *adis, unsigned int reg,
190*4882a593Smuzhiyun 	uint32_t val)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun 	return __adis_write_reg(adis, reg, val, 4);
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun /**
196*4882a593Smuzhiyun  * __adis_read_reg_16() - read 2 bytes from a 16-bit register (unlocked)
197*4882a593Smuzhiyun  * @adis: The adis device
198*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
199*4882a593Smuzhiyun  * @val: The value read back from the device
200*4882a593Smuzhiyun  */
__adis_read_reg_16(struct adis * adis,unsigned int reg,uint16_t * val)201*4882a593Smuzhiyun static inline int __adis_read_reg_16(struct adis *adis, unsigned int reg,
202*4882a593Smuzhiyun 	uint16_t *val)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	unsigned int tmp;
205*4882a593Smuzhiyun 	int ret;
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	ret = __adis_read_reg(adis, reg, &tmp, 2);
208*4882a593Smuzhiyun 	if (ret == 0)
209*4882a593Smuzhiyun 		*val = tmp;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	return ret;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun /**
215*4882a593Smuzhiyun  * __adis_read_reg_32() - read 4 bytes from a 32-bit register (unlocked)
216*4882a593Smuzhiyun  * @adis: The adis device
217*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
218*4882a593Smuzhiyun  * @val: The value read back from the device
219*4882a593Smuzhiyun  */
__adis_read_reg_32(struct adis * adis,unsigned int reg,uint32_t * val)220*4882a593Smuzhiyun static inline int __adis_read_reg_32(struct adis *adis, unsigned int reg,
221*4882a593Smuzhiyun 	uint32_t *val)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	unsigned int tmp;
224*4882a593Smuzhiyun 	int ret;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	ret = __adis_read_reg(adis, reg, &tmp, 4);
227*4882a593Smuzhiyun 	if (ret == 0)
228*4882a593Smuzhiyun 		*val = tmp;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	return ret;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun /**
234*4882a593Smuzhiyun  * adis_write_reg() - write N bytes to register
235*4882a593Smuzhiyun  * @adis: The adis device
236*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
237*4882a593Smuzhiyun  * @value: The value to write to device (up to 4 bytes)
238*4882a593Smuzhiyun  * @size: The size of the @value (in bytes)
239*4882a593Smuzhiyun  */
adis_write_reg(struct adis * adis,unsigned int reg,unsigned int val,unsigned int size)240*4882a593Smuzhiyun static inline int adis_write_reg(struct adis *adis, unsigned int reg,
241*4882a593Smuzhiyun 	unsigned int val, unsigned int size)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun 	int ret;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	mutex_lock(&adis->state_lock);
246*4882a593Smuzhiyun 	ret = __adis_write_reg(adis, reg, val, size);
247*4882a593Smuzhiyun 	mutex_unlock(&adis->state_lock);
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	return ret;
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun /**
253*4882a593Smuzhiyun  * adis_read_reg() - read N bytes from register
254*4882a593Smuzhiyun  * @adis: The adis device
255*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
256*4882a593Smuzhiyun  * @val: The value read back from the device
257*4882a593Smuzhiyun  * @size: The size of the @val buffer
258*4882a593Smuzhiyun  */
adis_read_reg(struct adis * adis,unsigned int reg,unsigned int * val,unsigned int size)259*4882a593Smuzhiyun static int adis_read_reg(struct adis *adis, unsigned int reg,
260*4882a593Smuzhiyun 	unsigned int *val, unsigned int size)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun 	int ret;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	mutex_lock(&adis->state_lock);
265*4882a593Smuzhiyun 	ret = __adis_read_reg(adis, reg, val, size);
266*4882a593Smuzhiyun 	mutex_unlock(&adis->state_lock);
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	return ret;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun /**
272*4882a593Smuzhiyun  * adis_write_reg_8() - Write single byte to a register
273*4882a593Smuzhiyun  * @adis: The adis device
274*4882a593Smuzhiyun  * @reg: The address of the register to be written
275*4882a593Smuzhiyun  * @value: The value to write
276*4882a593Smuzhiyun  */
adis_write_reg_8(struct adis * adis,unsigned int reg,uint8_t val)277*4882a593Smuzhiyun static inline int adis_write_reg_8(struct adis *adis, unsigned int reg,
278*4882a593Smuzhiyun 	uint8_t val)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun 	return adis_write_reg(adis, reg, val, 1);
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun /**
284*4882a593Smuzhiyun  * adis_write_reg_16() - Write 2 bytes to a pair of registers
285*4882a593Smuzhiyun  * @adis: The adis device
286*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
287*4882a593Smuzhiyun  * @value: Value to be written
288*4882a593Smuzhiyun  */
adis_write_reg_16(struct adis * adis,unsigned int reg,uint16_t val)289*4882a593Smuzhiyun static inline int adis_write_reg_16(struct adis *adis, unsigned int reg,
290*4882a593Smuzhiyun 	uint16_t val)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun 	return adis_write_reg(adis, reg, val, 2);
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun /**
296*4882a593Smuzhiyun  * adis_write_reg_32() - write 4 bytes to four registers
297*4882a593Smuzhiyun  * @adis: The adis device
298*4882a593Smuzhiyun  * @reg: The address of the lower of the four register
299*4882a593Smuzhiyun  * @value: Value to be written
300*4882a593Smuzhiyun  */
adis_write_reg_32(struct adis * adis,unsigned int reg,uint32_t val)301*4882a593Smuzhiyun static inline int adis_write_reg_32(struct adis *adis, unsigned int reg,
302*4882a593Smuzhiyun 	uint32_t val)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	return adis_write_reg(adis, reg, val, 4);
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun /**
308*4882a593Smuzhiyun  * adis_read_reg_16() - read 2 bytes from a 16-bit register
309*4882a593Smuzhiyun  * @adis: The adis device
310*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
311*4882a593Smuzhiyun  * @val: The value read back from the device
312*4882a593Smuzhiyun  */
adis_read_reg_16(struct adis * adis,unsigned int reg,uint16_t * val)313*4882a593Smuzhiyun static inline int adis_read_reg_16(struct adis *adis, unsigned int reg,
314*4882a593Smuzhiyun 	uint16_t *val)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun 	unsigned int tmp;
317*4882a593Smuzhiyun 	int ret;
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	ret = adis_read_reg(adis, reg, &tmp, 2);
320*4882a593Smuzhiyun 	if (ret == 0)
321*4882a593Smuzhiyun 		*val = tmp;
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	return ret;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun /**
327*4882a593Smuzhiyun  * adis_read_reg_32() - read 4 bytes from a 32-bit register
328*4882a593Smuzhiyun  * @adis: The adis device
329*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
330*4882a593Smuzhiyun  * @val: The value read back from the device
331*4882a593Smuzhiyun  */
adis_read_reg_32(struct adis * adis,unsigned int reg,uint32_t * val)332*4882a593Smuzhiyun static inline int adis_read_reg_32(struct adis *adis, unsigned int reg,
333*4882a593Smuzhiyun 	uint32_t *val)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun 	unsigned int tmp;
336*4882a593Smuzhiyun 	int ret;
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	ret = adis_read_reg(adis, reg, &tmp, 4);
339*4882a593Smuzhiyun 	if (ret == 0)
340*4882a593Smuzhiyun 		*val = tmp;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	return ret;
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun int __adis_update_bits_base(struct adis *adis, unsigned int reg, const u32 mask,
346*4882a593Smuzhiyun 			    const u32 val, u8 size);
347*4882a593Smuzhiyun /**
348*4882a593Smuzhiyun  * adis_update_bits_base() - ADIS Update bits function - Locked version
349*4882a593Smuzhiyun  * @adis: The adis device
350*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
351*4882a593Smuzhiyun  * @mask: Bitmask to change
352*4882a593Smuzhiyun  * @val: Value to be written
353*4882a593Smuzhiyun  * @size: Size of the register to update
354*4882a593Smuzhiyun  *
355*4882a593Smuzhiyun  * Updates the desired bits of @reg in accordance with @mask and @val.
356*4882a593Smuzhiyun  */
adis_update_bits_base(struct adis * adis,unsigned int reg,const u32 mask,const u32 val,u8 size)357*4882a593Smuzhiyun static inline int adis_update_bits_base(struct adis *adis, unsigned int reg,
358*4882a593Smuzhiyun 					const u32 mask, const u32 val, u8 size)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun 	int ret;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	mutex_lock(&adis->state_lock);
363*4882a593Smuzhiyun 	ret = __adis_update_bits_base(adis, reg, mask, val, size);
364*4882a593Smuzhiyun 	mutex_unlock(&adis->state_lock);
365*4882a593Smuzhiyun 	return ret;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun /**
369*4882a593Smuzhiyun  * adis_update_bits() - Wrapper macro for adis_update_bits_base - Locked version
370*4882a593Smuzhiyun  * @adis: The adis device
371*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
372*4882a593Smuzhiyun  * @mask: Bitmask to change
373*4882a593Smuzhiyun  * @val: Value to be written
374*4882a593Smuzhiyun  *
375*4882a593Smuzhiyun  * This macro evaluates the sizeof of @val at compile time and calls
376*4882a593Smuzhiyun  * adis_update_bits_base() accordingly. Be aware that using MACROS/DEFINES for
377*4882a593Smuzhiyun  * @val can lead to undesired behavior if the register to update is 16bit.
378*4882a593Smuzhiyun  */
379*4882a593Smuzhiyun #define adis_update_bits(adis, reg, mask, val) ({			\
380*4882a593Smuzhiyun 	BUILD_BUG_ON(sizeof(val) == 1 || sizeof(val) == 8);		\
381*4882a593Smuzhiyun 	__builtin_choose_expr(sizeof(val) == 4,				\
382*4882a593Smuzhiyun 		adis_update_bits_base(adis, reg, mask, val, 4),         \
383*4882a593Smuzhiyun 		adis_update_bits_base(adis, reg, mask, val, 2));	\
384*4882a593Smuzhiyun })
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun /**
387*4882a593Smuzhiyun  * adis_update_bits() - Wrapper macro for adis_update_bits_base
388*4882a593Smuzhiyun  * @adis: The adis device
389*4882a593Smuzhiyun  * @reg: The address of the lower of the two registers
390*4882a593Smuzhiyun  * @mask: Bitmask to change
391*4882a593Smuzhiyun  * @val: Value to be written
392*4882a593Smuzhiyun  *
393*4882a593Smuzhiyun  * This macro evaluates the sizeof of @val at compile time and calls
394*4882a593Smuzhiyun  * adis_update_bits_base() accordingly. Be aware that using MACROS/DEFINES for
395*4882a593Smuzhiyun  * @val can lead to undesired behavior if the register to update is 16bit.
396*4882a593Smuzhiyun  */
397*4882a593Smuzhiyun #define __adis_update_bits(adis, reg, mask, val) ({			\
398*4882a593Smuzhiyun 	BUILD_BUG_ON(sizeof(val) == 1 || sizeof(val) == 8);		\
399*4882a593Smuzhiyun 	__builtin_choose_expr(sizeof(val) == 4,				\
400*4882a593Smuzhiyun 		__adis_update_bits_base(adis, reg, mask, val, 4),	\
401*4882a593Smuzhiyun 		__adis_update_bits_base(adis, reg, mask, val, 2));	\
402*4882a593Smuzhiyun })
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun int adis_enable_irq(struct adis *adis, bool enable);
405*4882a593Smuzhiyun int __adis_check_status(struct adis *adis);
406*4882a593Smuzhiyun int __adis_initial_startup(struct adis *adis);
407*4882a593Smuzhiyun 
adis_check_status(struct adis * adis)408*4882a593Smuzhiyun static inline int adis_check_status(struct adis *adis)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun 	int ret;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	mutex_lock(&adis->state_lock);
413*4882a593Smuzhiyun 	ret = __adis_check_status(adis);
414*4882a593Smuzhiyun 	mutex_unlock(&adis->state_lock);
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	return ret;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun /* locked version of __adis_initial_startup() */
adis_initial_startup(struct adis * adis)420*4882a593Smuzhiyun static inline int adis_initial_startup(struct adis *adis)
421*4882a593Smuzhiyun {
422*4882a593Smuzhiyun 	int ret;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	mutex_lock(&adis->state_lock);
425*4882a593Smuzhiyun 	ret = __adis_initial_startup(adis);
426*4882a593Smuzhiyun 	mutex_unlock(&adis->state_lock);
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	return ret;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun int adis_single_conversion(struct iio_dev *indio_dev,
432*4882a593Smuzhiyun 	const struct iio_chan_spec *chan, unsigned int error_mask,
433*4882a593Smuzhiyun 	int *val);
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun #define ADIS_VOLTAGE_CHAN(addr, si, chan, name, info_all, bits) { \
436*4882a593Smuzhiyun 	.type = IIO_VOLTAGE, \
437*4882a593Smuzhiyun 	.indexed = 1, \
438*4882a593Smuzhiyun 	.channel = (chan), \
439*4882a593Smuzhiyun 	.extend_name = name, \
440*4882a593Smuzhiyun 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
441*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SCALE), \
442*4882a593Smuzhiyun 	.info_mask_shared_by_all = info_all, \
443*4882a593Smuzhiyun 	.address = (addr), \
444*4882a593Smuzhiyun 	.scan_index = (si), \
445*4882a593Smuzhiyun 	.scan_type = { \
446*4882a593Smuzhiyun 		.sign = 'u', \
447*4882a593Smuzhiyun 		.realbits = (bits), \
448*4882a593Smuzhiyun 		.storagebits = 16, \
449*4882a593Smuzhiyun 		.endianness = IIO_BE, \
450*4882a593Smuzhiyun 	}, \
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun #define ADIS_SUPPLY_CHAN(addr, si, info_all, bits) \
454*4882a593Smuzhiyun 	ADIS_VOLTAGE_CHAN(addr, si, 0, "supply", info_all, bits)
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun #define ADIS_AUX_ADC_CHAN(addr, si, info_all, bits) \
457*4882a593Smuzhiyun 	ADIS_VOLTAGE_CHAN(addr, si, 1, NULL, info_all, bits)
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun #define ADIS_TEMP_CHAN(addr, si, info_all, bits) { \
460*4882a593Smuzhiyun 	.type = IIO_TEMP, \
461*4882a593Smuzhiyun 	.indexed = 1, \
462*4882a593Smuzhiyun 	.channel = 0, \
463*4882a593Smuzhiyun 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
464*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SCALE) | \
465*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_OFFSET), \
466*4882a593Smuzhiyun 	.info_mask_shared_by_all = info_all, \
467*4882a593Smuzhiyun 	.address = (addr), \
468*4882a593Smuzhiyun 	.scan_index = (si), \
469*4882a593Smuzhiyun 	.scan_type = { \
470*4882a593Smuzhiyun 		.sign = 'u', \
471*4882a593Smuzhiyun 		.realbits = (bits), \
472*4882a593Smuzhiyun 		.storagebits = 16, \
473*4882a593Smuzhiyun 		.endianness = IIO_BE, \
474*4882a593Smuzhiyun 	}, \
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun #define ADIS_MOD_CHAN(_type, mod, addr, si, info_sep, info_all, bits) { \
478*4882a593Smuzhiyun 	.type = (_type), \
479*4882a593Smuzhiyun 	.modified = 1, \
480*4882a593Smuzhiyun 	.channel2 = IIO_MOD_ ## mod, \
481*4882a593Smuzhiyun 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
482*4882a593Smuzhiyun 		 info_sep, \
483*4882a593Smuzhiyun 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
484*4882a593Smuzhiyun 	.info_mask_shared_by_all = info_all, \
485*4882a593Smuzhiyun 	.address = (addr), \
486*4882a593Smuzhiyun 	.scan_index = (si), \
487*4882a593Smuzhiyun 	.scan_type = { \
488*4882a593Smuzhiyun 		.sign = 's', \
489*4882a593Smuzhiyun 		.realbits = (bits), \
490*4882a593Smuzhiyun 		.storagebits = 16, \
491*4882a593Smuzhiyun 		.endianness = IIO_BE, \
492*4882a593Smuzhiyun 	}, \
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun #define ADIS_ACCEL_CHAN(mod, addr, si, info_sep, info_all, bits) \
496*4882a593Smuzhiyun 	ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info_sep, info_all, bits)
497*4882a593Smuzhiyun 
498*4882a593Smuzhiyun #define ADIS_GYRO_CHAN(mod, addr, si, info_sep, info_all, bits)		\
499*4882a593Smuzhiyun 	ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info_sep, info_all, bits)
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun #define ADIS_INCLI_CHAN(mod, addr, si, info_sep, info_all, bits) \
502*4882a593Smuzhiyun 	ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info_sep, info_all, bits)
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun #define ADIS_ROT_CHAN(mod, addr, si, info_sep, info_all, bits) \
505*4882a593Smuzhiyun 	ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info_sep, info_all, bits)
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun #ifdef CONFIG_IIO_ADIS_LIB_BUFFER
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun int
510*4882a593Smuzhiyun devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
511*4882a593Smuzhiyun 				   irq_handler_t trigger_handler);
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev);
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun int adis_update_scan_mode(struct iio_dev *indio_dev,
516*4882a593Smuzhiyun 	const unsigned long *scan_mask);
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun #else /* CONFIG_IIO_BUFFER */
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun static inline int
devm_adis_setup_buffer_and_trigger(struct adis * adis,struct iio_dev * indio_dev,irq_handler_t trigger_handler)521*4882a593Smuzhiyun devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev,
522*4882a593Smuzhiyun 				   irq_handler_t trigger_handler)
523*4882a593Smuzhiyun {
524*4882a593Smuzhiyun 	return 0;
525*4882a593Smuzhiyun }
526*4882a593Smuzhiyun 
devm_adis_probe_trigger(struct adis * adis,struct iio_dev * indio_dev)527*4882a593Smuzhiyun static inline int devm_adis_probe_trigger(struct adis *adis,
528*4882a593Smuzhiyun 					  struct iio_dev *indio_dev)
529*4882a593Smuzhiyun {
530*4882a593Smuzhiyun 	return 0;
531*4882a593Smuzhiyun }
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun #define adis_update_scan_mode NULL
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun #endif /* CONFIG_IIO_BUFFER */
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun int adis_debugfs_reg_access(struct iio_dev *indio_dev,
540*4882a593Smuzhiyun 	unsigned int reg, unsigned int writeval, unsigned int *readval);
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun #else
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun #define adis_debugfs_reg_access NULL
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun #endif
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun #endif
549