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. 126Form 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 * @helper: data and func pointer allowing generic functions 152 * @us: actual spi_device 153 * @work_thresh: bh for threshold events 154 * @thresh_timestamp: timestamp for threshold interrupts. 155 * @inter: used to check if new interrupt has been triggered 156 * @trig: data ready trigger registered with iio 157 * @tx: transmit buffer 158 * @rx: recieve buffer 159 * @buf_lock: mutex to protect tx and rx 160 **/ 161struct lis3l02dq_state { 162 struct iio_sw_ring_helper_state help; 163 struct spi_device *us; 164 struct work_struct work_thresh; 165 s64 thresh_timestamp; 166 bool inter; 167 struct iio_trigger *trig; 168 u8 *tx; 169 u8 *rx; 170 struct mutex buf_lock; 171}; 172 173#define lis3l02dq_h_to_s(_h) \ 174 container_of(_h, struct lis3l02dq_state, help) 175 176int lis3l02dq_spi_read_reg_8(struct device *dev, 177 u8 reg_address, 178 u8 *val); 179 180int lis3l02dq_spi_write_reg_8(struct device *dev, 181 u8 reg_address, 182 u8 *val); 183 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 191ssize_t lis3l02dq_read_accel_from_ring(struct device *dev, 192 struct device_attribute *attr, 193 char *buf); 194 195 196int lis3l02dq_configure_ring(struct iio_dev *indio_dev); 197void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev); 198 199#else /* CONFIG_IIO_RING_BUFFER */ 200 201static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) 202{ 203} 204static inline int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) 205{ 206 return 0; 207} 208 209static inline ssize_t 210lis3l02dq_read_accel_from_ring(struct device *dev, 211 struct device_attribute *attr, 212 char *buf) 213{ 214 return 0; 215} 216 217static int lis3l02dq_configure_ring(struct iio_dev *indio_dev) 218{ 219 return 0; 220} 221static inline void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev) 222{ 223} 224#endif /* CONFIG_IIO_RING_BUFFER */ 225#endif /* SPI_LIS3L02DQ_H_ */ 226