• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * LISL02DQ.h -- support STMicroelectronics LISD02DQ
3  *               3d 2g Linear Accelerometers via SPI
4  *
5  * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.uk>
6  *
7  * Loosely based upon tle62x0.c
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13 
14 #ifndef SPI_LIS3L02DQ_H_
15 #define SPI_LIS3L02DQ_H_
16 #define LIS3L02DQ_READ_REG(a) ((a) | 0x80)
17 #define LIS3L02DQ_WRITE_REG(a) a
18 
19 /* Calibration parameters */
20 #define LIS3L02DQ_REG_OFFSET_X_ADDR		0x16
21 #define LIS3L02DQ_REG_OFFSET_Y_ADDR		0x17
22 #define LIS3L02DQ_REG_OFFSET_Z_ADDR		0x18
23 
24 #define LIS3L02DQ_REG_GAIN_X_ADDR		0x19
25 #define LIS3L02DQ_REG_GAIN_Y_ADDR		0x1A
26 #define LIS3L02DQ_REG_GAIN_Z_ADDR		0x1B
27 
28 /* Control Register (1 of 2) */
29 #define LIS3L02DQ_REG_CTRL_1_ADDR		0x20
30 /* Power ctrl - either bit set corresponds to on*/
31 #define LIS3L02DQ_REG_CTRL_1_PD_ON	0xC0
32 
33 /* Decimation Factor  */
34 #define LIS3L02DQ_DEC_MASK			0x30
35 #define LIS3L02DQ_REG_CTRL_1_DF_128		0x00
36 #define LIS3L02DQ_REG_CTRL_1_DF_64		0x10
37 #define LIS3L02DQ_REG_CTRL_1_DF_32		0x20
38 #define LIS3L02DQ_REG_CTRL_1_DF_8		(0x10 | 0x20)
39 
40 /* Self Test Enable */
41 #define LIS3L02DQ_REG_CTRL_1_SELF_TEST_ON	0x08
42 
43 /* Axes enable ctrls */
44 #define LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE	0x04
45 #define LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE	0x02
46 #define LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE	0x01
47 
48 /* Control Register (2 of 2) */
49 #define LIS3L02DQ_REG_CTRL_2_ADDR		0x21
50 
51 /* Block Data Update only after MSB and LSB read */
52 #define LIS3L02DQ_REG_CTRL_2_BLOCK_UPDATE	0x40
53 
54 /* Set to big endian output */
55 #define LIS3L02DQ_REG_CTRL_2_BIG_ENDIAN		0x20
56 
57 /* Reboot memory content */
58 #define LIS3L02DQ_REG_CTRL_2_REBOOT_MEMORY	0x10
59 
60 /* Interrupt Enable - applies data ready to the RDY pad */
61 #define LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT	0x08
62 
63 /* Enable Data Ready Generation - relationship with previous unclear in docs */
64 #define LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION 0x04
65 
66 /* SPI 3 wire mode */
67 #define LIS3L02DQ_REG_CTRL_2_THREE_WIRE_SPI_MODE	0x02
68 
69 /* Data alignment, default is 12 bit right justified
70  * - option for 16 bit left justified */
71 #define LIS3L02DQ_REG_CTRL_2_DATA_ALIGNMENT_16_BIT_LEFT_JUSTIFIED	0x01
72 
73 /* Interrupt related stuff */
74 #define LIS3L02DQ_REG_WAKE_UP_CFG_ADDR			0x23
75 
76 /* Switch from or combination fo conditions to and */
77 #define LIS3L02DQ_REG_WAKE_UP_CFG_BOOLEAN_AND		0x80
78 
79 /* Latch interrupt request,
80  * if on ack must be given by reading the ack register */
81 #define LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC		0x40
82 
83 /* Z Interrupt on High (above threshold)*/
84 #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH	0x20
85 /* Z Interrupt on Low */
86 #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW	0x10
87 /* Y Interrupt on High */
88 #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH	0x08
89 /* Y Interrupt on Low */
90 #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW	0x04
91 /* X Interrupt on High */
92 #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH	0x02
93 /* X Interrupt on Low */
94 #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW 0x01
95 
96 /* Register that gives description of what caused interrupt
97  * - latched if set in CFG_ADDRES */
98 #define LIS3L02DQ_REG_WAKE_UP_SRC_ADDR			0x24
99 /* top bit ignored */
100 /* Interrupt Active */
101 #define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_ACTIVATED	0x40
102 /* Interupts that have been triggered */
103 #define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH	0x20
104 #define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW	0x10
105 #define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH	0x08
106 #define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW	0x04
107 #define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH	0x02
108 #define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW	0x01
109 
110 #define LIS3L02DQ_REG_WAKE_UP_ACK_ADDR			0x25
111 
112 /* Status register */
113 #define LIS3L02DQ_REG_STATUS_ADDR			0x27
114 /* XYZ axis data overrun - first is all overrun? */
115 #define LIS3L02DQ_REG_STATUS_XYZ_OVERRUN		0x80
116 #define LIS3L02DQ_REG_STATUS_Z_OVERRUN			0x40
117 #define LIS3L02DQ_REG_STATUS_Y_OVERRUN			0x20
118 #define LIS3L02DQ_REG_STATUS_X_OVERRUN			0x10
119 /* XYZ new data available - first is all 3 available? */
120 #define LIS3L02DQ_REG_STATUS_XYZ_NEW_DATA 0x08
121 #define LIS3L02DQ_REG_STATUS_Z_NEW_DATA			0x04
122 #define LIS3L02DQ_REG_STATUS_Y_NEW_DATA			0x02
123 #define LIS3L02DQ_REG_STATUS_X_NEW_DATA			0x01
124 
125 /* The accelerometer readings - low and high bytes.
126 Form of high byte dependent on justification set in ctrl reg */
127 #define LIS3L02DQ_REG_OUT_X_L_ADDR			0x28
128 #define LIS3L02DQ_REG_OUT_X_H_ADDR			0x29
129 #define LIS3L02DQ_REG_OUT_Y_L_ADDR			0x2A
130 #define LIS3L02DQ_REG_OUT_Y_H_ADDR			0x2B
131 #define LIS3L02DQ_REG_OUT_Z_L_ADDR			0x2C
132 #define LIS3L02DQ_REG_OUT_Z_H_ADDR			0x2D
133 
134 /* Threshold values for all axes and both above and below thresholds
135  * - i.e. there is only one value */
136 #define LIS3L02DQ_REG_THS_L_ADDR			0x2E
137 #define LIS3L02DQ_REG_THS_H_ADDR			0x2F
138 
139 #define LIS3L02DQ_DEFAULT_CTRL1 (LIS3L02DQ_REG_CTRL_1_PD_ON	      \
140 				 | LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE \
141 				 | LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE \
142 				 | LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE \
143 				 | LIS3L02DQ_REG_CTRL_1_DF_128)
144 
145 #define LIS3L02DQ_DEFAULT_CTRL2	0
146 
147 #define LIS3L02DQ_MAX_TX 12
148 #define LIS3L02DQ_MAX_RX 12
149 /**
150  * struct lis3l02dq_state - device instance specific data
151  * @us:			actual spi_device
152  * @trig:		data ready trigger registered with iio
153  * @tx:			transmit buffer
154  * @rx:			receive buffer
155  * @buf_lock:		mutex to protect tx and rx
156  **/
157 struct lis3l02dq_state {
158 	struct spi_device		*us;
159 	struct iio_trigger		*trig;
160 	struct mutex			buf_lock;
161 	bool				trigger_on;
162 
163 	u8	tx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
164 	u8	rx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
165 };
166 
167 int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
168 			     u8 reg_address,
169 			     u8 *val);
170 
171 int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
172 			      u8 reg_address,
173 			      u8 val);
174 
175 int lis3l02dq_disable_all_events(struct iio_dev *indio_dev);
176 
177 #ifdef CONFIG_IIO_BUFFER
178 /* At the moment triggers are only used for buffer
179  * filling. This may change!
180  */
181 void lis3l02dq_remove_trigger(struct iio_dev *indio_dev);
182 int lis3l02dq_probe_trigger(struct iio_dev *indio_dev);
183 
184 int lis3l02dq_configure_buffer(struct iio_dev *indio_dev);
185 void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev);
186 
187 #ifdef CONFIG_LIS3L02DQ_BUF_RING_SW
188 #define lis3l02dq_free_buf iio_sw_rb_free
189 #define lis3l02dq_alloc_buf iio_sw_rb_allocate
190 #endif
191 #ifdef CONFIG_LIS3L02DQ_BUF_KFIFO
192 #define lis3l02dq_free_buf iio_kfifo_free
193 #define lis3l02dq_alloc_buf iio_kfifo_allocate
194 #endif
195 irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
196 #define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
197 
198 #else /* CONFIG_IIO_BUFFER */
199 #define lis3l02dq_th lis3l02dq_nobuffer
200 
lis3l02dq_remove_trigger(struct iio_dev * indio_dev)201 static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
202 {
203 }
lis3l02dq_probe_trigger(struct iio_dev * indio_dev)204 static inline int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
205 {
206 	return 0;
207 }
208 
lis3l02dq_configure_buffer(struct iio_dev * indio_dev)209 static int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
210 {
211 	return 0;
212 }
lis3l02dq_unconfigure_buffer(struct iio_dev * indio_dev)213 static inline void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev)
214 {
215 }
216 #endif /* CONFIG_IIO_BUFFER */
217 #endif /* SPI_LIS3L02DQ_H_ */
218