blob: 76f592bcb63d54676ef2088083c4839cf1b0833d [file] [log] [blame]
Jonathan Cameron66533b42009-08-18 18:06:22 +01001/*
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
Lucas De Marchi25985ed2011-03-30 22:57:33 -030060/* Interrupt Enable - applies data ready to the RDY pad */
Jonathan Cameron66533b42009-08-18 18:06:22 +010061#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
Lucas De Marchi25985ed2011-03-30 22:57:33 -030073/* Interrupt related stuff */
Jonathan Cameron66533b42009-08-18 18:06:22 +010074#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
Lucas De Marchi25985ed2011-03-30 22:57:33 -030079/* Latch interrupt request,
Jonathan Cameron66533b42009-08-18 18:06:22 +010080 * if on ack must be given by reading the ack register */
81#define LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC 0x40
82
Lucas De Marchi25985ed2011-03-30 22:57:33 -030083/* Z Interrupt on High (above threshold)*/
Jonathan Cameron66533b42009-08-18 18:06:22 +010084#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH 0x20
Lucas De Marchi25985ed2011-03-30 22:57:33 -030085/* Z Interrupt on Low */
Jonathan Cameron66533b42009-08-18 18:06:22 +010086#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW 0x10
Lucas De Marchi25985ed2011-03-30 22:57:33 -030087/* Y Interrupt on High */
Jonathan Cameron66533b42009-08-18 18:06:22 +010088#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH 0x08
Lucas De Marchi25985ed2011-03-30 22:57:33 -030089/* Y Interrupt on Low */
Jonathan Cameron66533b42009-08-18 18:06:22 +010090#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW 0x04
Lucas De Marchi25985ed2011-03-30 22:57:33 -030091/* X Interrupt on High */
Jonathan Cameron66533b42009-08-18 18:06:22 +010092#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH 0x02
Lucas De Marchi25985ed2011-03-30 22:57:33 -030093/* X Interrupt on Low */
Jonathan Cameron66533b42009-08-18 18:06:22 +010094#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW 0x01
95
Lucas De Marchi25985ed2011-03-30 22:57:33 -030096/* Register that gives description of what caused interrupt
Jonathan Cameron66533b42009-08-18 18:06:22 +010097 * - latched if set in CFG_ADDRES */
98#define LIS3L02DQ_REG_WAKE_UP_SRC_ADDR 0x24
99/* top bit ignored */
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300100/* Interrupt Active */
Jonathan Cameron66533b42009-08-18 18:06:22 +0100101#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.
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300126Form of high byte dependent on justification set in ctrl reg */
Jonathan Cameron66533b42009-08-18 18:06:22 +0100127#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
Jonathan Cameron73bce122010-07-11 16:39:19 +0100151 * @helper: data and func pointer allowing generic functions
Jonathan Cameron66533b42009-08-18 18:06:22 +0100152 * @us: actual spi_device
Jonathan Camerond0348e52010-06-26 12:54:15 +0100153 * @work_thresh: bh for threshold events
Jonathan Cameronb98c9e62010-07-29 17:50:47 +0100154 * @thresh_timestamp: timestamp for threshold interrupts.
Jonathan Cameron66533b42009-08-18 18:06:22 +0100155 * @inter: used to check if new interrupt has been triggered
Jonathan Cameron66533b42009-08-18 18:06:22 +0100156 * @trig: data ready trigger registered with iio
157 * @tx: transmit buffer
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300158 * @rx: receive buffer
Jonathan Cameron66533b42009-08-18 18:06:22 +0100159 * @buf_lock: mutex to protect tx and rx
160 **/
161struct lis3l02dq_state {
Jonathan Cameron73bce122010-07-11 16:39:19 +0100162 struct iio_sw_ring_helper_state help;
Jonathan Cameron66533b42009-08-18 18:06:22 +0100163 struct spi_device *us;
Jonathan Camerond0348e52010-06-26 12:54:15 +0100164 struct work_struct work_thresh;
Jonathan Cameronb98c9e62010-07-29 17:50:47 +0100165 s64 thresh_timestamp;
Jonathan Cameron66533b42009-08-18 18:06:22 +0100166 bool inter;
Jonathan Cameron66533b42009-08-18 18:06:22 +0100167 struct iio_trigger *trig;
168 u8 *tx;
169 u8 *rx;
170 struct mutex buf_lock;
171};
172
Jonathan Cameron73bce122010-07-11 16:39:19 +0100173#define lis3l02dq_h_to_s(_h) \
174 container_of(_h, struct lis3l02dq_state, help)
175
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100176int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
Jonathan Cameron66533b42009-08-18 18:06:22 +0100177 u8 reg_address,
178 u8 *val);
179
Jonathan Cameron1b076b52011-05-18 14:40:58 +0100180int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
Jonathan Cameron66533b42009-08-18 18:06:22 +0100181 u8 reg_address,
182 u8 *val);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100183
184#ifdef CONFIG_IIO_RING_BUFFER
185/* At the moment triggers are only used for ring buffer
186 * filling. This may change!
187 */
188void lis3l02dq_remove_trigger(struct iio_dev *indio_dev);
189int lis3l02dq_probe_trigger(struct iio_dev *indio_dev);
190
Jonathan Cameronf3736412011-05-18 14:40:52 +0100191ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
192 int index,
193 int *val);
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100194
195
196int lis3l02dq_configure_ring(struct iio_dev *indio_dev);
197void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev);
198
Jonathan Cameronb9497932011-02-11 13:09:11 +0000199#ifdef CONFIG_LIS3L02DQ_BUF_RING_SW
200#define lis3l02dq_free_buf iio_sw_rb_free
201#define lis3l02dq_alloc_buf iio_sw_rb_allocate
202#define lis3l02dq_register_buf_funcs iio_ring_sw_register_funcs
203#endif
204#ifdef CONFIG_LIS3L02DQ_BUF_KFIFO
205#define lis3l02dq_free_buf iio_kfifo_free
206#define lis3l02dq_alloc_buf iio_kfifo_allocate
207#define lis3l02dq_register_buf_funcs iio_kfifo_register_funcs
208#endif
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100209#else /* CONFIG_IIO_RING_BUFFER */
210
Mike Frysingerc608cb02010-05-23 03:10:30 -0400211static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
212{
213}
Jonathan Cameron66533b42009-08-18 18:06:22 +0100214static inline int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
215{
216 return 0;
Mike Frysingerc608cb02010-05-23 03:10:30 -0400217}
Jonathan Cameron66533b42009-08-18 18:06:22 +0100218static inline ssize_t
Jonathan Cameronf3736412011-05-18 14:40:52 +0100219lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
220 int index,
221 int *val)
Jonathan Cameron66533b42009-08-18 18:06:22 +0100222{
223 return 0;
Mike Frysingerc608cb02010-05-23 03:10:30 -0400224}
Jonathan Cameron66533b42009-08-18 18:06:22 +0100225
226static int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
227{
228 return 0;
Mike Frysingerc608cb02010-05-23 03:10:30 -0400229}
Jonathan Cameron66533b42009-08-18 18:06:22 +0100230static inline void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
Mike Frysingerc608cb02010-05-23 03:10:30 -0400231{
232}
Jonathan Cameron14cd9a72009-08-18 18:06:28 +0100233#endif /* CONFIG_IIO_RING_BUFFER */
Jonathan Cameron66533b42009-08-18 18:06:22 +0100234#endif /* SPI_LIS3L02DQ_H_ */