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)201static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) 202 { 203 } lis3l02dq_probe_trigger(struct iio_dev * indio_dev)204static inline int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) 205 { 206 return 0; 207 } 208 lis3l02dq_configure_buffer(struct iio_dev * indio_dev)209static int lis3l02dq_configure_buffer(struct iio_dev *indio_dev) 210 { 211 return 0; 212 } lis3l02dq_unconfigure_buffer(struct iio_dev * indio_dev)213static inline void lis3l02dq_unconfigure_buffer(struct iio_dev *indio_dev) 214 { 215 } 216 #endif /* CONFIG_IIO_BUFFER */ 217 #endif /* SPI_LIS3L02DQ_H_ */ 218