Commit | Line | Data |
---|---|---|
66533b48 JC |
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 | /* Interupt 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 | /* Interupt 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 interupt 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 Interupt on High (above threshold)*/ | |
84 | #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH 0x20 | |
85 | /* Z Interupt on Low */ | |
86 | #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW 0x10 | |
87 | /* Y Interupt on High */ | |
88 | #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH 0x08 | |
89 | /* Y Interupt on Low */ | |
90 | #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW 0x04 | |
91 | /* X Interupt on High */ | |
92 | #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH 0x02 | |
93 | /* X Interupt on Low */ | |
94 | #define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW 0x01 | |
95 | ||
96 | /* Register that gives description of what caused interupt | |
97 | * - latched if set in CFG_ADDRES */ | |
98 | #define LIS3L02DQ_REG_WAKE_UP_SRC_ADDR 0x24 | |
99 | /* top bit ignored */ | |
100 | /* Interupt 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 dependant 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 | * @work_trigger_to_ring: bh for triggered event handling | |
153 | * @work_cont_thresh: CLEAN | |
154 | * @inter: used to check if new interrupt has been triggered | |
155 | * @last_timestamp: passing timestamp from th to bh of interrupt handler | |
156 | * @indio_dev: industrial I/O device structure | |
157 | * @trig: data ready trigger registered with iio | |
158 | * @tx: transmit buffer | |
159 | * @rx: recieve buffer | |
160 | * @buf_lock: mutex to protect tx and rx | |
161 | **/ | |
162 | struct lis3l02dq_state { | |
163 | struct spi_device *us; | |
164 | struct work_struct work_trigger_to_ring; | |
165 | struct iio_work_cont work_cont_thresh; | |
166 | bool inter; | |
167 | s64 last_timestamp; | |
168 | struct iio_dev *indio_dev; | |
169 | struct iio_trigger *trig; | |
170 | u8 *tx; | |
171 | u8 *rx; | |
172 | struct mutex buf_lock; | |
173 | }; | |
174 | ||
175 | int lis3l02dq_spi_read_reg_8(struct device *dev, | |
176 | u8 reg_address, | |
177 | u8 *val); | |
178 | ||
179 | int lis3l02dq_spi_write_reg_8(struct device *dev, | |
180 | u8 reg_address, | |
181 | u8 *val); | |
14cd9a73 JC |
182 | |
183 | #ifdef CONFIG_IIO_RING_BUFFER | |
184 | /* At the moment triggers are only used for ring buffer | |
185 | * filling. This may change! | |
186 | */ | |
187 | void lis3l02dq_remove_trigger(struct iio_dev *indio_dev); | |
188 | int lis3l02dq_probe_trigger(struct iio_dev *indio_dev); | |
189 | ||
190 | ssize_t lis3l02dq_read_accel_from_ring(struct device *dev, | |
191 | struct device_attribute *attr, | |
192 | char *buf); | |
193 | ||
194 | ||
195 | int lis3l02dq_configure_ring(struct iio_dev *indio_dev); | |
196 | void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev); | |
197 | ||
198 | int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring); | |
199 | void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring); | |
200 | #else /* CONFIG_IIO_RING_BUFFER */ | |
201 | ||
66533b48 JC |
202 | static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) {}; |
203 | static inline int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) | |
204 | { | |
205 | return 0; | |
206 | }; | |
207 | ||
208 | static inline ssize_t | |
209 | lis3l02dq_read_accel_from_ring(struct device *dev, | |
210 | struct device_attribute *attr, | |
211 | char *buf) | |
212 | { | |
213 | return 0; | |
214 | }; | |
215 | ||
216 | static int lis3l02dq_configure_ring(struct iio_dev *indio_dev) | |
217 | { | |
218 | return 0; | |
219 | }; | |
220 | static inline void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev) | |
221 | {}; | |
222 | static inline int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring) | |
223 | { | |
224 | return 0; | |
225 | }; | |
226 | static inline void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring) {}; | |
14cd9a73 | 227 | #endif /* CONFIG_IIO_RING_BUFFER */ |
66533b48 | 228 | #endif /* SPI_LIS3L02DQ_H_ */ |